diff options
439 files changed, 10433 insertions, 15637 deletions
diff --git a/Documentation/BUG-HUNTING b/Documentation/BUG-HUNTING index 6c816751b868..65022a87bf17 100644 --- a/Documentation/BUG-HUNTING +++ b/Documentation/BUG-HUNTING | |||
@@ -214,6 +214,23 @@ And recompile the kernel with CONFIG_DEBUG_INFO enabled: | |||
214 | gdb vmlinux | 214 | gdb vmlinux |
215 | (gdb) p vt_ioctl | 215 | (gdb) p vt_ioctl |
216 | (gdb) l *(0x<address of vt_ioctl> + 0xda8) | 216 | (gdb) l *(0x<address of vt_ioctl> + 0xda8) |
217 | or, as one command | ||
218 | (gdb) l *(vt_ioctl + 0xda8) | ||
219 | |||
220 | If you have a call trace, such as :- | ||
221 | >Call Trace: | ||
222 | > [<ffffffff8802c8e9>] :jbd:log_wait_commit+0xa3/0xf5 | ||
223 | > [<ffffffff810482d9>] autoremove_wake_function+0x0/0x2e | ||
224 | > [<ffffffff8802770b>] :jbd:journal_stop+0x1be/0x1ee | ||
225 | > ... | ||
226 | this shows the problem in the :jbd: module. You can load that module in gdb | ||
227 | and list the relevant code. | ||
228 | gdb fs/jbd/jbd.ko | ||
229 | (gdb) p log_wait_commit | ||
230 | (gdb) l *(0x<address> + 0xa3) | ||
231 | or | ||
232 | (gdb) l *(log_wait_commit + 0xa3) | ||
233 | |||
217 | 234 | ||
218 | Another very useful option of the Kernel Hacking section in menuconfig is | 235 | Another very useful option of the Kernel Hacking section in menuconfig is |
219 | Debug memory allocations. This will help you see whether data has been | 236 | Debug memory allocations. This will help you see whether data has been |
diff --git a/Documentation/DocBook/kernel-locking.tmpl b/Documentation/DocBook/kernel-locking.tmpl index 01825ee7db64..2e9d6b41f034 100644 --- a/Documentation/DocBook/kernel-locking.tmpl +++ b/Documentation/DocBook/kernel-locking.tmpl | |||
@@ -717,7 +717,7 @@ used, and when it gets full, throws out the least used one. | |||
717 | <para> | 717 | <para> |
718 | For our first example, we assume that all operations are in user | 718 | For our first example, we assume that all operations are in user |
719 | context (ie. from system calls), so we can sleep. This means we can | 719 | context (ie. from system calls), so we can sleep. This means we can |
720 | use a semaphore to protect the cache and all the objects within | 720 | use a mutex to protect the cache and all the objects within |
721 | it. Here's the code: | 721 | it. Here's the code: |
722 | </para> | 722 | </para> |
723 | 723 | ||
@@ -725,7 +725,7 @@ it. Here's the code: | |||
725 | #include <linux/list.h> | 725 | #include <linux/list.h> |
726 | #include <linux/slab.h> | 726 | #include <linux/slab.h> |
727 | #include <linux/string.h> | 727 | #include <linux/string.h> |
728 | #include <asm/semaphore.h> | 728 | #include <linux/mutex.h> |
729 | #include <asm/errno.h> | 729 | #include <asm/errno.h> |
730 | 730 | ||
731 | struct object | 731 | struct object |
@@ -737,7 +737,7 @@ struct object | |||
737 | }; | 737 | }; |
738 | 738 | ||
739 | /* Protects the cache, cache_num, and the objects within it */ | 739 | /* Protects the cache, cache_num, and the objects within it */ |
740 | static DECLARE_MUTEX(cache_lock); | 740 | static DEFINE_MUTEX(cache_lock); |
741 | static LIST_HEAD(cache); | 741 | static LIST_HEAD(cache); |
742 | static unsigned int cache_num = 0; | 742 | static unsigned int cache_num = 0; |
743 | #define MAX_CACHE_SIZE 10 | 743 | #define MAX_CACHE_SIZE 10 |
@@ -789,17 +789,17 @@ int cache_add(int id, const char *name) | |||
789 | obj->id = id; | 789 | obj->id = id; |
790 | obj->popularity = 0; | 790 | obj->popularity = 0; |
791 | 791 | ||
792 | down(&cache_lock); | 792 | mutex_lock(&cache_lock); |
793 | __cache_add(obj); | 793 | __cache_add(obj); |
794 | up(&cache_lock); | 794 | mutex_unlock(&cache_lock); |
795 | return 0; | 795 | return 0; |
796 | } | 796 | } |
797 | 797 | ||
798 | void cache_delete(int id) | 798 | void cache_delete(int id) |
799 | { | 799 | { |
800 | down(&cache_lock); | 800 | mutex_lock(&cache_lock); |
801 | __cache_delete(__cache_find(id)); | 801 | __cache_delete(__cache_find(id)); |
802 | up(&cache_lock); | 802 | mutex_unlock(&cache_lock); |
803 | } | 803 | } |
804 | 804 | ||
805 | int cache_find(int id, char *name) | 805 | int cache_find(int id, char *name) |
@@ -807,13 +807,13 @@ int cache_find(int id, char *name) | |||
807 | struct object *obj; | 807 | struct object *obj; |
808 | int ret = -ENOENT; | 808 | int ret = -ENOENT; |
809 | 809 | ||
810 | down(&cache_lock); | 810 | mutex_lock(&cache_lock); |
811 | obj = __cache_find(id); | 811 | obj = __cache_find(id); |
812 | if (obj) { | 812 | if (obj) { |
813 | ret = 0; | 813 | ret = 0; |
814 | strcpy(name, obj->name); | 814 | strcpy(name, obj->name); |
815 | } | 815 | } |
816 | up(&cache_lock); | 816 | mutex_unlock(&cache_lock); |
817 | return ret; | 817 | return ret; |
818 | } | 818 | } |
819 | </programlisting> | 819 | </programlisting> |
@@ -853,7 +853,7 @@ The change is shown below, in standard patch format: the | |||
853 | int popularity; | 853 | int popularity; |
854 | }; | 854 | }; |
855 | 855 | ||
856 | -static DECLARE_MUTEX(cache_lock); | 856 | -static DEFINE_MUTEX(cache_lock); |
857 | +static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; | 857 | +static spinlock_t cache_lock = SPIN_LOCK_UNLOCKED; |
858 | static LIST_HEAD(cache); | 858 | static LIST_HEAD(cache); |
859 | static unsigned int cache_num = 0; | 859 | static unsigned int cache_num = 0; |
@@ -870,22 +870,22 @@ The change is shown below, in standard patch format: the | |||
870 | obj->id = id; | 870 | obj->id = id; |
871 | obj->popularity = 0; | 871 | obj->popularity = 0; |
872 | 872 | ||
873 | - down(&cache_lock); | 873 | - mutex_lock(&cache_lock); |
874 | + spin_lock_irqsave(&cache_lock, flags); | 874 | + spin_lock_irqsave(&cache_lock, flags); |
875 | __cache_add(obj); | 875 | __cache_add(obj); |
876 | - up(&cache_lock); | 876 | - mutex_unlock(&cache_lock); |
877 | + spin_unlock_irqrestore(&cache_lock, flags); | 877 | + spin_unlock_irqrestore(&cache_lock, flags); |
878 | return 0; | 878 | return 0; |
879 | } | 879 | } |
880 | 880 | ||
881 | void cache_delete(int id) | 881 | void cache_delete(int id) |
882 | { | 882 | { |
883 | - down(&cache_lock); | 883 | - mutex_lock(&cache_lock); |
884 | + unsigned long flags; | 884 | + unsigned long flags; |
885 | + | 885 | + |
886 | + spin_lock_irqsave(&cache_lock, flags); | 886 | + spin_lock_irqsave(&cache_lock, flags); |
887 | __cache_delete(__cache_find(id)); | 887 | __cache_delete(__cache_find(id)); |
888 | - up(&cache_lock); | 888 | - mutex_unlock(&cache_lock); |
889 | + spin_unlock_irqrestore(&cache_lock, flags); | 889 | + spin_unlock_irqrestore(&cache_lock, flags); |
890 | } | 890 | } |
891 | 891 | ||
@@ -895,14 +895,14 @@ The change is shown below, in standard patch format: the | |||
895 | int ret = -ENOENT; | 895 | int ret = -ENOENT; |
896 | + unsigned long flags; | 896 | + unsigned long flags; |
897 | 897 | ||
898 | - down(&cache_lock); | 898 | - mutex_lock(&cache_lock); |
899 | + spin_lock_irqsave(&cache_lock, flags); | 899 | + spin_lock_irqsave(&cache_lock, flags); |
900 | obj = __cache_find(id); | 900 | obj = __cache_find(id); |
901 | if (obj) { | 901 | if (obj) { |
902 | ret = 0; | 902 | ret = 0; |
903 | strcpy(name, obj->name); | 903 | strcpy(name, obj->name); |
904 | } | 904 | } |
905 | - up(&cache_lock); | 905 | - mutex_unlock(&cache_lock); |
906 | + spin_unlock_irqrestore(&cache_lock, flags); | 906 | + spin_unlock_irqrestore(&cache_lock, flags); |
907 | return ret; | 907 | return ret; |
908 | } | 908 | } |
diff --git a/Documentation/fb/deferred_io.txt b/Documentation/fb/deferred_io.txt index 63883a892120..748328370250 100644 --- a/Documentation/fb/deferred_io.txt +++ b/Documentation/fb/deferred_io.txt | |||
@@ -7,10 +7,10 @@ IO. The following example may be a useful explanation of how one such setup | |||
7 | works: | 7 | works: |
8 | 8 | ||
9 | - userspace app like Xfbdev mmaps framebuffer | 9 | - userspace app like Xfbdev mmaps framebuffer |
10 | - deferred IO and driver sets up nopage and page_mkwrite handlers | 10 | - deferred IO and driver sets up fault and page_mkwrite handlers |
11 | - userspace app tries to write to mmaped vaddress | 11 | - userspace app tries to write to mmaped vaddress |
12 | - we get pagefault and reach nopage handler | 12 | - we get pagefault and reach fault handler |
13 | - nopage handler finds and returns physical page | 13 | - fault handler finds and returns physical page |
14 | - we get page_mkwrite where we add this page to a list | 14 | - we get page_mkwrite where we add this page to a list |
15 | - schedule a workqueue task to be run after a delay | 15 | - schedule a workqueue task to be run after a delay |
16 | - app continues writing to that page with no additional cost. this is | 16 | - app continues writing to that page with no additional cost. this is |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a7d9d179131a..68ce1300a360 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -208,13 +208,6 @@ Who: Randy Dunlap <randy.dunlap@oracle.com> | |||
208 | 208 | ||
209 | --------------------------- | 209 | --------------------------- |
210 | 210 | ||
211 | What: drivers depending on OSS_OBSOLETE | ||
212 | When: options in 2.6.23, code in 2.6.25 | ||
213 | Why: obsolete OSS drivers | ||
214 | Who: Adrian Bunk <bunk@stusta.de> | ||
215 | |||
216 | --------------------------- | ||
217 | |||
218 | What: libata spindown skipping and warning | 211 | What: libata spindown skipping and warning |
219 | When: Dec 2008 | 212 | When: Dec 2008 |
220 | Why: Some halt(8) implementations synchronize caches for and spin | 213 | Why: Some halt(8) implementations synchronize caches for and spin |
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index e2799b5fafea..5681e2fa1496 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -1029,6 +1029,14 @@ nr_inodes | |||
1029 | Denotes the number of inodes the system has allocated. This number will | 1029 | Denotes the number of inodes the system has allocated. This number will |
1030 | grow and shrink dynamically. | 1030 | grow and shrink dynamically. |
1031 | 1031 | ||
1032 | nr_open | ||
1033 | ------- | ||
1034 | |||
1035 | Denotes the maximum number of file-handles a process can | ||
1036 | allocate. Default value is 1024*1024 (1048576) which should be | ||
1037 | enough for most machines. Actual limit depends on RLIMIT_NOFILE | ||
1038 | resource limit. | ||
1039 | |||
1032 | nr_free_inodes | 1040 | nr_free_inodes |
1033 | -------------- | 1041 | -------------- |
1034 | 1042 | ||
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9ad4e6fc56fd..8fd5aa40585f 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -780,6 +780,9 @@ and is between 256 and 4096 characters. It is defined in the file | |||
780 | loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same | 780 | loop use the MONITOR/MWAIT idle loop anyways. Performance should be the same |
781 | as idle=poll. | 781 | as idle=poll. |
782 | 782 | ||
783 | ide-pci-generic.all-generic-ide [HW] (E)IDE subsystem | ||
784 | Claim all unknown PCI IDE storage controllers. | ||
785 | |||
783 | ignore_loglevel [KNL] | 786 | ignore_loglevel [KNL] |
784 | Ignore loglevel setting - this will print /all/ | 787 | Ignore loglevel setting - this will print /all/ |
785 | kernel messages to the console. Useful for debugging. | 788 | kernel messages to the console. Useful for debugging. |
diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 53a63890aea4..30c101761d0d 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt | |||
@@ -96,7 +96,9 @@ or in registers (e.g., for x86_64 or for an i386 fastcall function). | |||
96 | The jprobe will work in either case, so long as the handler's | 96 | The jprobe will work in either case, so long as the handler's |
97 | prototype matches that of the probed function. | 97 | prototype matches that of the probed function. |
98 | 98 | ||
99 | 1.3 How Does a Return Probe Work? | 99 | 1.3 Return Probes |
100 | |||
101 | 1.3.1 How Does a Return Probe Work? | ||
100 | 102 | ||
101 | When you call register_kretprobe(), Kprobes establishes a kprobe at | 103 | When you call register_kretprobe(), Kprobes establishes a kprobe at |
102 | the entry to the function. When the probed function is called and this | 104 | the entry to the function. When the probed function is called and this |
@@ -107,9 +109,9 @@ At boot time, Kprobes registers a kprobe at the trampoline. | |||
107 | 109 | ||
108 | When the probed function executes its return instruction, control | 110 | When the probed function executes its return instruction, control |
109 | passes to the trampoline and that probe is hit. Kprobes' trampoline | 111 | passes to the trampoline and that probe is hit. Kprobes' trampoline |
110 | handler calls the user-specified handler associated with the kretprobe, | 112 | handler calls the user-specified return handler associated with the |
111 | then sets the saved instruction pointer to the saved return address, | 113 | kretprobe, then sets the saved instruction pointer to the saved return |
112 | and that's where execution resumes upon return from the trap. | 114 | address, and that's where execution resumes upon return from the trap. |
113 | 115 | ||
114 | While the probed function is executing, its return address is | 116 | While the probed function is executing, its return address is |
115 | stored in an object of type kretprobe_instance. Before calling | 117 | stored in an object of type kretprobe_instance. Before calling |
@@ -131,6 +133,30 @@ zero when the return probe is registered, and is incremented every | |||
131 | time the probed function is entered but there is no kretprobe_instance | 133 | time the probed function is entered but there is no kretprobe_instance |
132 | object available for establishing the return probe. | 134 | object available for establishing the return probe. |
133 | 135 | ||
136 | 1.3.2 Kretprobe entry-handler | ||
137 | |||
138 | Kretprobes also provides an optional user-specified handler which runs | ||
139 | on function entry. This handler is specified by setting the entry_handler | ||
140 | field of the kretprobe struct. Whenever the kprobe placed by kretprobe at the | ||
141 | function entry is hit, the user-defined entry_handler, if any, is invoked. | ||
142 | If the entry_handler returns 0 (success) then a corresponding return handler | ||
143 | is guaranteed to be called upon function return. If the entry_handler | ||
144 | returns a non-zero error then Kprobes leaves the return address as is, and | ||
145 | the kretprobe has no further effect for that particular function instance. | ||
146 | |||
147 | Multiple entry and return handler invocations are matched using the unique | ||
148 | kretprobe_instance object associated with them. Additionally, a user | ||
149 | may also specify per return-instance private data to be part of each | ||
150 | kretprobe_instance object. This is especially useful when sharing private | ||
151 | data between corresponding user entry and return handlers. The size of each | ||
152 | private data object can be specified at kretprobe registration time by | ||
153 | setting the data_size field of the kretprobe struct. This data can be | ||
154 | accessed through the data field of each kretprobe_instance object. | ||
155 | |||
156 | In case probed function is entered but there is no kretprobe_instance | ||
157 | object available, then in addition to incrementing the nmissed count, | ||
158 | the user entry_handler invocation is also skipped. | ||
159 | |||
134 | 2. Architectures Supported | 160 | 2. Architectures Supported |
135 | 161 | ||
136 | Kprobes, jprobes, and return probes are implemented on the following | 162 | Kprobes, jprobes, and return probes are implemented on the following |
@@ -274,6 +300,8 @@ of interest: | |||
274 | - ret_addr: the return address | 300 | - ret_addr: the return address |
275 | - rp: points to the corresponding kretprobe object | 301 | - rp: points to the corresponding kretprobe object |
276 | - task: points to the corresponding task struct | 302 | - task: points to the corresponding task struct |
303 | - data: points to per return-instance private data; see "Kretprobe | ||
304 | entry-handler" for details. | ||
277 | 305 | ||
278 | The regs_return_value(regs) macro provides a simple abstraction to | 306 | The regs_return_value(regs) macro provides a simple abstraction to |
279 | extract the return value from the appropriate register as defined by | 307 | extract the return value from the appropriate register as defined by |
@@ -556,23 +584,52 @@ report failed calls to sys_open(). | |||
556 | #include <linux/kernel.h> | 584 | #include <linux/kernel.h> |
557 | #include <linux/module.h> | 585 | #include <linux/module.h> |
558 | #include <linux/kprobes.h> | 586 | #include <linux/kprobes.h> |
587 | #include <linux/ktime.h> | ||
588 | |||
589 | /* per-instance private data */ | ||
590 | struct my_data { | ||
591 | ktime_t entry_stamp; | ||
592 | }; | ||
559 | 593 | ||
560 | static const char *probed_func = "sys_open"; | 594 | static const char *probed_func = "sys_open"; |
561 | 595 | ||
562 | /* Return-probe handler: If the probed function fails, log the return value. */ | 596 | /* Timestamp function entry. */ |
563 | static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | 597 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) |
598 | { | ||
599 | struct my_data *data; | ||
600 | |||
601 | if(!current->mm) | ||
602 | return 1; /* skip kernel threads */ | ||
603 | |||
604 | data = (struct my_data *)ri->data; | ||
605 | data->entry_stamp = ktime_get(); | ||
606 | return 0; | ||
607 | } | ||
608 | |||
609 | /* If the probed function failed, log the return value and duration. | ||
610 | * Duration may turn out to be zero consistently, depending upon the | ||
611 | * granularity of time accounting on the platform. */ | ||
612 | static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
564 | { | 613 | { |
565 | int retval = regs_return_value(regs); | 614 | int retval = regs_return_value(regs); |
615 | struct my_data *data = (struct my_data *)ri->data; | ||
616 | s64 delta; | ||
617 | ktime_t now; | ||
618 | |||
566 | if (retval < 0) { | 619 | if (retval < 0) { |
567 | printk("%s returns %d\n", probed_func, retval); | 620 | now = ktime_get(); |
621 | delta = ktime_to_ns(ktime_sub(now, data->entry_stamp)); | ||
622 | printk("%s: return val = %d (duration = %lld ns)\n", | ||
623 | probed_func, retval, delta); | ||
568 | } | 624 | } |
569 | return 0; | 625 | return 0; |
570 | } | 626 | } |
571 | 627 | ||
572 | static struct kretprobe my_kretprobe = { | 628 | static struct kretprobe my_kretprobe = { |
573 | .handler = ret_handler, | 629 | .handler = return_handler, |
574 | /* Probe up to 20 instances concurrently. */ | 630 | .entry_handler = entry_handler, |
575 | .maxactive = 20 | 631 | .data_size = sizeof(struct my_data), |
632 | .maxactive = 20, /* probe up to 20 instances concurrently */ | ||
576 | }; | 633 | }; |
577 | 634 | ||
578 | static int __init kretprobe_init(void) | 635 | static int __init kretprobe_init(void) |
@@ -584,7 +641,7 @@ static int __init kretprobe_init(void) | |||
584 | printk("register_kretprobe failed, returned %d\n", ret); | 641 | printk("register_kretprobe failed, returned %d\n", ret); |
585 | return -1; | 642 | return -1; |
586 | } | 643 | } |
587 | printk("Planted return probe at %p\n", my_kretprobe.kp.addr); | 644 | printk("Kretprobe active on %s\n", my_kretprobe.kp.symbol_name); |
588 | return 0; | 645 | return 0; |
589 | } | 646 | } |
590 | 647 | ||
@@ -594,7 +651,7 @@ static void __exit kretprobe_exit(void) | |||
594 | printk("kretprobe unregistered\n"); | 651 | printk("kretprobe unregistered\n"); |
595 | /* nmissed > 0 suggests that maxactive was set too low. */ | 652 | /* nmissed > 0 suggests that maxactive was set too low. */ |
596 | printk("Missed probing %d instances of %s\n", | 653 | printk("Missed probing %d instances of %s\n", |
597 | my_kretprobe.nmissed, probed_func); | 654 | my_kretprobe.nmissed, probed_func); |
598 | } | 655 | } |
599 | 656 | ||
600 | module_init(kretprobe_init) | 657 | module_init(kretprobe_init) |
diff --git a/Documentation/kref.txt b/Documentation/kref.txt index f38b59d00c63..130b6e87aa7e 100644 --- a/Documentation/kref.txt +++ b/Documentation/kref.txt | |||
@@ -141,10 +141,10 @@ The last rule (rule 3) is the nastiest one to handle. Say, for | |||
141 | instance, you have a list of items that are each kref-ed, and you wish | 141 | instance, you have a list of items that are each kref-ed, and you wish |
142 | to get the first one. You can't just pull the first item off the list | 142 | to get the first one. You can't just pull the first item off the list |
143 | and kref_get() it. That violates rule 3 because you are not already | 143 | and kref_get() it. That violates rule 3 because you are not already |
144 | holding a valid pointer. You must add locks or semaphores. For | 144 | holding a valid pointer. You must add a mutex (or some other lock). |
145 | instance: | 145 | For instance: |
146 | 146 | ||
147 | static DECLARE_MUTEX(sem); | 147 | static DEFINE_MUTEX(mutex); |
148 | static LIST_HEAD(q); | 148 | static LIST_HEAD(q); |
149 | struct my_data | 149 | struct my_data |
150 | { | 150 | { |
@@ -155,12 +155,12 @@ struct my_data | |||
155 | static struct my_data *get_entry() | 155 | static struct my_data *get_entry() |
156 | { | 156 | { |
157 | struct my_data *entry = NULL; | 157 | struct my_data *entry = NULL; |
158 | down(&sem); | 158 | mutex_lock(&mutex); |
159 | if (!list_empty(&q)) { | 159 | if (!list_empty(&q)) { |
160 | entry = container_of(q.next, struct my_q_entry, link); | 160 | entry = container_of(q.next, struct my_q_entry, link); |
161 | kref_get(&entry->refcount); | 161 | kref_get(&entry->refcount); |
162 | } | 162 | } |
163 | up(&sem); | 163 | mutex_unlock(&mutex); |
164 | return entry; | 164 | return entry; |
165 | } | 165 | } |
166 | 166 | ||
@@ -174,9 +174,9 @@ static void release_entry(struct kref *ref) | |||
174 | 174 | ||
175 | static void put_entry(struct my_data *entry) | 175 | static void put_entry(struct my_data *entry) |
176 | { | 176 | { |
177 | down(&sem); | 177 | mutex_lock(&mutex); |
178 | kref_put(&entry->refcount, release_entry); | 178 | kref_put(&entry->refcount, release_entry); |
179 | up(&sem); | 179 | mutex_unlock(&mutex); |
180 | } | 180 | } |
181 | 181 | ||
182 | The kref_put() return value is useful if you do not want to hold the | 182 | The kref_put() return value is useful if you do not want to hold the |
@@ -191,13 +191,13 @@ static void release_entry(struct kref *ref) | |||
191 | 191 | ||
192 | static void put_entry(struct my_data *entry) | 192 | static void put_entry(struct my_data *entry) |
193 | { | 193 | { |
194 | down(&sem); | 194 | mutex_lock(&mutex); |
195 | if (kref_put(&entry->refcount, release_entry)) { | 195 | if (kref_put(&entry->refcount, release_entry)) { |
196 | list_del(&entry->link); | 196 | list_del(&entry->link); |
197 | up(&sem); | 197 | mutex_unlock(&mutex); |
198 | kfree(entry); | 198 | kfree(entry); |
199 | } else | 199 | } else |
200 | up(&sem); | 200 | mutex_unlock(&mutex); |
201 | } | 201 | } |
202 | 202 | ||
203 | This is really more useful if you have to call other routines as part | 203 | This is really more useful if you have to call other routines as part |
diff --git a/Documentation/md.txt b/Documentation/md.txt index 5818628207b5..396cdd982c26 100644 --- a/Documentation/md.txt +++ b/Documentation/md.txt | |||
@@ -416,6 +416,16 @@ also have | |||
416 | sectors in total that could need to be processed. The two | 416 | sectors in total that could need to be processed. The two |
417 | numbers are separated by a '/' thus effectively showing one | 417 | numbers are separated by a '/' thus effectively showing one |
418 | value, a fraction of the process that is complete. | 418 | value, a fraction of the process that is complete. |
419 | A 'select' on this attribute will return when resync completes, | ||
420 | when it reaches the current sync_max (below) and possibly at | ||
421 | other times. | ||
422 | |||
423 | sync_max | ||
424 | This is a number of sectors at which point a resync/recovery | ||
425 | process will pause. When a resync is active, the value can | ||
426 | only ever be increased, never decreased. The value of 'max' | ||
427 | effectively disables the limit. | ||
428 | |||
419 | 429 | ||
420 | sync_speed | 430 | sync_speed |
421 | This shows the current actual speed, in K/sec, of the current | 431 | This shows the current actual speed, in K/sec, of the current |
diff --git a/Documentation/rtc.txt b/Documentation/rtc.txt index e20b19c1b60d..8deffcd68cb8 100644 --- a/Documentation/rtc.txt +++ b/Documentation/rtc.txt | |||
@@ -182,8 +182,8 @@ driver returns ENOIOCTLCMD. Some common examples: | |||
182 | since the frequency is stored in the irq_freq member of the rtc_device | 182 | since the frequency is stored in the irq_freq member of the rtc_device |
183 | structure. Your driver needs to initialize the irq_freq member during | 183 | structure. Your driver needs to initialize the irq_freq member during |
184 | init. Make sure you check the requested frequency is in range of your | 184 | init. Make sure you check the requested frequency is in range of your |
185 | hardware in the irq_set_freq function. If you cannot actually change | 185 | hardware in the irq_set_freq function. If it isn't, return -EINVAL. If |
186 | the frequency, just return -ENOTTY. | 186 | you cannot actually change the frequency, do not define irq_set_freq. |
187 | 187 | ||
188 | If all else fails, check out the rtc-test.c driver! | 188 | If all else fails, check out the rtc-test.c driver! |
189 | 189 | ||
@@ -268,8 +268,8 @@ int main(int argc, char **argv) | |||
268 | /* This read will block */ | 268 | /* This read will block */ |
269 | retval = read(fd, &data, sizeof(unsigned long)); | 269 | retval = read(fd, &data, sizeof(unsigned long)); |
270 | if (retval == -1) { | 270 | if (retval == -1) { |
271 | perror("read"); | 271 | perror("read"); |
272 | exit(errno); | 272 | exit(errno); |
273 | } | 273 | } |
274 | fprintf(stderr, " %d",i); | 274 | fprintf(stderr, " %d",i); |
275 | fflush(stderr); | 275 | fflush(stderr); |
@@ -326,11 +326,11 @@ test_READ: | |||
326 | rtc_tm.tm_sec %= 60; | 326 | rtc_tm.tm_sec %= 60; |
327 | rtc_tm.tm_min++; | 327 | rtc_tm.tm_min++; |
328 | } | 328 | } |
329 | if (rtc_tm.tm_min == 60) { | 329 | if (rtc_tm.tm_min == 60) { |
330 | rtc_tm.tm_min = 0; | 330 | rtc_tm.tm_min = 0; |
331 | rtc_tm.tm_hour++; | 331 | rtc_tm.tm_hour++; |
332 | } | 332 | } |
333 | if (rtc_tm.tm_hour == 24) | 333 | if (rtc_tm.tm_hour == 24) |
334 | rtc_tm.tm_hour = 0; | 334 | rtc_tm.tm_hour = 0; |
335 | 335 | ||
336 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); | 336 | retval = ioctl(fd, RTC_ALM_SET, &rtc_tm); |
@@ -407,8 +407,8 @@ test_PIE: | |||
407 | "\n...Periodic IRQ rate is fixed\n"); | 407 | "\n...Periodic IRQ rate is fixed\n"); |
408 | goto done; | 408 | goto done; |
409 | } | 409 | } |
410 | perror("RTC_IRQP_SET ioctl"); | 410 | perror("RTC_IRQP_SET ioctl"); |
411 | exit(errno); | 411 | exit(errno); |
412 | } | 412 | } |
413 | 413 | ||
414 | fprintf(stderr, "\n%ldHz:\t", tmp); | 414 | fprintf(stderr, "\n%ldHz:\t", tmp); |
@@ -417,27 +417,27 @@ test_PIE: | |||
417 | /* Enable periodic interrupts */ | 417 | /* Enable periodic interrupts */ |
418 | retval = ioctl(fd, RTC_PIE_ON, 0); | 418 | retval = ioctl(fd, RTC_PIE_ON, 0); |
419 | if (retval == -1) { | 419 | if (retval == -1) { |
420 | perror("RTC_PIE_ON ioctl"); | 420 | perror("RTC_PIE_ON ioctl"); |
421 | exit(errno); | 421 | exit(errno); |
422 | } | 422 | } |
423 | 423 | ||
424 | for (i=1; i<21; i++) { | 424 | for (i=1; i<21; i++) { |
425 | /* This blocks */ | 425 | /* This blocks */ |
426 | retval = read(fd, &data, sizeof(unsigned long)); | 426 | retval = read(fd, &data, sizeof(unsigned long)); |
427 | if (retval == -1) { | 427 | if (retval == -1) { |
428 | perror("read"); | 428 | perror("read"); |
429 | exit(errno); | 429 | exit(errno); |
430 | } | 430 | } |
431 | fprintf(stderr, " %d",i); | 431 | fprintf(stderr, " %d",i); |
432 | fflush(stderr); | 432 | fflush(stderr); |
433 | irqcount++; | 433 | irqcount++; |
434 | } | 434 | } |
435 | 435 | ||
436 | /* Disable periodic interrupts */ | 436 | /* Disable periodic interrupts */ |
437 | retval = ioctl(fd, RTC_PIE_OFF, 0); | 437 | retval = ioctl(fd, RTC_PIE_OFF, 0); |
438 | if (retval == -1) { | 438 | if (retval == -1) { |
439 | perror("RTC_PIE_OFF ioctl"); | 439 | perror("RTC_PIE_OFF ioctl"); |
440 | exit(errno); | 440 | exit(errno); |
441 | } | 441 | } |
442 | } | 442 | } |
443 | 443 | ||
diff --git a/Documentation/sysctl/fs.txt b/Documentation/sysctl/fs.txt index aa986a35e994..f99254327ae5 100644 --- a/Documentation/sysctl/fs.txt +++ b/Documentation/sysctl/fs.txt | |||
@@ -23,6 +23,7 @@ Currently, these files are in /proc/sys/fs: | |||
23 | - inode-max | 23 | - inode-max |
24 | - inode-nr | 24 | - inode-nr |
25 | - inode-state | 25 | - inode-state |
26 | - nr_open | ||
26 | - overflowuid | 27 | - overflowuid |
27 | - overflowgid | 28 | - overflowgid |
28 | - suid_dumpable | 29 | - suid_dumpable |
@@ -91,6 +92,15 @@ usage of file handles and you don't need to increase the maximum. | |||
91 | 92 | ||
92 | ============================================================== | 93 | ============================================================== |
93 | 94 | ||
95 | nr_open: | ||
96 | |||
97 | This denotes the maximum number of file-handles a process can | ||
98 | allocate. Default value is 1024*1024 (1048576) which should be | ||
99 | enough for most machines. Actual limit depends on RLIMIT_NOFILE | ||
100 | resource limit. | ||
101 | |||
102 | ============================================================== | ||
103 | |||
94 | inode-max, inode-nr & inode-state: | 104 | inode-max, inode-nr & inode-state: |
95 | 105 | ||
96 | As with file handles, the kernel allocates the inode structures | 106 | As with file handles, the kernel allocates the inode structures |
diff --git a/Documentation/unaligned-memory-access.txt b/Documentation/unaligned-memory-access.txt new file mode 100644 index 000000000000..6223eace3c09 --- /dev/null +++ b/Documentation/unaligned-memory-access.txt | |||
@@ -0,0 +1,226 @@ | |||
1 | UNALIGNED MEMORY ACCESSES | ||
2 | ========================= | ||
3 | |||
4 | Linux runs on a wide variety of architectures which have varying behaviour | ||
5 | when it comes to memory access. This document presents some details about | ||
6 | unaligned accesses, why you need to write code that doesn't cause them, | ||
7 | and how to write such code! | ||
8 | |||
9 | |||
10 | The definition of an unaligned access | ||
11 | ===================================== | ||
12 | |||
13 | Unaligned memory accesses occur when you try to read N bytes of data starting | ||
14 | from an address that is not evenly divisible by N (i.e. addr % N != 0). | ||
15 | For example, reading 4 bytes of data from address 0x10004 is fine, but | ||
16 | reading 4 bytes of data from address 0x10005 would be an unaligned memory | ||
17 | access. | ||
18 | |||
19 | The above may seem a little vague, as memory access can happen in different | ||
20 | ways. The context here is at the machine code level: certain instructions read | ||
21 | or write a number of bytes to or from memory (e.g. movb, movw, movl in x86 | ||
22 | assembly). As will become clear, it is relatively easy to spot C statements | ||
23 | which will compile to multiple-byte memory access instructions, namely when | ||
24 | dealing with types such as u16, u32 and u64. | ||
25 | |||
26 | |||
27 | Natural alignment | ||
28 | ================= | ||
29 | |||
30 | The rule mentioned above forms what we refer to as natural alignment: | ||
31 | When accessing N bytes of memory, the base memory address must be evenly | ||
32 | divisible by N, i.e. addr % N == 0. | ||
33 | |||
34 | When writing code, assume the target architecture has natural alignment | ||
35 | requirements. | ||
36 | |||
37 | In reality, only a few architectures require natural alignment on all sizes | ||
38 | of memory access. However, we must consider ALL supported architectures; | ||
39 | writing code that satisfies natural alignment requirements is the easiest way | ||
40 | to achieve full portability. | ||
41 | |||
42 | |||
43 | Why unaligned access is bad | ||
44 | =========================== | ||
45 | |||
46 | The effects of performing an unaligned memory access vary from architecture | ||
47 | to architecture. It would be easy to write a whole document on the differences | ||
48 | here; a summary of the common scenarios is presented below: | ||
49 | |||
50 | - Some architectures are able to perform unaligned memory accesses | ||
51 | transparently, but there is usually a significant performance cost. | ||
52 | - Some architectures raise processor exceptions when unaligned accesses | ||
53 | happen. The exception handler is able to correct the unaligned access, | ||
54 | at significant cost to performance. | ||
55 | - Some architectures raise processor exceptions when unaligned accesses | ||
56 | happen, but the exceptions do not contain enough information for the | ||
57 | unaligned access to be corrected. | ||
58 | - Some architectures are not capable of unaligned memory access, but will | ||
59 | silently perform a different memory access to the one that was requested, | ||
60 | resulting a a subtle code bug that is hard to detect! | ||
61 | |||
62 | It should be obvious from the above that if your code causes unaligned | ||
63 | memory accesses to happen, your code will not work correctly on certain | ||
64 | platforms and will cause performance problems on others. | ||
65 | |||
66 | |||
67 | Code that does not cause unaligned access | ||
68 | ========================================= | ||
69 | |||
70 | At first, the concepts above may seem a little hard to relate to actual | ||
71 | coding practice. After all, you don't have a great deal of control over | ||
72 | memory addresses of certain variables, etc. | ||
73 | |||
74 | Fortunately things are not too complex, as in most cases, the compiler | ||
75 | ensures that things will work for you. For example, take the following | ||
76 | structure: | ||
77 | |||
78 | struct foo { | ||
79 | u16 field1; | ||
80 | u32 field2; | ||
81 | u8 field3; | ||
82 | }; | ||
83 | |||
84 | Let us assume that an instance of the above structure resides in memory | ||
85 | starting at address 0x10000. With a basic level of understanding, it would | ||
86 | not be unreasonable to expect that accessing field2 would cause an unaligned | ||
87 | access. You'd be expecting field2 to be located at offset 2 bytes into the | ||
88 | structure, i.e. address 0x10002, but that address is not evenly divisible | ||
89 | by 4 (remember, we're reading a 4 byte value here). | ||
90 | |||
91 | Fortunately, the compiler understands the alignment constraints, so in the | ||
92 | above case it would insert 2 bytes of padding in between field1 and field2. | ||
93 | Therefore, for standard structure types you can always rely on the compiler | ||
94 | to pad structures so that accesses to fields are suitably aligned (assuming | ||
95 | you do not cast the field to a type of different length). | ||
96 | |||
97 | Similarly, you can also rely on the compiler to align variables and function | ||
98 | parameters to a naturally aligned scheme, based on the size of the type of | ||
99 | the variable. | ||
100 | |||
101 | At this point, it should be clear that accessing a single byte (u8 or char) | ||
102 | will never cause an unaligned access, because all memory addresses are evenly | ||
103 | divisible by one. | ||
104 | |||
105 | On a related topic, with the above considerations in mind you may observe | ||
106 | that you could reorder the fields in the structure in order to place fields | ||
107 | where padding would otherwise be inserted, and hence reduce the overall | ||
108 | resident memory size of structure instances. The optimal layout of the | ||
109 | above example is: | ||
110 | |||
111 | struct foo { | ||
112 | u32 field2; | ||
113 | u16 field1; | ||
114 | u8 field3; | ||
115 | }; | ||
116 | |||
117 | For a natural alignment scheme, the compiler would only have to add a single | ||
118 | byte of padding at the end of the structure. This padding is added in order | ||
119 | to satisfy alignment constraints for arrays of these structures. | ||
120 | |||
121 | Another point worth mentioning is the use of __attribute__((packed)) on a | ||
122 | structure type. This GCC-specific attribute tells the compiler never to | ||
123 | insert any padding within structures, useful when you want to use a C struct | ||
124 | to represent some data that comes in a fixed arrangement 'off the wire'. | ||
125 | |||
126 | You might be inclined to believe that usage of this attribute can easily | ||
127 | lead to unaligned accesses when accessing fields that do not satisfy | ||
128 | architectural alignment requirements. However, again, the compiler is aware | ||
129 | of the alignment constraints and will generate extra instructions to perform | ||
130 | the memory access in a way that does not cause unaligned access. Of course, | ||
131 | the extra instructions obviously cause a loss in performance compared to the | ||
132 | non-packed case, so the packed attribute should only be used when avoiding | ||
133 | structure padding is of importance. | ||
134 | |||
135 | |||
136 | Code that causes unaligned access | ||
137 | ================================= | ||
138 | |||
139 | With the above in mind, let's move onto a real life example of a function | ||
140 | that can cause an unaligned memory access. The following function adapted | ||
141 | from include/linux/etherdevice.h is an optimized routine to compare two | ||
142 | ethernet MAC addresses for equality. | ||
143 | |||
144 | unsigned int compare_ether_addr(const u8 *addr1, const u8 *addr2) | ||
145 | { | ||
146 | const u16 *a = (const u16 *) addr1; | ||
147 | const u16 *b = (const u16 *) addr2; | ||
148 | return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) != 0; | ||
149 | } | ||
150 | |||
151 | In the above function, the reference to a[0] causes 2 bytes (16 bits) to | ||
152 | be read from memory starting at address addr1. Think about what would happen | ||
153 | if addr1 was an odd address such as 0x10003. (Hint: it'd be an unaligned | ||
154 | access.) | ||
155 | |||
156 | Despite the potential unaligned access problems with the above function, it | ||
157 | is included in the kernel anyway but is understood to only work on | ||
158 | 16-bit-aligned addresses. It is up to the caller to ensure this alignment or | ||
159 | not use this function at all. This alignment-unsafe function is still useful | ||
160 | as it is a decent optimization for the cases when you can ensure alignment, | ||
161 | which is true almost all of the time in ethernet networking context. | ||
162 | |||
163 | |||
164 | Here is another example of some code that could cause unaligned accesses: | ||
165 | void myfunc(u8 *data, u32 value) | ||
166 | { | ||
167 | [...] | ||
168 | *((u32 *) data) = cpu_to_le32(value); | ||
169 | [...] | ||
170 | } | ||
171 | |||
172 | This code will cause unaligned accesses every time the data parameter points | ||
173 | to an address that is not evenly divisible by 4. | ||
174 | |||
175 | In summary, the 2 main scenarios where you may run into unaligned access | ||
176 | problems involve: | ||
177 | 1. Casting variables to types of different lengths | ||
178 | 2. Pointer arithmetic followed by access to at least 2 bytes of data | ||
179 | |||
180 | |||
181 | Avoiding unaligned accesses | ||
182 | =========================== | ||
183 | |||
184 | The easiest way to avoid unaligned access is to use the get_unaligned() and | ||
185 | put_unaligned() macros provided by the <asm/unaligned.h> header file. | ||
186 | |||
187 | Going back to an earlier example of code that potentially causes unaligned | ||
188 | access: | ||
189 | |||
190 | void myfunc(u8 *data, u32 value) | ||
191 | { | ||
192 | [...] | ||
193 | *((u32 *) data) = cpu_to_le32(value); | ||
194 | [...] | ||
195 | } | ||
196 | |||
197 | To avoid the unaligned memory access, you would rewrite it as follows: | ||
198 | |||
199 | void myfunc(u8 *data, u32 value) | ||
200 | { | ||
201 | [...] | ||
202 | value = cpu_to_le32(value); | ||
203 | put_unaligned(value, (u32 *) data); | ||
204 | [...] | ||
205 | } | ||
206 | |||
207 | The get_unaligned() macro works similarly. Assuming 'data' is a pointer to | ||
208 | memory and you wish to avoid unaligned access, its usage is as follows: | ||
209 | |||
210 | u32 value = get_unaligned((u32 *) data); | ||
211 | |||
212 | These macros work work for memory accesses of any length (not just 32 bits as | ||
213 | in the examples above). Be aware that when compared to standard access of | ||
214 | aligned memory, using these macros to access unaligned memory can be costly in | ||
215 | terms of performance. | ||
216 | |||
217 | If use of such macros is not convenient, another option is to use memcpy(), | ||
218 | where the source or destination (or both) are of type u8* or unsigned char*. | ||
219 | Due to the byte-wise nature of this operation, unaligned accesses are avoided. | ||
220 | |||
221 | -- | ||
222 | Author: Daniel Drake <dsd@gentoo.org> | ||
223 | With help from: Alan Cox, Avuton Olrich, Heikki Orsila, Jan Engelhardt, | ||
224 | Johannes Berg, Kyle McMartin, Kyle Moffett, Randy Dunlap, Robert Hancock, | ||
225 | Uli Kunitz, Vadim Lobanov | ||
226 | |||
diff --git a/Documentation/w1/masters/00-INDEX b/Documentation/w1/masters/00-INDEX index 752613c4cea2..7b0ceaaad7af 100644 --- a/Documentation/w1/masters/00-INDEX +++ b/Documentation/w1/masters/00-INDEX | |||
@@ -4,3 +4,5 @@ ds2482 | |||
4 | - The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses. | 4 | - The Maxim/Dallas Semiconductor DS2482 provides 1-wire busses. |
5 | ds2490 | 5 | ds2490 |
6 | - The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges. | 6 | - The Maxim/Dallas Semiconductor DS2490 builds USB <-> W1 bridges. |
7 | w1-gpio | ||
8 | - GPIO 1-wire bus master driver. | ||
diff --git a/Documentation/w1/masters/w1-gpio b/Documentation/w1/masters/w1-gpio new file mode 100644 index 000000000000..af5d3b4aa851 --- /dev/null +++ b/Documentation/w1/masters/w1-gpio | |||
@@ -0,0 +1,33 @@ | |||
1 | Kernel driver w1-gpio | ||
2 | ===================== | ||
3 | |||
4 | Author: Ville Syrjala <syrjala@sci.fi> | ||
5 | |||
6 | |||
7 | Description | ||
8 | ----------- | ||
9 | |||
10 | GPIO 1-wire bus master driver. The driver uses the GPIO API to control the | ||
11 | wire and the GPIO pin can be specified using platform data. | ||
12 | |||
13 | |||
14 | Example (mach-at91) | ||
15 | ------------------- | ||
16 | |||
17 | #include <linux/w1-gpio.h> | ||
18 | |||
19 | static struct w1_gpio_platform_data foo_w1_gpio_pdata = { | ||
20 | .pin = AT91_PIN_PB20, | ||
21 | .is_open_drain = 1, | ||
22 | }; | ||
23 | |||
24 | static struct platform_device foo_w1_device = { | ||
25 | .name = "w1-gpio", | ||
26 | .id = -1, | ||
27 | .dev.platform_data = &foo_w1_gpio_pdata, | ||
28 | }; | ||
29 | |||
30 | ... | ||
31 | at91_set_GPIO_periph(foo_w1_gpio_pdata.pin, 1); | ||
32 | at91_set_multi_drive(foo_w1_gpio_pdata.pin, 1); | ||
33 | platform_device_register(&foo_w1_device); | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 4f3da8b56979..c5325d2bb86d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -338,13 +338,12 @@ S: Maintained for 2.4; PCI support for 2.6. | |||
338 | AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER | 338 | AMD GEODE CS5536 USB DEVICE CONTROLLER DRIVER |
339 | P: Thomas Dahlmann | 339 | P: Thomas Dahlmann |
340 | M: thomas.dahlmann@amd.com | 340 | M: thomas.dahlmann@amd.com |
341 | L: info-linux@geode.amd.com | 341 | L: info-linux@geode.amd.com (subscribers-only) |
342 | S: Supported | 342 | S: Supported |
343 | 343 | ||
344 | AMD GEODE PROCESSOR/CHIPSET SUPPORT | 344 | AMD GEODE PROCESSOR/CHIPSET SUPPORT |
345 | P: Jordan Crouse | 345 | P: Jordan Crouse |
346 | M: info-linux@geode.amd.com | 346 | L: info-linux@geode.amd.com (subscribers-only) |
347 | L: info-linux@geode.amd.com | ||
348 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html | 347 | W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html |
349 | S: Supported | 348 | S: Supported |
350 | 349 | ||
@@ -841,6 +840,12 @@ L: linux-kernel@vger.kernel.org | |||
841 | T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git | 840 | T: git kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git |
842 | S: Maintained | 841 | S: Maintained |
843 | 842 | ||
843 | BLOCK2MTD DRIVER | ||
844 | P: Joern Engel | ||
845 | M: joern@lazybastard.org | ||
846 | L: linux-mtd@lists.infradead.org | ||
847 | S: Maintained | ||
848 | |||
844 | BLUETOOTH SUBSYSTEM | 849 | BLUETOOTH SUBSYSTEM |
845 | P: Marcel Holtmann | 850 | P: Marcel Holtmann |
846 | M: marcel@holtmann.org | 851 | M: marcel@holtmann.org |
@@ -3031,8 +3036,8 @@ L: linux-abi-devel@lists.sourceforge.net | |||
3031 | S: Maintained | 3036 | S: Maintained |
3032 | 3037 | ||
3033 | PHRAM MTD DRIVER | 3038 | PHRAM MTD DRIVER |
3034 | P: Jörn Engel | 3039 | P: Joern Engel |
3035 | M: joern@wh.fh-wedel.de | 3040 | M: joern@lazybastard.org |
3036 | L: linux-mtd@lists.infradead.org | 3041 | L: linux-mtd@lists.infradead.org |
3037 | S: Maintained | 3042 | S: Maintained |
3038 | 3043 | ||
@@ -3856,6 +3861,12 @@ M: oliver@neukum.name | |||
3856 | L: linux-usb@vger.kernel.org | 3861 | L: linux-usb@vger.kernel.org |
3857 | S: Maintained | 3862 | S: Maintained |
3858 | 3863 | ||
3864 | USB AUERSWALD DRIVER | ||
3865 | P: Wolfgang Muees | ||
3866 | M: wolfgang@iksw-muees.de | ||
3867 | L: linux-usb@vger.kernel.org | ||
3868 | S: Maintained | ||
3869 | |||
3859 | USB BLOCK DRIVER (UB ub) | 3870 | USB BLOCK DRIVER (UB ub) |
3860 | P: Pete Zaitcev | 3871 | P: Pete Zaitcev |
3861 | M: zaitcev@redhat.com | 3872 | M: zaitcev@redhat.com |
@@ -4006,12 +4017,6 @@ S: Maintained | |||
4006 | W: http://geocities.com/i0xox0i | 4017 | W: http://geocities.com/i0xox0i |
4007 | W: http://firstlight.net/cvs | 4018 | W: http://firstlight.net/cvs |
4008 | 4019 | ||
4009 | USB AUERSWALD DRIVER | ||
4010 | P: Wolfgang Muees | ||
4011 | M: wolfgang@iksw-muees.de | ||
4012 | L: linux-usb@vger.kernel.org | ||
4013 | S: Maintained | ||
4014 | |||
4015 | USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER | 4020 | USB SERIAL EMPEG EMPEG-CAR MARK I/II DRIVER |
4016 | P: Gary Brubaker | 4021 | P: Gary Brubaker |
4017 | M: xavyer@ix.netcom.com | 4022 | M: xavyer@ix.netcom.com |
diff --git a/arch/alpha/Kconfig.debug b/arch/alpha/Kconfig.debug index f45f28cc10da..3f6265f2d9d4 100644 --- a/arch/alpha/Kconfig.debug +++ b/arch/alpha/Kconfig.debug | |||
@@ -7,15 +7,6 @@ config EARLY_PRINTK | |||
7 | depends on ALPHA_GENERIC || ALPHA_SRM | 7 | depends on ALPHA_GENERIC || ALPHA_SRM |
8 | default y | 8 | default y |
9 | 9 | ||
10 | config DEBUG_RWLOCK | ||
11 | bool "Read-write spinlock debugging" | ||
12 | depends on DEBUG_KERNEL | ||
13 | help | ||
14 | If you say Y here then read-write lock processing will count how many | ||
15 | times it has tried to get the lock and issue an error message after | ||
16 | too many attempts. If you suspect a rwlock problem or a kernel | ||
17 | hacker asks for this option then say Y. Otherwise say N. | ||
18 | |||
19 | config ALPHA_LEGACY_START_ADDRESS | 10 | config ALPHA_LEGACY_START_ADDRESS |
20 | bool "Legacy kernel start address" | 11 | bool "Legacy kernel start address" |
21 | depends on ALPHA_GENERIC | 12 | depends on ALPHA_GENERIC |
diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 6da9c3dbde44..e43f68fd66b0 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig | |||
@@ -882,7 +882,6 @@ CONFIG_MAGIC_SYSRQ=y | |||
882 | # CONFIG_DEBUG_SPINLOCK is not set | 882 | # CONFIG_DEBUG_SPINLOCK is not set |
883 | CONFIG_DEBUG_INFO=y | 883 | CONFIG_DEBUG_INFO=y |
884 | CONFIG_EARLY_PRINTK=y | 884 | CONFIG_EARLY_PRINTK=y |
885 | # CONFIG_DEBUG_RWLOCK is not set | ||
886 | # CONFIG_DEBUG_SEMAPHORE is not set | 885 | # CONFIG_DEBUG_SEMAPHORE is not set |
887 | CONFIG_ALPHA_LEGACY_START_ADDRESS=y | 886 | CONFIG_ALPHA_LEGACY_START_ADDRESS=y |
888 | CONFIG_MATHEMU=y | 887 | CONFIG_MATHEMU=y |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 6413c5f23226..72f9a619a66d 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -430,7 +430,7 @@ sys_getpagesize(void) | |||
430 | asmlinkage unsigned long | 430 | asmlinkage unsigned long |
431 | sys_getdtablesize(void) | 431 | sys_getdtablesize(void) |
432 | { | 432 | { |
433 | return NR_OPEN; | 433 | return sysctl_nr_open; |
434 | } | 434 | } |
435 | 435 | ||
436 | /* | 436 | /* |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index f4ab233201b2..63c2073401ee 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -77,10 +77,6 @@ int smp_num_probed; /* Internal processor count */ | |||
77 | int smp_num_cpus = 1; /* Number that came online. */ | 77 | int smp_num_cpus = 1; /* Number that came online. */ |
78 | EXPORT_SYMBOL(smp_num_cpus); | 78 | EXPORT_SYMBOL(smp_num_cpus); |
79 | 79 | ||
80 | extern void calibrate_delay(void); | ||
81 | |||
82 | |||
83 | |||
84 | /* | 80 | /* |
85 | * Called by both boot and secondaries to move global data into | 81 | * Called by both boot and secondaries to move global data into |
86 | * per-processor storage. | 82 | * per-processor storage. |
diff --git a/arch/arm/mach-at91/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c index aa29ea58ca09..0ce38dfa6ebe 100644 --- a/arch/arm/mach-at91/board-sam9261ek.c +++ b/arch/arm/mach-at91/board-sam9261ek.c | |||
@@ -383,6 +383,7 @@ static void at91_lcdc_tft_power_control(int on) | |||
383 | } | 383 | } |
384 | 384 | ||
385 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | 385 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { |
386 | .lcdcon_is_backlight = true, | ||
386 | .default_bpp = 16, | 387 | .default_bpp = 16, |
387 | .default_dmacon = ATMEL_LCDC_DMAEN, | 388 | .default_dmacon = ATMEL_LCDC_DMAEN, |
388 | .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, | 389 | .default_lcdcon2 = AT91SAM9261_DEFAULT_TFT_LCDCON2, |
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c index f09347a86e71..38313abef657 100644 --- a/arch/arm/mach-at91/board-sam9263ek.c +++ b/arch/arm/mach-at91/board-sam9263ek.c | |||
@@ -253,6 +253,7 @@ static void at91_lcdc_power_control(int on) | |||
253 | 253 | ||
254 | /* Driver datas */ | 254 | /* Driver datas */ |
255 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { | 255 | static struct atmel_lcdfb_info __initdata ek_lcdc_data = { |
256 | .lcdcon_is_backlight = true, | ||
256 | .default_bpp = 16, | 257 | .default_bpp = 16, |
257 | .default_dmacon = ATMEL_LCDC_DMAEN, | 258 | .default_dmacon = ATMEL_LCDC_DMAEN, |
258 | .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, | 259 | .default_lcdcon2 = AT91SAM9263_DEFAULT_LCDCON2, |
diff --git a/arch/avr32/kernel/syscall_table.S b/arch/avr32/kernel/syscall_table.S index 75c81f2dd0b3..478bda4c4a09 100644 --- a/arch/avr32/kernel/syscall_table.S +++ b/arch/avr32/kernel/syscall_table.S | |||
@@ -293,6 +293,6 @@ sys_call_table: | |||
293 | .long sys_shmctl | 293 | .long sys_shmctl |
294 | .long sys_utimensat | 294 | .long sys_utimensat |
295 | .long sys_signalfd | 295 | .long sys_signalfd |
296 | .long sys_timerfd /* 280 */ | 296 | .long sys_ni_syscall /* 280, was sys_timerfd */ |
297 | .long sys_eventfd | 297 | .long sys_eventfd |
298 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ | 298 | .long sys_ni_syscall /* r8 is saturated at nr_syscalls */ |
diff --git a/arch/avr32/lib/delay.c b/arch/avr32/lib/delay.c index b3bc0b56e2c6..9aa8800830f3 100644 --- a/arch/avr32/lib/delay.c +++ b/arch/avr32/lib/delay.c | |||
@@ -12,13 +12,15 @@ | |||
12 | 12 | ||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/timex.h> | ||
15 | #include <linux/param.h> | 16 | #include <linux/param.h> |
16 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/init.h> | ||
17 | 19 | ||
18 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
19 | #include <asm/sysreg.h> | 21 | #include <asm/sysreg.h> |
20 | 22 | ||
21 | int read_current_timer(unsigned long *timer_value) | 23 | int __devinit read_current_timer(unsigned long *timer_value) |
22 | { | 24 | { |
23 | *timer_value = sysreg_read(COUNT); | 25 | *timer_value = sysreg_read(COUNT); |
24 | return 0; | 26 | return 0; |
diff --git a/arch/frv/kernel/entry.S b/arch/frv/kernel/entry.S index 99046b1f51c8..ca6a345b87e4 100644 --- a/arch/frv/kernel/entry.S +++ b/arch/frv/kernel/entry.S | |||
@@ -1494,7 +1494,7 @@ sys_call_table: | |||
1494 | .long sys_epoll_pwait | 1494 | .long sys_epoll_pwait |
1495 | .long sys_utimensat /* 320 */ | 1495 | .long sys_utimensat /* 320 */ |
1496 | .long sys_signalfd | 1496 | .long sys_signalfd |
1497 | .long sys_timerfd | 1497 | .long sys_ni_syscall |
1498 | .long sys_eventfd | 1498 | .long sys_eventfd |
1499 | .long sys_fallocate | 1499 | .long sys_fallocate |
1500 | 1500 | ||
diff --git a/arch/frv/kernel/setup.c b/arch/frv/kernel/setup.c index a74c08786b21..b38ae1fc15fd 100644 --- a/arch/frv/kernel/setup.c +++ b/arch/frv/kernel/setup.c | |||
@@ -708,7 +708,7 @@ static void __init reserve_dma_coherent(void) | |||
708 | /* | 708 | /* |
709 | * calibrate the delay loop | 709 | * calibrate the delay loop |
710 | */ | 710 | */ |
711 | void __init calibrate_delay(void) | 711 | void __cpuinit calibrate_delay(void) |
712 | { | 712 | { |
713 | loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ); | 713 | loops_per_jiffy = __delay_loops_MHz * (1000000 / HZ); |
714 | 714 | ||
diff --git a/arch/h8300/kernel/irq.c b/arch/h8300/kernel/irq.c index 8dec4dd57b4e..5a1b4cfea05b 100644 --- a/arch/h8300/kernel/irq.c +++ b/arch/h8300/kernel/irq.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/random.h> | 14 | #include <linux/random.h> |
15 | #include <linux/bootmem.h> | 15 | #include <linux/bootmem.h> |
16 | #include <linux/irq.h> | 16 | #include <linux/irq.h> |
17 | #include <linux/interrupt.h> | ||
17 | 18 | ||
18 | #include <asm/system.h> | 19 | #include <asm/system.h> |
19 | #include <asm/traps.h> | 20 | #include <asm/traps.h> |
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c index 480b1a5085d5..32ee5979a042 100644 --- a/arch/ia64/kernel/smpboot.c +++ b/arch/ia64/kernel/smpboot.c | |||
@@ -120,7 +120,6 @@ static volatile unsigned long go[SLAVE + 1]; | |||
120 | 120 | ||
121 | #define DEBUG_ITC_SYNC 0 | 121 | #define DEBUG_ITC_SYNC 0 |
122 | 122 | ||
123 | extern void __devinit calibrate_delay (void); | ||
124 | extern void start_ap (void); | 123 | extern void start_ap (void); |
125 | extern unsigned long ia64_iobase; | 124 | extern unsigned long ia64_iobase; |
126 | 125 | ||
@@ -477,7 +476,7 @@ start_secondary (void *unused) | |||
477 | return 0; | 476 | return 0; |
478 | } | 477 | } |
479 | 478 | ||
480 | struct pt_regs * __devinit idle_regs(struct pt_regs *regs) | 479 | struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) |
481 | { | 480 | { |
482 | return NULL; | 481 | return NULL; |
483 | } | 482 | } |
diff --git a/arch/ia64/sn/pci/pcibr/pcibr_provider.c b/arch/ia64/sn/pci/pcibr/pcibr_provider.c index ab3eaf85fe4d..2c676cc05418 100644 --- a/arch/ia64/sn/pci/pcibr/pcibr_provider.c +++ b/arch/ia64/sn/pci/pcibr/pcibr_provider.c | |||
@@ -100,11 +100,11 @@ u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus) | |||
100 | static irqreturn_t | 100 | static irqreturn_t |
101 | pcibr_error_intr_handler(int irq, void *arg) | 101 | pcibr_error_intr_handler(int irq, void *arg) |
102 | { | 102 | { |
103 | struct pcibus_info *soft = (struct pcibus_info *)arg; | 103 | struct pcibus_info *soft = arg; |
104 | 104 | ||
105 | if (sal_pcibr_error_interrupt(soft) < 0) { | 105 | if (sal_pcibr_error_interrupt(soft) < 0) |
106 | panic("pcibr_error_intr_handler(): Fatal Bridge Error"); | 106 | panic("pcibr_error_intr_handler(): Fatal Bridge Error"); |
107 | } | 107 | |
108 | return IRQ_HANDLED; | 108 | return IRQ_HANDLED; |
109 | } | 109 | } |
110 | 110 | ||
diff --git a/arch/m32r/kernel/syscall_table.S b/arch/m32r/kernel/syscall_table.S index 95aa79874847..aa3bf4cfab37 100644 --- a/arch/m32r/kernel/syscall_table.S +++ b/arch/m32r/kernel/syscall_table.S | |||
@@ -321,6 +321,6 @@ ENTRY(sys_call_table) | |||
321 | .long sys_epoll_pwait | 321 | .long sys_epoll_pwait |
322 | .long sys_utimensat /* 320 */ | 322 | .long sys_utimensat /* 320 */ |
323 | .long sys_signalfd | 323 | .long sys_signalfd |
324 | .long sys_timerfd | 324 | .long sys_ni_syscall |
325 | .long sys_eventfd | 325 | .long sys_eventfd |
326 | .long sys_fallocate | 326 | .long sys_fallocate |
diff --git a/arch/m68k/amiga/chipram.c b/arch/m68k/amiga/chipram.c index d10726f9038b..cbe36538af47 100644 --- a/arch/m68k/amiga/chipram.c +++ b/arch/m68k/amiga/chipram.c | |||
@@ -32,12 +32,10 @@ void __init amiga_chip_init(void) | |||
32 | if (!AMIGAHW_PRESENT(CHIP_RAM)) | 32 | if (!AMIGAHW_PRESENT(CHIP_RAM)) |
33 | return; | 33 | return; |
34 | 34 | ||
35 | #ifndef CONFIG_APUS_FAST_EXCEPT | ||
36 | /* | 35 | /* |
37 | * Remove the first 4 pages where PPC exception handlers will be located | 36 | * Remove the first 4 pages where PPC exception handlers will be located |
38 | */ | 37 | */ |
39 | amiga_chip_size -= 0x4000; | 38 | amiga_chip_size -= 0x4000; |
40 | #endif | ||
41 | chipram_res.end = amiga_chip_size-1; | 39 | chipram_res.end = amiga_chip_size-1; |
42 | request_resource(&iomem_resource, &chipram_res); | 40 | request_resource(&iomem_resource, &chipram_res); |
43 | 41 | ||
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c index c4a4ffd45bc0..343fab49bd9a 100644 --- a/arch/m68k/amiga/cia.c +++ b/arch/m68k/amiga/cia.c | |||
@@ -84,7 +84,7 @@ unsigned char cia_able_irq(struct ciabase *base, unsigned char mask) | |||
84 | 84 | ||
85 | static irqreturn_t cia_handler(int irq, void *dev_id) | 85 | static irqreturn_t cia_handler(int irq, void *dev_id) |
86 | { | 86 | { |
87 | struct ciabase *base = (struct ciabase *)dev_id; | 87 | struct ciabase *base = dev_id; |
88 | int mach_irq; | 88 | int mach_irq; |
89 | unsigned char ints; | 89 | unsigned char ints; |
90 | 90 | ||
diff --git a/arch/m68knommu/lib/memcpy.c b/arch/m68knommu/lib/memcpy.c index 0d5577569e4c..b50dbcad4746 100644 --- a/arch/m68knommu/lib/memcpy.c +++ b/arch/m68knommu/lib/memcpy.c | |||
@@ -1,6 +1,5 @@ | |||
1 | 1 | ||
2 | #include <linux/types.h> | 2 | #include <linux/types.h> |
3 | #include <linux/autoconf.h> | ||
4 | 3 | ||
5 | void * memcpy(void * to, const void * from, size_t n) | 4 | void * memcpy(void * to, const void * from, size_t n) |
6 | { | 5 | { |
diff --git a/arch/mips/au1000/common/gpio.c b/arch/mips/au1000/common/gpio.c index 8527856aec45..0b658f1db4ce 100644 --- a/arch/mips/au1000/common/gpio.c +++ b/arch/mips/au1000/common/gpio.c | |||
@@ -27,7 +27,6 @@ | |||
27 | * others have a second one : GPIO2 | 27 | * others have a second one : GPIO2 |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/autoconf.h> | ||
31 | #include <linux/init.h> | 30 | #include <linux/init.h> |
32 | #include <linux/io.h> | 31 | #include <linux/io.h> |
33 | #include <linux/types.h> | 32 | #include <linux/types.h> |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1e5dfc28294a..9d41dab90a80 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -52,7 +52,6 @@ int __cpu_logical_map[NR_CPUS]; /* Map logical to physical */ | |||
52 | EXPORT_SYMBOL(phys_cpu_present_map); | 52 | EXPORT_SYMBOL(phys_cpu_present_map); |
53 | EXPORT_SYMBOL(cpu_online_map); | 53 | EXPORT_SYMBOL(cpu_online_map); |
54 | 54 | ||
55 | extern void __init calibrate_delay(void); | ||
56 | extern void cpu_idle(void); | 55 | extern void cpu_idle(void); |
57 | 56 | ||
58 | /* Number of TCs (or siblings in Intel speak) per CPU core */ | 57 | /* Number of TCs (or siblings in Intel speak) per CPU core */ |
diff --git a/arch/mips/kernel/sysirix.c b/arch/mips/kernel/sysirix.c index 4c477c7ff74a..22fd41e946b2 100644 --- a/arch/mips/kernel/sysirix.c +++ b/arch/mips/kernel/sysirix.c | |||
@@ -356,7 +356,7 @@ asmlinkage int irix_syssgi(struct pt_regs *regs) | |||
356 | retval = NGROUPS_MAX; | 356 | retval = NGROUPS_MAX; |
357 | goto out; | 357 | goto out; |
358 | case 5: | 358 | case 5: |
359 | retval = NR_OPEN; | 359 | retval = sysctl_nr_open; |
360 | goto out; | 360 | goto out; |
361 | case 6: | 361 | case 6: |
362 | retval = 1; | 362 | retval = 1; |
diff --git a/arch/parisc/Kconfig.debug b/arch/parisc/Kconfig.debug index 9166bd117267..bc989e522a04 100644 --- a/arch/parisc/Kconfig.debug +++ b/arch/parisc/Kconfig.debug | |||
@@ -2,15 +2,6 @@ menu "Kernel hacking" | |||
2 | 2 | ||
3 | source "lib/Kconfig.debug" | 3 | source "lib/Kconfig.debug" |
4 | 4 | ||
5 | config DEBUG_RWLOCK | ||
6 | bool "Read-write spinlock debugging" | ||
7 | depends on DEBUG_KERNEL && SMP | ||
8 | help | ||
9 | If you say Y here then read-write lock processing will count how many | ||
10 | times it has tried to get the lock and issue an error message after | ||
11 | too many attempts. If you suspect a rwlock problem or a kernel | ||
12 | hacker asks for this option then say Y. Otherwise say N. | ||
13 | |||
14 | config DEBUG_RODATA | 5 | config DEBUG_RODATA |
15 | bool "Write protect kernel read-only data structures" | 6 | bool "Write protect kernel read-only data structures" |
16 | depends on DEBUG_KERNEL | 7 | depends on DEBUG_KERNEL |
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig index ea071218a3ed..ddacc72e38fb 100644 --- a/arch/parisc/configs/a500_defconfig +++ b/arch/parisc/configs/a500_defconfig | |||
@@ -1050,7 +1050,6 @@ CONFIG_SCHED_DEBUG=y | |||
1050 | CONFIG_FORCED_INLINING=y | 1050 | CONFIG_FORCED_INLINING=y |
1051 | # CONFIG_RCU_TORTURE_TEST is not set | 1051 | # CONFIG_RCU_TORTURE_TEST is not set |
1052 | # CONFIG_FAULT_INJECTION is not set | 1052 | # CONFIG_FAULT_INJECTION is not set |
1053 | # CONFIG_DEBUG_RWLOCK is not set | ||
1054 | # CONFIG_DEBUG_RODATA is not set | 1053 | # CONFIG_DEBUG_RODATA is not set |
1055 | 1054 | ||
1056 | # | 1055 | # |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 5cd3db5cae41..3b26fbd6bec9 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <asm/smp.h> | 66 | #include <asm/smp.h> |
67 | #include <asm/vdso_datapage.h> | 67 | #include <asm/vdso_datapage.h> |
68 | #include <asm/firmware.h> | 68 | #include <asm/firmware.h> |
69 | #include <asm/cputime.h> | ||
69 | #ifdef CONFIG_PPC_ISERIES | 70 | #ifdef CONFIG_PPC_ISERIES |
70 | #include <asm/iseries/it_lp_queue.h> | 71 | #include <asm/iseries/it_lp_queue.h> |
71 | #include <asm/iseries/hv_call_xm.h> | 72 | #include <asm/iseries/hv_call_xm.h> |
@@ -189,6 +190,8 @@ u64 __cputime_sec_factor; | |||
189 | EXPORT_SYMBOL(__cputime_sec_factor); | 190 | EXPORT_SYMBOL(__cputime_sec_factor); |
190 | u64 __cputime_clockt_factor; | 191 | u64 __cputime_clockt_factor; |
191 | EXPORT_SYMBOL(__cputime_clockt_factor); | 192 | EXPORT_SYMBOL(__cputime_clockt_factor); |
193 | DEFINE_PER_CPU(unsigned long, cputime_last_delta); | ||
194 | DEFINE_PER_CPU(unsigned long, cputime_scaled_last_delta); | ||
192 | 195 | ||
193 | static void calc_cputime_factors(void) | 196 | static void calc_cputime_factors(void) |
194 | { | 197 | { |
@@ -257,8 +260,8 @@ void account_system_vtime(struct task_struct *tsk) | |||
257 | } | 260 | } |
258 | account_system_time(tsk, 0, delta); | 261 | account_system_time(tsk, 0, delta); |
259 | account_system_time_scaled(tsk, deltascaled); | 262 | account_system_time_scaled(tsk, deltascaled); |
260 | get_paca()->purrdelta = delta; | 263 | per_cpu(cputime_last_delta, smp_processor_id()) = delta; |
261 | get_paca()->spurrdelta = deltascaled; | 264 | per_cpu(cputime_scaled_last_delta, smp_processor_id()) = deltascaled; |
262 | local_irq_restore(flags); | 265 | local_irq_restore(flags); |
263 | } | 266 | } |
264 | 267 | ||
@@ -276,10 +279,7 @@ void account_process_tick(struct task_struct *tsk, int user_tick) | |||
276 | get_paca()->user_time = 0; | 279 | get_paca()->user_time = 0; |
277 | account_user_time(tsk, utime); | 280 | account_user_time(tsk, utime); |
278 | 281 | ||
279 | /* Estimate the scaled utime by scaling the real utime based | 282 | utimescaled = cputime_to_scaled(utime); |
280 | * on the last spurr to purr ratio */ | ||
281 | utimescaled = utime * get_paca()->spurrdelta / get_paca()->purrdelta; | ||
282 | get_paca()->spurrdelta = get_paca()->purrdelta = 0; | ||
283 | account_user_time_scaled(tsk, utimescaled); | 283 | account_user_time_scaled(tsk, utimescaled); |
284 | } | 284 | } |
285 | 285 | ||
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index c04abcc28a7a..792d3ce8112e 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c | |||
@@ -113,8 +113,6 @@ static inline void debug_calc_bogomips(void) | |||
113 | * result. We backup/restore the value to avoid affecting the | 113 | * result. We backup/restore the value to avoid affecting the |
114 | * core cpufreq framework's own calculation. | 114 | * core cpufreq framework's own calculation. |
115 | */ | 115 | */ |
116 | extern void calibrate_delay(void); | ||
117 | |||
118 | unsigned long save_lpj = loops_per_jiffy; | 116 | unsigned long save_lpj = loops_per_jiffy; |
119 | calibrate_delay(); | 117 | calibrate_delay(); |
120 | loops_per_jiffy = save_lpj; | 118 | loops_per_jiffy = save_lpj; |
diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 25ef55bacd99..ec1defea9c1e 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c | |||
@@ -418,7 +418,7 @@ scc_enet_rx(struct net_device *dev) | |||
418 | struct sk_buff *skb; | 418 | struct sk_buff *skb; |
419 | ushort pkt_len; | 419 | ushort pkt_len; |
420 | 420 | ||
421 | cep = (struct scc_enet_private *)dev->priv; | 421 | cep = dev->priv; |
422 | 422 | ||
423 | /* First, grab all of the stats for the incoming packet. | 423 | /* First, grab all of the stats for the incoming packet. |
424 | * These get messed up if we get called due to a busy condition. | 424 | * These get messed up if we get called due to a busy condition. |
diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index a3a27dafff1f..bcc3aa9d04f3 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c | |||
@@ -682,7 +682,7 @@ fcc_enet_rx(struct net_device *dev) | |||
682 | struct sk_buff *skb; | 682 | struct sk_buff *skb; |
683 | ushort pkt_len; | 683 | ushort pkt_len; |
684 | 684 | ||
685 | cep = (struct fcc_enet_private *)dev->priv; | 685 | cep = dev->priv; |
686 | 686 | ||
687 | /* First, grab all of the stats for the incoming packet. | 687 | /* First, grab all of the stats for the incoming packet. |
688 | * These get messed up if we get called due to a busy condition. | 688 | * These get messed up if we get called due to a busy condition. |
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 52b64fcbdfc5..8a24bc47eb6c 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S | |||
@@ -143,11 +143,6 @@ SECTIONS | |||
143 | 143 | ||
144 | . = ALIGN(4096); | 144 | . = ALIGN(4096); |
145 | __init_end = .; | 145 | __init_end = .; |
146 | |||
147 | . = ALIGN(4096); | ||
148 | _sextratext = .; | ||
149 | _eextratext = .; | ||
150 | |||
151 | __bss_start = .; | 146 | __bss_start = .; |
152 | .bss : | 147 | .bss : |
153 | { | 148 | { |
diff --git a/arch/ppc/platforms/prep_setup.c b/arch/ppc/platforms/prep_setup.c index 3c56654bfc6f..38449855d5ff 100644 --- a/arch/ppc/platforms/prep_setup.c +++ b/arch/ppc/platforms/prep_setup.c | |||
@@ -91,20 +91,11 @@ extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi | |||
91 | #define cached_21 (((char *)(ppc_cached_irq_mask))[3]) | 91 | #define cached_21 (((char *)(ppc_cached_irq_mask))[3]) |
92 | #define cached_A1 (((char *)(ppc_cached_irq_mask))[2]) | 92 | #define cached_A1 (((char *)(ppc_cached_irq_mask))[2]) |
93 | 93 | ||
94 | #ifdef CONFIG_SOUND_CS4232 | ||
95 | long ppc_cs4232_dma, ppc_cs4232_dma2; | ||
96 | #endif | ||
97 | |||
98 | extern PTE *Hash, *Hash_end; | 94 | extern PTE *Hash, *Hash_end; |
99 | extern unsigned long Hash_size, Hash_mask; | 95 | extern unsigned long Hash_size, Hash_mask; |
100 | extern int probingmem; | 96 | extern int probingmem; |
101 | extern unsigned long loops_per_jiffy; | 97 | extern unsigned long loops_per_jiffy; |
102 | 98 | ||
103 | #ifdef CONFIG_SOUND_CS4232 | ||
104 | EXPORT_SYMBOL(ppc_cs4232_dma); | ||
105 | EXPORT_SYMBOL(ppc_cs4232_dma2); | ||
106 | #endif | ||
107 | |||
108 | /* useful ISA ports */ | 99 | /* useful ISA ports */ |
109 | #define PREP_SYSCTL 0x81c | 100 | #define PREP_SYSCTL 0x81c |
110 | /* present in the IBM reference design; possibly identical in Mot boxes: */ | 101 | /* present in the IBM reference design; possibly identical in Mot boxes: */ |
@@ -569,74 +560,6 @@ prep_show_percpuinfo(struct seq_file *m, int i) | |||
569 | return 0; | 560 | return 0; |
570 | } | 561 | } |
571 | 562 | ||
572 | #ifdef CONFIG_SOUND_CS4232 | ||
573 | static long __init masktoint(unsigned int i) | ||
574 | { | ||
575 | int t = -1; | ||
576 | while (i >> ++t) | ||
577 | ; | ||
578 | return (t-1); | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * ppc_cs4232_dma and ppc_cs4232_dma2 are used in include/asm/dma.h | ||
583 | * to distinguish sound dma-channels from others. This is because | ||
584 | * blocksize on 16 bit dma-channels 5,6,7 is 128k, but | ||
585 | * the cs4232.c uses 64k like on 8 bit dma-channels 0,1,2,3 | ||
586 | */ | ||
587 | |||
588 | static void __init prep_init_sound(void) | ||
589 | { | ||
590 | PPC_DEVICE *audiodevice = NULL; | ||
591 | |||
592 | /* | ||
593 | * Get the needed resource information from residual data. | ||
594 | * | ||
595 | */ | ||
596 | if (have_residual_data) | ||
597 | audiodevice = residual_find_device(~0, NULL, | ||
598 | MultimediaController, AudioController, -1, 0); | ||
599 | |||
600 | if (audiodevice != NULL) { | ||
601 | PnP_TAG_PACKET *pkt; | ||
602 | |||
603 | pkt = PnP_find_packet((unsigned char *)&res->DevicePnPHeap[audiodevice->AllocatedOffset], | ||
604 | S5_Packet, 0); | ||
605 | if (pkt != NULL) | ||
606 | ppc_cs4232_dma = masktoint(pkt->S5_Pack.DMAMask); | ||
607 | pkt = PnP_find_packet((unsigned char*)&res->DevicePnPHeap[audiodevice->AllocatedOffset], | ||
608 | S5_Packet, 1); | ||
609 | if (pkt != NULL) | ||
610 | ppc_cs4232_dma2 = masktoint(pkt->S5_Pack.DMAMask); | ||
611 | } | ||
612 | |||
613 | /* | ||
614 | * These are the PReP specs' defaults for the cs4231. We use these | ||
615 | * as fallback incase we don't have residual data. | ||
616 | * At least the IBM Thinkpad 850 with IDE DMA Channels at 6 and 7 | ||
617 | * will use the other values. | ||
618 | */ | ||
619 | if (audiodevice == NULL) { | ||
620 | switch (_prep_type) { | ||
621 | case _PREP_IBM: | ||
622 | ppc_cs4232_dma = 1; | ||
623 | ppc_cs4232_dma2 = -1; | ||
624 | break; | ||
625 | default: | ||
626 | ppc_cs4232_dma = 6; | ||
627 | ppc_cs4232_dma2 = 7; | ||
628 | } | ||
629 | } | ||
630 | |||
631 | /* | ||
632 | * Find a way to push this information to the cs4232 driver | ||
633 | * Give it out with printk, when not in cmd_line? | ||
634 | * Append it to cmd_line and boot_command_line? | ||
635 | * Format is cs4232=io,irq,dma,dma2 | ||
636 | */ | ||
637 | } | ||
638 | #endif /* CONFIG_SOUND_CS4232 */ | ||
639 | |||
640 | /* | 563 | /* |
641 | * Fill out screen_info according to the residual data. This allows us to use | 564 | * Fill out screen_info according to the residual data. This allows us to use |
642 | * at least vesafb. | 565 | * at least vesafb. |
@@ -898,10 +821,6 @@ prep_setup_arch(void) | |||
898 | } | 821 | } |
899 | } | 822 | } |
900 | 823 | ||
901 | #ifdef CONFIG_SOUND_CS4232 | ||
902 | prep_init_sound(); | ||
903 | #endif /* CONFIG_SOUND_CS4232 */ | ||
904 | |||
905 | prep_init_vesa(); | 824 | prep_init_vesa(); |
906 | 825 | ||
907 | switch (_prep_type) { | 826 | switch (_prep_type) { |
diff --git a/arch/sh/kernel/syscalls_32.S b/arch/sh/kernel/syscalls_32.S index 10bec45415ba..719e127a7c05 100644 --- a/arch/sh/kernel/syscalls_32.S +++ b/arch/sh/kernel/syscalls_32.S | |||
@@ -338,6 +338,6 @@ ENTRY(sys_call_table) | |||
338 | .long sys_epoll_pwait | 338 | .long sys_epoll_pwait |
339 | .long sys_utimensat /* 320 */ | 339 | .long sys_utimensat /* 320 */ |
340 | .long sys_signalfd | 340 | .long sys_signalfd |
341 | .long sys_timerfd | 341 | .long sys_ni_syscall |
342 | .long sys_eventfd | 342 | .long sys_eventfd |
343 | .long sys_fallocate | 343 | .long sys_fallocate |
diff --git a/arch/sh/kernel/syscalls_64.S b/arch/sh/kernel/syscalls_64.S index 98a93efe3691..12c7340356ae 100644 --- a/arch/sh/kernel/syscalls_64.S +++ b/arch/sh/kernel/syscalls_64.S | |||
@@ -376,6 +376,6 @@ sys_call_table: | |||
376 | .long sys_epoll_pwait | 376 | .long sys_epoll_pwait |
377 | .long sys_utimensat | 377 | .long sys_utimensat |
378 | .long sys_signalfd | 378 | .long sys_signalfd |
379 | .long sys_timerfd /* 350 */ | 379 | .long sys_ni_syscall /* 350 */ |
380 | .long sys_eventfd | 380 | .long sys_eventfd |
381 | .long sys_fallocate | 381 | .long sys_fallocate |
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c index 89a6de95070c..0def48158c7d 100644 --- a/arch/sparc/kernel/sun4d_smp.c +++ b/arch/sparc/kernel/sun4d_smp.c | |||
@@ -19,12 +19,12 @@ | |||
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/swap.h> | 20 | #include <linux/swap.h> |
21 | #include <linux/profile.h> | 21 | #include <linux/profile.h> |
22 | #include <linux/delay.h> | ||
22 | 23 | ||
23 | #include <asm/ptrace.h> | 24 | #include <asm/ptrace.h> |
24 | #include <asm/atomic.h> | 25 | #include <asm/atomic.h> |
25 | #include <asm/irq_regs.h> | 26 | #include <asm/irq_regs.h> |
26 | 27 | ||
27 | #include <asm/delay.h> | ||
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/pgalloc.h> | 30 | #include <asm/pgalloc.h> |
@@ -41,8 +41,6 @@ | |||
41 | 41 | ||
42 | extern ctxd_t *srmmu_ctx_table_phys; | 42 | extern ctxd_t *srmmu_ctx_table_phys; |
43 | 43 | ||
44 | extern void calibrate_delay(void); | ||
45 | |||
46 | static volatile int smp_processors_ready = 0; | 44 | static volatile int smp_processors_ready = 0; |
47 | static int smp_highest_cpu; | 45 | static int smp_highest_cpu; |
48 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; | 46 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; |
diff --git a/arch/sparc/kernel/sun4m_smp.c b/arch/sparc/kernel/sun4m_smp.c index 730eb5796f8e..0b9407267162 100644 --- a/arch/sparc/kernel/sun4m_smp.c +++ b/arch/sparc/kernel/sun4m_smp.c | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/mm.h> | 16 | #include <linux/mm.h> |
17 | #include <linux/swap.h> | 17 | #include <linux/swap.h> |
18 | #include <linux/profile.h> | 18 | #include <linux/profile.h> |
19 | #include <linux/delay.h> | ||
20 | |||
19 | #include <asm/cacheflush.h> | 21 | #include <asm/cacheflush.h> |
20 | #include <asm/tlbflush.h> | 22 | #include <asm/tlbflush.h> |
21 | #include <asm/irq_regs.h> | 23 | #include <asm/irq_regs.h> |
@@ -23,7 +25,6 @@ | |||
23 | #include <asm/ptrace.h> | 25 | #include <asm/ptrace.h> |
24 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
25 | 27 | ||
26 | #include <asm/delay.h> | ||
27 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
28 | #include <asm/page.h> | 29 | #include <asm/page.h> |
29 | #include <asm/pgalloc.h> | 30 | #include <asm/pgalloc.h> |
@@ -39,8 +40,6 @@ | |||
39 | 40 | ||
40 | extern ctxd_t *srmmu_ctx_table_phys; | 41 | extern ctxd_t *srmmu_ctx_table_phys; |
41 | 42 | ||
42 | extern void calibrate_delay(void); | ||
43 | |||
44 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; | 43 | extern volatile unsigned long cpu_callin_map[NR_CPUS]; |
45 | extern unsigned char boot_cpu_id; | 44 | extern unsigned char boot_cpu_id; |
46 | 45 | ||
diff --git a/arch/sparc/kernel/systbls.S b/arch/sparc/kernel/systbls.S index ee010f4532a0..9064485dc40b 100644 --- a/arch/sparc/kernel/systbls.S +++ b/arch/sparc/kernel/systbls.S | |||
@@ -79,7 +79,8 @@ sys_call_table: | |||
79 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 79 | /*295*/ .long sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
80 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 80 | /*300*/ .long sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
81 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 81 | /*305*/ .long sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate | 82 | /*310*/ .long sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
83 | /*315*/ .long sys_timerfd_settime, sys_timerfd_gettime | ||
83 | 84 | ||
84 | #ifdef CONFIG_SUNOS_EMUL | 85 | #ifdef CONFIG_SUNOS_EMUL |
85 | /* Now the SunOS syscall table. */ | 86 | /* Now the SunOS syscall table. */ |
@@ -197,6 +198,7 @@ sunos_sys_table: | |||
197 | .long sunos_nosys, sunos_nosys, sunos_nosys | 198 | .long sunos_nosys, sunos_nosys, sunos_nosys |
198 | .long sunos_nosys | 199 | .long sunos_nosys |
199 | /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys | 200 | /*310*/ .long sunos_nosys, sunos_nosys, sunos_nosys |
200 | .long sunos_nosys, sunos_nosys | 201 | .long sunos_nosys, sunos_nosys, sunos_nosys |
202 | .long sunos_nosys | ||
201 | 203 | ||
202 | #endif | 204 | #endif |
diff --git a/arch/sparc64/defconfig b/arch/sparc64/defconfig index f62d9f6c5e2a..833d74b2b192 100644 --- a/arch/sparc64/defconfig +++ b/arch/sparc64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.24-rc4 | 3 | # Linux kernel version: 2.6.24 |
4 | # Tue Dec 4 00:37:59 2007 | 4 | # Tue Feb 5 17:28:19 2008 |
5 | # | 5 | # |
6 | CONFIG_SPARC=y | 6 | CONFIG_SPARC=y |
7 | CONFIG_SPARC64=y | 7 | CONFIG_SPARC64=y |
@@ -17,6 +17,7 @@ CONFIG_ARCH_MAY_HAVE_PC_FDC=y | |||
17 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set | 17 | # CONFIG_ARCH_HAS_ILOG2_U32 is not set |
18 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set | 18 | # CONFIG_ARCH_HAS_ILOG2_U64 is not set |
19 | CONFIG_AUDIT_ARCH=y | 19 | CONFIG_AUDIT_ARCH=y |
20 | CONFIG_HAVE_SETUP_PER_CPU_AREA=y | ||
20 | CONFIG_ARCH_NO_VIRT_TO_BUS=y | 21 | CONFIG_ARCH_NO_VIRT_TO_BUS=y |
21 | CONFIG_OF=y | 22 | CONFIG_OF=y |
22 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y | 23 | CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y |
@@ -30,13 +31,15 @@ CONFIG_HZ_100=y | |||
30 | # CONFIG_HZ_300 is not set | 31 | # CONFIG_HZ_300 is not set |
31 | # CONFIG_HZ_1000 is not set | 32 | # CONFIG_HZ_1000 is not set |
32 | CONFIG_HZ=100 | 33 | CONFIG_HZ=100 |
34 | # CONFIG_SCHED_HRTICK is not set | ||
35 | CONFIG_HOTPLUG_CPU=y | ||
33 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" | 36 | CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" |
34 | 37 | ||
35 | # | 38 | # |
36 | # General setup | 39 | # General setup |
37 | # | 40 | # |
38 | CONFIG_EXPERIMENTAL=y | 41 | CONFIG_EXPERIMENTAL=y |
39 | CONFIG_BROKEN_ON_SMP=y | 42 | CONFIG_LOCK_KERNEL=y |
40 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 43 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
41 | CONFIG_LOCALVERSION="" | 44 | CONFIG_LOCALVERSION="" |
42 | # CONFIG_LOCALVERSION_AUTO is not set | 45 | # CONFIG_LOCALVERSION_AUTO is not set |
@@ -76,6 +79,7 @@ CONFIG_FUTEX=y | |||
76 | CONFIG_ANON_INODES=y | 79 | CONFIG_ANON_INODES=y |
77 | CONFIG_EPOLL=y | 80 | CONFIG_EPOLL=y |
78 | CONFIG_SIGNALFD=y | 81 | CONFIG_SIGNALFD=y |
82 | CONFIG_TIMERFD=y | ||
79 | CONFIG_EVENTFD=y | 83 | CONFIG_EVENTFD=y |
80 | CONFIG_SHMEM=y | 84 | CONFIG_SHMEM=y |
81 | CONFIG_VM_EVENT_COUNTERS=y | 85 | CONFIG_VM_EVENT_COUNTERS=y |
@@ -83,6 +87,14 @@ CONFIG_SLUB_DEBUG=y | |||
83 | # CONFIG_SLAB is not set | 87 | # CONFIG_SLAB is not set |
84 | CONFIG_SLUB=y | 88 | CONFIG_SLUB=y |
85 | # CONFIG_SLOB is not set | 89 | # CONFIG_SLOB is not set |
90 | CONFIG_PROFILING=y | ||
91 | # CONFIG_MARKERS is not set | ||
92 | CONFIG_OPROFILE=m | ||
93 | CONFIG_HAVE_OPROFILE=y | ||
94 | CONFIG_KPROBES=y | ||
95 | CONFIG_HAVE_KPROBES=y | ||
96 | CONFIG_PROC_PAGE_MONITOR=y | ||
97 | CONFIG_SLABINFO=y | ||
86 | CONFIG_RT_MUTEXES=y | 98 | CONFIG_RT_MUTEXES=y |
87 | # CONFIG_TINY_SHMEM is not set | 99 | # CONFIG_TINY_SHMEM is not set |
88 | CONFIG_BASE_SMALL=0 | 100 | CONFIG_BASE_SMALL=0 |
@@ -92,6 +104,7 @@ CONFIG_MODULE_FORCE_UNLOAD=y | |||
92 | CONFIG_MODVERSIONS=y | 104 | CONFIG_MODVERSIONS=y |
93 | CONFIG_MODULE_SRCVERSION_ALL=y | 105 | CONFIG_MODULE_SRCVERSION_ALL=y |
94 | CONFIG_KMOD=y | 106 | CONFIG_KMOD=y |
107 | CONFIG_STOP_MACHINE=y | ||
95 | CONFIG_BLOCK=y | 108 | CONFIG_BLOCK=y |
96 | CONFIG_BLK_DEV_IO_TRACE=y | 109 | CONFIG_BLK_DEV_IO_TRACE=y |
97 | CONFIG_BLK_DEV_BSG=y | 110 | CONFIG_BLK_DEV_BSG=y |
@@ -109,6 +122,8 @@ CONFIG_DEFAULT_AS=y | |||
109 | # CONFIG_DEFAULT_CFQ is not set | 122 | # CONFIG_DEFAULT_CFQ is not set |
110 | # CONFIG_DEFAULT_NOOP is not set | 123 | # CONFIG_DEFAULT_NOOP is not set |
111 | CONFIG_DEFAULT_IOSCHED="anticipatory" | 124 | CONFIG_DEFAULT_IOSCHED="anticipatory" |
125 | CONFIG_CLASSIC_RCU=y | ||
126 | # CONFIG_PREEMPT_RCU is not set | ||
112 | CONFIG_SYSVIPC_COMPAT=y | 127 | CONFIG_SYSVIPC_COMPAT=y |
113 | CONFIG_GENERIC_HARDIRQS=y | 128 | CONFIG_GENERIC_HARDIRQS=y |
114 | 129 | ||
@@ -119,7 +134,8 @@ CONFIG_TICK_ONESHOT=y | |||
119 | CONFIG_NO_HZ=y | 134 | CONFIG_NO_HZ=y |
120 | CONFIG_HIGH_RES_TIMERS=y | 135 | CONFIG_HIGH_RES_TIMERS=y |
121 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y | 136 | CONFIG_GENERIC_CLOCKEVENTS_BUILD=y |
122 | # CONFIG_SMP is not set | 137 | CONFIG_SMP=y |
138 | CONFIG_NR_CPUS=64 | ||
123 | # CONFIG_CPU_FREQ is not set | 139 | # CONFIG_CPU_FREQ is not set |
124 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 140 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
125 | CONFIG_GENERIC_FIND_NEXT_BIT=y | 141 | CONFIG_GENERIC_FIND_NEXT_BIT=y |
@@ -169,9 +185,12 @@ CONFIG_BINFMT_ELF32=y | |||
169 | CONFIG_BINFMT_ELF=y | 185 | CONFIG_BINFMT_ELF=y |
170 | CONFIG_BINFMT_MISC=m | 186 | CONFIG_BINFMT_MISC=m |
171 | CONFIG_SOLARIS_EMUL=y | 187 | CONFIG_SOLARIS_EMUL=y |
188 | CONFIG_SCHED_SMT=y | ||
189 | CONFIG_SCHED_MC=y | ||
172 | # CONFIG_PREEMPT_NONE is not set | 190 | # CONFIG_PREEMPT_NONE is not set |
173 | CONFIG_PREEMPT_VOLUNTARY=y | 191 | CONFIG_PREEMPT_VOLUNTARY=y |
174 | # CONFIG_PREEMPT is not set | 192 | # CONFIG_PREEMPT is not set |
193 | # CONFIG_RCU_TRACE is not set | ||
175 | # CONFIG_CMDLINE_BOOL is not set | 194 | # CONFIG_CMDLINE_BOOL is not set |
176 | 195 | ||
177 | # | 196 | # |
@@ -189,6 +208,7 @@ CONFIG_XFRM=y | |||
189 | CONFIG_XFRM_USER=m | 208 | CONFIG_XFRM_USER=m |
190 | # CONFIG_XFRM_SUB_POLICY is not set | 209 | # CONFIG_XFRM_SUB_POLICY is not set |
191 | CONFIG_XFRM_MIGRATE=y | 210 | CONFIG_XFRM_MIGRATE=y |
211 | # CONFIG_XFRM_STATISTICS is not set | ||
192 | CONFIG_NET_KEY=m | 212 | CONFIG_NET_KEY=m |
193 | CONFIG_NET_KEY_MIGRATE=y | 213 | CONFIG_NET_KEY_MIGRATE=y |
194 | CONFIG_INET=y | 214 | CONFIG_INET=y |
@@ -249,9 +269,9 @@ CONFIG_IP_DCCP_ACKVEC=y | |||
249 | CONFIG_IP_DCCP_CCID2=m | 269 | CONFIG_IP_DCCP_CCID2=m |
250 | # CONFIG_IP_DCCP_CCID2_DEBUG is not set | 270 | # CONFIG_IP_DCCP_CCID2_DEBUG is not set |
251 | CONFIG_IP_DCCP_CCID3=m | 271 | CONFIG_IP_DCCP_CCID3=m |
252 | CONFIG_IP_DCCP_TFRC_LIB=m | ||
253 | # CONFIG_IP_DCCP_CCID3_DEBUG is not set | 272 | # CONFIG_IP_DCCP_CCID3_DEBUG is not set |
254 | CONFIG_IP_DCCP_CCID3_RTO=100 | 273 | CONFIG_IP_DCCP_CCID3_RTO=100 |
274 | CONFIG_IP_DCCP_TFRC_LIB=m | ||
255 | 275 | ||
256 | # | 276 | # |
257 | # DCCP Kernel Hacking | 277 | # DCCP Kernel Hacking |
@@ -279,6 +299,7 @@ CONFIG_VLAN_8021Q=m | |||
279 | CONFIG_NET_PKTGEN=m | 299 | CONFIG_NET_PKTGEN=m |
280 | CONFIG_NET_TCPPROBE=m | 300 | CONFIG_NET_TCPPROBE=m |
281 | # CONFIG_HAMRADIO is not set | 301 | # CONFIG_HAMRADIO is not set |
302 | # CONFIG_CAN is not set | ||
282 | # CONFIG_IRDA is not set | 303 | # CONFIG_IRDA is not set |
283 | # CONFIG_BT is not set | 304 | # CONFIG_BT is not set |
284 | # CONFIG_AF_RXRPC is not set | 305 | # CONFIG_AF_RXRPC is not set |
@@ -343,6 +364,7 @@ CONFIG_BLK_DEV_IDE=y | |||
343 | CONFIG_BLK_DEV_IDEDISK=y | 364 | CONFIG_BLK_DEV_IDEDISK=y |
344 | # CONFIG_IDEDISK_MULTI_MODE is not set | 365 | # CONFIG_IDEDISK_MULTI_MODE is not set |
345 | CONFIG_BLK_DEV_IDECD=y | 366 | CONFIG_BLK_DEV_IDECD=y |
367 | CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y | ||
346 | # CONFIG_BLK_DEV_IDETAPE is not set | 368 | # CONFIG_BLK_DEV_IDETAPE is not set |
347 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | 369 | # CONFIG_BLK_DEV_IDEFLOPPY is not set |
348 | # CONFIG_BLK_DEV_IDESCSI is not set | 370 | # CONFIG_BLK_DEV_IDESCSI is not set |
@@ -359,7 +381,6 @@ CONFIG_IDE_GENERIC=y | |||
359 | # PCI IDE chipsets support | 381 | # PCI IDE chipsets support |
360 | # | 382 | # |
361 | CONFIG_BLK_DEV_IDEPCI=y | 383 | CONFIG_BLK_DEV_IDEPCI=y |
362 | # CONFIG_IDEPCI_SHARE_IRQ is not set | ||
363 | CONFIG_IDEPCI_PCIBUS_ORDER=y | 384 | CONFIG_IDEPCI_PCIBUS_ORDER=y |
364 | # CONFIG_BLK_DEV_GENERIC is not set | 385 | # CONFIG_BLK_DEV_GENERIC is not set |
365 | # CONFIG_BLK_DEV_OPTI621 is not set | 386 | # CONFIG_BLK_DEV_OPTI621 is not set |
@@ -389,7 +410,6 @@ CONFIG_BLK_DEV_ALI15X3=y | |||
389 | # CONFIG_BLK_DEV_TRM290 is not set | 410 | # CONFIG_BLK_DEV_TRM290 is not set |
390 | # CONFIG_BLK_DEV_VIA82CXXX is not set | 411 | # CONFIG_BLK_DEV_VIA82CXXX is not set |
391 | # CONFIG_BLK_DEV_TC86C001 is not set | 412 | # CONFIG_BLK_DEV_TC86C001 is not set |
392 | # CONFIG_IDE_ARM is not set | ||
393 | CONFIG_BLK_DEV_IDEDMA=y | 413 | CONFIG_BLK_DEV_IDEDMA=y |
394 | CONFIG_IDE_ARCH_OBSOLETE_INIT=y | 414 | CONFIG_IDE_ARCH_OBSOLETE_INIT=y |
395 | # CONFIG_BLK_DEV_HD is not set | 415 | # CONFIG_BLK_DEV_HD is not set |
@@ -501,7 +521,6 @@ CONFIG_NETDEVICES=y | |||
501 | # CONFIG_EQUALIZER is not set | 521 | # CONFIG_EQUALIZER is not set |
502 | # CONFIG_TUN is not set | 522 | # CONFIG_TUN is not set |
503 | # CONFIG_VETH is not set | 523 | # CONFIG_VETH is not set |
504 | # CONFIG_IP1000 is not set | ||
505 | # CONFIG_ARCNET is not set | 524 | # CONFIG_ARCNET is not set |
506 | # CONFIG_PHYLIB is not set | 525 | # CONFIG_PHYLIB is not set |
507 | CONFIG_NET_ETHERNET=y | 526 | CONFIG_NET_ETHERNET=y |
@@ -533,6 +552,7 @@ CONFIG_NET_PCI=y | |||
533 | # CONFIG_NE2K_PCI is not set | 552 | # CONFIG_NE2K_PCI is not set |
534 | # CONFIG_8139CP is not set | 553 | # CONFIG_8139CP is not set |
535 | # CONFIG_8139TOO is not set | 554 | # CONFIG_8139TOO is not set |
555 | # CONFIG_R6040 is not set | ||
536 | # CONFIG_SIS900 is not set | 556 | # CONFIG_SIS900 is not set |
537 | # CONFIG_EPIC100 is not set | 557 | # CONFIG_EPIC100 is not set |
538 | # CONFIG_SUNDANCE is not set | 558 | # CONFIG_SUNDANCE is not set |
@@ -545,6 +565,9 @@ CONFIG_E1000=m | |||
545 | CONFIG_E1000_NAPI=y | 565 | CONFIG_E1000_NAPI=y |
546 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set | 566 | # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set |
547 | # CONFIG_E1000E is not set | 567 | # CONFIG_E1000E is not set |
568 | # CONFIG_E1000E_ENABLED is not set | ||
569 | # CONFIG_IP1000 is not set | ||
570 | # CONFIG_IGB is not set | ||
548 | # CONFIG_MYRI_SBUS is not set | 571 | # CONFIG_MYRI_SBUS is not set |
549 | # CONFIG_NS83820 is not set | 572 | # CONFIG_NS83820 is not set |
550 | # CONFIG_HAMACHI is not set | 573 | # CONFIG_HAMACHI is not set |
@@ -570,6 +593,7 @@ CONFIG_NETDEV_10000=y | |||
570 | CONFIG_NIU=m | 593 | CONFIG_NIU=m |
571 | # CONFIG_MLX4_CORE is not set | 594 | # CONFIG_MLX4_CORE is not set |
572 | # CONFIG_TEHUTI is not set | 595 | # CONFIG_TEHUTI is not set |
596 | # CONFIG_BNX2X is not set | ||
573 | # CONFIG_TR is not set | 597 | # CONFIG_TR is not set |
574 | 598 | ||
575 | # | 599 | # |
@@ -602,7 +626,6 @@ CONFIG_PPPOE=m | |||
602 | # CONFIG_SLIP is not set | 626 | # CONFIG_SLIP is not set |
603 | CONFIG_SLHC=m | 627 | CONFIG_SLHC=m |
604 | # CONFIG_NET_FC is not set | 628 | # CONFIG_NET_FC is not set |
605 | # CONFIG_SHAPER is not set | ||
606 | # CONFIG_NETCONSOLE is not set | 629 | # CONFIG_NETCONSOLE is not set |
607 | # CONFIG_NETPOLL is not set | 630 | # CONFIG_NETPOLL is not set |
608 | # CONFIG_NET_POLL_CONTROLLER is not set | 631 | # CONFIG_NET_POLL_CONTROLLER is not set |
@@ -679,6 +702,7 @@ CONFIG_VT_CONSOLE=y | |||
679 | CONFIG_HW_CONSOLE=y | 702 | CONFIG_HW_CONSOLE=y |
680 | # CONFIG_VT_HW_CONSOLE_BINDING is not set | 703 | # CONFIG_VT_HW_CONSOLE_BINDING is not set |
681 | # CONFIG_SERIAL_NONSTANDARD is not set | 704 | # CONFIG_SERIAL_NONSTANDARD is not set |
705 | # CONFIG_NOZOMI is not set | ||
682 | 706 | ||
683 | # | 707 | # |
684 | # Serial drivers | 708 | # Serial drivers |
@@ -747,13 +771,13 @@ CONFIG_I2C_ALGOBIT=y | |||
747 | # | 771 | # |
748 | # Miscellaneous I2C Chip support | 772 | # Miscellaneous I2C Chip support |
749 | # | 773 | # |
750 | # CONFIG_SENSORS_DS1337 is not set | ||
751 | # CONFIG_SENSORS_DS1374 is not set | ||
752 | # CONFIG_DS1682 is not set | 774 | # CONFIG_DS1682 is not set |
753 | # CONFIG_SENSORS_EEPROM is not set | 775 | # CONFIG_SENSORS_EEPROM is not set |
754 | # CONFIG_SENSORS_PCF8574 is not set | 776 | # CONFIG_SENSORS_PCF8574 is not set |
777 | # CONFIG_PCF8575 is not set | ||
755 | # CONFIG_SENSORS_PCA9539 is not set | 778 | # CONFIG_SENSORS_PCA9539 is not set |
756 | # CONFIG_SENSORS_PCF8591 is not set | 779 | # CONFIG_SENSORS_PCF8591 is not set |
780 | # CONFIG_TPS65010 is not set | ||
757 | # CONFIG_SENSORS_MAX6875 is not set | 781 | # CONFIG_SENSORS_MAX6875 is not set |
758 | # CONFIG_SENSORS_TSL2550 is not set | 782 | # CONFIG_SENSORS_TSL2550 is not set |
759 | # CONFIG_I2C_DEBUG_CORE is not set | 783 | # CONFIG_I2C_DEBUG_CORE is not set |
@@ -990,6 +1014,7 @@ CONFIG_SND_ALI5451=m | |||
990 | # CONFIG_SND_BT87X is not set | 1014 | # CONFIG_SND_BT87X is not set |
991 | # CONFIG_SND_CA0106 is not set | 1015 | # CONFIG_SND_CA0106 is not set |
992 | # CONFIG_SND_CMIPCI is not set | 1016 | # CONFIG_SND_CMIPCI is not set |
1017 | # CONFIG_SND_OXYGEN is not set | ||
993 | # CONFIG_SND_CS4281 is not set | 1018 | # CONFIG_SND_CS4281 is not set |
994 | # CONFIG_SND_CS46XX is not set | 1019 | # CONFIG_SND_CS46XX is not set |
995 | # CONFIG_SND_DARLA20 is not set | 1020 | # CONFIG_SND_DARLA20 is not set |
@@ -1014,6 +1039,7 @@ CONFIG_SND_ALI5451=m | |||
1014 | # CONFIG_SND_HDA_INTEL is not set | 1039 | # CONFIG_SND_HDA_INTEL is not set |
1015 | # CONFIG_SND_HDSP is not set | 1040 | # CONFIG_SND_HDSP is not set |
1016 | # CONFIG_SND_HDSPM is not set | 1041 | # CONFIG_SND_HDSPM is not set |
1042 | # CONFIG_SND_HIFIER is not set | ||
1017 | # CONFIG_SND_ICE1712 is not set | 1043 | # CONFIG_SND_ICE1712 is not set |
1018 | # CONFIG_SND_ICE1724 is not set | 1044 | # CONFIG_SND_ICE1724 is not set |
1019 | # CONFIG_SND_INTEL8X0 is not set | 1045 | # CONFIG_SND_INTEL8X0 is not set |
@@ -1031,6 +1057,7 @@ CONFIG_SND_ALI5451=m | |||
1031 | # CONFIG_SND_TRIDENT is not set | 1057 | # CONFIG_SND_TRIDENT is not set |
1032 | # CONFIG_SND_VIA82XX is not set | 1058 | # CONFIG_SND_VIA82XX is not set |
1033 | # CONFIG_SND_VIA82XX_MODEM is not set | 1059 | # CONFIG_SND_VIA82XX_MODEM is not set |
1060 | # CONFIG_SND_VIRTUOSO is not set | ||
1034 | # CONFIG_SND_VX222 is not set | 1061 | # CONFIG_SND_VX222 is not set |
1035 | # CONFIG_SND_YMFPCI is not set | 1062 | # CONFIG_SND_YMFPCI is not set |
1036 | # CONFIG_SND_AC97_POWER_SAVE is not set | 1063 | # CONFIG_SND_AC97_POWER_SAVE is not set |
@@ -1058,6 +1085,10 @@ CONFIG_SND_SUN_CS4231=m | |||
1058 | # | 1085 | # |
1059 | 1086 | ||
1060 | # | 1087 | # |
1088 | # ALSA SoC audio for Freescale SOCs | ||
1089 | # | ||
1090 | |||
1091 | # | ||
1061 | # Open Sound System | 1092 | # Open Sound System |
1062 | # | 1093 | # |
1063 | # CONFIG_SOUND_PRIME is not set | 1094 | # CONFIG_SOUND_PRIME is not set |
@@ -1080,6 +1111,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
1080 | CONFIG_USB_ARCH_HAS_EHCI=y | 1111 | CONFIG_USB_ARCH_HAS_EHCI=y |
1081 | CONFIG_USB=y | 1112 | CONFIG_USB=y |
1082 | # CONFIG_USB_DEBUG is not set | 1113 | # CONFIG_USB_DEBUG is not set |
1114 | # CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set | ||
1083 | 1115 | ||
1084 | # | 1116 | # |
1085 | # Miscellaneous USB options | 1117 | # Miscellaneous USB options |
@@ -1093,7 +1125,6 @@ CONFIG_USB_DEVICEFS=y | |||
1093 | # USB Host Controller Drivers | 1125 | # USB Host Controller Drivers |
1094 | # | 1126 | # |
1095 | CONFIG_USB_EHCI_HCD=m | 1127 | CONFIG_USB_EHCI_HCD=m |
1096 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
1097 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | 1128 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set |
1098 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set | 1129 | # CONFIG_USB_EHCI_TT_NEWSCHED is not set |
1099 | # CONFIG_USB_ISP116X_HCD is not set | 1130 | # CONFIG_USB_ISP116X_HCD is not set |
@@ -1143,10 +1174,6 @@ CONFIG_USB_STORAGE=m | |||
1143 | # | 1174 | # |
1144 | # USB port drivers | 1175 | # USB port drivers |
1145 | # | 1176 | # |
1146 | |||
1147 | # | ||
1148 | # USB Serial Converter support | ||
1149 | # | ||
1150 | # CONFIG_USB_SERIAL is not set | 1177 | # CONFIG_USB_SERIAL is not set |
1151 | 1178 | ||
1152 | # | 1179 | # |
@@ -1172,14 +1199,6 @@ CONFIG_USB_STORAGE=m | |||
1172 | # CONFIG_USB_TRANCEVIBRATOR is not set | 1199 | # CONFIG_USB_TRANCEVIBRATOR is not set |
1173 | # CONFIG_USB_IOWARRIOR is not set | 1200 | # CONFIG_USB_IOWARRIOR is not set |
1174 | # CONFIG_USB_TEST is not set | 1201 | # CONFIG_USB_TEST is not set |
1175 | |||
1176 | # | ||
1177 | # USB DSL modem support | ||
1178 | # | ||
1179 | |||
1180 | # | ||
1181 | # USB Gadget Support | ||
1182 | # | ||
1183 | # CONFIG_USB_GADGET is not set | 1202 | # CONFIG_USB_GADGET is not set |
1184 | # CONFIG_MMC is not set | 1203 | # CONFIG_MMC is not set |
1185 | # CONFIG_NEW_LEDS is not set | 1204 | # CONFIG_NEW_LEDS is not set |
@@ -1332,11 +1351,6 @@ CONFIG_NLS_DEFAULT="iso8859-1" | |||
1332 | # CONFIG_NLS_KOI8_U is not set | 1351 | # CONFIG_NLS_KOI8_U is not set |
1333 | # CONFIG_NLS_UTF8 is not set | 1352 | # CONFIG_NLS_UTF8 is not set |
1334 | # CONFIG_DLM is not set | 1353 | # CONFIG_DLM is not set |
1335 | CONFIG_INSTRUMENTATION=y | ||
1336 | CONFIG_PROFILING=y | ||
1337 | CONFIG_OPROFILE=m | ||
1338 | CONFIG_KPROBES=y | ||
1339 | # CONFIG_MARKERS is not set | ||
1340 | 1354 | ||
1341 | # | 1355 | # |
1342 | # Kernel hacking | 1356 | # Kernel hacking |
@@ -1374,6 +1388,8 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1374 | CONFIG_FORCED_INLINING=y | 1388 | CONFIG_FORCED_INLINING=y |
1375 | # CONFIG_BOOT_PRINTK_DELAY is not set | 1389 | # CONFIG_BOOT_PRINTK_DELAY is not set |
1376 | # CONFIG_RCU_TORTURE_TEST is not set | 1390 | # CONFIG_RCU_TORTURE_TEST is not set |
1391 | # CONFIG_KPROBES_SANITY_TEST is not set | ||
1392 | # CONFIG_BACKTRACE_SELF_TEST is not set | ||
1377 | # CONFIG_LKDTM is not set | 1393 | # CONFIG_LKDTM is not set |
1378 | # CONFIG_FAULT_INJECTION is not set | 1394 | # CONFIG_FAULT_INJECTION is not set |
1379 | # CONFIG_SAMPLES is not set | 1395 | # CONFIG_SAMPLES is not set |
@@ -1396,8 +1412,9 @@ CONFIG_ASYNC_MEMCPY=m | |||
1396 | CONFIG_ASYNC_XOR=m | 1412 | CONFIG_ASYNC_XOR=m |
1397 | CONFIG_CRYPTO=y | 1413 | CONFIG_CRYPTO=y |
1398 | CONFIG_CRYPTO_ALGAPI=y | 1414 | CONFIG_CRYPTO_ALGAPI=y |
1399 | CONFIG_CRYPTO_AEAD=m | 1415 | CONFIG_CRYPTO_AEAD=y |
1400 | CONFIG_CRYPTO_BLKCIPHER=y | 1416 | CONFIG_CRYPTO_BLKCIPHER=y |
1417 | # CONFIG_CRYPTO_SEQIV is not set | ||
1401 | CONFIG_CRYPTO_HASH=y | 1418 | CONFIG_CRYPTO_HASH=y |
1402 | CONFIG_CRYPTO_MANAGER=y | 1419 | CONFIG_CRYPTO_MANAGER=y |
1403 | CONFIG_CRYPTO_HMAC=y | 1420 | CONFIG_CRYPTO_HMAC=y |
@@ -1416,6 +1433,9 @@ CONFIG_CRYPTO_CBC=y | |||
1416 | CONFIG_CRYPTO_PCBC=m | 1433 | CONFIG_CRYPTO_PCBC=m |
1417 | CONFIG_CRYPTO_LRW=m | 1434 | CONFIG_CRYPTO_LRW=m |
1418 | CONFIG_CRYPTO_XTS=m | 1435 | CONFIG_CRYPTO_XTS=m |
1436 | # CONFIG_CRYPTO_CTR is not set | ||
1437 | # CONFIG_CRYPTO_GCM is not set | ||
1438 | # CONFIG_CRYPTO_CCM is not set | ||
1419 | # CONFIG_CRYPTO_CRYPTD is not set | 1439 | # CONFIG_CRYPTO_CRYPTD is not set |
1420 | CONFIG_CRYPTO_DES=y | 1440 | CONFIG_CRYPTO_DES=y |
1421 | CONFIG_CRYPTO_FCRYPT=m | 1441 | CONFIG_CRYPTO_FCRYPT=m |
@@ -1431,13 +1451,16 @@ CONFIG_CRYPTO_ARC4=m | |||
1431 | CONFIG_CRYPTO_KHAZAD=m | 1451 | CONFIG_CRYPTO_KHAZAD=m |
1432 | CONFIG_CRYPTO_ANUBIS=m | 1452 | CONFIG_CRYPTO_ANUBIS=m |
1433 | CONFIG_CRYPTO_SEED=m | 1453 | CONFIG_CRYPTO_SEED=m |
1454 | # CONFIG_CRYPTO_SALSA20 is not set | ||
1434 | CONFIG_CRYPTO_DEFLATE=y | 1455 | CONFIG_CRYPTO_DEFLATE=y |
1435 | CONFIG_CRYPTO_MICHAEL_MIC=m | 1456 | CONFIG_CRYPTO_MICHAEL_MIC=m |
1436 | CONFIG_CRYPTO_CRC32C=m | 1457 | CONFIG_CRYPTO_CRC32C=m |
1437 | CONFIG_CRYPTO_CAMELLIA=m | 1458 | CONFIG_CRYPTO_CAMELLIA=m |
1438 | CONFIG_CRYPTO_TEST=m | 1459 | CONFIG_CRYPTO_TEST=m |
1439 | CONFIG_CRYPTO_AUTHENC=m | 1460 | CONFIG_CRYPTO_AUTHENC=m |
1461 | # CONFIG_CRYPTO_LZO is not set | ||
1440 | CONFIG_CRYPTO_HW=y | 1462 | CONFIG_CRYPTO_HW=y |
1463 | # CONFIG_CRYPTO_DEV_HIFN_795X is not set | ||
1441 | 1464 | ||
1442 | # | 1465 | # |
1443 | # Library routines | 1466 | # Library routines |
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index ef50d217432f..4b78b24ef413 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -11,7 +11,7 @@ obj-y := process.o setup.o cpu.o idprom.o \ | |||
11 | traps.o auxio.o una_asm.o sysfs.o iommu.o \ | 11 | traps.o auxio.o una_asm.o sysfs.o iommu.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o \ | 14 | power.o sbus.o sparc64_ksyms.o chmc.o \ |
15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o | 15 | visemul.o prom.o of_device.o hvapi.o sstate.o mdesc.o |
16 | 16 | ||
17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o | 17 | obj-$(CONFIG_STACKTRACE) += stacktrace.o |
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c index 4b9115a4d92e..5623a4d59dff 100644 --- a/arch/sparc64/kernel/iommu.c +++ b/arch/sparc64/kernel/iommu.c | |||
@@ -472,94 +472,15 @@ static void dma_4u_unmap_single(struct device *dev, dma_addr_t bus_addr, | |||
472 | spin_unlock_irqrestore(&iommu->lock, flags); | 472 | spin_unlock_irqrestore(&iommu->lock, flags); |
473 | } | 473 | } |
474 | 474 | ||
475 | #define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG)))) | ||
476 | |||
477 | static void fill_sg(iopte_t *iopte, struct scatterlist *sg, | ||
478 | int nused, int nelems, | ||
479 | unsigned long iopte_protection) | ||
480 | { | ||
481 | struct scatterlist *dma_sg = sg; | ||
482 | int i; | ||
483 | |||
484 | for (i = 0; i < nused; i++) { | ||
485 | unsigned long pteval = ~0UL; | ||
486 | u32 dma_npages; | ||
487 | |||
488 | dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) + | ||
489 | dma_sg->dma_length + | ||
490 | ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT; | ||
491 | do { | ||
492 | unsigned long offset; | ||
493 | signed int len; | ||
494 | |||
495 | /* If we are here, we know we have at least one | ||
496 | * more page to map. So walk forward until we | ||
497 | * hit a page crossing, and begin creating new | ||
498 | * mappings from that spot. | ||
499 | */ | ||
500 | for (;;) { | ||
501 | unsigned long tmp; | ||
502 | |||
503 | tmp = SG_ENT_PHYS_ADDRESS(sg); | ||
504 | len = sg->length; | ||
505 | if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { | ||
506 | pteval = tmp & IO_PAGE_MASK; | ||
507 | offset = tmp & (IO_PAGE_SIZE - 1UL); | ||
508 | break; | ||
509 | } | ||
510 | if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) { | ||
511 | pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK; | ||
512 | offset = 0UL; | ||
513 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); | ||
514 | break; | ||
515 | } | ||
516 | sg = sg_next(sg); | ||
517 | nelems--; | ||
518 | } | ||
519 | |||
520 | pteval = iopte_protection | (pteval & IOPTE_PAGE); | ||
521 | while (len > 0) { | ||
522 | *iopte++ = __iopte(pteval); | ||
523 | pteval += IO_PAGE_SIZE; | ||
524 | len -= (IO_PAGE_SIZE - offset); | ||
525 | offset = 0; | ||
526 | dma_npages--; | ||
527 | } | ||
528 | |||
529 | pteval = (pteval & IOPTE_PAGE) + len; | ||
530 | sg = sg_next(sg); | ||
531 | nelems--; | ||
532 | |||
533 | /* Skip over any tail mappings we've fully mapped, | ||
534 | * adjusting pteval along the way. Stop when we | ||
535 | * detect a page crossing event. | ||
536 | */ | ||
537 | while (nelems && | ||
538 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && | ||
539 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && | ||
540 | ((pteval ^ | ||
541 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { | ||
542 | pteval += sg->length; | ||
543 | sg = sg_next(sg); | ||
544 | nelems--; | ||
545 | } | ||
546 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) | ||
547 | pteval = ~0UL; | ||
548 | } while (dma_npages != 0); | ||
549 | dma_sg = sg_next(dma_sg); | ||
550 | } | ||
551 | } | ||
552 | |||
553 | static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | 475 | static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, |
554 | int nelems, enum dma_data_direction direction) | 476 | int nelems, enum dma_data_direction direction) |
555 | { | 477 | { |
556 | struct iommu *iommu; | 478 | unsigned long flags, ctx, i, npages, iopte_protection; |
479 | struct scatterlist *sg; | ||
557 | struct strbuf *strbuf; | 480 | struct strbuf *strbuf; |
558 | unsigned long flags, ctx, npages, iopte_protection; | 481 | struct iommu *iommu; |
559 | iopte_t *base; | 482 | iopte_t *base; |
560 | u32 dma_base; | 483 | u32 dma_base; |
561 | struct scatterlist *sgtmp; | ||
562 | int used; | ||
563 | 484 | ||
564 | /* Fast path single entry scatterlists. */ | 485 | /* Fast path single entry scatterlists. */ |
565 | if (nelems == 1) { | 486 | if (nelems == 1) { |
@@ -578,11 +499,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | |||
578 | if (unlikely(direction == DMA_NONE)) | 499 | if (unlikely(direction == DMA_NONE)) |
579 | goto bad_no_ctx; | 500 | goto bad_no_ctx; |
580 | 501 | ||
581 | /* Step 1: Prepare scatter list. */ | 502 | npages = calc_npages(sglist, nelems); |
582 | |||
583 | npages = prepare_sg(dev, sglist, nelems); | ||
584 | |||
585 | /* Step 2: Allocate a cluster and context, if necessary. */ | ||
586 | 503 | ||
587 | spin_lock_irqsave(&iommu->lock, flags); | 504 | spin_lock_irqsave(&iommu->lock, flags); |
588 | 505 | ||
@@ -599,18 +516,6 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | |||
599 | dma_base = iommu->page_table_map_base + | 516 | dma_base = iommu->page_table_map_base + |
600 | ((base - iommu->page_table) << IO_PAGE_SHIFT); | 517 | ((base - iommu->page_table) << IO_PAGE_SHIFT); |
601 | 518 | ||
602 | /* Step 3: Normalize DMA addresses. */ | ||
603 | used = nelems; | ||
604 | |||
605 | sgtmp = sglist; | ||
606 | while (used && sgtmp->dma_length) { | ||
607 | sgtmp->dma_address += dma_base; | ||
608 | sgtmp = sg_next(sgtmp); | ||
609 | used--; | ||
610 | } | ||
611 | used = nelems - used; | ||
612 | |||
613 | /* Step 4: Create the mappings. */ | ||
614 | if (strbuf->strbuf_enabled) | 519 | if (strbuf->strbuf_enabled) |
615 | iopte_protection = IOPTE_STREAMING(ctx); | 520 | iopte_protection = IOPTE_STREAMING(ctx); |
616 | else | 521 | else |
@@ -618,13 +523,27 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist, | |||
618 | if (direction != DMA_TO_DEVICE) | 523 | if (direction != DMA_TO_DEVICE) |
619 | iopte_protection |= IOPTE_WRITE; | 524 | iopte_protection |= IOPTE_WRITE; |
620 | 525 | ||
621 | fill_sg(base, sglist, used, nelems, iopte_protection); | 526 | for_each_sg(sglist, sg, nelems, i) { |
527 | unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg); | ||
528 | unsigned long slen = sg->length; | ||
529 | unsigned long this_npages; | ||
622 | 530 | ||
623 | #ifdef VERIFY_SG | 531 | this_npages = iommu_num_pages(paddr, slen); |
624 | verify_sglist(sglist, nelems, base, npages); | ||
625 | #endif | ||
626 | 532 | ||
627 | return used; | 533 | sg->dma_address = dma_base | (paddr & ~IO_PAGE_MASK); |
534 | sg->dma_length = slen; | ||
535 | |||
536 | paddr &= IO_PAGE_MASK; | ||
537 | while (this_npages--) { | ||
538 | iopte_val(*base) = iopte_protection | paddr; | ||
539 | |||
540 | base++; | ||
541 | paddr += IO_PAGE_SIZE; | ||
542 | dma_base += IO_PAGE_SIZE; | ||
543 | } | ||
544 | } | ||
545 | |||
546 | return nelems; | ||
628 | 547 | ||
629 | bad: | 548 | bad: |
630 | iommu_free_ctx(iommu, ctx); | 549 | iommu_free_ctx(iommu, ctx); |
@@ -637,11 +556,10 @@ bad_no_ctx: | |||
637 | static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | 556 | static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, |
638 | int nelems, enum dma_data_direction direction) | 557 | int nelems, enum dma_data_direction direction) |
639 | { | 558 | { |
640 | struct iommu *iommu; | 559 | unsigned long flags, ctx, i, npages; |
641 | struct strbuf *strbuf; | 560 | struct strbuf *strbuf; |
561 | struct iommu *iommu; | ||
642 | iopte_t *base; | 562 | iopte_t *base; |
643 | unsigned long flags, ctx, i, npages; | ||
644 | struct scatterlist *sg, *sgprv; | ||
645 | u32 bus_addr; | 563 | u32 bus_addr; |
646 | 564 | ||
647 | if (unlikely(direction == DMA_NONE)) { | 565 | if (unlikely(direction == DMA_NONE)) { |
@@ -654,15 +572,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
654 | 572 | ||
655 | bus_addr = sglist->dma_address & IO_PAGE_MASK; | 573 | bus_addr = sglist->dma_address & IO_PAGE_MASK; |
656 | 574 | ||
657 | sgprv = NULL; | 575 | npages = calc_npages(sglist, nelems); |
658 | for_each_sg(sglist, sg, nelems, i) { | ||
659 | if (sg->dma_length == 0) | ||
660 | break; | ||
661 | sgprv = sg; | ||
662 | } | ||
663 | |||
664 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - | ||
665 | bus_addr) >> IO_PAGE_SHIFT; | ||
666 | 576 | ||
667 | base = iommu->page_table + | 577 | base = iommu->page_table + |
668 | ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | 578 | ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); |
diff --git a/arch/sparc64/kernel/iommu_common.c b/arch/sparc64/kernel/iommu_common.c deleted file mode 100644 index 72a4acfe8c7b..000000000000 --- a/arch/sparc64/kernel/iommu_common.c +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | /* $Id: iommu_common.c,v 1.9 2001/12/17 07:05:09 davem Exp $ | ||
2 | * iommu_common.c: UltraSparc SBUS/PCI common iommu code. | ||
3 | * | ||
4 | * Copyright (C) 1999 David S. Miller (davem@redhat.com) | ||
5 | */ | ||
6 | |||
7 | #include <linux/dma-mapping.h> | ||
8 | #include "iommu_common.h" | ||
9 | |||
10 | /* You are _strongly_ advised to enable the following debugging code | ||
11 | * any time you make changes to the sg code below, run it for a while | ||
12 | * with filesystems mounted read-only before buying the farm... -DaveM | ||
13 | */ | ||
14 | |||
15 | #ifdef VERIFY_SG | ||
16 | static int verify_lengths(struct scatterlist *sglist, int nents, int npages) | ||
17 | { | ||
18 | int sg_len, dma_len; | ||
19 | int i, pgcount; | ||
20 | struct scatterlist *sg; | ||
21 | |||
22 | sg_len = 0; | ||
23 | for_each_sg(sglist, sg, nents, i) | ||
24 | sg_len += sg->length; | ||
25 | |||
26 | dma_len = 0; | ||
27 | for_each_sg(sglist, sg, nents, i) { | ||
28 | if (!sg->dma_length) | ||
29 | break; | ||
30 | dma_len += sg->dma_length; | ||
31 | } | ||
32 | |||
33 | if (sg_len != dma_len) { | ||
34 | printk("verify_lengths: Error, different, sg[%d] dma[%d]\n", | ||
35 | sg_len, dma_len); | ||
36 | return -1; | ||
37 | } | ||
38 | |||
39 | pgcount = 0; | ||
40 | for_each_sg(sglist, sg, nents, i) { | ||
41 | unsigned long start, end; | ||
42 | |||
43 | if (!sg->dma_length) | ||
44 | break; | ||
45 | |||
46 | start = sg->dma_address; | ||
47 | start = start & IO_PAGE_MASK; | ||
48 | |||
49 | end = sg->dma_address + sg->dma_length; | ||
50 | end = (end + (IO_PAGE_SIZE - 1)) & IO_PAGE_MASK; | ||
51 | |||
52 | pgcount += ((end - start) >> IO_PAGE_SHIFT); | ||
53 | } | ||
54 | |||
55 | if (pgcount != npages) { | ||
56 | printk("verify_lengths: Error, page count wrong, " | ||
57 | "npages[%d] pgcount[%d]\n", | ||
58 | npages, pgcount); | ||
59 | return -1; | ||
60 | } | ||
61 | |||
62 | /* This test passes... */ | ||
63 | return 0; | ||
64 | } | ||
65 | |||
66 | static int verify_one_map(struct scatterlist *dma_sg, struct scatterlist **__sg, int nents, iopte_t **__iopte) | ||
67 | { | ||
68 | struct scatterlist *sg = *__sg; | ||
69 | iopte_t *iopte = *__iopte; | ||
70 | u32 dlen = dma_sg->dma_length; | ||
71 | u32 daddr; | ||
72 | unsigned int sglen; | ||
73 | unsigned long sgaddr; | ||
74 | |||
75 | daddr = dma_sg->dma_address; | ||
76 | sglen = sg->length; | ||
77 | sgaddr = (unsigned long) sg_virt(sg); | ||
78 | while (dlen > 0) { | ||
79 | unsigned long paddr; | ||
80 | |||
81 | /* SG and DMA_SG must begin at the same sub-page boundary. */ | ||
82 | if ((sgaddr & ~IO_PAGE_MASK) != (daddr & ~IO_PAGE_MASK)) { | ||
83 | printk("verify_one_map: Wrong start offset " | ||
84 | "sg[%08lx] dma[%08x]\n", | ||
85 | sgaddr, daddr); | ||
86 | nents = -1; | ||
87 | goto out; | ||
88 | } | ||
89 | |||
90 | /* Verify the IOPTE points to the right page. */ | ||
91 | paddr = iopte_val(*iopte) & IOPTE_PAGE; | ||
92 | if ((paddr + PAGE_OFFSET) != (sgaddr & IO_PAGE_MASK)) { | ||
93 | printk("verify_one_map: IOPTE[%08lx] maps the " | ||
94 | "wrong page, should be [%08lx]\n", | ||
95 | iopte_val(*iopte), (sgaddr & IO_PAGE_MASK) - PAGE_OFFSET); | ||
96 | nents = -1; | ||
97 | goto out; | ||
98 | } | ||
99 | |||
100 | /* If this SG crosses a page, adjust to that next page | ||
101 | * boundary and loop. | ||
102 | */ | ||
103 | if ((sgaddr & IO_PAGE_MASK) ^ ((sgaddr + sglen - 1) & IO_PAGE_MASK)) { | ||
104 | unsigned long next_page, diff; | ||
105 | |||
106 | next_page = (sgaddr + IO_PAGE_SIZE) & IO_PAGE_MASK; | ||
107 | diff = next_page - sgaddr; | ||
108 | sgaddr += diff; | ||
109 | daddr += diff; | ||
110 | sglen -= diff; | ||
111 | dlen -= diff; | ||
112 | if (dlen > 0) | ||
113 | iopte++; | ||
114 | continue; | ||
115 | } | ||
116 | |||
117 | /* SG wholly consumed within this page. */ | ||
118 | daddr += sglen; | ||
119 | dlen -= sglen; | ||
120 | |||
121 | if (dlen > 0 && ((daddr & ~IO_PAGE_MASK) == 0)) | ||
122 | iopte++; | ||
123 | |||
124 | sg = sg_next(sg); | ||
125 | if (--nents <= 0) | ||
126 | break; | ||
127 | sgaddr = (unsigned long) sg_virt(sg); | ||
128 | sglen = sg->length; | ||
129 | } | ||
130 | if (dlen < 0) { | ||
131 | /* Transfer overrun, big problems. */ | ||
132 | printk("verify_one_map: Transfer overrun by %d bytes.\n", | ||
133 | -dlen); | ||
134 | nents = -1; | ||
135 | } else { | ||
136 | /* Advance to next dma_sg implies that the next iopte will | ||
137 | * begin it. | ||
138 | */ | ||
139 | iopte++; | ||
140 | } | ||
141 | |||
142 | out: | ||
143 | *__sg = sg; | ||
144 | *__iopte = iopte; | ||
145 | return nents; | ||
146 | } | ||
147 | |||
148 | static int verify_maps(struct scatterlist *sg, int nents, iopte_t *iopte) | ||
149 | { | ||
150 | struct scatterlist *dma_sg = sg; | ||
151 | struct scatterlist *orig_dma_sg = dma_sg; | ||
152 | int orig_nents = nents; | ||
153 | |||
154 | for (;;) { | ||
155 | nents = verify_one_map(dma_sg, &sg, nents, &iopte); | ||
156 | if (nents <= 0) | ||
157 | break; | ||
158 | dma_sg = sg_next(dma_sg); | ||
159 | if (dma_sg->dma_length == 0) | ||
160 | break; | ||
161 | } | ||
162 | |||
163 | if (nents > 0) { | ||
164 | printk("verify_maps: dma maps consumed by some sgs remain (%d)\n", | ||
165 | nents); | ||
166 | return -1; | ||
167 | } | ||
168 | |||
169 | if (nents < 0) { | ||
170 | printk("verify_maps: Error, messed up mappings, " | ||
171 | "at sg %d dma_sg %d\n", | ||
172 | (int) (orig_nents + nents), (int) (dma_sg - orig_dma_sg)); | ||
173 | return -1; | ||
174 | } | ||
175 | |||
176 | /* This test passes... */ | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | void verify_sglist(struct scatterlist *sglist, int nents, iopte_t *iopte, int npages) | ||
181 | { | ||
182 | struct scatterlist *sg; | ||
183 | |||
184 | if (verify_lengths(sglist, nents, npages) < 0 || | ||
185 | verify_maps(sglist, nents, iopte) < 0) { | ||
186 | int i; | ||
187 | |||
188 | printk("verify_sglist: Crap, messed up mappings, dumping, iodma at "); | ||
189 | printk("%016lx.\n", sglist->dma_address & IO_PAGE_MASK); | ||
190 | |||
191 | for_each_sg(sglist, sg, nents, i) { | ||
192 | printk("sg(%d): page_addr(%p) off(%x) length(%x) " | ||
193 | "dma_address[%016x] dma_length[%016x]\n", | ||
194 | i, | ||
195 | page_address(sg_page(sg)), sg->offset, | ||
196 | sg->length, | ||
197 | sg->dma_address, sg->dma_length); | ||
198 | } | ||
199 | } | ||
200 | |||
201 | /* Seems to be ok */ | ||
202 | } | ||
203 | #endif | ||
204 | |||
205 | unsigned long prepare_sg(struct device *dev, struct scatterlist *sg, int nents) | ||
206 | { | ||
207 | struct scatterlist *dma_sg = sg; | ||
208 | unsigned long prev; | ||
209 | u32 dent_addr, dent_len; | ||
210 | unsigned int max_seg_size; | ||
211 | |||
212 | prev = (unsigned long) sg_virt(sg); | ||
213 | prev += (unsigned long) (dent_len = sg->length); | ||
214 | dent_addr = (u32) ((unsigned long)(sg_virt(sg)) & (IO_PAGE_SIZE - 1UL)); | ||
215 | max_seg_size = dma_get_max_seg_size(dev); | ||
216 | while (--nents) { | ||
217 | unsigned long addr; | ||
218 | |||
219 | sg = sg_next(sg); | ||
220 | addr = (unsigned long) sg_virt(sg); | ||
221 | if (! VCONTIG(prev, addr) || | ||
222 | dent_len + sg->length > max_seg_size) { | ||
223 | dma_sg->dma_address = dent_addr; | ||
224 | dma_sg->dma_length = dent_len; | ||
225 | dma_sg = sg_next(dma_sg); | ||
226 | |||
227 | dent_addr = ((dent_addr + | ||
228 | dent_len + | ||
229 | (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT); | ||
230 | dent_addr <<= IO_PAGE_SHIFT; | ||
231 | dent_addr += addr & (IO_PAGE_SIZE - 1UL); | ||
232 | dent_len = 0; | ||
233 | } | ||
234 | dent_len += sg->length; | ||
235 | prev = addr + sg->length; | ||
236 | } | ||
237 | dma_sg->dma_address = dent_addr; | ||
238 | dma_sg->dma_length = dent_len; | ||
239 | |||
240 | if (dma_sg != sg) { | ||
241 | dma_sg = sg_next(dma_sg); | ||
242 | dma_sg->dma_length = 0; | ||
243 | } | ||
244 | |||
245 | return ((unsigned long) dent_addr + | ||
246 | (unsigned long) dent_len + | ||
247 | (IO_PAGE_SIZE - 1UL)) >> IO_PAGE_SHIFT; | ||
248 | } | ||
diff --git a/arch/sparc64/kernel/iommu_common.h b/arch/sparc64/kernel/iommu_common.h index a90d046e8024..4b5cafa2877a 100644 --- a/arch/sparc64/kernel/iommu_common.h +++ b/arch/sparc64/kernel/iommu_common.h | |||
@@ -30,6 +30,32 @@ | |||
30 | */ | 30 | */ |
31 | #define IOMMU_PAGE_SHIFT 13 | 31 | #define IOMMU_PAGE_SHIFT 13 |
32 | 32 | ||
33 | #define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG)))) | ||
34 | |||
35 | static inline unsigned long iommu_num_pages(unsigned long vaddr, | ||
36 | unsigned long slen) | ||
37 | { | ||
38 | unsigned long npages; | ||
39 | |||
40 | npages = IO_PAGE_ALIGN(vaddr + slen) - (vaddr & IO_PAGE_MASK); | ||
41 | npages >>= IO_PAGE_SHIFT; | ||
42 | |||
43 | return npages; | ||
44 | } | ||
45 | |||
46 | static inline unsigned long calc_npages(struct scatterlist *sglist, int nelems) | ||
47 | { | ||
48 | unsigned long i, npages = 0; | ||
49 | struct scatterlist *sg; | ||
50 | |||
51 | for_each_sg(sglist, sg, nelems, i) { | ||
52 | unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg); | ||
53 | npages += iommu_num_pages(paddr, sg->length); | ||
54 | } | ||
55 | |||
56 | return npages; | ||
57 | } | ||
58 | |||
33 | /* You are _strongly_ advised to enable the following debugging code | 59 | /* You are _strongly_ advised to enable the following debugging code |
34 | * any time you make changes to the sg code below, run it for a while | 60 | * any time you make changes to the sg code below, run it for a while |
35 | * with filesystems mounted read-only before buying the farm... -DaveM | 61 | * with filesystems mounted read-only before buying the farm... -DaveM |
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 5ea2eab1ccda..61baf8dc095e 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c | |||
@@ -365,113 +365,14 @@ static void dma_4v_unmap_single(struct device *dev, dma_addr_t bus_addr, | |||
365 | spin_unlock_irqrestore(&iommu->lock, flags); | 365 | spin_unlock_irqrestore(&iommu->lock, flags); |
366 | } | 366 | } |
367 | 367 | ||
368 | #define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG)))) | ||
369 | |||
370 | static long fill_sg(long entry, struct device *dev, | ||
371 | struct scatterlist *sg, | ||
372 | int nused, int nelems, unsigned long prot) | ||
373 | { | ||
374 | struct scatterlist *dma_sg = sg; | ||
375 | unsigned long flags; | ||
376 | int i; | ||
377 | |||
378 | local_irq_save(flags); | ||
379 | |||
380 | iommu_batch_start(dev, prot, entry); | ||
381 | |||
382 | for (i = 0; i < nused; i++) { | ||
383 | unsigned long pteval = ~0UL; | ||
384 | u32 dma_npages; | ||
385 | |||
386 | dma_npages = ((dma_sg->dma_address & (IO_PAGE_SIZE - 1UL)) + | ||
387 | dma_sg->dma_length + | ||
388 | ((IO_PAGE_SIZE - 1UL))) >> IO_PAGE_SHIFT; | ||
389 | do { | ||
390 | unsigned long offset; | ||
391 | signed int len; | ||
392 | |||
393 | /* If we are here, we know we have at least one | ||
394 | * more page to map. So walk forward until we | ||
395 | * hit a page crossing, and begin creating new | ||
396 | * mappings from that spot. | ||
397 | */ | ||
398 | for (;;) { | ||
399 | unsigned long tmp; | ||
400 | |||
401 | tmp = SG_ENT_PHYS_ADDRESS(sg); | ||
402 | len = sg->length; | ||
403 | if (((tmp ^ pteval) >> IO_PAGE_SHIFT) != 0UL) { | ||
404 | pteval = tmp & IO_PAGE_MASK; | ||
405 | offset = tmp & (IO_PAGE_SIZE - 1UL); | ||
406 | break; | ||
407 | } | ||
408 | if (((tmp ^ (tmp + len - 1UL)) >> IO_PAGE_SHIFT) != 0UL) { | ||
409 | pteval = (tmp + IO_PAGE_SIZE) & IO_PAGE_MASK; | ||
410 | offset = 0UL; | ||
411 | len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); | ||
412 | break; | ||
413 | } | ||
414 | sg = sg_next(sg); | ||
415 | nelems--; | ||
416 | } | ||
417 | |||
418 | pteval = (pteval & IOPTE_PAGE); | ||
419 | while (len > 0) { | ||
420 | long err; | ||
421 | |||
422 | err = iommu_batch_add(pteval); | ||
423 | if (unlikely(err < 0L)) | ||
424 | goto iommu_map_failed; | ||
425 | |||
426 | pteval += IO_PAGE_SIZE; | ||
427 | len -= (IO_PAGE_SIZE - offset); | ||
428 | offset = 0; | ||
429 | dma_npages--; | ||
430 | } | ||
431 | |||
432 | pteval = (pteval & IOPTE_PAGE) + len; | ||
433 | sg = sg_next(sg); | ||
434 | nelems--; | ||
435 | |||
436 | /* Skip over any tail mappings we've fully mapped, | ||
437 | * adjusting pteval along the way. Stop when we | ||
438 | * detect a page crossing event. | ||
439 | */ | ||
440 | while (nelems && | ||
441 | (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && | ||
442 | (pteval == SG_ENT_PHYS_ADDRESS(sg)) && | ||
443 | ((pteval ^ | ||
444 | (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { | ||
445 | pteval += sg->length; | ||
446 | sg = sg_next(sg); | ||
447 | nelems--; | ||
448 | } | ||
449 | if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) | ||
450 | pteval = ~0UL; | ||
451 | } while (dma_npages != 0); | ||
452 | dma_sg = sg_next(dma_sg); | ||
453 | } | ||
454 | |||
455 | if (unlikely(iommu_batch_end() < 0L)) | ||
456 | goto iommu_map_failed; | ||
457 | |||
458 | local_irq_restore(flags); | ||
459 | return 0; | ||
460 | |||
461 | iommu_map_failed: | ||
462 | local_irq_restore(flags); | ||
463 | return -1L; | ||
464 | } | ||
465 | |||
466 | static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | 368 | static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, |
467 | int nelems, enum dma_data_direction direction) | 369 | int nelems, enum dma_data_direction direction) |
468 | { | 370 | { |
371 | unsigned long flags, npages, i, prot; | ||
372 | struct scatterlist *sg; | ||
469 | struct iommu *iommu; | 373 | struct iommu *iommu; |
470 | unsigned long flags, npages, prot; | ||
471 | u32 dma_base; | ||
472 | struct scatterlist *sgtmp; | ||
473 | long entry, err; | 374 | long entry, err; |
474 | int used; | 375 | u32 dma_base; |
475 | 376 | ||
476 | /* Fast path single entry scatterlists. */ | 377 | /* Fast path single entry scatterlists. */ |
477 | if (nelems == 1) { | 378 | if (nelems == 1) { |
@@ -489,10 +390,8 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | |||
489 | if (unlikely(direction == DMA_NONE)) | 390 | if (unlikely(direction == DMA_NONE)) |
490 | goto bad; | 391 | goto bad; |
491 | 392 | ||
492 | /* Step 1: Prepare scatter list. */ | 393 | npages = calc_npages(sglist, nelems); |
493 | npages = prepare_sg(dev, sglist, nelems); | ||
494 | 394 | ||
495 | /* Step 2: Allocate a cluster and context, if necessary. */ | ||
496 | spin_lock_irqsave(&iommu->lock, flags); | 395 | spin_lock_irqsave(&iommu->lock, flags); |
497 | entry = arena_alloc(&iommu->arena, npages); | 396 | entry = arena_alloc(&iommu->arena, npages); |
498 | spin_unlock_irqrestore(&iommu->lock, flags); | 397 | spin_unlock_irqrestore(&iommu->lock, flags); |
@@ -503,27 +402,45 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist, | |||
503 | dma_base = iommu->page_table_map_base + | 402 | dma_base = iommu->page_table_map_base + |
504 | (entry << IO_PAGE_SHIFT); | 403 | (entry << IO_PAGE_SHIFT); |
505 | 404 | ||
506 | /* Step 3: Normalize DMA addresses. */ | ||
507 | used = nelems; | ||
508 | |||
509 | sgtmp = sglist; | ||
510 | while (used && sgtmp->dma_length) { | ||
511 | sgtmp->dma_address += dma_base; | ||
512 | sgtmp = sg_next(sgtmp); | ||
513 | used--; | ||
514 | } | ||
515 | used = nelems - used; | ||
516 | |||
517 | /* Step 4: Create the mappings. */ | ||
518 | prot = HV_PCI_MAP_ATTR_READ; | 405 | prot = HV_PCI_MAP_ATTR_READ; |
519 | if (direction != DMA_TO_DEVICE) | 406 | if (direction != DMA_TO_DEVICE) |
520 | prot |= HV_PCI_MAP_ATTR_WRITE; | 407 | prot |= HV_PCI_MAP_ATTR_WRITE; |
521 | 408 | ||
522 | err = fill_sg(entry, dev, sglist, used, nelems, prot); | 409 | local_irq_save(flags); |
410 | |||
411 | iommu_batch_start(dev, prot, entry); | ||
412 | |||
413 | for_each_sg(sglist, sg, nelems, i) { | ||
414 | unsigned long paddr = SG_ENT_PHYS_ADDRESS(sg); | ||
415 | unsigned long slen = sg->length; | ||
416 | unsigned long this_npages; | ||
417 | |||
418 | this_npages = iommu_num_pages(paddr, slen); | ||
419 | |||
420 | sg->dma_address = dma_base | (paddr & ~IO_PAGE_MASK); | ||
421 | sg->dma_length = slen; | ||
422 | |||
423 | paddr &= IO_PAGE_MASK; | ||
424 | while (this_npages--) { | ||
425 | err = iommu_batch_add(paddr); | ||
426 | if (unlikely(err < 0L)) { | ||
427 | local_irq_restore(flags); | ||
428 | goto iommu_map_failed; | ||
429 | } | ||
430 | |||
431 | paddr += IO_PAGE_SIZE; | ||
432 | dma_base += IO_PAGE_SIZE; | ||
433 | } | ||
434 | } | ||
435 | |||
436 | err = iommu_batch_end(); | ||
437 | |||
438 | local_irq_restore(flags); | ||
439 | |||
523 | if (unlikely(err < 0L)) | 440 | if (unlikely(err < 0L)) |
524 | goto iommu_map_failed; | 441 | goto iommu_map_failed; |
525 | 442 | ||
526 | return used; | 443 | return nelems; |
527 | 444 | ||
528 | bad: | 445 | bad: |
529 | if (printk_ratelimit()) | 446 | if (printk_ratelimit()) |
@@ -541,12 +458,11 @@ iommu_map_failed: | |||
541 | static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | 458 | static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, |
542 | int nelems, enum dma_data_direction direction) | 459 | int nelems, enum dma_data_direction direction) |
543 | { | 460 | { |
461 | unsigned long flags, npages; | ||
544 | struct pci_pbm_info *pbm; | 462 | struct pci_pbm_info *pbm; |
463 | u32 devhandle, bus_addr; | ||
545 | struct iommu *iommu; | 464 | struct iommu *iommu; |
546 | unsigned long flags, i, npages; | ||
547 | struct scatterlist *sg, *sgprv; | ||
548 | long entry; | 465 | long entry; |
549 | u32 devhandle, bus_addr; | ||
550 | 466 | ||
551 | if (unlikely(direction == DMA_NONE)) { | 467 | if (unlikely(direction == DMA_NONE)) { |
552 | if (printk_ratelimit()) | 468 | if (printk_ratelimit()) |
@@ -558,16 +474,8 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist, | |||
558 | devhandle = pbm->devhandle; | 474 | devhandle = pbm->devhandle; |
559 | 475 | ||
560 | bus_addr = sglist->dma_address & IO_PAGE_MASK; | 476 | bus_addr = sglist->dma_address & IO_PAGE_MASK; |
561 | sgprv = NULL; | ||
562 | for_each_sg(sglist, sg, nelems, i) { | ||
563 | if (sg->dma_length == 0) | ||
564 | break; | ||
565 | |||
566 | sgprv = sg; | ||
567 | } | ||
568 | 477 | ||
569 | npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) - | 478 | npages = calc_npages(sglist, nelems); |
570 | bus_addr) >> IO_PAGE_SHIFT; | ||
571 | 479 | ||
572 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); | 480 | entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); |
573 | 481 | ||
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index c39944927f1a..a8052b76df41 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c | |||
@@ -46,8 +46,6 @@ | |||
46 | #include <asm/ldc.h> | 46 | #include <asm/ldc.h> |
47 | #include <asm/hypervisor.h> | 47 | #include <asm/hypervisor.h> |
48 | 48 | ||
49 | extern void calibrate_delay(void); | ||
50 | |||
51 | int sparc64_multi_core __read_mostly; | 49 | int sparc64_multi_core __read_mostly; |
52 | 50 | ||
53 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; | 51 | cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; |
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 60765e314bd8..8649635d6d74 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -277,6 +277,7 @@ EXPORT_SYMBOL(sys_getpid); | |||
277 | EXPORT_SYMBOL(sys_geteuid); | 277 | EXPORT_SYMBOL(sys_geteuid); |
278 | EXPORT_SYMBOL(sys_getuid); | 278 | EXPORT_SYMBOL(sys_getuid); |
279 | EXPORT_SYMBOL(sys_getegid); | 279 | EXPORT_SYMBOL(sys_getegid); |
280 | EXPORT_SYMBOL(sysctl_nr_open); | ||
280 | EXPORT_SYMBOL(sys_getgid); | 281 | EXPORT_SYMBOL(sys_getgid); |
281 | EXPORT_SYMBOL(svr4_getcontext); | 282 | EXPORT_SYMBOL(svr4_getcontext); |
282 | EXPORT_SYMBOL(svr4_setcontext); | 283 | EXPORT_SYMBOL(svr4_setcontext); |
diff --git a/arch/sparc64/kernel/systbls.S b/arch/sparc64/kernel/systbls.S index b8058906e727..adc62f490f36 100644 --- a/arch/sparc64/kernel/systbls.S +++ b/arch/sparc64/kernel/systbls.S | |||
@@ -80,7 +80,8 @@ sys_call_table32: | |||
80 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare | 80 | .word sys_fchmodat, sys_faccessat, compat_sys_pselect6, compat_sys_ppoll, sys_unshare |
81 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy | 81 | /*300*/ .word compat_sys_set_robust_list, compat_sys_get_robust_list, compat_sys_migrate_pages, compat_sys_mbind, compat_sys_get_mempolicy |
82 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait | 82 | .word compat_sys_set_mempolicy, compat_sys_kexec_load, compat_sys_move_pages, sys_getcpu, compat_sys_epoll_pwait |
83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_ni_syscall, sys_eventfd, compat_sys_fallocate | 83 | /*310*/ .word compat_sys_utimensat, compat_sys_signalfd, sys_timerfd_create, sys_eventfd, compat_sys_fallocate |
84 | .word compat_sys_timerfd_settime, compat_sys_timerfd_gettime | ||
84 | 85 | ||
85 | #endif /* CONFIG_COMPAT */ | 86 | #endif /* CONFIG_COMPAT */ |
86 | 87 | ||
@@ -152,7 +153,8 @@ sys_call_table: | |||
152 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare | 153 | .word sys_fchmodat, sys_faccessat, sys_pselect6, sys_ppoll, sys_unshare |
153 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy | 154 | /*300*/ .word sys_set_robust_list, sys_get_robust_list, sys_migrate_pages, sys_mbind, sys_get_mempolicy |
154 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait | 155 | .word sys_set_mempolicy, sys_kexec_load, sys_move_pages, sys_getcpu, sys_epoll_pwait |
155 | /*310*/ .word sys_utimensat, sys_signalfd, sys_ni_syscall, sys_eventfd, sys_fallocate | 156 | /*310*/ .word sys_utimensat, sys_signalfd, sys_timerfd_create, sys_eventfd, sys_fallocate |
157 | .word sys_timerfd_settime, sys_timerfd_gettime | ||
156 | 158 | ||
157 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ | 159 | #if defined(CONFIG_SUNOS_EMUL) || defined(CONFIG_SOLARIS_EMUL) || \ |
158 | defined(CONFIG_SOLARIS_EMUL_MODULE) | 160 | defined(CONFIG_SOLARIS_EMUL_MODULE) |
@@ -271,6 +273,7 @@ sunos_sys_table: | |||
271 | .word sunos_nosys, sunos_nosys, sunos_nosys | 273 | .word sunos_nosys, sunos_nosys, sunos_nosys |
272 | .word sunos_nosys | 274 | .word sunos_nosys |
273 | /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys | 275 | /*310*/ .word sunos_nosys, sunos_nosys, sunos_nosys |
274 | .word sunos_nosys, sunos_nosys | 276 | .word sunos_nosys, sunos_nosys, sunos_nosys |
277 | .word sunos_nosys | ||
275 | 278 | ||
276 | #endif | 279 | #endif |
diff --git a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c index 4352ee4d8dac..d204f1ab1d4c 100644 --- a/arch/sparc64/kernel/time.c +++ b/arch/sparc64/kernel/time.c | |||
@@ -1707,6 +1707,11 @@ static void __exit rtc_mini_exit(void) | |||
1707 | misc_deregister(&rtc_mini_dev); | 1707 | misc_deregister(&rtc_mini_dev); |
1708 | } | 1708 | } |
1709 | 1709 | ||
1710 | int __devinit read_current_timer(unsigned long *timer_val) | ||
1711 | { | ||
1712 | *timer_val = tick_ops->get_tick(); | ||
1713 | return 0; | ||
1714 | } | ||
1710 | 1715 | ||
1711 | module_init(rtc_mini_init); | 1716 | module_init(rtc_mini_init); |
1712 | module_exit(rtc_mini_exit); | 1717 | module_exit(rtc_mini_exit); |
diff --git a/arch/sparc64/solaris/fs.c b/arch/sparc64/solaris/fs.c index 61be597bf430..9311bfe4f2f7 100644 --- a/arch/sparc64/solaris/fs.c +++ b/arch/sparc64/solaris/fs.c | |||
@@ -624,7 +624,7 @@ asmlinkage int solaris_ulimit(int cmd, int val) | |||
624 | case 3: /* UL_GMEMLIM */ | 624 | case 3: /* UL_GMEMLIM */ |
625 | return current->signal->rlim[RLIMIT_DATA].rlim_cur; | 625 | return current->signal->rlim[RLIMIT_DATA].rlim_cur; |
626 | case 4: /* UL_GDESLIM */ | 626 | case 4: /* UL_GDESLIM */ |
627 | return NR_OPEN; | 627 | return sysctl_nr_open; |
628 | } | 628 | } |
629 | return -EINVAL; | 629 | return -EINVAL; |
630 | } | 630 | } |
diff --git a/arch/sparc64/solaris/timod.c b/arch/sparc64/solaris/timod.c index a9d32ceabf26..f53123c02c2b 100644 --- a/arch/sparc64/solaris/timod.c +++ b/arch/sparc64/solaris/timod.c | |||
@@ -859,7 +859,8 @@ asmlinkage int solaris_getmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) | |||
859 | 859 | ||
860 | SOLD("entry"); | 860 | SOLD("entry"); |
861 | lock_kernel(); | 861 | lock_kernel(); |
862 | if(fd >= NR_OPEN) goto out; | 862 | if (fd >= sysctl_nr_open) |
863 | goto out; | ||
863 | 864 | ||
864 | fdt = files_fdtable(current->files); | 865 | fdt = files_fdtable(current->files); |
865 | filp = fdt->fd[fd]; | 866 | filp = fdt->fd[fd]; |
@@ -927,7 +928,8 @@ asmlinkage int solaris_putmsg(unsigned int fd, u32 arg1, u32 arg2, u32 arg3) | |||
927 | 928 | ||
928 | SOLD("entry"); | 929 | SOLD("entry"); |
929 | lock_kernel(); | 930 | lock_kernel(); |
930 | if(fd >= NR_OPEN) goto out; | 931 | if (fd >= sysctl_nr_open) |
932 | goto out; | ||
931 | 933 | ||
932 | fdt = files_fdtable(current->files); | 934 | fdt = files_fdtable(current->files); |
933 | filp = fdt->fd[fd]; | 935 | filp = fdt->fd[fd]; |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 434821187cfc..e6728bd61cc1 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -415,7 +415,7 @@ config HPET_TIMER | |||
415 | 415 | ||
416 | config HPET_EMULATE_RTC | 416 | config HPET_EMULATE_RTC |
417 | def_bool y | 417 | def_bool y |
418 | depends on HPET_TIMER && (RTC=y || RTC=m) | 418 | depends on HPET_TIMER && (RTC=y || RTC=m || RTC_DRV_CMOS=m || RTC_DRV_CMOS=y) |
419 | 419 | ||
420 | # Mark as embedded because too many people got it wrong. | 420 | # Mark as embedded because too many people got it wrong. |
421 | # The code disables itself when not needed. | 421 | # The code disables itself when not needed. |
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index d9313d9adced..f86a3c4a2669 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -637,7 +637,7 @@ void __init early_cpu_init(void) | |||
637 | } | 637 | } |
638 | 638 | ||
639 | /* Make sure %fs is initialized properly in idle threads */ | 639 | /* Make sure %fs is initialized properly in idle threads */ |
640 | struct pt_regs * __devinit idle_regs(struct pt_regs *regs) | 640 | struct pt_regs * __cpuinit idle_regs(struct pt_regs *regs) |
641 | { | 641 | { |
642 | memset(regs, 0, sizeof(struct pt_regs)); | 642 | memset(regs, 0, sizeof(struct pt_regs)); |
643 | regs->fs = __KERNEL_PERCPU; | 643 | regs->fs = __KERNEL_PERCPU; |
diff --git a/arch/x86/kernel/cpu/cyrix.c b/arch/x86/kernel/cpu/cyrix.c index 404a6a2d4016..7139b0262703 100644 --- a/arch/x86/kernel/cpu/cyrix.c +++ b/arch/x86/kernel/cpu/cyrix.c | |||
@@ -83,8 +83,6 @@ static char cyrix_model_mult2[] __cpuinitdata = "12233445"; | |||
83 | * FIXME: our newer udelay uses the tsc. We don't need to frob with SLOP | 83 | * FIXME: our newer udelay uses the tsc. We don't need to frob with SLOP |
84 | */ | 84 | */ |
85 | 85 | ||
86 | extern void calibrate_delay(void) __init; | ||
87 | |||
88 | static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) | 86 | static void __cpuinit check_cx686_slop(struct cpuinfo_x86 *c) |
89 | { | 87 | { |
90 | unsigned long flags; | 88 | unsigned long flags; |
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c index 5787a0c3e296..579b9b740c7c 100644 --- a/arch/x86/kernel/smpboot_32.c +++ b/arch/x86/kernel/smpboot_32.c | |||
@@ -202,8 +202,6 @@ valid_k7: | |||
202 | ; | 202 | ; |
203 | } | 203 | } |
204 | 204 | ||
205 | extern void calibrate_delay(void); | ||
206 | |||
207 | static atomic_t init_deasserted; | 205 | static atomic_t init_deasserted; |
208 | 206 | ||
209 | static void __cpuinit smp_callin(void) | 207 | static void __cpuinit smp_callin(void) |
diff --git a/arch/x86/lib/delay_32.c b/arch/x86/lib/delay_32.c index aad9d95469dc..4535e6d147ad 100644 --- a/arch/x86/lib/delay_32.c +++ b/arch/x86/lib/delay_32.c | |||
@@ -12,8 +12,10 @@ | |||
12 | 12 | ||
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/timex.h> | ||
15 | #include <linux/preempt.h> | 16 | #include <linux/preempt.h> |
16 | #include <linux/delay.h> | 17 | #include <linux/delay.h> |
18 | #include <linux/init.h> | ||
17 | 19 | ||
18 | #include <asm/processor.h> | 20 | #include <asm/processor.h> |
19 | #include <asm/delay.h> | 21 | #include <asm/delay.h> |
@@ -63,7 +65,7 @@ void use_tsc_delay(void) | |||
63 | delay_fn = delay_tsc; | 65 | delay_fn = delay_tsc; |
64 | } | 66 | } |
65 | 67 | ||
66 | int read_current_timer(unsigned long *timer_val) | 68 | int __devinit read_current_timer(unsigned long *timer_val) |
67 | { | 69 | { |
68 | if (delay_fn == delay_tsc) { | 70 | if (delay_fn == delay_tsc) { |
69 | rdtscl(*timer_val); | 71 | rdtscl(*timer_val); |
diff --git a/arch/x86/lib/delay_64.c b/arch/x86/lib/delay_64.c index 45cdd3fbd91c..bbc610518516 100644 --- a/arch/x86/lib/delay_64.c +++ b/arch/x86/lib/delay_64.c | |||
@@ -10,8 +10,10 @@ | |||
10 | 10 | ||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
13 | #include <linux/timex.h> | ||
13 | #include <linux/preempt.h> | 14 | #include <linux/preempt.h> |
14 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/init.h> | ||
15 | 17 | ||
16 | #include <asm/delay.h> | 18 | #include <asm/delay.h> |
17 | #include <asm/msr.h> | 19 | #include <asm/msr.h> |
@@ -20,7 +22,7 @@ | |||
20 | #include <asm/smp.h> | 22 | #include <asm/smp.h> |
21 | #endif | 23 | #endif |
22 | 24 | ||
23 | int read_current_timer(unsigned long *timer_value) | 25 | int __devinit read_current_timer(unsigned long *timer_value) |
24 | { | 26 | { |
25 | rdtscll(*timer_value); | 27 | rdtscll(*timer_value); |
26 | return 0; | 28 | return 0; |
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c index dffa786f61fe..3cc8eb2f36a9 100644 --- a/arch/x86/mach-voyager/voyager_smp.c +++ b/arch/x86/mach-voyager/voyager_smp.c | |||
@@ -444,8 +444,6 @@ static __u32 __init setup_trampoline(void) | |||
444 | static void __init start_secondary(void *unused) | 444 | static void __init start_secondary(void *unused) |
445 | { | 445 | { |
446 | __u8 cpuid = hard_smp_processor_id(); | 446 | __u8 cpuid = hard_smp_processor_id(); |
447 | /* external functions not defined in the headers */ | ||
448 | extern void calibrate_delay(void); | ||
449 | 447 | ||
450 | cpu_init(); | 448 | cpu_init(); |
451 | 449 | ||
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index bb55a78dcd62..16ce841f08d6 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -237,7 +237,6 @@ static void __set_pmd_pte(pte_t *kpte, unsigned long address, pte_t pte) | |||
237 | if (!SHARED_KERNEL_PMD) { | 237 | if (!SHARED_KERNEL_PMD) { |
238 | struct page *page; | 238 | struct page *page; |
239 | 239 | ||
240 | address = __pa(address); | ||
241 | list_for_each_entry(page, &pgd_list, lru) { | 240 | list_for_each_entry(page, &pgd_list, lru) { |
242 | pgd_t *pgd; | 241 | pgd_t *pgd; |
243 | pud_t *pud; | 242 | pud_t *pud; |
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 60d29fe0b1bd..8df1e842f6d4 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -204,7 +204,7 @@ again: | |||
204 | } | 204 | } |
205 | 205 | ||
206 | #ifndef CONFIG_GENERIC_CALIBRATE_DELAY | 206 | #ifndef CONFIG_GENERIC_CALIBRATE_DELAY |
207 | void __devinit calibrate_delay(void) | 207 | void __cpuinit calibrate_delay(void) |
208 | { | 208 | { |
209 | loops_per_jiffy = CCOUNT_PER_JIFFY; | 209 | loops_per_jiffy = CCOUNT_PER_JIFFY; |
210 | printk("Calibrating delay loop (skipped)... " | 210 | printk("Calibrating delay loop (skipped)... " |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 63e09c015ca0..c66637392bbc 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -5,7 +5,7 @@ obj-y := core.o sys.o bus.o dd.o \ | |||
5 | cpu.o firmware.o init.o map.o devres.o \ | 5 | cpu.o firmware.o init.o map.o devres.o \ |
6 | attribute_container.o transport_class.o | 6 | attribute_container.o transport_class.o |
7 | obj-y += power/ | 7 | obj-y += power/ |
8 | obj-$(CONFIG_HAS_DMA) += dma-mapping.o dmapool.o | 8 | obj-$(CONFIG_HAS_DMA) += dma-mapping.o |
9 | obj-$(CONFIG_ISA) += isa.o | 9 | obj-$(CONFIG_ISA) += isa.o |
10 | obj-$(CONFIG_FW_LOADER) += firmware_class.o | 10 | obj-$(CONFIG_FW_LOADER) += firmware_class.o |
11 | obj-$(CONFIG_NUMA) += node.o | 11 | obj-$(CONFIG_NUMA) += node.o |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index c5885f5ce0ac..499b003f9278 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -110,7 +110,7 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL); | |||
110 | * | 110 | * |
111 | * Initialize and register the CPU device. | 111 | * Initialize and register the CPU device. |
112 | */ | 112 | */ |
113 | int __devinit register_cpu(struct cpu *cpu, int num) | 113 | int __cpuinit register_cpu(struct cpu *cpu, int num) |
114 | { | 114 | { |
115 | int error; | 115 | int error; |
116 | cpu->node_id = cpu_to_node(num); | 116 | cpu->node_id = cpu_to_node(num); |
diff --git a/drivers/base/dmapool.c b/drivers/base/dmapool.c deleted file mode 100644 index b5034dc72a05..000000000000 --- a/drivers/base/dmapool.c +++ /dev/null | |||
@@ -1,481 +0,0 @@ | |||
1 | |||
2 | #include <linux/device.h> | ||
3 | #include <linux/mm.h> | ||
4 | #include <asm/io.h> /* Needed for i386 to build */ | ||
5 | #include <linux/dma-mapping.h> | ||
6 | #include <linux/dmapool.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/module.h> | ||
9 | #include <linux/poison.h> | ||
10 | #include <linux/sched.h> | ||
11 | |||
12 | /* | ||
13 | * Pool allocator ... wraps the dma_alloc_coherent page allocator, so | ||
14 | * small blocks are easily used by drivers for bus mastering controllers. | ||
15 | * This should probably be sharing the guts of the slab allocator. | ||
16 | */ | ||
17 | |||
18 | struct dma_pool { /* the pool */ | ||
19 | struct list_head page_list; | ||
20 | spinlock_t lock; | ||
21 | size_t blocks_per_page; | ||
22 | size_t size; | ||
23 | struct device *dev; | ||
24 | size_t allocation; | ||
25 | char name [32]; | ||
26 | wait_queue_head_t waitq; | ||
27 | struct list_head pools; | ||
28 | }; | ||
29 | |||
30 | struct dma_page { /* cacheable header for 'allocation' bytes */ | ||
31 | struct list_head page_list; | ||
32 | void *vaddr; | ||
33 | dma_addr_t dma; | ||
34 | unsigned in_use; | ||
35 | unsigned long bitmap [0]; | ||
36 | }; | ||
37 | |||
38 | #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) | ||
39 | |||
40 | static DEFINE_MUTEX (pools_lock); | ||
41 | |||
42 | static ssize_t | ||
43 | show_pools (struct device *dev, struct device_attribute *attr, char *buf) | ||
44 | { | ||
45 | unsigned temp; | ||
46 | unsigned size; | ||
47 | char *next; | ||
48 | struct dma_page *page; | ||
49 | struct dma_pool *pool; | ||
50 | |||
51 | next = buf; | ||
52 | size = PAGE_SIZE; | ||
53 | |||
54 | temp = scnprintf(next, size, "poolinfo - 0.1\n"); | ||
55 | size -= temp; | ||
56 | next += temp; | ||
57 | |||
58 | mutex_lock(&pools_lock); | ||
59 | list_for_each_entry(pool, &dev->dma_pools, pools) { | ||
60 | unsigned pages = 0; | ||
61 | unsigned blocks = 0; | ||
62 | |||
63 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
64 | pages++; | ||
65 | blocks += page->in_use; | ||
66 | } | ||
67 | |||
68 | /* per-pool info, no real statistics yet */ | ||
69 | temp = scnprintf(next, size, "%-16s %4u %4Zu %4Zu %2u\n", | ||
70 | pool->name, | ||
71 | blocks, pages * pool->blocks_per_page, | ||
72 | pool->size, pages); | ||
73 | size -= temp; | ||
74 | next += temp; | ||
75 | } | ||
76 | mutex_unlock(&pools_lock); | ||
77 | |||
78 | return PAGE_SIZE - size; | ||
79 | } | ||
80 | static DEVICE_ATTR (pools, S_IRUGO, show_pools, NULL); | ||
81 | |||
82 | /** | ||
83 | * dma_pool_create - Creates a pool of consistent memory blocks, for dma. | ||
84 | * @name: name of pool, for diagnostics | ||
85 | * @dev: device that will be doing the DMA | ||
86 | * @size: size of the blocks in this pool. | ||
87 | * @align: alignment requirement for blocks; must be a power of two | ||
88 | * @allocation: returned blocks won't cross this boundary (or zero) | ||
89 | * Context: !in_interrupt() | ||
90 | * | ||
91 | * Returns a dma allocation pool with the requested characteristics, or | ||
92 | * null if one can't be created. Given one of these pools, dma_pool_alloc() | ||
93 | * may be used to allocate memory. Such memory will all have "consistent" | ||
94 | * DMA mappings, accessible by the device and its driver without using | ||
95 | * cache flushing primitives. The actual size of blocks allocated may be | ||
96 | * larger than requested because of alignment. | ||
97 | * | ||
98 | * If allocation is nonzero, objects returned from dma_pool_alloc() won't | ||
99 | * cross that size boundary. This is useful for devices which have | ||
100 | * addressing restrictions on individual DMA transfers, such as not crossing | ||
101 | * boundaries of 4KBytes. | ||
102 | */ | ||
103 | struct dma_pool * | ||
104 | dma_pool_create (const char *name, struct device *dev, | ||
105 | size_t size, size_t align, size_t allocation) | ||
106 | { | ||
107 | struct dma_pool *retval; | ||
108 | |||
109 | if (align == 0) | ||
110 | align = 1; | ||
111 | if (size == 0) | ||
112 | return NULL; | ||
113 | else if (size < align) | ||
114 | size = align; | ||
115 | else if ((size % align) != 0) { | ||
116 | size += align + 1; | ||
117 | size &= ~(align - 1); | ||
118 | } | ||
119 | |||
120 | if (allocation == 0) { | ||
121 | if (PAGE_SIZE < size) | ||
122 | allocation = size; | ||
123 | else | ||
124 | allocation = PAGE_SIZE; | ||
125 | // FIXME: round up for less fragmentation | ||
126 | } else if (allocation < size) | ||
127 | return NULL; | ||
128 | |||
129 | if (!(retval = kmalloc_node (sizeof *retval, GFP_KERNEL, dev_to_node(dev)))) | ||
130 | return retval; | ||
131 | |||
132 | strlcpy (retval->name, name, sizeof retval->name); | ||
133 | |||
134 | retval->dev = dev; | ||
135 | |||
136 | INIT_LIST_HEAD (&retval->page_list); | ||
137 | spin_lock_init (&retval->lock); | ||
138 | retval->size = size; | ||
139 | retval->allocation = allocation; | ||
140 | retval->blocks_per_page = allocation / size; | ||
141 | init_waitqueue_head (&retval->waitq); | ||
142 | |||
143 | if (dev) { | ||
144 | int ret; | ||
145 | |||
146 | mutex_lock(&pools_lock); | ||
147 | if (list_empty (&dev->dma_pools)) | ||
148 | ret = device_create_file (dev, &dev_attr_pools); | ||
149 | else | ||
150 | ret = 0; | ||
151 | /* note: not currently insisting "name" be unique */ | ||
152 | if (!ret) | ||
153 | list_add (&retval->pools, &dev->dma_pools); | ||
154 | else { | ||
155 | kfree(retval); | ||
156 | retval = NULL; | ||
157 | } | ||
158 | mutex_unlock(&pools_lock); | ||
159 | } else | ||
160 | INIT_LIST_HEAD (&retval->pools); | ||
161 | |||
162 | return retval; | ||
163 | } | ||
164 | |||
165 | |||
166 | static struct dma_page * | ||
167 | pool_alloc_page (struct dma_pool *pool, gfp_t mem_flags) | ||
168 | { | ||
169 | struct dma_page *page; | ||
170 | int mapsize; | ||
171 | |||
172 | mapsize = pool->blocks_per_page; | ||
173 | mapsize = (mapsize + BITS_PER_LONG - 1) / BITS_PER_LONG; | ||
174 | mapsize *= sizeof (long); | ||
175 | |||
176 | page = kmalloc(mapsize + sizeof *page, mem_flags); | ||
177 | if (!page) | ||
178 | return NULL; | ||
179 | page->vaddr = dma_alloc_coherent (pool->dev, | ||
180 | pool->allocation, | ||
181 | &page->dma, | ||
182 | mem_flags); | ||
183 | if (page->vaddr) { | ||
184 | memset (page->bitmap, 0xff, mapsize); // bit set == free | ||
185 | #ifdef CONFIG_DEBUG_SLAB | ||
186 | memset (page->vaddr, POOL_POISON_FREED, pool->allocation); | ||
187 | #endif | ||
188 | list_add (&page->page_list, &pool->page_list); | ||
189 | page->in_use = 0; | ||
190 | } else { | ||
191 | kfree (page); | ||
192 | page = NULL; | ||
193 | } | ||
194 | return page; | ||
195 | } | ||
196 | |||
197 | |||
198 | static inline int | ||
199 | is_page_busy (int blocks, unsigned long *bitmap) | ||
200 | { | ||
201 | while (blocks > 0) { | ||
202 | if (*bitmap++ != ~0UL) | ||
203 | return 1; | ||
204 | blocks -= BITS_PER_LONG; | ||
205 | } | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | static void | ||
210 | pool_free_page (struct dma_pool *pool, struct dma_page *page) | ||
211 | { | ||
212 | dma_addr_t dma = page->dma; | ||
213 | |||
214 | #ifdef CONFIG_DEBUG_SLAB | ||
215 | memset (page->vaddr, POOL_POISON_FREED, pool->allocation); | ||
216 | #endif | ||
217 | dma_free_coherent (pool->dev, pool->allocation, page->vaddr, dma); | ||
218 | list_del (&page->page_list); | ||
219 | kfree (page); | ||
220 | } | ||
221 | |||
222 | |||
223 | /** | ||
224 | * dma_pool_destroy - destroys a pool of dma memory blocks. | ||
225 | * @pool: dma pool that will be destroyed | ||
226 | * Context: !in_interrupt() | ||
227 | * | ||
228 | * Caller guarantees that no more memory from the pool is in use, | ||
229 | * and that nothing will try to use the pool after this call. | ||
230 | */ | ||
231 | void | ||
232 | dma_pool_destroy (struct dma_pool *pool) | ||
233 | { | ||
234 | mutex_lock(&pools_lock); | ||
235 | list_del (&pool->pools); | ||
236 | if (pool->dev && list_empty (&pool->dev->dma_pools)) | ||
237 | device_remove_file (pool->dev, &dev_attr_pools); | ||
238 | mutex_unlock(&pools_lock); | ||
239 | |||
240 | while (!list_empty (&pool->page_list)) { | ||
241 | struct dma_page *page; | ||
242 | page = list_entry (pool->page_list.next, | ||
243 | struct dma_page, page_list); | ||
244 | if (is_page_busy (pool->blocks_per_page, page->bitmap)) { | ||
245 | if (pool->dev) | ||
246 | dev_err(pool->dev, "dma_pool_destroy %s, %p busy\n", | ||
247 | pool->name, page->vaddr); | ||
248 | else | ||
249 | printk (KERN_ERR "dma_pool_destroy %s, %p busy\n", | ||
250 | pool->name, page->vaddr); | ||
251 | /* leak the still-in-use consistent memory */ | ||
252 | list_del (&page->page_list); | ||
253 | kfree (page); | ||
254 | } else | ||
255 | pool_free_page (pool, page); | ||
256 | } | ||
257 | |||
258 | kfree (pool); | ||
259 | } | ||
260 | |||
261 | |||
262 | /** | ||
263 | * dma_pool_alloc - get a block of consistent memory | ||
264 | * @pool: dma pool that will produce the block | ||
265 | * @mem_flags: GFP_* bitmask | ||
266 | * @handle: pointer to dma address of block | ||
267 | * | ||
268 | * This returns the kernel virtual address of a currently unused block, | ||
269 | * and reports its dma address through the handle. | ||
270 | * If such a memory block can't be allocated, null is returned. | ||
271 | */ | ||
272 | void * | ||
273 | dma_pool_alloc (struct dma_pool *pool, gfp_t mem_flags, dma_addr_t *handle) | ||
274 | { | ||
275 | unsigned long flags; | ||
276 | struct dma_page *page; | ||
277 | int map, block; | ||
278 | size_t offset; | ||
279 | void *retval; | ||
280 | |||
281 | restart: | ||
282 | spin_lock_irqsave (&pool->lock, flags); | ||
283 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
284 | int i; | ||
285 | /* only cachable accesses here ... */ | ||
286 | for (map = 0, i = 0; | ||
287 | i < pool->blocks_per_page; | ||
288 | i += BITS_PER_LONG, map++) { | ||
289 | if (page->bitmap [map] == 0) | ||
290 | continue; | ||
291 | block = ffz (~ page->bitmap [map]); | ||
292 | if ((i + block) < pool->blocks_per_page) { | ||
293 | clear_bit (block, &page->bitmap [map]); | ||
294 | offset = (BITS_PER_LONG * map) + block; | ||
295 | offset *= pool->size; | ||
296 | goto ready; | ||
297 | } | ||
298 | } | ||
299 | } | ||
300 | if (!(page = pool_alloc_page (pool, GFP_ATOMIC))) { | ||
301 | if (mem_flags & __GFP_WAIT) { | ||
302 | DECLARE_WAITQUEUE (wait, current); | ||
303 | |||
304 | __set_current_state(TASK_INTERRUPTIBLE); | ||
305 | add_wait_queue (&pool->waitq, &wait); | ||
306 | spin_unlock_irqrestore (&pool->lock, flags); | ||
307 | |||
308 | schedule_timeout (POOL_TIMEOUT_JIFFIES); | ||
309 | |||
310 | remove_wait_queue (&pool->waitq, &wait); | ||
311 | goto restart; | ||
312 | } | ||
313 | retval = NULL; | ||
314 | goto done; | ||
315 | } | ||
316 | |||
317 | clear_bit (0, &page->bitmap [0]); | ||
318 | offset = 0; | ||
319 | ready: | ||
320 | page->in_use++; | ||
321 | retval = offset + page->vaddr; | ||
322 | *handle = offset + page->dma; | ||
323 | #ifdef CONFIG_DEBUG_SLAB | ||
324 | memset (retval, POOL_POISON_ALLOCATED, pool->size); | ||
325 | #endif | ||
326 | done: | ||
327 | spin_unlock_irqrestore (&pool->lock, flags); | ||
328 | return retval; | ||
329 | } | ||
330 | |||
331 | |||
332 | static struct dma_page * | ||
333 | pool_find_page (struct dma_pool *pool, dma_addr_t dma) | ||
334 | { | ||
335 | unsigned long flags; | ||
336 | struct dma_page *page; | ||
337 | |||
338 | spin_lock_irqsave (&pool->lock, flags); | ||
339 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
340 | if (dma < page->dma) | ||
341 | continue; | ||
342 | if (dma < (page->dma + pool->allocation)) | ||
343 | goto done; | ||
344 | } | ||
345 | page = NULL; | ||
346 | done: | ||
347 | spin_unlock_irqrestore (&pool->lock, flags); | ||
348 | return page; | ||
349 | } | ||
350 | |||
351 | |||
352 | /** | ||
353 | * dma_pool_free - put block back into dma pool | ||
354 | * @pool: the dma pool holding the block | ||
355 | * @vaddr: virtual address of block | ||
356 | * @dma: dma address of block | ||
357 | * | ||
358 | * Caller promises neither device nor driver will again touch this block | ||
359 | * unless it is first re-allocated. | ||
360 | */ | ||
361 | void | ||
362 | dma_pool_free (struct dma_pool *pool, void *vaddr, dma_addr_t dma) | ||
363 | { | ||
364 | struct dma_page *page; | ||
365 | unsigned long flags; | ||
366 | int map, block; | ||
367 | |||
368 | if ((page = pool_find_page(pool, dma)) == NULL) { | ||
369 | if (pool->dev) | ||
370 | dev_err(pool->dev, "dma_pool_free %s, %p/%lx (bad dma)\n", | ||
371 | pool->name, vaddr, (unsigned long) dma); | ||
372 | else | ||
373 | printk (KERN_ERR "dma_pool_free %s, %p/%lx (bad dma)\n", | ||
374 | pool->name, vaddr, (unsigned long) dma); | ||
375 | return; | ||
376 | } | ||
377 | |||
378 | block = dma - page->dma; | ||
379 | block /= pool->size; | ||
380 | map = block / BITS_PER_LONG; | ||
381 | block %= BITS_PER_LONG; | ||
382 | |||
383 | #ifdef CONFIG_DEBUG_SLAB | ||
384 | if (((dma - page->dma) + (void *)page->vaddr) != vaddr) { | ||
385 | if (pool->dev) | ||
386 | dev_err(pool->dev, "dma_pool_free %s, %p (bad vaddr)/%Lx\n", | ||
387 | pool->name, vaddr, (unsigned long long) dma); | ||
388 | else | ||
389 | printk (KERN_ERR "dma_pool_free %s, %p (bad vaddr)/%Lx\n", | ||
390 | pool->name, vaddr, (unsigned long long) dma); | ||
391 | return; | ||
392 | } | ||
393 | if (page->bitmap [map] & (1UL << block)) { | ||
394 | if (pool->dev) | ||
395 | dev_err(pool->dev, "dma_pool_free %s, dma %Lx already free\n", | ||
396 | pool->name, (unsigned long long)dma); | ||
397 | else | ||
398 | printk (KERN_ERR "dma_pool_free %s, dma %Lx already free\n", | ||
399 | pool->name, (unsigned long long)dma); | ||
400 | return; | ||
401 | } | ||
402 | memset (vaddr, POOL_POISON_FREED, pool->size); | ||
403 | #endif | ||
404 | |||
405 | spin_lock_irqsave (&pool->lock, flags); | ||
406 | page->in_use--; | ||
407 | set_bit (block, &page->bitmap [map]); | ||
408 | if (waitqueue_active (&pool->waitq)) | ||
409 | wake_up (&pool->waitq); | ||
410 | /* | ||
411 | * Resist a temptation to do | ||
412 | * if (!is_page_busy(bpp, page->bitmap)) pool_free_page(pool, page); | ||
413 | * Better have a few empty pages hang around. | ||
414 | */ | ||
415 | spin_unlock_irqrestore (&pool->lock, flags); | ||
416 | } | ||
417 | |||
418 | /* | ||
419 | * Managed DMA pool | ||
420 | */ | ||
421 | static void dmam_pool_release(struct device *dev, void *res) | ||
422 | { | ||
423 | struct dma_pool *pool = *(struct dma_pool **)res; | ||
424 | |||
425 | dma_pool_destroy(pool); | ||
426 | } | ||
427 | |||
428 | static int dmam_pool_match(struct device *dev, void *res, void *match_data) | ||
429 | { | ||
430 | return *(struct dma_pool **)res == match_data; | ||
431 | } | ||
432 | |||
433 | /** | ||
434 | * dmam_pool_create - Managed dma_pool_create() | ||
435 | * @name: name of pool, for diagnostics | ||
436 | * @dev: device that will be doing the DMA | ||
437 | * @size: size of the blocks in this pool. | ||
438 | * @align: alignment requirement for blocks; must be a power of two | ||
439 | * @allocation: returned blocks won't cross this boundary (or zero) | ||
440 | * | ||
441 | * Managed dma_pool_create(). DMA pool created with this function is | ||
442 | * automatically destroyed on driver detach. | ||
443 | */ | ||
444 | struct dma_pool *dmam_pool_create(const char *name, struct device *dev, | ||
445 | size_t size, size_t align, size_t allocation) | ||
446 | { | ||
447 | struct dma_pool **ptr, *pool; | ||
448 | |||
449 | ptr = devres_alloc(dmam_pool_release, sizeof(*ptr), GFP_KERNEL); | ||
450 | if (!ptr) | ||
451 | return NULL; | ||
452 | |||
453 | pool = *ptr = dma_pool_create(name, dev, size, align, allocation); | ||
454 | if (pool) | ||
455 | devres_add(dev, ptr); | ||
456 | else | ||
457 | devres_free(ptr); | ||
458 | |||
459 | return pool; | ||
460 | } | ||
461 | |||
462 | /** | ||
463 | * dmam_pool_destroy - Managed dma_pool_destroy() | ||
464 | * @pool: dma pool that will be destroyed | ||
465 | * | ||
466 | * Managed dma_pool_destroy(). | ||
467 | */ | ||
468 | void dmam_pool_destroy(struct dma_pool *pool) | ||
469 | { | ||
470 | struct device *dev = pool->dev; | ||
471 | |||
472 | dma_pool_destroy(pool); | ||
473 | WARN_ON(devres_destroy(dev, dmam_pool_release, dmam_pool_match, pool)); | ||
474 | } | ||
475 | |||
476 | EXPORT_SYMBOL (dma_pool_create); | ||
477 | EXPORT_SYMBOL (dma_pool_destroy); | ||
478 | EXPORT_SYMBOL (dma_pool_alloc); | ||
479 | EXPORT_SYMBOL (dma_pool_free); | ||
480 | EXPORT_SYMBOL (dmam_pool_create); | ||
481 | EXPORT_SYMBOL (dmam_pool_destroy); | ||
diff --git a/drivers/block/ataflop.c b/drivers/block/ataflop.c index 94268c75d04f..424995073c6b 100644 --- a/drivers/block/ataflop.c +++ b/drivers/block/ataflop.c | |||
@@ -90,7 +90,7 @@ static struct atari_disk_type { | |||
90 | unsigned blocks; /* total number of blocks */ | 90 | unsigned blocks; /* total number of blocks */ |
91 | unsigned fdc_speed; /* fdc_speed setting */ | 91 | unsigned fdc_speed; /* fdc_speed setting */ |
92 | unsigned stretch; /* track doubling ? */ | 92 | unsigned stretch; /* track doubling ? */ |
93 | } disk_type[] = { | 93 | } atari_disk_type[] = { |
94 | { "d360", 9, 720, 0, 0}, /* 0: 360kB diskette */ | 94 | { "d360", 9, 720, 0, 0}, /* 0: 360kB diskette */ |
95 | { "D360", 9, 720, 0, 1}, /* 1: 360kb in 720k or 1.2MB drive */ | 95 | { "D360", 9, 720, 0, 1}, /* 1: 360kb in 720k or 1.2MB drive */ |
96 | { "D720", 9,1440, 0, 0}, /* 2: 720kb in 720k or 1.2MB drive */ | 96 | { "D720", 9,1440, 0, 0}, /* 2: 720kb in 720k or 1.2MB drive */ |
@@ -658,7 +658,7 @@ static int do_format(int drive, int type, struct atari_format_descr *desc) | |||
658 | return -EINVAL; | 658 | return -EINVAL; |
659 | } | 659 | } |
660 | type = minor2disktype[type].index; | 660 | type = minor2disktype[type].index; |
661 | UDT = &disk_type[type]; | 661 | UDT = &atari_disk_type[type]; |
662 | } | 662 | } |
663 | 663 | ||
664 | if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { | 664 | if (!UDT || desc->track >= UDT->blocks/UDT->spt/2 || desc->head >= 2) { |
@@ -1064,7 +1064,7 @@ static void fd_rwsec_done1(int status) | |||
1064 | searched for a non-existent sector! */ | 1064 | searched for a non-existent sector! */ |
1065 | !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) { | 1065 | !(read_track && FDC_READ(FDCREG_SECTOR) > SUDT->spt)) { |
1066 | if (Probing) { | 1066 | if (Probing) { |
1067 | if (SUDT > disk_type) { | 1067 | if (SUDT > atari_disk_type) { |
1068 | if (SUDT[-1].blocks > ReqBlock) { | 1068 | if (SUDT[-1].blocks > ReqBlock) { |
1069 | /* try another disk type */ | 1069 | /* try another disk type */ |
1070 | SUDT--; | 1070 | SUDT--; |
@@ -1082,7 +1082,7 @@ static void fd_rwsec_done1(int status) | |||
1082 | } else { | 1082 | } else { |
1083 | /* record not found, but not probing. Maybe stretch wrong ? Restart probing */ | 1083 | /* record not found, but not probing. Maybe stretch wrong ? Restart probing */ |
1084 | if (SUD.autoprobe) { | 1084 | if (SUD.autoprobe) { |
1085 | SUDT = disk_type + StartDiskType[DriveType]; | 1085 | SUDT = atari_disk_type + StartDiskType[DriveType]; |
1086 | set_capacity(unit[SelectedDrive].disk, | 1086 | set_capacity(unit[SelectedDrive].disk, |
1087 | SUDT->blocks); | 1087 | SUDT->blocks); |
1088 | Probing = 1; | 1088 | Probing = 1; |
@@ -1421,7 +1421,7 @@ repeat: | |||
1421 | if (type == 0) { | 1421 | if (type == 0) { |
1422 | if (!UDT) { | 1422 | if (!UDT) { |
1423 | Probing = 1; | 1423 | Probing = 1; |
1424 | UDT = disk_type + StartDiskType[DriveType]; | 1424 | UDT = atari_disk_type + StartDiskType[DriveType]; |
1425 | set_capacity(floppy->disk, UDT->blocks); | 1425 | set_capacity(floppy->disk, UDT->blocks); |
1426 | UD.autoprobe = 1; | 1426 | UD.autoprobe = 1; |
1427 | } | 1427 | } |
@@ -1439,7 +1439,7 @@ repeat: | |||
1439 | goto repeat; | 1439 | goto repeat; |
1440 | } | 1440 | } |
1441 | type = minor2disktype[type].index; | 1441 | type = minor2disktype[type].index; |
1442 | UDT = &disk_type[type]; | 1442 | UDT = &atari_disk_type[type]; |
1443 | set_capacity(floppy->disk, UDT->blocks); | 1443 | set_capacity(floppy->disk, UDT->blocks); |
1444 | UD.autoprobe = 0; | 1444 | UD.autoprobe = 0; |
1445 | } | 1445 | } |
@@ -1505,7 +1505,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, | |||
1505 | if (minor2disktype[type].drive_types > DriveType) | 1505 | if (minor2disktype[type].drive_types > DriveType) |
1506 | return -ENODEV; | 1506 | return -ENODEV; |
1507 | type = minor2disktype[type].index; | 1507 | type = minor2disktype[type].index; |
1508 | dtp = &disk_type[type]; | 1508 | dtp = &atari_disk_type[type]; |
1509 | if (UD.flags & FTD_MSG) | 1509 | if (UD.flags & FTD_MSG) |
1510 | printk (KERN_ERR "floppy%d: found dtp %p name %s!\n", | 1510 | printk (KERN_ERR "floppy%d: found dtp %p name %s!\n", |
1511 | drive, dtp, dtp->name); | 1511 | drive, dtp, dtp->name); |
@@ -1576,7 +1576,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, | |||
1576 | continue; | 1576 | continue; |
1577 | } | 1577 | } |
1578 | setidx = minor2disktype[settype].index; | 1578 | setidx = minor2disktype[settype].index; |
1579 | dtp = &disk_type[setidx]; | 1579 | dtp = &atari_disk_type[setidx]; |
1580 | 1580 | ||
1581 | /* found matching entry ?? */ | 1581 | /* found matching entry ?? */ |
1582 | if ( dtp->blocks == setprm.size | 1582 | if ( dtp->blocks == setprm.size |
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 855ce8e5efba..9715be3f2487 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c | |||
@@ -2630,12 +2630,14 @@ static void do_cciss_request(struct request_queue *q) | |||
2630 | c->Request.CDB[8] = creq->nr_sectors & 0xff; | 2630 | c->Request.CDB[8] = creq->nr_sectors & 0xff; |
2631 | c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; | 2631 | c->Request.CDB[9] = c->Request.CDB[11] = c->Request.CDB[12] = 0; |
2632 | } else { | 2632 | } else { |
2633 | u32 upper32 = upper_32_bits(start_blk); | ||
2634 | |||
2633 | c->Request.CDBLen = 16; | 2635 | c->Request.CDBLen = 16; |
2634 | c->Request.CDB[1]= 0; | 2636 | c->Request.CDB[1]= 0; |
2635 | c->Request.CDB[2]= (start_blk >> 56) & 0xff; //MSB | 2637 | c->Request.CDB[2]= (upper32 >> 24) & 0xff; //MSB |
2636 | c->Request.CDB[3]= (start_blk >> 48) & 0xff; | 2638 | c->Request.CDB[3]= (upper32 >> 16) & 0xff; |
2637 | c->Request.CDB[4]= (start_blk >> 40) & 0xff; | 2639 | c->Request.CDB[4]= (upper32 >> 8) & 0xff; |
2638 | c->Request.CDB[5]= (start_blk >> 32) & 0xff; | 2640 | c->Request.CDB[5]= upper32 & 0xff; |
2639 | c->Request.CDB[6]= (start_blk >> 24) & 0xff; | 2641 | c->Request.CDB[6]= (start_blk >> 24) & 0xff; |
2640 | c->Request.CDB[7]= (start_blk >> 16) & 0xff; | 2642 | c->Request.CDB[7]= (start_blk >> 16) & 0xff; |
2641 | c->Request.CDB[8]= (start_blk >> 8) & 0xff; | 2643 | c->Request.CDB[8]= (start_blk >> 8) & 0xff; |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index b8af22e610df..91ebb007416c 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c | |||
@@ -973,6 +973,10 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) | |||
973 | lo->transfer = xfer->transfer; | 973 | lo->transfer = xfer->transfer; |
974 | lo->ioctl = xfer->ioctl; | 974 | lo->ioctl = xfer->ioctl; |
975 | 975 | ||
976 | if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) != | ||
977 | (info->lo_flags & LO_FLAGS_AUTOCLEAR)) | ||
978 | lo->lo_flags ^= LO_FLAGS_AUTOCLEAR; | ||
979 | |||
976 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; | 980 | lo->lo_encrypt_key_size = info->lo_encrypt_key_size; |
977 | lo->lo_init[0] = info->lo_init[0]; | 981 | lo->lo_init[0] = info->lo_init[0]; |
978 | lo->lo_init[1] = info->lo_init[1]; | 982 | lo->lo_init[1] = info->lo_init[1]; |
@@ -1331,6 +1335,10 @@ static int lo_release(struct inode *inode, struct file *file) | |||
1331 | 1335 | ||
1332 | mutex_lock(&lo->lo_ctl_mutex); | 1336 | mutex_lock(&lo->lo_ctl_mutex); |
1333 | --lo->lo_refcnt; | 1337 | --lo->lo_refcnt; |
1338 | |||
1339 | if ((lo->lo_flags & LO_FLAGS_AUTOCLEAR) && !lo->lo_refcnt) | ||
1340 | loop_clr_fd(lo, inode->i_bdev); | ||
1341 | |||
1334 | mutex_unlock(&lo->lo_ctl_mutex); | 1342 | mutex_unlock(&lo->lo_ctl_mutex); |
1335 | 1343 | ||
1336 | return 0; | 1344 | return 0; |
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c index 76096cad798f..8b9549ab4a4e 100644 --- a/drivers/block/paride/pt.c +++ b/drivers/block/paride/pt.c | |||
@@ -660,7 +660,7 @@ static int pt_open(struct inode *inode, struct file *file) | |||
660 | pt_identify(tape); | 660 | pt_identify(tape); |
661 | 661 | ||
662 | err = -ENODEV; | 662 | err = -ENODEV; |
663 | if (!tape->flags & PT_MEDIA) | 663 | if (!(tape->flags & PT_MEDIA)) |
664 | goto out; | 664 | goto out; |
665 | 665 | ||
666 | err = -EROFS; | 666 | err = -EROFS; |
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index e9de1712e5a0..674cd66dcaba 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -2212,11 +2212,11 @@ static int pkt_media_speed(struct pktcdvd_device *pd, unsigned *speed) | |||
2212 | return ret; | 2212 | return ret; |
2213 | } | 2213 | } |
2214 | 2214 | ||
2215 | if (!buf[6] & 0x40) { | 2215 | if (!(buf[6] & 0x40)) { |
2216 | printk(DRIVER_NAME": Disc type is not CD-RW\n"); | 2216 | printk(DRIVER_NAME": Disc type is not CD-RW\n"); |
2217 | return 1; | 2217 | return 1; |
2218 | } | 2218 | } |
2219 | if (!buf[6] & 0x4) { | 2219 | if (!(buf[6] & 0x4)) { |
2220 | printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n"); | 2220 | printk(DRIVER_NAME": A1 values on media are not valid, maybe not CDRW?\n"); |
2221 | return 1; | 2221 | return 1; |
2222 | } | 2222 | } |
diff --git a/drivers/block/rd.c b/drivers/block/rd.c index 82f4eecc8699..06e23be70904 100644 --- a/drivers/block/rd.c +++ b/drivers/block/rd.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/backing-dev.h> | 56 | #include <linux/backing-dev.h> |
57 | #include <linux/blkpg.h> | 57 | #include <linux/blkpg.h> |
58 | #include <linux/writeback.h> | 58 | #include <linux/writeback.h> |
59 | #include <linux/log2.h> | ||
59 | 60 | ||
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | 62 | ||
@@ -450,7 +451,7 @@ static int __init rd_init(void) | |||
450 | err = -ENOMEM; | 451 | err = -ENOMEM; |
451 | 452 | ||
452 | if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 || | 453 | if (rd_blocksize > PAGE_SIZE || rd_blocksize < 512 || |
453 | (rd_blocksize & (rd_blocksize-1))) { | 454 | !is_power_of_2(rd_blocksize)) { |
454 | printk("RAMDISK: wrong blocksize %d, reverting to defaults\n", | 455 | printk("RAMDISK: wrong blocksize %d, reverting to defaults\n", |
455 | rd_blocksize); | 456 | rd_blocksize); |
456 | rd_blocksize = BLOCK_SIZE; | 457 | rd_blocksize = BLOCK_SIZE; |
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 47e5b40510cb..db259e60289b 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c | |||
@@ -1206,25 +1206,26 @@ int check_for_audio_disc(struct cdrom_device_info * cdi, | |||
1206 | return 0; | 1206 | return 0; |
1207 | } | 1207 | } |
1208 | 1208 | ||
1209 | /* Admittedly, the logic below could be performed in a nicer way. */ | ||
1210 | int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) | 1209 | int cdrom_release(struct cdrom_device_info *cdi, struct file *fp) |
1211 | { | 1210 | { |
1212 | struct cdrom_device_ops *cdo = cdi->ops; | 1211 | struct cdrom_device_ops *cdo = cdi->ops; |
1213 | int opened_for_data; | 1212 | int opened_for_data; |
1214 | 1213 | ||
1215 | cdinfo(CD_CLOSE, "entering cdrom_release\n"); | 1214 | cdinfo(CD_CLOSE, "entering cdrom_release\n"); |
1216 | 1215 | ||
1217 | if (cdi->use_count > 0) | 1216 | if (cdi->use_count > 0) |
1218 | cdi->use_count--; | 1217 | cdi->use_count--; |
1219 | if (cdi->use_count == 0) | 1218 | |
1219 | if (cdi->use_count == 0) { | ||
1220 | cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name); | 1220 | cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name); |
1221 | if (cdi->use_count == 0) | ||
1222 | cdrom_dvd_rw_close_write(cdi); | 1221 | cdrom_dvd_rw_close_write(cdi); |
1223 | if (cdi->use_count == 0 && | 1222 | |
1224 | (cdo->capability & CDC_LOCK) && !keeplocked) { | 1223 | if ((cdo->capability & CDC_LOCK) && !keeplocked) { |
1225 | cdinfo(CD_CLOSE, "Unlocking door!\n"); | 1224 | cdinfo(CD_CLOSE, "Unlocking door!\n"); |
1226 | cdo->lock_door(cdi, 0); | 1225 | cdo->lock_door(cdi, 0); |
1226 | } | ||
1227 | } | 1227 | } |
1228 | |||
1228 | opened_for_data = !(cdi->options & CDO_USE_FFLAGS) || | 1229 | opened_for_data = !(cdi->options & CDO_USE_FFLAGS) || |
1229 | !(fp && fp->f_flags & O_NONBLOCK); | 1230 | !(fp && fp->f_flags & O_NONBLOCK); |
1230 | 1231 | ||
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 466629594776..85bf9b2aa74a 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -276,7 +276,7 @@ config N_HDLC | |||
276 | 276 | ||
277 | config RISCOM8 | 277 | config RISCOM8 |
278 | tristate "SDL RISCom/8 card support" | 278 | tristate "SDL RISCom/8 card support" |
279 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 279 | depends on SERIAL_NONSTANDARD |
280 | help | 280 | help |
281 | This is a driver for the SDL Communications RISCom/8 multiport card, | 281 | This is a driver for the SDL Communications RISCom/8 multiport card, |
282 | which gives you many serial ports. You would need something like | 282 | which gives you many serial ports. You would need something like |
@@ -765,7 +765,7 @@ config JS_RTC | |||
765 | 765 | ||
766 | config SGI_DS1286 | 766 | config SGI_DS1286 |
767 | tristate "SGI DS1286 RTC support" | 767 | tristate "SGI DS1286 RTC support" |
768 | depends on SGI_IP22 | 768 | depends on SGI_HAS_DS1286 |
769 | help | 769 | help |
770 | If you say Y here and create a character special file /dev/rtc with | 770 | If you say Y here and create a character special file /dev/rtc with |
771 | major number 10 and minor number 135 using mknod ("man mknod"), you | 771 | major number 10 and minor number 135 using mknod ("man mknod"), you |
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c index 480fae29c9b2..44160d5ebca0 100644 --- a/drivers/char/hvc_console.c +++ b/drivers/char/hvc_console.c | |||
@@ -93,7 +93,7 @@ struct hvc_struct { | |||
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* dynamic list of hvc_struct instances */ | 95 | /* dynamic list of hvc_struct instances */ |
96 | static struct list_head hvc_structs = LIST_HEAD_INIT(hvc_structs); | 96 | static LIST_HEAD(hvc_structs); |
97 | 97 | ||
98 | /* | 98 | /* |
99 | * Protect the list of hvc_struct instances from inserts and removals during | 99 | * Protect the list of hvc_struct instances from inserts and removals during |
diff --git a/drivers/char/hvcs.c b/drivers/char/hvcs.c index 3402def22007..786d518e9477 100644 --- a/drivers/char/hvcs.c +++ b/drivers/char/hvcs.c | |||
@@ -306,7 +306,7 @@ struct hvcs_struct { | |||
306 | /* Required to back map a kref to its containing object */ | 306 | /* Required to back map a kref to its containing object */ |
307 | #define from_kref(k) container_of(k, struct hvcs_struct, kref) | 307 | #define from_kref(k) container_of(k, struct hvcs_struct, kref) |
308 | 308 | ||
309 | static struct list_head hvcs_structs = LIST_HEAD_INIT(hvcs_structs); | 309 | static LIST_HEAD(hvcs_structs); |
310 | static DEFINE_SPINLOCK(hvcs_structs_lock); | 310 | static DEFINE_SPINLOCK(hvcs_structs_lock); |
311 | 311 | ||
312 | static void hvcs_unthrottle(struct tty_struct *tty); | 312 | static void hvcs_unthrottle(struct tty_struct *tty); |
diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 868e39fd42e4..f7feae4ebb5e 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c | |||
@@ -42,6 +42,8 @@ enum { | |||
42 | VIA_STRFILT_ENABLE = (1 << 14), | 42 | VIA_STRFILT_ENABLE = (1 << 14), |
43 | VIA_RAWBITS_ENABLE = (1 << 13), | 43 | VIA_RAWBITS_ENABLE = (1 << 13), |
44 | VIA_RNG_ENABLE = (1 << 6), | 44 | VIA_RNG_ENABLE = (1 << 6), |
45 | VIA_NOISESRC1 = (1 << 8), | ||
46 | VIA_NOISESRC2 = (1 << 9), | ||
45 | VIA_XSTORE_CNT_MASK = 0x0F, | 47 | VIA_XSTORE_CNT_MASK = 0x0F, |
46 | 48 | ||
47 | VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */ | 49 | VIA_RNG_CHUNK_8 = 0x00, /* 64 rand bits, 64 stored bits */ |
@@ -119,6 +121,7 @@ static int via_rng_data_read(struct hwrng *rng, u32 *data) | |||
119 | 121 | ||
120 | static int via_rng_init(struct hwrng *rng) | 122 | static int via_rng_init(struct hwrng *rng) |
121 | { | 123 | { |
124 | struct cpuinfo_x86 *c = &cpu_data(0); | ||
122 | u32 lo, hi, old_lo; | 125 | u32 lo, hi, old_lo; |
123 | 126 | ||
124 | /* Control the RNG via MSR. Tread lightly and pay very close | 127 | /* Control the RNG via MSR. Tread lightly and pay very close |
@@ -134,6 +137,17 @@ static int via_rng_init(struct hwrng *rng) | |||
134 | lo &= ~VIA_XSTORE_CNT_MASK; | 137 | lo &= ~VIA_XSTORE_CNT_MASK; |
135 | lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE); | 138 | lo &= ~(VIA_STRFILT_ENABLE | VIA_STRFILT_FAIL | VIA_RAWBITS_ENABLE); |
136 | lo |= VIA_RNG_ENABLE; | 139 | lo |= VIA_RNG_ENABLE; |
140 | lo |= VIA_NOISESRC1; | ||
141 | |||
142 | /* Enable secondary noise source on CPUs where it is present. */ | ||
143 | |||
144 | /* Nehemiah stepping 8 and higher */ | ||
145 | if ((c->x86_model == 9) && (c->x86_mask > 7)) | ||
146 | lo |= VIA_NOISESRC2; | ||
147 | |||
148 | /* Esther */ | ||
149 | if (c->x86_model >= 10) | ||
150 | lo |= VIA_NOISESRC2; | ||
137 | 151 | ||
138 | if (lo != old_lo) | 152 | if (lo != old_lo) |
139 | wrmsr(MSR_VIA_RNG, lo, hi); | 153 | wrmsr(MSR_VIA_RNG, lo, hi); |
diff --git a/drivers/char/i8k.c b/drivers/char/i8k.c index 30e564516422..179223a17414 100644 --- a/drivers/char/i8k.c +++ b/drivers/char/i8k.c | |||
@@ -439,6 +439,13 @@ static struct dmi_system_id __initdata i8k_dmi_table[] = { | |||
439 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), | 439 | DMI_MATCH(DMI_PRODUCT_NAME, "Latitude"), |
440 | }, | 440 | }, |
441 | }, | 441 | }, |
442 | { /* UK Inspiron 6400 */ | ||
443 | .ident = "Dell Inspiron 3", | ||
444 | .matches = { | ||
445 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | ||
446 | DMI_MATCH(DMI_PRODUCT_NAME, "MM061"), | ||
447 | }, | ||
448 | }, | ||
442 | { } | 449 | { } |
443 | }; | 450 | }; |
444 | 451 | ||
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c index 932264a657d0..86e6538a77b0 100644 --- a/drivers/char/ip27-rtc.c +++ b/drivers/char/ip27-rtc.c | |||
@@ -46,8 +46,8 @@ | |||
46 | #include <asm/sn/sn0/hub.h> | 46 | #include <asm/sn/sn0/hub.h> |
47 | #include <asm/sn/sn_private.h> | 47 | #include <asm/sn/sn_private.h> |
48 | 48 | ||
49 | static int rtc_ioctl(struct inode *inode, struct file *file, | 49 | static long rtc_ioctl(struct file *filp, unsigned int cmd, |
50 | unsigned int cmd, unsigned long arg); | 50 | unsigned long arg); |
51 | 51 | ||
52 | static int rtc_read_proc(char *page, char **start, off_t off, | 52 | static int rtc_read_proc(char *page, char **start, off_t off, |
53 | int count, int *eof, void *data); | 53 | int count, int *eof, void *data); |
@@ -75,8 +75,7 @@ static unsigned long epoch = 1970; /* year corresponding to 0x00 */ | |||
75 | static const unsigned char days_in_mo[] = | 75 | static const unsigned char days_in_mo[] = |
76 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; | 76 | {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
77 | 77 | ||
78 | static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 78 | static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
79 | unsigned long arg) | ||
80 | { | 79 | { |
81 | 80 | ||
82 | struct rtc_time wtime; | 81 | struct rtc_time wtime; |
@@ -197,7 +196,7 @@ static int rtc_release(struct inode *inode, struct file *file) | |||
197 | 196 | ||
198 | static const struct file_operations rtc_fops = { | 197 | static const struct file_operations rtc_fops = { |
199 | .owner = THIS_MODULE, | 198 | .owner = THIS_MODULE, |
200 | .ioctl = rtc_ioctl, | 199 | .unlocked_ioctl = rtc_ioctl, |
201 | .open = rtc_open, | 200 | .open = rtc_open, |
202 | .release = rtc_release, | 201 | .release = rtc_release, |
203 | }; | 202 | }; |
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 5dc1265ce1d5..32b2b22996dc 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c | |||
@@ -365,12 +365,12 @@ static struct device_driver ipmidriver = { | |||
365 | }; | 365 | }; |
366 | static DEFINE_MUTEX(ipmidriver_mutex); | 366 | static DEFINE_MUTEX(ipmidriver_mutex); |
367 | 367 | ||
368 | static struct list_head ipmi_interfaces = LIST_HEAD_INIT(ipmi_interfaces); | 368 | static LIST_HEAD(ipmi_interfaces); |
369 | static DEFINE_MUTEX(ipmi_interfaces_mutex); | 369 | static DEFINE_MUTEX(ipmi_interfaces_mutex); |
370 | 370 | ||
371 | /* List of watchers that want to know when smi's are added and | 371 | /* List of watchers that want to know when smi's are added and |
372 | deleted. */ | 372 | deleted. */ |
373 | static struct list_head smi_watchers = LIST_HEAD_INIT(smi_watchers); | 373 | static LIST_HEAD(smi_watchers); |
374 | static DEFINE_MUTEX(smi_watchers_mutex); | 374 | static DEFINE_MUTEX(smi_watchers_mutex); |
375 | 375 | ||
376 | 376 | ||
@@ -441,7 +441,7 @@ struct watcher_entry { | |||
441 | int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) | 441 | int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher) |
442 | { | 442 | { |
443 | ipmi_smi_t intf; | 443 | ipmi_smi_t intf; |
444 | struct list_head to_deliver = LIST_HEAD_INIT(to_deliver); | 444 | LIST_HEAD(to_deliver); |
445 | struct watcher_entry *e, *e2; | 445 | struct watcher_entry *e, *e2; |
446 | 446 | ||
447 | mutex_lock(&smi_watchers_mutex); | 447 | mutex_lock(&smi_watchers_mutex); |
diff --git a/drivers/char/lp.c b/drivers/char/lp.c index 81674d7c56c7..60ac642752be 100644 --- a/drivers/char/lp.c +++ b/drivers/char/lp.c | |||
@@ -312,7 +312,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, | |||
312 | if (copy_size > LP_BUFFER_SIZE) | 312 | if (copy_size > LP_BUFFER_SIZE) |
313 | copy_size = LP_BUFFER_SIZE; | 313 | copy_size = LP_BUFFER_SIZE; |
314 | 314 | ||
315 | if (down_interruptible (&lp_table[minor].port_mutex)) | 315 | if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) |
316 | return -EINTR; | 316 | return -EINTR; |
317 | 317 | ||
318 | if (copy_from_user (kbuf, buf, copy_size)) { | 318 | if (copy_from_user (kbuf, buf, copy_size)) { |
@@ -399,7 +399,7 @@ static ssize_t lp_write(struct file * file, const char __user * buf, | |||
399 | lp_release_parport (&lp_table[minor]); | 399 | lp_release_parport (&lp_table[minor]); |
400 | } | 400 | } |
401 | out_unlock: | 401 | out_unlock: |
402 | up (&lp_table[minor].port_mutex); | 402 | mutex_unlock(&lp_table[minor].port_mutex); |
403 | 403 | ||
404 | return retv; | 404 | return retv; |
405 | } | 405 | } |
@@ -421,7 +421,7 @@ static ssize_t lp_read(struct file * file, char __user * buf, | |||
421 | if (count > LP_BUFFER_SIZE) | 421 | if (count > LP_BUFFER_SIZE) |
422 | count = LP_BUFFER_SIZE; | 422 | count = LP_BUFFER_SIZE; |
423 | 423 | ||
424 | if (down_interruptible (&lp_table[minor].port_mutex)) | 424 | if (mutex_lock_interruptible(&lp_table[minor].port_mutex)) |
425 | return -EINTR; | 425 | return -EINTR; |
426 | 426 | ||
427 | lp_claim_parport_or_block (&lp_table[minor]); | 427 | lp_claim_parport_or_block (&lp_table[minor]); |
@@ -479,7 +479,7 @@ static ssize_t lp_read(struct file * file, char __user * buf, | |||
479 | if (retval > 0 && copy_to_user (buf, kbuf, retval)) | 479 | if (retval > 0 && copy_to_user (buf, kbuf, retval)) |
480 | retval = -EFAULT; | 480 | retval = -EFAULT; |
481 | 481 | ||
482 | up (&lp_table[minor].port_mutex); | 482 | mutex_unlock(&lp_table[minor].port_mutex); |
483 | 483 | ||
484 | return retval; | 484 | return retval; |
485 | } | 485 | } |
@@ -888,7 +888,7 @@ static int __init lp_init (void) | |||
888 | lp_table[i].last_error = 0; | 888 | lp_table[i].last_error = 0; |
889 | init_waitqueue_head (&lp_table[i].waitq); | 889 | init_waitqueue_head (&lp_table[i].waitq); |
890 | init_waitqueue_head (&lp_table[i].dataq); | 890 | init_waitqueue_head (&lp_table[i].dataq); |
891 | init_MUTEX (&lp_table[i].port_mutex); | 891 | mutex_init(&lp_table[i].port_mutex); |
892 | lp_table[i].timeout = 10 * HZ; | 892 | lp_table[i].timeout = 10 * HZ; |
893 | } | 893 | } |
894 | 894 | ||
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c index fd0abef7ee08..47420787a017 100644 --- a/drivers/char/mxser.c +++ b/drivers/char/mxser.c | |||
@@ -37,7 +37,6 @@ | |||
37 | 37 | ||
38 | 38 | ||
39 | #include <linux/module.h> | 39 | #include <linux/module.h> |
40 | #include <linux/autoconf.h> | ||
41 | #include <linux/errno.h> | 40 | #include <linux/errno.h> |
42 | #include <linux/signal.h> | 41 | #include <linux/signal.h> |
43 | #include <linux/sched.h> | 42 | #include <linux/sched.h> |
diff --git a/drivers/char/mxser_new.c b/drivers/char/mxser_new.c index 081c84c7b548..bf1bee4e1f5e 100644 --- a/drivers/char/mxser_new.c +++ b/drivers/char/mxser_new.c | |||
@@ -20,7 +20,6 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/autoconf.h> | ||
24 | #include <linux/errno.h> | 23 | #include <linux/errno.h> |
25 | #include <linux/signal.h> | 24 | #include <linux/signal.h> |
26 | #include <linux/sched.h> | 25 | #include <linux/sched.h> |
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c index 596c7173997b..90c3969012a3 100644 --- a/drivers/char/n_tty.c +++ b/drivers/char/n_tty.c | |||
@@ -695,17 +695,16 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
695 | return; | 695 | return; |
696 | } | 696 | } |
697 | 697 | ||
698 | if (tty->stopped && !tty->flow_stopped && | ||
699 | I_IXON(tty) && I_IXANY(tty)) { | ||
700 | start_tty(tty); | ||
701 | return; | ||
702 | } | ||
703 | |||
704 | if (I_ISTRIP(tty)) | 698 | if (I_ISTRIP(tty)) |
705 | c &= 0x7f; | 699 | c &= 0x7f; |
706 | if (I_IUCLC(tty) && L_IEXTEN(tty)) | 700 | if (I_IUCLC(tty) && L_IEXTEN(tty)) |
707 | c=tolower(c); | 701 | c=tolower(c); |
708 | 702 | ||
703 | if (tty->stopped && !tty->flow_stopped && I_IXON(tty) && | ||
704 | ((I_IXANY(tty) && c != START_CHAR(tty) && c != STOP_CHAR(tty)) || | ||
705 | c == INTR_CHAR(tty) || c == QUIT_CHAR(tty))) | ||
706 | start_tty(tty); | ||
707 | |||
709 | if (tty->closing) { | 708 | if (tty->closing) { |
710 | if (I_IXON(tty)) { | 709 | if (I_IXON(tty)) { |
711 | if (c == START_CHAR(tty)) | 710 | if (c == START_CHAR(tty)) |
@@ -769,7 +768,21 @@ static inline void n_tty_receive_char(struct tty_struct *tty, unsigned char c) | |||
769 | signal = SIGTSTP; | 768 | signal = SIGTSTP; |
770 | if (c == SUSP_CHAR(tty)) { | 769 | if (c == SUSP_CHAR(tty)) { |
771 | send_signal: | 770 | send_signal: |
772 | isig(signal, tty, 0); | 771 | /* |
772 | * Echo character, and then send the signal. | ||
773 | * Note that we do not use isig() here because we want | ||
774 | * the order to be: | ||
775 | * 1) flush, 2) echo, 3) signal | ||
776 | */ | ||
777 | if (!L_NOFLSH(tty)) { | ||
778 | n_tty_flush_buffer(tty); | ||
779 | if (tty->driver->flush_buffer) | ||
780 | tty->driver->flush_buffer(tty); | ||
781 | } | ||
782 | if (L_ECHO(tty)) | ||
783 | echo_char(c, tty); | ||
784 | if (tty->pgrp) | ||
785 | kill_pgrp(tty->pgrp, signal, 1); | ||
773 | return; | 786 | return; |
774 | } | 787 | } |
775 | } | 788 | } |
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 8caff0ca80ff..279ff5005cec 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
58 | #include <linux/delay.h> | 58 | #include <linux/delay.h> |
59 | #include <linux/ioctl.h> | 59 | #include <linux/ioctl.h> |
60 | #include <linux/synclink.h> | ||
60 | 61 | ||
61 | #include <asm/system.h> | 62 | #include <asm/system.h> |
62 | #include <asm/io.h> | 63 | #include <asm/io.h> |
@@ -87,8 +88,6 @@ | |||
87 | 88 | ||
88 | #include <asm/uaccess.h> | 89 | #include <asm/uaccess.h> |
89 | 90 | ||
90 | #include "linux/synclink.h" | ||
91 | |||
92 | static MGSL_PARAMS default_params = { | 91 | static MGSL_PARAMS default_params = { |
93 | MGSL_MODE_HDLC, /* unsigned long mode */ | 92 | MGSL_MODE_HDLC, /* unsigned long mode */ |
94 | 0, /* unsigned char loopback; */ | 93 | 0, /* unsigned char loopback; */ |
diff --git a/drivers/char/random.c b/drivers/char/random.c index c511a831f0c0..f43c89f7c449 100644 --- a/drivers/char/random.c +++ b/drivers/char/random.c | |||
@@ -1039,6 +1039,7 @@ write_pool(struct entropy_store *r, const char __user *buffer, size_t count) | |||
1039 | p += bytes; | 1039 | p += bytes; |
1040 | 1040 | ||
1041 | add_entropy_words(r, buf, (bytes + 3) / 4); | 1041 | add_entropy_words(r, buf, (bytes + 3) / 4); |
1042 | cond_resched(); | ||
1042 | } | 1043 | } |
1043 | 1044 | ||
1044 | return 0; | 1045 | return 0; |
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c index 102ece4c4e0e..d130b87d8ed7 100644 --- a/drivers/char/riscom8.c +++ b/drivers/char/riscom8.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/init.h> | 47 | #include <linux/init.h> |
48 | #include <linux/delay.h> | 48 | #include <linux/delay.h> |
49 | #include <linux/tty_flip.h> | 49 | #include <linux/tty_flip.h> |
50 | #include <linux/spinlock.h> | ||
50 | 51 | ||
51 | #include <asm/uaccess.h> | 52 | #include <asm/uaccess.h> |
52 | 53 | ||
@@ -81,6 +82,8 @@ | |||
81 | 82 | ||
82 | static struct tty_driver *riscom_driver; | 83 | static struct tty_driver *riscom_driver; |
83 | 84 | ||
85 | static DEFINE_SPINLOCK(riscom_lock); | ||
86 | |||
84 | static struct riscom_board rc_board[RC_NBOARD] = { | 87 | static struct riscom_board rc_board[RC_NBOARD] = { |
85 | { | 88 | { |
86 | .base = RC_IOBASE1, | 89 | .base = RC_IOBASE1, |
@@ -217,13 +220,14 @@ static void __init rc_init_CD180(struct riscom_board const * bp) | |||
217 | { | 220 | { |
218 | unsigned long flags; | 221 | unsigned long flags; |
219 | 222 | ||
220 | save_flags(flags); cli(); | 223 | spin_lock_irqsave(&riscom_lock, flags); |
224 | |||
221 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ | 225 | rc_out(bp, RC_CTOUT, 0); /* Clear timeout */ |
222 | rc_wait_CCR(bp); /* Wait for CCR ready */ | 226 | rc_wait_CCR(bp); /* Wait for CCR ready */ |
223 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ | 227 | rc_out(bp, CD180_CCR, CCR_HARDRESET); /* Reset CD180 chip */ |
224 | sti(); | 228 | spin_unlock_irqrestore(&riscom_lock, flags); |
225 | msleep(50); /* Delay 0.05 sec */ | 229 | msleep(50); /* Delay 0.05 sec */ |
226 | cli(); | 230 | spin_lock_irqsave(&riscom_lock, flags); |
227 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ | 231 | rc_out(bp, CD180_GIVR, RC_ID); /* Set ID for this chip */ |
228 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ | 232 | rc_out(bp, CD180_GICR, 0); /* Clear all bits */ |
229 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ | 233 | rc_out(bp, CD180_PILR1, RC_ACK_MINT); /* Prio for modem intr */ |
@@ -234,7 +238,7 @@ static void __init rc_init_CD180(struct riscom_board const * bp) | |||
234 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); | 238 | rc_out(bp, CD180_PPRH, (RC_OSCFREQ/(1000000/RISCOM_TPS)) >> 8); |
235 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); | 239 | rc_out(bp, CD180_PPRL, (RC_OSCFREQ/(1000000/RISCOM_TPS)) & 0xff); |
236 | 240 | ||
237 | restore_flags(flags); | 241 | spin_unlock_irqrestore(&riscom_lock, flags); |
238 | } | 242 | } |
239 | 243 | ||
240 | /* Main probing routine, also sets irq. */ | 244 | /* Main probing routine, also sets irq. */ |
@@ -812,9 +816,9 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | |||
812 | } | 816 | } |
813 | port->xmit_buf = (unsigned char *) tmp; | 817 | port->xmit_buf = (unsigned char *) tmp; |
814 | } | 818 | } |
815 | 819 | ||
816 | save_flags(flags); cli(); | 820 | spin_lock_irqsave(&riscom_lock, flags); |
817 | 821 | ||
818 | if (port->tty) | 822 | if (port->tty) |
819 | clear_bit(TTY_IO_ERROR, &port->tty->flags); | 823 | clear_bit(TTY_IO_ERROR, &port->tty->flags); |
820 | 824 | ||
@@ -825,7 +829,7 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port) | |||
825 | rc_change_speed(bp, port); | 829 | rc_change_speed(bp, port); |
826 | port->flags |= ASYNC_INITIALIZED; | 830 | port->flags |= ASYNC_INITIALIZED; |
827 | 831 | ||
828 | restore_flags(flags); | 832 | spin_unlock_irqrestore(&riscom_lock, flags); |
829 | return 0; | 833 | return 0; |
830 | } | 834 | } |
831 | 835 | ||
@@ -901,6 +905,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
901 | int retval; | 905 | int retval; |
902 | int do_clocal = 0; | 906 | int do_clocal = 0; |
903 | int CD; | 907 | int CD; |
908 | unsigned long flags; | ||
904 | 909 | ||
905 | /* | 910 | /* |
906 | * If the device is in the middle of being closed, then block | 911 | * If the device is in the middle of being closed, then block |
@@ -936,19 +941,26 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, | |||
936 | */ | 941 | */ |
937 | retval = 0; | 942 | retval = 0; |
938 | add_wait_queue(&port->open_wait, &wait); | 943 | add_wait_queue(&port->open_wait, &wait); |
939 | cli(); | 944 | |
945 | spin_lock_irqsave(&riscom_lock, flags); | ||
946 | |||
940 | if (!tty_hung_up_p(filp)) | 947 | if (!tty_hung_up_p(filp)) |
941 | port->count--; | 948 | port->count--; |
942 | sti(); | 949 | |
950 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
951 | |||
943 | port->blocked_open++; | 952 | port->blocked_open++; |
944 | while (1) { | 953 | while (1) { |
945 | cli(); | 954 | spin_lock_irqsave(&riscom_lock, flags); |
955 | |||
946 | rc_out(bp, CD180_CAR, port_No(port)); | 956 | rc_out(bp, CD180_CAR, port_No(port)); |
947 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; | 957 | CD = rc_in(bp, CD180_MSVR) & MSVR_CD; |
948 | rc_out(bp, CD180_MSVR, MSVR_RTS); | 958 | rc_out(bp, CD180_MSVR, MSVR_RTS); |
949 | bp->DTR &= ~(1u << port_No(port)); | 959 | bp->DTR &= ~(1u << port_No(port)); |
950 | rc_out(bp, RC_DTR, bp->DTR); | 960 | rc_out(bp, RC_DTR, bp->DTR); |
951 | sti(); | 961 | |
962 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
963 | |||
952 | set_current_state(TASK_INTERRUPTIBLE); | 964 | set_current_state(TASK_INTERRUPTIBLE); |
953 | if (tty_hung_up_p(filp) || | 965 | if (tty_hung_up_p(filp) || |
954 | !(port->flags & ASYNC_INITIALIZED)) { | 966 | !(port->flags & ASYNC_INITIALIZED)) { |
@@ -1020,8 +1032,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1020 | 1032 | ||
1021 | if (!port || rc_paranoia_check(port, tty->name, "close")) | 1033 | if (!port || rc_paranoia_check(port, tty->name, "close")) |
1022 | return; | 1034 | return; |
1023 | 1035 | ||
1024 | save_flags(flags); cli(); | 1036 | spin_lock_irqsave(&riscom_lock, flags); |
1037 | |||
1025 | if (tty_hung_up_p(filp)) | 1038 | if (tty_hung_up_p(filp)) |
1026 | goto out; | 1039 | goto out; |
1027 | 1040 | ||
@@ -1088,7 +1101,9 @@ static void rc_close(struct tty_struct * tty, struct file * filp) | |||
1088 | } | 1101 | } |
1089 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); | 1102 | port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); |
1090 | wake_up_interruptible(&port->close_wait); | 1103 | wake_up_interruptible(&port->close_wait); |
1091 | out: restore_flags(flags); | 1104 | |
1105 | out: | ||
1106 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1092 | } | 1107 | } |
1093 | 1108 | ||
1094 | static int rc_write(struct tty_struct * tty, | 1109 | static int rc_write(struct tty_struct * tty, |
@@ -1107,34 +1122,33 @@ static int rc_write(struct tty_struct * tty, | |||
1107 | if (!tty || !port->xmit_buf) | 1122 | if (!tty || !port->xmit_buf) |
1108 | return 0; | 1123 | return 0; |
1109 | 1124 | ||
1110 | save_flags(flags); | ||
1111 | while (1) { | 1125 | while (1) { |
1112 | cli(); | 1126 | spin_lock_irqsave(&riscom_lock, flags); |
1127 | |||
1113 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, | 1128 | c = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, |
1114 | SERIAL_XMIT_SIZE - port->xmit_head)); | 1129 | SERIAL_XMIT_SIZE - port->xmit_head)); |
1115 | if (c <= 0) { | 1130 | if (c <= 0) |
1116 | restore_flags(flags); | 1131 | break; /* lock continues to be held */ |
1117 | break; | ||
1118 | } | ||
1119 | 1132 | ||
1120 | memcpy(port->xmit_buf + port->xmit_head, buf, c); | 1133 | memcpy(port->xmit_buf + port->xmit_head, buf, c); |
1121 | port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); | 1134 | port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); |
1122 | port->xmit_cnt += c; | 1135 | port->xmit_cnt += c; |
1123 | restore_flags(flags); | 1136 | |
1137 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1124 | 1138 | ||
1125 | buf += c; | 1139 | buf += c; |
1126 | count -= c; | 1140 | count -= c; |
1127 | total += c; | 1141 | total += c; |
1128 | } | 1142 | } |
1129 | 1143 | ||
1130 | cli(); | ||
1131 | if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && | 1144 | if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped && |
1132 | !(port->IER & IER_TXRDY)) { | 1145 | !(port->IER & IER_TXRDY)) { |
1133 | port->IER |= IER_TXRDY; | 1146 | port->IER |= IER_TXRDY; |
1134 | rc_out(bp, CD180_CAR, port_No(port)); | 1147 | rc_out(bp, CD180_CAR, port_No(port)); |
1135 | rc_out(bp, CD180_IER, port->IER); | 1148 | rc_out(bp, CD180_IER, port->IER); |
1136 | } | 1149 | } |
1137 | restore_flags(flags); | 1150 | |
1151 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1138 | 1152 | ||
1139 | return total; | 1153 | return total; |
1140 | } | 1154 | } |
@@ -1150,7 +1164,7 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch) | |||
1150 | if (!tty || !port->xmit_buf) | 1164 | if (!tty || !port->xmit_buf) |
1151 | return; | 1165 | return; |
1152 | 1166 | ||
1153 | save_flags(flags); cli(); | 1167 | spin_lock_irqsave(&riscom_lock, flags); |
1154 | 1168 | ||
1155 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) | 1169 | if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) |
1156 | goto out; | 1170 | goto out; |
@@ -1158,7 +1172,9 @@ static void rc_put_char(struct tty_struct * tty, unsigned char ch) | |||
1158 | port->xmit_buf[port->xmit_head++] = ch; | 1172 | port->xmit_buf[port->xmit_head++] = ch; |
1159 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; | 1173 | port->xmit_head &= SERIAL_XMIT_SIZE - 1; |
1160 | port->xmit_cnt++; | 1174 | port->xmit_cnt++; |
1161 | out: restore_flags(flags); | 1175 | |
1176 | out: | ||
1177 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1162 | } | 1178 | } |
1163 | 1179 | ||
1164 | static void rc_flush_chars(struct tty_struct * tty) | 1180 | static void rc_flush_chars(struct tty_struct * tty) |
@@ -1173,11 +1189,13 @@ static void rc_flush_chars(struct tty_struct * tty) | |||
1173 | !port->xmit_buf) | 1189 | !port->xmit_buf) |
1174 | return; | 1190 | return; |
1175 | 1191 | ||
1176 | save_flags(flags); cli(); | 1192 | spin_lock_irqsave(&riscom_lock, flags); |
1193 | |||
1177 | port->IER |= IER_TXRDY; | 1194 | port->IER |= IER_TXRDY; |
1178 | rc_out(port_Board(port), CD180_CAR, port_No(port)); | 1195 | rc_out(port_Board(port), CD180_CAR, port_No(port)); |
1179 | rc_out(port_Board(port), CD180_IER, port->IER); | 1196 | rc_out(port_Board(port), CD180_IER, port->IER); |
1180 | restore_flags(flags); | 1197 | |
1198 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1181 | } | 1199 | } |
1182 | 1200 | ||
1183 | static int rc_write_room(struct tty_struct * tty) | 1201 | static int rc_write_room(struct tty_struct * tty) |
@@ -1212,9 +1230,11 @@ static void rc_flush_buffer(struct tty_struct *tty) | |||
1212 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) | 1230 | if (rc_paranoia_check(port, tty->name, "rc_flush_buffer")) |
1213 | return; | 1231 | return; |
1214 | 1232 | ||
1215 | save_flags(flags); cli(); | 1233 | spin_lock_irqsave(&riscom_lock, flags); |
1234 | |||
1216 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; | 1235 | port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; |
1217 | restore_flags(flags); | 1236 | |
1237 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1218 | 1238 | ||
1219 | tty_wakeup(tty); | 1239 | tty_wakeup(tty); |
1220 | } | 1240 | } |
@@ -1231,11 +1251,15 @@ static int rc_tiocmget(struct tty_struct *tty, struct file *file) | |||
1231 | return -ENODEV; | 1251 | return -ENODEV; |
1232 | 1252 | ||
1233 | bp = port_Board(port); | 1253 | bp = port_Board(port); |
1234 | save_flags(flags); cli(); | 1254 | |
1255 | spin_lock_irqsave(&riscom_lock, flags); | ||
1256 | |||
1235 | rc_out(bp, CD180_CAR, port_No(port)); | 1257 | rc_out(bp, CD180_CAR, port_No(port)); |
1236 | status = rc_in(bp, CD180_MSVR); | 1258 | status = rc_in(bp, CD180_MSVR); |
1237 | result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; | 1259 | result = rc_in(bp, RC_RI) & (1u << port_No(port)) ? 0 : TIOCM_RNG; |
1238 | restore_flags(flags); | 1260 | |
1261 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1262 | |||
1239 | result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) | 1263 | result |= ((status & MSVR_RTS) ? TIOCM_RTS : 0) |
1240 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) | 1264 | | ((status & MSVR_DTR) ? TIOCM_DTR : 0) |
1241 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) | 1265 | | ((status & MSVR_CD) ? TIOCM_CAR : 0) |
@@ -1256,7 +1280,8 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1256 | 1280 | ||
1257 | bp = port_Board(port); | 1281 | bp = port_Board(port); |
1258 | 1282 | ||
1259 | save_flags(flags); cli(); | 1283 | spin_lock_irqsave(&riscom_lock, flags); |
1284 | |||
1260 | if (set & TIOCM_RTS) | 1285 | if (set & TIOCM_RTS) |
1261 | port->MSVR |= MSVR_RTS; | 1286 | port->MSVR |= MSVR_RTS; |
1262 | if (set & TIOCM_DTR) | 1287 | if (set & TIOCM_DTR) |
@@ -1270,7 +1295,9 @@ static int rc_tiocmset(struct tty_struct *tty, struct file *file, | |||
1270 | rc_out(bp, CD180_CAR, port_No(port)); | 1295 | rc_out(bp, CD180_CAR, port_No(port)); |
1271 | rc_out(bp, CD180_MSVR, port->MSVR); | 1296 | rc_out(bp, CD180_MSVR, port->MSVR); |
1272 | rc_out(bp, RC_DTR, bp->DTR); | 1297 | rc_out(bp, RC_DTR, bp->DTR); |
1273 | restore_flags(flags); | 1298 | |
1299 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1300 | |||
1274 | return 0; | 1301 | return 0; |
1275 | } | 1302 | } |
1276 | 1303 | ||
@@ -1279,7 +1306,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length | |||
1279 | struct riscom_board *bp = port_Board(port); | 1306 | struct riscom_board *bp = port_Board(port); |
1280 | unsigned long flags; | 1307 | unsigned long flags; |
1281 | 1308 | ||
1282 | save_flags(flags); cli(); | 1309 | spin_lock_irqsave(&riscom_lock, flags); |
1310 | |||
1283 | port->break_length = RISCOM_TPS / HZ * length; | 1311 | port->break_length = RISCOM_TPS / HZ * length; |
1284 | port->COR2 |= COR2_ETC; | 1312 | port->COR2 |= COR2_ETC; |
1285 | port->IER |= IER_TXRDY; | 1313 | port->IER |= IER_TXRDY; |
@@ -1289,7 +1317,8 @@ static inline void rc_send_break(struct riscom_port * port, unsigned long length | |||
1289 | rc_wait_CCR(bp); | 1317 | rc_wait_CCR(bp); |
1290 | rc_out(bp, CD180_CCR, CCR_CORCHG2); | 1318 | rc_out(bp, CD180_CCR, CCR_CORCHG2); |
1291 | rc_wait_CCR(bp); | 1319 | rc_wait_CCR(bp); |
1292 | restore_flags(flags); | 1320 | |
1321 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1293 | } | 1322 | } |
1294 | 1323 | ||
1295 | static inline int rc_set_serial_info(struct riscom_port * port, | 1324 | static inline int rc_set_serial_info(struct riscom_port * port, |
@@ -1298,7 +1327,6 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1298 | struct serial_struct tmp; | 1327 | struct serial_struct tmp; |
1299 | struct riscom_board *bp = port_Board(port); | 1328 | struct riscom_board *bp = port_Board(port); |
1300 | int change_speed; | 1329 | int change_speed; |
1301 | unsigned long flags; | ||
1302 | 1330 | ||
1303 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) | 1331 | if (copy_from_user(&tmp, newinfo, sizeof(tmp))) |
1304 | return -EFAULT; | 1332 | return -EFAULT; |
@@ -1332,9 +1360,11 @@ static inline int rc_set_serial_info(struct riscom_port * port, | |||
1332 | port->closing_wait = tmp.closing_wait; | 1360 | port->closing_wait = tmp.closing_wait; |
1333 | } | 1361 | } |
1334 | if (change_speed) { | 1362 | if (change_speed) { |
1335 | save_flags(flags); cli(); | 1363 | unsigned long flags; |
1364 | |||
1365 | spin_lock_irqsave(&riscom_lock, flags); | ||
1336 | rc_change_speed(bp, port); | 1366 | rc_change_speed(bp, port); |
1337 | restore_flags(flags); | 1367 | spin_unlock_irqrestore(&riscom_lock, flags); |
1338 | } | 1368 | } |
1339 | return 0; | 1369 | return 0; |
1340 | } | 1370 | } |
@@ -1414,17 +1444,19 @@ static void rc_throttle(struct tty_struct * tty) | |||
1414 | return; | 1444 | return; |
1415 | 1445 | ||
1416 | bp = port_Board(port); | 1446 | bp = port_Board(port); |
1417 | 1447 | ||
1418 | save_flags(flags); cli(); | 1448 | spin_lock_irqsave(&riscom_lock, flags); |
1449 | |||
1419 | port->MSVR &= ~MSVR_RTS; | 1450 | port->MSVR &= ~MSVR_RTS; |
1420 | rc_out(bp, CD180_CAR, port_No(port)); | 1451 | rc_out(bp, CD180_CAR, port_No(port)); |
1421 | if (I_IXOFF(tty)) { | 1452 | if (I_IXOFF(tty)) { |
1422 | rc_wait_CCR(bp); | 1453 | rc_wait_CCR(bp); |
1423 | rc_out(bp, CD180_CCR, CCR_SSCH2); | 1454 | rc_out(bp, CD180_CCR, CCR_SSCH2); |
1424 | rc_wait_CCR(bp); | 1455 | rc_wait_CCR(bp); |
1425 | } | 1456 | } |
1426 | rc_out(bp, CD180_MSVR, port->MSVR); | 1457 | rc_out(bp, CD180_MSVR, port->MSVR); |
1427 | restore_flags(flags); | 1458 | |
1459 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1428 | } | 1460 | } |
1429 | 1461 | ||
1430 | static void rc_unthrottle(struct tty_struct * tty) | 1462 | static void rc_unthrottle(struct tty_struct * tty) |
@@ -1438,7 +1470,8 @@ static void rc_unthrottle(struct tty_struct * tty) | |||
1438 | 1470 | ||
1439 | bp = port_Board(port); | 1471 | bp = port_Board(port); |
1440 | 1472 | ||
1441 | save_flags(flags); cli(); | 1473 | spin_lock_irqsave(&riscom_lock, flags); |
1474 | |||
1442 | port->MSVR |= MSVR_RTS; | 1475 | port->MSVR |= MSVR_RTS; |
1443 | rc_out(bp, CD180_CAR, port_No(port)); | 1476 | rc_out(bp, CD180_CAR, port_No(port)); |
1444 | if (I_IXOFF(tty)) { | 1477 | if (I_IXOFF(tty)) { |
@@ -1447,7 +1480,8 @@ static void rc_unthrottle(struct tty_struct * tty) | |||
1447 | rc_wait_CCR(bp); | 1480 | rc_wait_CCR(bp); |
1448 | } | 1481 | } |
1449 | rc_out(bp, CD180_MSVR, port->MSVR); | 1482 | rc_out(bp, CD180_MSVR, port->MSVR); |
1450 | restore_flags(flags); | 1483 | |
1484 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1451 | } | 1485 | } |
1452 | 1486 | ||
1453 | static void rc_stop(struct tty_struct * tty) | 1487 | static void rc_stop(struct tty_struct * tty) |
@@ -1461,11 +1495,13 @@ static void rc_stop(struct tty_struct * tty) | |||
1461 | 1495 | ||
1462 | bp = port_Board(port); | 1496 | bp = port_Board(port); |
1463 | 1497 | ||
1464 | save_flags(flags); cli(); | 1498 | spin_lock_irqsave(&riscom_lock, flags); |
1499 | |||
1465 | port->IER &= ~IER_TXRDY; | 1500 | port->IER &= ~IER_TXRDY; |
1466 | rc_out(bp, CD180_CAR, port_No(port)); | 1501 | rc_out(bp, CD180_CAR, port_No(port)); |
1467 | rc_out(bp, CD180_IER, port->IER); | 1502 | rc_out(bp, CD180_IER, port->IER); |
1468 | restore_flags(flags); | 1503 | |
1504 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1469 | } | 1505 | } |
1470 | 1506 | ||
1471 | static void rc_start(struct tty_struct * tty) | 1507 | static void rc_start(struct tty_struct * tty) |
@@ -1479,13 +1515,15 @@ static void rc_start(struct tty_struct * tty) | |||
1479 | 1515 | ||
1480 | bp = port_Board(port); | 1516 | bp = port_Board(port); |
1481 | 1517 | ||
1482 | save_flags(flags); cli(); | 1518 | spin_lock_irqsave(&riscom_lock, flags); |
1519 | |||
1483 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { | 1520 | if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { |
1484 | port->IER |= IER_TXRDY; | 1521 | port->IER |= IER_TXRDY; |
1485 | rc_out(bp, CD180_CAR, port_No(port)); | 1522 | rc_out(bp, CD180_CAR, port_No(port)); |
1486 | rc_out(bp, CD180_IER, port->IER); | 1523 | rc_out(bp, CD180_IER, port->IER); |
1487 | } | 1524 | } |
1488 | restore_flags(flags); | 1525 | |
1526 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1489 | } | 1527 | } |
1490 | 1528 | ||
1491 | /* | 1529 | /* |
@@ -1537,9 +1575,9 @@ static void rc_set_termios(struct tty_struct * tty, struct ktermios * old_termio | |||
1537 | tty->termios->c_iflag == old_termios->c_iflag) | 1575 | tty->termios->c_iflag == old_termios->c_iflag) |
1538 | return; | 1576 | return; |
1539 | 1577 | ||
1540 | save_flags(flags); cli(); | 1578 | spin_lock_irqsave(&riscom_lock, flags); |
1541 | rc_change_speed(port_Board(port), port); | 1579 | rc_change_speed(port_Board(port), port); |
1542 | restore_flags(flags); | 1580 | spin_unlock_irqrestore(&riscom_lock, flags); |
1543 | 1581 | ||
1544 | if ((old_termios->c_cflag & CRTSCTS) && | 1582 | if ((old_termios->c_cflag & CRTSCTS) && |
1545 | !(tty->termios->c_cflag & CRTSCTS)) { | 1583 | !(tty->termios->c_cflag & CRTSCTS)) { |
@@ -1627,11 +1665,12 @@ static void rc_release_drivers(void) | |||
1627 | { | 1665 | { |
1628 | unsigned long flags; | 1666 | unsigned long flags; |
1629 | 1667 | ||
1630 | save_flags(flags); | 1668 | spin_lock_irqsave(&riscom_lock, flags); |
1631 | cli(); | 1669 | |
1632 | tty_unregister_driver(riscom_driver); | 1670 | tty_unregister_driver(riscom_driver); |
1633 | put_tty_driver(riscom_driver); | 1671 | put_tty_driver(riscom_driver); |
1634 | restore_flags(flags); | 1672 | |
1673 | spin_unlock_irqrestore(&riscom_lock, flags); | ||
1635 | } | 1674 | } |
1636 | 1675 | ||
1637 | #ifndef MODULE | 1676 | #ifndef MODULE |
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c index 3c869145bfdc..4ba3aec9e1cd 100644 --- a/drivers/char/ser_a2232.c +++ b/drivers/char/ser_a2232.c | |||
@@ -653,7 +653,7 @@ static void a2232_init_portstructs(void) | |||
653 | port->gs.closing_wait = 30 * HZ; | 653 | port->gs.closing_wait = 30 * HZ; |
654 | port->gs.rd = &a2232_real_driver; | 654 | port->gs.rd = &a2232_real_driver; |
655 | #ifdef NEW_WRITE_LOCKING | 655 | #ifdef NEW_WRITE_LOCKING |
656 | init_MUTEX(&(port->gs.port_write_mutex)); | 656 | mutex_init(&(port->gs.port_write_mutex)); |
657 | #endif | 657 | #endif |
658 | init_waitqueue_head(&port->gs.open_wait); | 658 | init_waitqueue_head(&port->gs.open_wait); |
659 | init_waitqueue_head(&port->gs.close_wait); | 659 | init_waitqueue_head(&port->gs.close_wait); |
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c index d010ed95ed3b..ddc74d1f4f1b 100644 --- a/drivers/char/synclink.c +++ b/drivers/char/synclink.c | |||
@@ -85,6 +85,7 @@ | |||
85 | #include <linux/vmalloc.h> | 85 | #include <linux/vmalloc.h> |
86 | #include <linux/init.h> | 86 | #include <linux/init.h> |
87 | #include <linux/ioctl.h> | 87 | #include <linux/ioctl.h> |
88 | #include <linux/synclink.h> | ||
88 | 89 | ||
89 | #include <asm/system.h> | 90 | #include <asm/system.h> |
90 | #include <asm/io.h> | 91 | #include <asm/io.h> |
@@ -110,8 +111,6 @@ | |||
110 | 111 | ||
111 | #include <asm/uaccess.h> | 112 | #include <asm/uaccess.h> |
112 | 113 | ||
113 | #include "linux/synclink.h" | ||
114 | |||
115 | #define RCLRVALUE 0xffff | 114 | #define RCLRVALUE 0xffff |
116 | 115 | ||
117 | static MGSL_PARAMS default_params = { | 116 | static MGSL_PARAMS default_params = { |
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index 64e835f62438..1f954acf2bac 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #include <linux/bitops.h> | 73 | #include <linux/bitops.h> |
74 | #include <linux/workqueue.h> | 74 | #include <linux/workqueue.h> |
75 | #include <linux/hdlc.h> | 75 | #include <linux/hdlc.h> |
76 | #include <linux/synclink.h> | ||
76 | 77 | ||
77 | #include <asm/system.h> | 78 | #include <asm/system.h> |
78 | #include <asm/io.h> | 79 | #include <asm/io.h> |
@@ -81,8 +82,6 @@ | |||
81 | #include <asm/types.h> | 82 | #include <asm/types.h> |
82 | #include <asm/uaccess.h> | 83 | #include <asm/uaccess.h> |
83 | 84 | ||
84 | #include "linux/synclink.h" | ||
85 | |||
86 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) | 85 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINK_GT_MODULE)) |
87 | #define SYNCLINK_GENERIC_HDLC 1 | 86 | #define SYNCLINK_GENERIC_HDLC 1 |
88 | #else | 87 | #else |
@@ -2040,37 +2039,41 @@ static void bh_transmit(struct slgt_info *info) | |||
2040 | tty_wakeup(tty); | 2039 | tty_wakeup(tty); |
2041 | } | 2040 | } |
2042 | 2041 | ||
2043 | static void dsr_change(struct slgt_info *info) | 2042 | static void dsr_change(struct slgt_info *info, unsigned short status) |
2044 | { | 2043 | { |
2045 | get_signals(info); | 2044 | if (status & BIT3) { |
2045 | info->signals |= SerialSignal_DSR; | ||
2046 | info->input_signal_events.dsr_up++; | ||
2047 | } else { | ||
2048 | info->signals &= ~SerialSignal_DSR; | ||
2049 | info->input_signal_events.dsr_down++; | ||
2050 | } | ||
2046 | DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); | 2051 | DBGISR(("dsr_change %s signals=%04X\n", info->device_name, info->signals)); |
2047 | if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { | 2052 | if ((info->dsr_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { |
2048 | slgt_irq_off(info, IRQ_DSR); | 2053 | slgt_irq_off(info, IRQ_DSR); |
2049 | return; | 2054 | return; |
2050 | } | 2055 | } |
2051 | info->icount.dsr++; | 2056 | info->icount.dsr++; |
2052 | if (info->signals & SerialSignal_DSR) | ||
2053 | info->input_signal_events.dsr_up++; | ||
2054 | else | ||
2055 | info->input_signal_events.dsr_down++; | ||
2056 | wake_up_interruptible(&info->status_event_wait_q); | 2057 | wake_up_interruptible(&info->status_event_wait_q); |
2057 | wake_up_interruptible(&info->event_wait_q); | 2058 | wake_up_interruptible(&info->event_wait_q); |
2058 | info->pending_bh |= BH_STATUS; | 2059 | info->pending_bh |= BH_STATUS; |
2059 | } | 2060 | } |
2060 | 2061 | ||
2061 | static void cts_change(struct slgt_info *info) | 2062 | static void cts_change(struct slgt_info *info, unsigned short status) |
2062 | { | 2063 | { |
2063 | get_signals(info); | 2064 | if (status & BIT2) { |
2065 | info->signals |= SerialSignal_CTS; | ||
2066 | info->input_signal_events.cts_up++; | ||
2067 | } else { | ||
2068 | info->signals &= ~SerialSignal_CTS; | ||
2069 | info->input_signal_events.cts_down++; | ||
2070 | } | ||
2064 | DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); | 2071 | DBGISR(("cts_change %s signals=%04X\n", info->device_name, info->signals)); |
2065 | if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { | 2072 | if ((info->cts_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { |
2066 | slgt_irq_off(info, IRQ_CTS); | 2073 | slgt_irq_off(info, IRQ_CTS); |
2067 | return; | 2074 | return; |
2068 | } | 2075 | } |
2069 | info->icount.cts++; | 2076 | info->icount.cts++; |
2070 | if (info->signals & SerialSignal_CTS) | ||
2071 | info->input_signal_events.cts_up++; | ||
2072 | else | ||
2073 | info->input_signal_events.cts_down++; | ||
2074 | wake_up_interruptible(&info->status_event_wait_q); | 2077 | wake_up_interruptible(&info->status_event_wait_q); |
2075 | wake_up_interruptible(&info->event_wait_q); | 2078 | wake_up_interruptible(&info->event_wait_q); |
2076 | info->pending_bh |= BH_STATUS; | 2079 | info->pending_bh |= BH_STATUS; |
@@ -2091,20 +2094,21 @@ static void cts_change(struct slgt_info *info) | |||
2091 | } | 2094 | } |
2092 | } | 2095 | } |
2093 | 2096 | ||
2094 | static void dcd_change(struct slgt_info *info) | 2097 | static void dcd_change(struct slgt_info *info, unsigned short status) |
2095 | { | 2098 | { |
2096 | get_signals(info); | 2099 | if (status & BIT1) { |
2100 | info->signals |= SerialSignal_DCD; | ||
2101 | info->input_signal_events.dcd_up++; | ||
2102 | } else { | ||
2103 | info->signals &= ~SerialSignal_DCD; | ||
2104 | info->input_signal_events.dcd_down++; | ||
2105 | } | ||
2097 | DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); | 2106 | DBGISR(("dcd_change %s signals=%04X\n", info->device_name, info->signals)); |
2098 | if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { | 2107 | if ((info->dcd_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { |
2099 | slgt_irq_off(info, IRQ_DCD); | 2108 | slgt_irq_off(info, IRQ_DCD); |
2100 | return; | 2109 | return; |
2101 | } | 2110 | } |
2102 | info->icount.dcd++; | 2111 | info->icount.dcd++; |
2103 | if (info->signals & SerialSignal_DCD) { | ||
2104 | info->input_signal_events.dcd_up++; | ||
2105 | } else { | ||
2106 | info->input_signal_events.dcd_down++; | ||
2107 | } | ||
2108 | #if SYNCLINK_GENERIC_HDLC | 2112 | #if SYNCLINK_GENERIC_HDLC |
2109 | if (info->netcount) { | 2113 | if (info->netcount) { |
2110 | if (info->signals & SerialSignal_DCD) | 2114 | if (info->signals & SerialSignal_DCD) |
@@ -2127,20 +2131,21 @@ static void dcd_change(struct slgt_info *info) | |||
2127 | } | 2131 | } |
2128 | } | 2132 | } |
2129 | 2133 | ||
2130 | static void ri_change(struct slgt_info *info) | 2134 | static void ri_change(struct slgt_info *info, unsigned short status) |
2131 | { | 2135 | { |
2132 | get_signals(info); | 2136 | if (status & BIT0) { |
2137 | info->signals |= SerialSignal_RI; | ||
2138 | info->input_signal_events.ri_up++; | ||
2139 | } else { | ||
2140 | info->signals &= ~SerialSignal_RI; | ||
2141 | info->input_signal_events.ri_down++; | ||
2142 | } | ||
2133 | DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); | 2143 | DBGISR(("ri_change %s signals=%04X\n", info->device_name, info->signals)); |
2134 | if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { | 2144 | if ((info->ri_chkcount)++ == IO_PIN_SHUTDOWN_LIMIT) { |
2135 | slgt_irq_off(info, IRQ_RI); | 2145 | slgt_irq_off(info, IRQ_RI); |
2136 | return; | 2146 | return; |
2137 | } | 2147 | } |
2138 | info->icount.dcd++; | 2148 | info->icount.rng++; |
2139 | if (info->signals & SerialSignal_RI) { | ||
2140 | info->input_signal_events.ri_up++; | ||
2141 | } else { | ||
2142 | info->input_signal_events.ri_down++; | ||
2143 | } | ||
2144 | wake_up_interruptible(&info->status_event_wait_q); | 2149 | wake_up_interruptible(&info->status_event_wait_q); |
2145 | wake_up_interruptible(&info->event_wait_q); | 2150 | wake_up_interruptible(&info->event_wait_q); |
2146 | info->pending_bh |= BH_STATUS; | 2151 | info->pending_bh |= BH_STATUS; |
@@ -2191,13 +2196,13 @@ static void isr_serial(struct slgt_info *info) | |||
2191 | } | 2196 | } |
2192 | 2197 | ||
2193 | if (status & IRQ_DSR) | 2198 | if (status & IRQ_DSR) |
2194 | dsr_change(info); | 2199 | dsr_change(info, status); |
2195 | if (status & IRQ_CTS) | 2200 | if (status & IRQ_CTS) |
2196 | cts_change(info); | 2201 | cts_change(info, status); |
2197 | if (status & IRQ_DCD) | 2202 | if (status & IRQ_DCD) |
2198 | dcd_change(info); | 2203 | dcd_change(info, status); |
2199 | if (status & IRQ_RI) | 2204 | if (status & IRQ_RI) |
2200 | ri_change(info); | 2205 | ri_change(info, status); |
2201 | } | 2206 | } |
2202 | 2207 | ||
2203 | static void isr_rdma(struct slgt_info *info) | 2208 | static void isr_rdma(struct slgt_info *info) |
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c index c63013b2fc36..f3e7807f78d9 100644 --- a/drivers/char/synclinkmp.c +++ b/drivers/char/synclinkmp.c | |||
@@ -66,6 +66,7 @@ | |||
66 | #include <linux/termios.h> | 66 | #include <linux/termios.h> |
67 | #include <linux/workqueue.h> | 67 | #include <linux/workqueue.h> |
68 | #include <linux/hdlc.h> | 68 | #include <linux/hdlc.h> |
69 | #include <linux/synclink.h> | ||
69 | 70 | ||
70 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) | 71 | #if defined(CONFIG_HDLC) || (defined(CONFIG_HDLC_MODULE) && defined(CONFIG_SYNCLINKMP_MODULE)) |
71 | #define SYNCLINK_GENERIC_HDLC 1 | 72 | #define SYNCLINK_GENERIC_HDLC 1 |
@@ -80,8 +81,6 @@ | |||
80 | 81 | ||
81 | #include <asm/uaccess.h> | 82 | #include <asm/uaccess.h> |
82 | 83 | ||
83 | #include "linux/synclink.h" | ||
84 | |||
85 | static MGSL_PARAMS default_params = { | 84 | static MGSL_PARAMS default_params = { |
86 | MGSL_MODE_HDLC, /* unsigned long mode */ | 85 | MGSL_MODE_HDLC, /* unsigned long mode */ |
87 | 0, /* unsigned char loopback; */ | 86 | 0, /* unsigned char loopback; */ |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index c88424a0c89b..a5d8bcb40000 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -1031,18 +1031,13 @@ void tpm_remove_hardware(struct device *dev) | |||
1031 | 1031 | ||
1032 | spin_unlock(&driver_lock); | 1032 | spin_unlock(&driver_lock); |
1033 | 1033 | ||
1034 | dev_set_drvdata(dev, NULL); | ||
1035 | misc_deregister(&chip->vendor.miscdev); | 1034 | misc_deregister(&chip->vendor.miscdev); |
1036 | kfree(chip->vendor.miscdev.name); | ||
1037 | 1035 | ||
1038 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); | 1036 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); |
1039 | tpm_bios_log_teardown(chip->bios_dir); | 1037 | tpm_bios_log_teardown(chip->bios_dir); |
1040 | 1038 | ||
1041 | clear_bit(chip->dev_num, dev_mask); | 1039 | /* write it this way to be explicit (chip->dev == dev) */ |
1042 | 1040 | put_device(chip->dev); | |
1043 | kfree(chip); | ||
1044 | |||
1045 | put_device(dev); | ||
1046 | } | 1041 | } |
1047 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); | 1042 | EXPORT_SYMBOL_GPL(tpm_remove_hardware); |
1048 | 1043 | ||
@@ -1083,6 +1078,26 @@ int tpm_pm_resume(struct device *dev) | |||
1083 | EXPORT_SYMBOL_GPL(tpm_pm_resume); | 1078 | EXPORT_SYMBOL_GPL(tpm_pm_resume); |
1084 | 1079 | ||
1085 | /* | 1080 | /* |
1081 | * Once all references to platform device are down to 0, | ||
1082 | * release all allocated structures. | ||
1083 | * In case vendor provided release function, | ||
1084 | * call it too. | ||
1085 | */ | ||
1086 | static void tpm_dev_release(struct device *dev) | ||
1087 | { | ||
1088 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
1089 | |||
1090 | if (chip->vendor.release) | ||
1091 | chip->vendor.release(dev); | ||
1092 | |||
1093 | chip->release(dev); | ||
1094 | |||
1095 | clear_bit(chip->dev_num, dev_mask); | ||
1096 | kfree(chip->vendor.miscdev.name); | ||
1097 | kfree(chip); | ||
1098 | } | ||
1099 | |||
1100 | /* | ||
1086 | * Called from tpm_<specific>.c probe function only for devices | 1101 | * Called from tpm_<specific>.c probe function only for devices |
1087 | * the driver has determined it should claim. Prior to calling | 1102 | * the driver has determined it should claim. Prior to calling |
1088 | * this function the specific probe function has called pci_enable_device | 1103 | * this function the specific probe function has called pci_enable_device |
@@ -1136,23 +1151,21 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1136 | 1151 | ||
1137 | chip->vendor.miscdev.parent = dev; | 1152 | chip->vendor.miscdev.parent = dev; |
1138 | chip->dev = get_device(dev); | 1153 | chip->dev = get_device(dev); |
1154 | chip->release = dev->release; | ||
1155 | dev->release = tpm_dev_release; | ||
1156 | dev_set_drvdata(dev, chip); | ||
1139 | 1157 | ||
1140 | if (misc_register(&chip->vendor.miscdev)) { | 1158 | if (misc_register(&chip->vendor.miscdev)) { |
1141 | dev_err(chip->dev, | 1159 | dev_err(chip->dev, |
1142 | "unable to misc_register %s, minor %d\n", | 1160 | "unable to misc_register %s, minor %d\n", |
1143 | chip->vendor.miscdev.name, | 1161 | chip->vendor.miscdev.name, |
1144 | chip->vendor.miscdev.minor); | 1162 | chip->vendor.miscdev.minor); |
1145 | put_device(dev); | 1163 | put_device(chip->dev); |
1146 | clear_bit(chip->dev_num, dev_mask); | ||
1147 | kfree(chip); | ||
1148 | kfree(devname); | ||
1149 | return NULL; | 1164 | return NULL; |
1150 | } | 1165 | } |
1151 | 1166 | ||
1152 | spin_lock(&driver_lock); | 1167 | spin_lock(&driver_lock); |
1153 | 1168 | ||
1154 | dev_set_drvdata(dev, chip); | ||
1155 | |||
1156 | list_add(&chip->list, &tpm_chip_list); | 1169 | list_add(&chip->list, &tpm_chip_list); |
1157 | 1170 | ||
1158 | spin_unlock(&driver_lock); | 1171 | spin_unlock(&driver_lock); |
@@ -1160,10 +1173,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vend | |||
1160 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { | 1173 | if (sysfs_create_group(&dev->kobj, chip->vendor.attr_group)) { |
1161 | list_del(&chip->list); | 1174 | list_del(&chip->list); |
1162 | misc_deregister(&chip->vendor.miscdev); | 1175 | misc_deregister(&chip->vendor.miscdev); |
1163 | put_device(dev); | 1176 | put_device(chip->dev); |
1164 | clear_bit(chip->dev_num, dev_mask); | ||
1165 | kfree(chip); | ||
1166 | kfree(devname); | ||
1167 | return NULL; | 1177 | return NULL; |
1168 | } | 1178 | } |
1169 | 1179 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index d15ccddc92eb..e885148b4cfb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -74,6 +74,7 @@ struct tpm_vendor_specific { | |||
74 | int (*send) (struct tpm_chip *, u8 *, size_t); | 74 | int (*send) (struct tpm_chip *, u8 *, size_t); |
75 | void (*cancel) (struct tpm_chip *); | 75 | void (*cancel) (struct tpm_chip *); |
76 | u8 (*status) (struct tpm_chip *); | 76 | u8 (*status) (struct tpm_chip *); |
77 | void (*release) (struct device *); | ||
77 | struct miscdevice miscdev; | 78 | struct miscdevice miscdev; |
78 | struct attribute_group *attr_group; | 79 | struct attribute_group *attr_group; |
79 | struct list_head list; | 80 | struct list_head list; |
@@ -106,6 +107,7 @@ struct tpm_chip { | |||
106 | struct dentry **bios_dir; | 107 | struct dentry **bios_dir; |
107 | 108 | ||
108 | struct list_head list; | 109 | struct list_head list; |
110 | void (*release) (struct device *); | ||
109 | }; | 111 | }; |
110 | 112 | ||
111 | #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) | 113 | #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) |
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 967002a5a1e5..726ee8a0277f 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -611,7 +611,7 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
611 | } | 611 | } |
612 | } | 612 | } |
613 | 613 | ||
614 | static struct pnp_driver tpm_inf_pnp = { | 614 | static struct pnp_driver tpm_inf_pnp_driver = { |
615 | .name = "tpm_inf_pnp", | 615 | .name = "tpm_inf_pnp", |
616 | .driver = { | 616 | .driver = { |
617 | .owner = THIS_MODULE, | 617 | .owner = THIS_MODULE, |
@@ -625,12 +625,12 @@ static struct pnp_driver tpm_inf_pnp = { | |||
625 | 625 | ||
626 | static int __init init_inf(void) | 626 | static int __init init_inf(void) |
627 | { | 627 | { |
628 | return pnp_register_driver(&tpm_inf_pnp); | 628 | return pnp_register_driver(&tpm_inf_pnp_driver); |
629 | } | 629 | } |
630 | 630 | ||
631 | static void __exit cleanup_inf(void) | 631 | static void __exit cleanup_inf(void) |
632 | { | 632 | { |
633 | pnp_unregister_driver(&tpm_inf_pnp); | 633 | pnp_unregister_driver(&tpm_inf_pnp_driver); |
634 | } | 634 | } |
635 | 635 | ||
636 | module_init(init_inf); | 636 | module_init(init_inf); |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index f36fecd3fd26..79c86c47947f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -138,7 +138,7 @@ EXPORT_SYMBOL(tty_mutex); | |||
138 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ | 138 | extern struct tty_driver *ptm_driver; /* Unix98 pty masters; for /dev/ptmx */ |
139 | extern int pty_limit; /* Config limit on Unix98 ptys */ | 139 | extern int pty_limit; /* Config limit on Unix98 ptys */ |
140 | static DEFINE_IDR(allocated_ptys); | 140 | static DEFINE_IDR(allocated_ptys); |
141 | static DECLARE_MUTEX(allocated_ptys_lock); | 141 | static DEFINE_MUTEX(allocated_ptys_lock); |
142 | static int ptmx_open(struct inode *, struct file *); | 142 | static int ptmx_open(struct inode *, struct file *); |
143 | #endif | 143 | #endif |
144 | 144 | ||
@@ -2571,9 +2571,9 @@ static void release_dev(struct file * filp) | |||
2571 | #ifdef CONFIG_UNIX98_PTYS | 2571 | #ifdef CONFIG_UNIX98_PTYS |
2572 | /* Make this pty number available for reallocation */ | 2572 | /* Make this pty number available for reallocation */ |
2573 | if (devpts) { | 2573 | if (devpts) { |
2574 | down(&allocated_ptys_lock); | 2574 | mutex_lock(&allocated_ptys_lock); |
2575 | idr_remove(&allocated_ptys, idx); | 2575 | idr_remove(&allocated_ptys, idx); |
2576 | up(&allocated_ptys_lock); | 2576 | mutex_unlock(&allocated_ptys_lock); |
2577 | } | 2577 | } |
2578 | #endif | 2578 | #endif |
2579 | 2579 | ||
@@ -2737,24 +2737,24 @@ static int ptmx_open(struct inode * inode, struct file * filp) | |||
2737 | nonseekable_open(inode, filp); | 2737 | nonseekable_open(inode, filp); |
2738 | 2738 | ||
2739 | /* find a device that is not in use. */ | 2739 | /* find a device that is not in use. */ |
2740 | down(&allocated_ptys_lock); | 2740 | mutex_lock(&allocated_ptys_lock); |
2741 | if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { | 2741 | if (!idr_pre_get(&allocated_ptys, GFP_KERNEL)) { |
2742 | up(&allocated_ptys_lock); | 2742 | mutex_unlock(&allocated_ptys_lock); |
2743 | return -ENOMEM; | 2743 | return -ENOMEM; |
2744 | } | 2744 | } |
2745 | idr_ret = idr_get_new(&allocated_ptys, NULL, &index); | 2745 | idr_ret = idr_get_new(&allocated_ptys, NULL, &index); |
2746 | if (idr_ret < 0) { | 2746 | if (idr_ret < 0) { |
2747 | up(&allocated_ptys_lock); | 2747 | mutex_unlock(&allocated_ptys_lock); |
2748 | if (idr_ret == -EAGAIN) | 2748 | if (idr_ret == -EAGAIN) |
2749 | return -ENOMEM; | 2749 | return -ENOMEM; |
2750 | return -EIO; | 2750 | return -EIO; |
2751 | } | 2751 | } |
2752 | if (index >= pty_limit) { | 2752 | if (index >= pty_limit) { |
2753 | idr_remove(&allocated_ptys, index); | 2753 | idr_remove(&allocated_ptys, index); |
2754 | up(&allocated_ptys_lock); | 2754 | mutex_unlock(&allocated_ptys_lock); |
2755 | return -EIO; | 2755 | return -EIO; |
2756 | } | 2756 | } |
2757 | up(&allocated_ptys_lock); | 2757 | mutex_unlock(&allocated_ptys_lock); |
2758 | 2758 | ||
2759 | mutex_lock(&tty_mutex); | 2759 | mutex_lock(&tty_mutex); |
2760 | retval = init_dev(ptm_driver, index, &tty); | 2760 | retval = init_dev(ptm_driver, index, &tty); |
@@ -2781,9 +2781,9 @@ out1: | |||
2781 | release_dev(filp); | 2781 | release_dev(filp); |
2782 | return retval; | 2782 | return retval; |
2783 | out: | 2783 | out: |
2784 | down(&allocated_ptys_lock); | 2784 | mutex_lock(&allocated_ptys_lock); |
2785 | idr_remove(&allocated_ptys, index); | 2785 | idr_remove(&allocated_ptys, index); |
2786 | up(&allocated_ptys_lock); | 2786 | mutex_unlock(&allocated_ptys_lock); |
2787 | return retval; | 2787 | return retval; |
2788 | } | 2788 | } |
2789 | #endif | 2789 | #endif |
@@ -3721,7 +3721,6 @@ static void initialize_tty_struct(struct tty_struct *tty) | |||
3721 | tty->buf.head = tty->buf.tail = NULL; | 3721 | tty->buf.head = tty->buf.tail = NULL; |
3722 | tty_buffer_init(tty); | 3722 | tty_buffer_init(tty); |
3723 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); | 3723 | INIT_DELAYED_WORK(&tty->buf.work, flush_to_ldisc); |
3724 | init_MUTEX(&tty->buf.pty_sem); | ||
3725 | mutex_init(&tty->termios_mutex); | 3724 | mutex_init(&tty->termios_mutex); |
3726 | init_waitqueue_head(&tty->write_wait); | 3725 | init_waitqueue_head(&tty->write_wait); |
3727 | init_waitqueue_head(&tty->read_wait); | 3726 | init_waitqueue_head(&tty->read_wait); |
@@ -4048,10 +4047,6 @@ void __init console_init(void) | |||
4048 | } | 4047 | } |
4049 | } | 4048 | } |
4050 | 4049 | ||
4051 | #ifdef CONFIG_VT | ||
4052 | extern int vty_init(void); | ||
4053 | #endif | ||
4054 | |||
4055 | static int __init tty_class_init(void) | 4050 | static int __init tty_class_init(void) |
4056 | { | 4051 | { |
4057 | tty_class = class_create(THIS_MODULE, "tty"); | 4052 | tty_class = class_create(THIS_MODULE, "tty"); |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 7a5badfb7d84..367be9175061 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2400,13 +2400,15 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2400 | { | 2400 | { |
2401 | struct vc_data *vc = vc_cons[fg_console].d; | 2401 | struct vc_data *vc = vc_cons[fg_console].d; |
2402 | unsigned char c; | 2402 | unsigned char c; |
2403 | static unsigned long printing; | 2403 | static DEFINE_SPINLOCK(printing_lock); |
2404 | const ushort *start; | 2404 | const ushort *start; |
2405 | ushort cnt = 0; | 2405 | ushort cnt = 0; |
2406 | ushort myx; | 2406 | ushort myx; |
2407 | 2407 | ||
2408 | /* console busy or not yet initialized */ | 2408 | /* console busy or not yet initialized */ |
2409 | if (!printable || test_and_set_bit(0, &printing)) | 2409 | if (!printable) |
2410 | return; | ||
2411 | if (!spin_trylock(&printing_lock)) | ||
2410 | return; | 2412 | return; |
2411 | 2413 | ||
2412 | if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) | 2414 | if (kmsg_redirect && vc_cons_allocated(kmsg_redirect - 1)) |
@@ -2481,7 +2483,7 @@ static void vt_console_print(struct console *co, const char *b, unsigned count) | |||
2481 | notify_update(vc); | 2483 | notify_update(vc); |
2482 | 2484 | ||
2483 | quit: | 2485 | quit: |
2484 | clear_bit(0, &printing); | 2486 | spin_unlock(&printing_lock); |
2485 | } | 2487 | } |
2486 | 2488 | ||
2487 | static struct tty_driver *vt_console_device(struct console *c, int *index) | 2489 | static struct tty_driver *vt_console_device(struct console *c, int *index) |
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 18cdcb3ae1ca..1636806ec55e 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
@@ -658,4 +658,5 @@ MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")"); | |||
658 | MODULE_VERSION(DRIVER_VERSION); | 658 | MODULE_VERSION(DRIVER_VERSION); |
659 | MODULE_AUTHOR("Dell Inc."); | 659 | MODULE_AUTHOR("Dell Inc."); |
660 | MODULE_LICENSE("GPL"); | 660 | MODULE_LICENSE("GPL"); |
661 | 661 | /* Any System or BIOS claiming to be by Dell */ | |
662 | MODULE_ALIAS("dmi:*:[bs]vnD[Ee][Ll][Ll]*:*"); | ||
diff --git a/drivers/firmware/dmi-id.c b/drivers/firmware/dmi-id.c index 313c99cbdc62..e880d6c8d896 100644 --- a/drivers/firmware/dmi-id.c +++ b/drivers/firmware/dmi-id.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/dmi.h> | 12 | #include <linux/dmi.h> |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/autoconf.h> | ||
15 | 14 | ||
16 | struct dmi_device_attribute{ | 15 | struct dmi_device_attribute{ |
17 | struct device_attribute dev_attr; | 16 | struct device_attribute dev_attr; |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 74fac0f5c348..bbd28342e771 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -27,15 +27,16 @@ config DEBUG_GPIO | |||
27 | 27 | ||
28 | comment "I2C GPIO expanders:" | 28 | comment "I2C GPIO expanders:" |
29 | 29 | ||
30 | config GPIO_PCA9539 | 30 | config GPIO_PCA953X |
31 | tristate "PCA9539 16-bit I/O port" | 31 | tristate "PCA953x I/O ports" |
32 | depends on I2C | 32 | depends on I2C |
33 | help | 33 | help |
34 | Say yes here to support the PCA9539 16-bit I/O port. These | 34 | Say yes here to support the PCA9534 (8-bit), PCA9535 (16-bit), |
35 | parts are made by NXP and TI. | 35 | PCA9536 (4-bit), PCA9537 (4-bit), PCA9538 (8-bit), and PCA9539 |
36 | (16-bit) I/O ports. These parts are made by NXP and TI. | ||
36 | 37 | ||
37 | This driver can also be built as a module. If so, the module | 38 | This driver can also be built as a module. If so, the module |
38 | will be called pca9539. | 39 | will be called pca953x. |
39 | 40 | ||
40 | config GPIO_PCF857X | 41 | config GPIO_PCF857X |
41 | tristate "PCF857x, PCA857x, and PCA967x I2C GPIO expanders" | 42 | tristate "PCF857x, PCA857x, and PCA967x I2C GPIO expanders" |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 470ecd6aa778..fdde9923cf33 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -5,5 +5,5 @@ ccflags-$(CONFIG_DEBUG_GPIO) += -DDEBUG | |||
5 | obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o | 5 | obj-$(CONFIG_HAVE_GPIO_LIB) += gpiolib.o |
6 | 6 | ||
7 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o | 7 | obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o |
8 | obj-$(CONFIG_GPIO_PCA9539) += pca9539.o | 8 | obj-$(CONFIG_GPIO_PCA953X) += pca953x.o |
9 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o | 9 | obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o |
diff --git a/drivers/gpio/pca9539.c b/drivers/gpio/pca9539.c deleted file mode 100644 index 3e85c92a7d59..000000000000 --- a/drivers/gpio/pca9539.c +++ /dev/null | |||
@@ -1,271 +0,0 @@ | |||
1 | /* | ||
2 | * pca9539.c - 16-bit I/O port with interrupt and reset | ||
3 | * | ||
4 | * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> | ||
5 | * Copyright (C) 2007 Marvell International Ltd. | ||
6 | * | ||
7 | * Derived from drivers/i2c/chips/pca9539.c | ||
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 as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/i2c/pca9539.h> | ||
18 | |||
19 | #include <asm/gpio.h> | ||
20 | |||
21 | |||
22 | #define NR_PCA9539_GPIOS 16 | ||
23 | |||
24 | #define PCA9539_INPUT 0 | ||
25 | #define PCA9539_OUTPUT 2 | ||
26 | #define PCA9539_INVERT 4 | ||
27 | #define PCA9539_DIRECTION 6 | ||
28 | |||
29 | struct pca9539_chip { | ||
30 | unsigned gpio_start; | ||
31 | uint16_t reg_output; | ||
32 | uint16_t reg_direction; | ||
33 | |||
34 | struct i2c_client *client; | ||
35 | struct gpio_chip gpio_chip; | ||
36 | }; | ||
37 | |||
38 | /* NOTE: we can't currently rely on fault codes to come from SMBus | ||
39 | * calls, so we map all errors to EIO here and return zero otherwise. | ||
40 | */ | ||
41 | static int pca9539_write_reg(struct pca9539_chip *chip, int reg, uint16_t val) | ||
42 | { | ||
43 | if (i2c_smbus_write_word_data(chip->client, reg, val) < 0) | ||
44 | return -EIO; | ||
45 | else | ||
46 | return 0; | ||
47 | } | ||
48 | |||
49 | static int pca9539_read_reg(struct pca9539_chip *chip, int reg, uint16_t *val) | ||
50 | { | ||
51 | int ret; | ||
52 | |||
53 | ret = i2c_smbus_read_word_data(chip->client, reg); | ||
54 | if (ret < 0) { | ||
55 | dev_err(&chip->client->dev, "failed reading register\n"); | ||
56 | return -EIO; | ||
57 | } | ||
58 | |||
59 | *val = (uint16_t)ret; | ||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static int pca9539_gpio_direction_input(struct gpio_chip *gc, unsigned off) | ||
64 | { | ||
65 | struct pca9539_chip *chip; | ||
66 | uint16_t reg_val; | ||
67 | int ret; | ||
68 | |||
69 | chip = container_of(gc, struct pca9539_chip, gpio_chip); | ||
70 | |||
71 | reg_val = chip->reg_direction | (1u << off); | ||
72 | ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val); | ||
73 | if (ret) | ||
74 | return ret; | ||
75 | |||
76 | chip->reg_direction = reg_val; | ||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | static int pca9539_gpio_direction_output(struct gpio_chip *gc, | ||
81 | unsigned off, int val) | ||
82 | { | ||
83 | struct pca9539_chip *chip; | ||
84 | uint16_t reg_val; | ||
85 | int ret; | ||
86 | |||
87 | chip = container_of(gc, struct pca9539_chip, gpio_chip); | ||
88 | |||
89 | /* set output level */ | ||
90 | if (val) | ||
91 | reg_val = chip->reg_output | (1u << off); | ||
92 | else | ||
93 | reg_val = chip->reg_output & ~(1u << off); | ||
94 | |||
95 | ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val); | ||
96 | if (ret) | ||
97 | return ret; | ||
98 | |||
99 | chip->reg_output = reg_val; | ||
100 | |||
101 | /* then direction */ | ||
102 | reg_val = chip->reg_direction & ~(1u << off); | ||
103 | ret = pca9539_write_reg(chip, PCA9539_DIRECTION, reg_val); | ||
104 | if (ret) | ||
105 | return ret; | ||
106 | |||
107 | chip->reg_direction = reg_val; | ||
108 | return 0; | ||
109 | } | ||
110 | |||
111 | static int pca9539_gpio_get_value(struct gpio_chip *gc, unsigned off) | ||
112 | { | ||
113 | struct pca9539_chip *chip; | ||
114 | uint16_t reg_val; | ||
115 | int ret; | ||
116 | |||
117 | chip = container_of(gc, struct pca9539_chip, gpio_chip); | ||
118 | |||
119 | ret = pca9539_read_reg(chip, PCA9539_INPUT, ®_val); | ||
120 | if (ret < 0) { | ||
121 | /* NOTE: diagnostic already emitted; that's all we should | ||
122 | * do unless gpio_*_value_cansleep() calls become different | ||
123 | * from their nonsleeping siblings (and report faults). | ||
124 | */ | ||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | return (reg_val & (1u << off)) ? 1 : 0; | ||
129 | } | ||
130 | |||
131 | static void pca9539_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | ||
132 | { | ||
133 | struct pca9539_chip *chip; | ||
134 | uint16_t reg_val; | ||
135 | int ret; | ||
136 | |||
137 | chip = container_of(gc, struct pca9539_chip, gpio_chip); | ||
138 | |||
139 | if (val) | ||
140 | reg_val = chip->reg_output | (1u << off); | ||
141 | else | ||
142 | reg_val = chip->reg_output & ~(1u << off); | ||
143 | |||
144 | ret = pca9539_write_reg(chip, PCA9539_OUTPUT, reg_val); | ||
145 | if (ret) | ||
146 | return; | ||
147 | |||
148 | chip->reg_output = reg_val; | ||
149 | } | ||
150 | |||
151 | static int pca9539_init_gpio(struct pca9539_chip *chip) | ||
152 | { | ||
153 | struct gpio_chip *gc; | ||
154 | |||
155 | gc = &chip->gpio_chip; | ||
156 | |||
157 | gc->direction_input = pca9539_gpio_direction_input; | ||
158 | gc->direction_output = pca9539_gpio_direction_output; | ||
159 | gc->get = pca9539_gpio_get_value; | ||
160 | gc->set = pca9539_gpio_set_value; | ||
161 | |||
162 | gc->base = chip->gpio_start; | ||
163 | gc->ngpio = NR_PCA9539_GPIOS; | ||
164 | gc->label = "pca9539"; | ||
165 | |||
166 | return gpiochip_add(gc); | ||
167 | } | ||
168 | |||
169 | static int __devinit pca9539_probe(struct i2c_client *client) | ||
170 | { | ||
171 | struct pca9539_platform_data *pdata; | ||
172 | struct pca9539_chip *chip; | ||
173 | int ret; | ||
174 | |||
175 | pdata = client->dev.platform_data; | ||
176 | if (pdata == NULL) | ||
177 | return -ENODEV; | ||
178 | |||
179 | chip = kzalloc(sizeof(struct pca9539_chip), GFP_KERNEL); | ||
180 | if (chip == NULL) | ||
181 | return -ENOMEM; | ||
182 | |||
183 | chip->client = client; | ||
184 | |||
185 | chip->gpio_start = pdata->gpio_base; | ||
186 | |||
187 | /* initialize cached registers from their original values. | ||
188 | * we can't share this chip with another i2c master. | ||
189 | */ | ||
190 | ret = pca9539_read_reg(chip, PCA9539_OUTPUT, &chip->reg_output); | ||
191 | if (ret) | ||
192 | goto out_failed; | ||
193 | |||
194 | ret = pca9539_read_reg(chip, PCA9539_DIRECTION, &chip->reg_direction); | ||
195 | if (ret) | ||
196 | goto out_failed; | ||
197 | |||
198 | /* set platform specific polarity inversion */ | ||
199 | ret = pca9539_write_reg(chip, PCA9539_INVERT, pdata->invert); | ||
200 | if (ret) | ||
201 | goto out_failed; | ||
202 | |||
203 | ret = pca9539_init_gpio(chip); | ||
204 | if (ret) | ||
205 | goto out_failed; | ||
206 | |||
207 | if (pdata->setup) { | ||
208 | ret = pdata->setup(client, chip->gpio_chip.base, | ||
209 | chip->gpio_chip.ngpio, pdata->context); | ||
210 | if (ret < 0) | ||
211 | dev_warn(&client->dev, "setup failed, %d\n", ret); | ||
212 | } | ||
213 | |||
214 | i2c_set_clientdata(client, chip); | ||
215 | return 0; | ||
216 | |||
217 | out_failed: | ||
218 | kfree(chip); | ||
219 | return ret; | ||
220 | } | ||
221 | |||
222 | static int pca9539_remove(struct i2c_client *client) | ||
223 | { | ||
224 | struct pca9539_platform_data *pdata = client->dev.platform_data; | ||
225 | struct pca9539_chip *chip = i2c_get_clientdata(client); | ||
226 | int ret = 0; | ||
227 | |||
228 | if (pdata->teardown) { | ||
229 | ret = pdata->teardown(client, chip->gpio_chip.base, | ||
230 | chip->gpio_chip.ngpio, pdata->context); | ||
231 | if (ret < 0) { | ||
232 | dev_err(&client->dev, "%s failed, %d\n", | ||
233 | "teardown", ret); | ||
234 | return ret; | ||
235 | } | ||
236 | } | ||
237 | |||
238 | ret = gpiochip_remove(&chip->gpio_chip); | ||
239 | if (ret) { | ||
240 | dev_err(&client->dev, "%s failed, %d\n", | ||
241 | "gpiochip_remove()", ret); | ||
242 | return ret; | ||
243 | } | ||
244 | |||
245 | kfree(chip); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static struct i2c_driver pca9539_driver = { | ||
250 | .driver = { | ||
251 | .name = "pca9539", | ||
252 | }, | ||
253 | .probe = pca9539_probe, | ||
254 | .remove = pca9539_remove, | ||
255 | }; | ||
256 | |||
257 | static int __init pca9539_init(void) | ||
258 | { | ||
259 | return i2c_add_driver(&pca9539_driver); | ||
260 | } | ||
261 | module_init(pca9539_init); | ||
262 | |||
263 | static void __exit pca9539_exit(void) | ||
264 | { | ||
265 | i2c_del_driver(&pca9539_driver); | ||
266 | } | ||
267 | module_exit(pca9539_exit); | ||
268 | |||
269 | MODULE_AUTHOR("eric miao <eric.miao@marvell.com>"); | ||
270 | MODULE_DESCRIPTION("GPIO expander driver for PCA9539"); | ||
271 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/gpio/pca953x.c b/drivers/gpio/pca953x.c new file mode 100644 index 000000000000..92583cd4bffd --- /dev/null +++ b/drivers/gpio/pca953x.c | |||
@@ -0,0 +1,308 @@ | |||
1 | /* | ||
2 | * pca953x.c - 4/8/16 bit I/O ports | ||
3 | * | ||
4 | * Copyright (C) 2005 Ben Gardner <bgardner@wabtec.com> | ||
5 | * Copyright (C) 2007 Marvell International Ltd. | ||
6 | * | ||
7 | * Derived from drivers/i2c/chips/pca9539.c | ||
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 as published by | ||
11 | * the Free Software Foundation; version 2 of the License. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/i2c.h> | ||
17 | #include <linux/i2c/pca953x.h> | ||
18 | |||
19 | #include <asm/gpio.h> | ||
20 | |||
21 | #define PCA953X_INPUT 0 | ||
22 | #define PCA953X_OUTPUT 1 | ||
23 | #define PCA953X_INVERT 2 | ||
24 | #define PCA953X_DIRECTION 3 | ||
25 | |||
26 | /* This is temporary - in 2.6.26 i2c_driver_data should replace it. */ | ||
27 | struct pca953x_desc { | ||
28 | char name[I2C_NAME_SIZE]; | ||
29 | unsigned long driver_data; | ||
30 | }; | ||
31 | |||
32 | static const struct pca953x_desc pca953x_descs[] = { | ||
33 | { "pca9534", 8, }, | ||
34 | { "pca9535", 16, }, | ||
35 | { "pca9536", 4, }, | ||
36 | { "pca9537", 4, }, | ||
37 | { "pca9538", 8, }, | ||
38 | { "pca9539", 16, }, | ||
39 | /* REVISIT several pca955x parts should work here too */ | ||
40 | }; | ||
41 | |||
42 | struct pca953x_chip { | ||
43 | unsigned gpio_start; | ||
44 | uint16_t reg_output; | ||
45 | uint16_t reg_direction; | ||
46 | |||
47 | struct i2c_client *client; | ||
48 | struct gpio_chip gpio_chip; | ||
49 | }; | ||
50 | |||
51 | /* NOTE: we can't currently rely on fault codes to come from SMBus | ||
52 | * calls, so we map all errors to EIO here and return zero otherwise. | ||
53 | */ | ||
54 | static int pca953x_write_reg(struct pca953x_chip *chip, int reg, uint16_t val) | ||
55 | { | ||
56 | int ret; | ||
57 | |||
58 | if (chip->gpio_chip.ngpio <= 8) | ||
59 | ret = i2c_smbus_write_byte_data(chip->client, reg, val); | ||
60 | else | ||
61 | ret = i2c_smbus_write_word_data(chip->client, reg << 1, val); | ||
62 | |||
63 | if (ret < 0) { | ||
64 | dev_err(&chip->client->dev, "failed writing register\n"); | ||
65 | return -EIO; | ||
66 | } | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int pca953x_read_reg(struct pca953x_chip *chip, int reg, uint16_t *val) | ||
72 | { | ||
73 | int ret; | ||
74 | |||
75 | if (chip->gpio_chip.ngpio <= 8) | ||
76 | ret = i2c_smbus_read_byte_data(chip->client, reg); | ||
77 | else | ||
78 | ret = i2c_smbus_read_word_data(chip->client, reg << 1); | ||
79 | |||
80 | if (ret < 0) { | ||
81 | dev_err(&chip->client->dev, "failed reading register\n"); | ||
82 | return -EIO; | ||
83 | } | ||
84 | |||
85 | *val = (uint16_t)ret; | ||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int pca953x_gpio_direction_input(struct gpio_chip *gc, unsigned off) | ||
90 | { | ||
91 | struct pca953x_chip *chip; | ||
92 | uint16_t reg_val; | ||
93 | int ret; | ||
94 | |||
95 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | ||
96 | |||
97 | reg_val = chip->reg_direction | (1u << off); | ||
98 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | ||
99 | if (ret) | ||
100 | return ret; | ||
101 | |||
102 | chip->reg_direction = reg_val; | ||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static int pca953x_gpio_direction_output(struct gpio_chip *gc, | ||
107 | unsigned off, int val) | ||
108 | { | ||
109 | struct pca953x_chip *chip; | ||
110 | uint16_t reg_val; | ||
111 | int ret; | ||
112 | |||
113 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | ||
114 | |||
115 | /* set output level */ | ||
116 | if (val) | ||
117 | reg_val = chip->reg_output | (1u << off); | ||
118 | else | ||
119 | reg_val = chip->reg_output & ~(1u << off); | ||
120 | |||
121 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | ||
122 | if (ret) | ||
123 | return ret; | ||
124 | |||
125 | chip->reg_output = reg_val; | ||
126 | |||
127 | /* then direction */ | ||
128 | reg_val = chip->reg_direction & ~(1u << off); | ||
129 | ret = pca953x_write_reg(chip, PCA953X_DIRECTION, reg_val); | ||
130 | if (ret) | ||
131 | return ret; | ||
132 | |||
133 | chip->reg_direction = reg_val; | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int pca953x_gpio_get_value(struct gpio_chip *gc, unsigned off) | ||
138 | { | ||
139 | struct pca953x_chip *chip; | ||
140 | uint16_t reg_val; | ||
141 | int ret; | ||
142 | |||
143 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | ||
144 | |||
145 | ret = pca953x_read_reg(chip, PCA953X_INPUT, ®_val); | ||
146 | if (ret < 0) { | ||
147 | /* NOTE: diagnostic already emitted; that's all we should | ||
148 | * do unless gpio_*_value_cansleep() calls become different | ||
149 | * from their nonsleeping siblings (and report faults). | ||
150 | */ | ||
151 | return 0; | ||
152 | } | ||
153 | |||
154 | return (reg_val & (1u << off)) ? 1 : 0; | ||
155 | } | ||
156 | |||
157 | static void pca953x_gpio_set_value(struct gpio_chip *gc, unsigned off, int val) | ||
158 | { | ||
159 | struct pca953x_chip *chip; | ||
160 | uint16_t reg_val; | ||
161 | int ret; | ||
162 | |||
163 | chip = container_of(gc, struct pca953x_chip, gpio_chip); | ||
164 | |||
165 | if (val) | ||
166 | reg_val = chip->reg_output | (1u << off); | ||
167 | else | ||
168 | reg_val = chip->reg_output & ~(1u << off); | ||
169 | |||
170 | ret = pca953x_write_reg(chip, PCA953X_OUTPUT, reg_val); | ||
171 | if (ret) | ||
172 | return; | ||
173 | |||
174 | chip->reg_output = reg_val; | ||
175 | } | ||
176 | |||
177 | static void pca953x_setup_gpio(struct pca953x_chip *chip, int gpios) | ||
178 | { | ||
179 | struct gpio_chip *gc; | ||
180 | |||
181 | gc = &chip->gpio_chip; | ||
182 | |||
183 | gc->direction_input = pca953x_gpio_direction_input; | ||
184 | gc->direction_output = pca953x_gpio_direction_output; | ||
185 | gc->get = pca953x_gpio_get_value; | ||
186 | gc->set = pca953x_gpio_set_value; | ||
187 | |||
188 | gc->base = chip->gpio_start; | ||
189 | gc->ngpio = gpios; | ||
190 | gc->label = chip->client->name; | ||
191 | } | ||
192 | |||
193 | static int __devinit pca953x_probe(struct i2c_client *client) | ||
194 | { | ||
195 | struct pca953x_platform_data *pdata; | ||
196 | struct pca953x_chip *chip; | ||
197 | int ret, i; | ||
198 | const struct pca953x_desc *id = NULL; | ||
199 | |||
200 | pdata = client->dev.platform_data; | ||
201 | if (pdata == NULL) | ||
202 | return -ENODEV; | ||
203 | |||
204 | /* this loop vanishes when we get i2c_device_id */ | ||
205 | for (i = 0; i < ARRAY_SIZE(pca953x_descs); i++) | ||
206 | if (!strcmp(pca953x_descs[i].name, client->name)) { | ||
207 | id = pca953x_descs + i; | ||
208 | break; | ||
209 | } | ||
210 | if (!id) | ||
211 | return -ENODEV; | ||
212 | |||
213 | chip = kzalloc(sizeof(struct pca953x_chip), GFP_KERNEL); | ||
214 | if (chip == NULL) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | chip->client = client; | ||
218 | |||
219 | chip->gpio_start = pdata->gpio_base; | ||
220 | |||
221 | /* initialize cached registers from their original values. | ||
222 | * we can't share this chip with another i2c master. | ||
223 | */ | ||
224 | pca953x_setup_gpio(chip, id->driver_data); | ||
225 | |||
226 | ret = pca953x_read_reg(chip, PCA953X_OUTPUT, &chip->reg_output); | ||
227 | if (ret) | ||
228 | goto out_failed; | ||
229 | |||
230 | ret = pca953x_read_reg(chip, PCA953X_DIRECTION, &chip->reg_direction); | ||
231 | if (ret) | ||
232 | goto out_failed; | ||
233 | |||
234 | /* set platform specific polarity inversion */ | ||
235 | ret = pca953x_write_reg(chip, PCA953X_INVERT, pdata->invert); | ||
236 | if (ret) | ||
237 | goto out_failed; | ||
238 | |||
239 | |||
240 | ret = gpiochip_add(&chip->gpio_chip); | ||
241 | if (ret) | ||
242 | goto out_failed; | ||
243 | |||
244 | if (pdata->setup) { | ||
245 | ret = pdata->setup(client, chip->gpio_chip.base, | ||
246 | chip->gpio_chip.ngpio, pdata->context); | ||
247 | if (ret < 0) | ||
248 | dev_warn(&client->dev, "setup failed, %d\n", ret); | ||
249 | } | ||
250 | |||
251 | i2c_set_clientdata(client, chip); | ||
252 | return 0; | ||
253 | |||
254 | out_failed: | ||
255 | kfree(chip); | ||
256 | return ret; | ||
257 | } | ||
258 | |||
259 | static int pca953x_remove(struct i2c_client *client) | ||
260 | { | ||
261 | struct pca953x_platform_data *pdata = client->dev.platform_data; | ||
262 | struct pca953x_chip *chip = i2c_get_clientdata(client); | ||
263 | int ret = 0; | ||
264 | |||
265 | if (pdata->teardown) { | ||
266 | ret = pdata->teardown(client, chip->gpio_chip.base, | ||
267 | chip->gpio_chip.ngpio, pdata->context); | ||
268 | if (ret < 0) { | ||
269 | dev_err(&client->dev, "%s failed, %d\n", | ||
270 | "teardown", ret); | ||
271 | return ret; | ||
272 | } | ||
273 | } | ||
274 | |||
275 | ret = gpiochip_remove(&chip->gpio_chip); | ||
276 | if (ret) { | ||
277 | dev_err(&client->dev, "%s failed, %d\n", | ||
278 | "gpiochip_remove()", ret); | ||
279 | return ret; | ||
280 | } | ||
281 | |||
282 | kfree(chip); | ||
283 | return 0; | ||
284 | } | ||
285 | |||
286 | static struct i2c_driver pca953x_driver = { | ||
287 | .driver = { | ||
288 | .name = "pca953x", | ||
289 | }, | ||
290 | .probe = pca953x_probe, | ||
291 | .remove = pca953x_remove, | ||
292 | }; | ||
293 | |||
294 | static int __init pca953x_init(void) | ||
295 | { | ||
296 | return i2c_add_driver(&pca953x_driver); | ||
297 | } | ||
298 | module_init(pca953x_init); | ||
299 | |||
300 | static void __exit pca953x_exit(void) | ||
301 | { | ||
302 | i2c_del_driver(&pca953x_driver); | ||
303 | } | ||
304 | module_exit(pca953x_exit); | ||
305 | |||
306 | MODULE_AUTHOR("eric miao <eric.miao@marvell.com>"); | ||
307 | MODULE_DESCRIPTION("GPIO expander driver for PCA953x"); | ||
308 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 45b26ed351cf..ab8fb257528e 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -1009,6 +1009,15 @@ config BLK_DEV_Q40IDE | |||
1009 | normally be on; disable it only if you are running a custom hard | 1009 | normally be on; disable it only if you are running a custom hard |
1010 | drive subsystem through an expansion card. | 1010 | drive subsystem through an expansion card. |
1011 | 1011 | ||
1012 | config BLK_DEV_PALMCHIP_BK3710 | ||
1013 | tristate "Palmchip bk3710 IDE controller support" | ||
1014 | depends on ARCH_DAVINCI | ||
1015 | select BLK_DEV_IDEDMA_PCI | ||
1016 | help | ||
1017 | Say Y here if you want to support the onchip IDE controller on the | ||
1018 | TI DaVinci SoC | ||
1019 | |||
1020 | |||
1012 | config BLK_DEV_MPC8xx_IDE | 1021 | config BLK_DEV_MPC8xx_IDE |
1013 | tristate "MPC8xx IDE support" | 1022 | tristate "MPC8xx IDE support" |
1014 | depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE | 1023 | depends on 8xx && (LWMON || IVMS8 || IVML24 || TQM8xxL) && IDE=y && BLK_DEV_IDE=y && !PPC_MERGE |
diff --git a/drivers/ide/arm/Makefile b/drivers/ide/arm/Makefile index 5f63ad216862..936e7b0237f5 100644 --- a/drivers/ide/arm/Makefile +++ b/drivers/ide/arm/Makefile | |||
@@ -2,6 +2,7 @@ | |||
2 | obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o | 2 | obj-$(CONFIG_BLK_DEV_IDE_ICSIDE) += icside.o |
3 | obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o | 3 | obj-$(CONFIG_BLK_DEV_IDE_RAPIDE) += rapide.o |
4 | obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o | 4 | obj-$(CONFIG_BLK_DEV_IDE_BAST) += bast-ide.o |
5 | obj-$(CONFIG_BLK_DEV_PALMCHIP_BK3710) += palm_bk3710.o | ||
5 | 6 | ||
6 | ifeq ($(CONFIG_IDE_ARM), m) | 7 | ifeq ($(CONFIG_IDE_ARM), m) |
7 | obj-m += ide_arm.o | 8 | obj-m += ide_arm.o |
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c index fb00f3827ecd..e816b0ffcfe6 100644 --- a/drivers/ide/arm/icside.c +++ b/drivers/ide/arm/icside.c | |||
@@ -365,7 +365,7 @@ static void icside_dma_timeout(ide_drive_t *drive) | |||
365 | if (icside_dma_test_irq(drive)) | 365 | if (icside_dma_test_irq(drive)) |
366 | return; | 366 | return; |
367 | 367 | ||
368 | ide_dump_status(drive, "DMA timeout", HWIF(drive)->INB(IDE_STATUS_REG)); | 368 | ide_dump_status(drive, "DMA timeout", ide_read_status(drive)); |
369 | 369 | ||
370 | icside_dma_end(drive); | 370 | icside_dma_end(drive); |
371 | } | 371 | } |
diff --git a/drivers/ide/arm/palm_bk3710.c b/drivers/ide/arm/palm_bk3710.c new file mode 100644 index 000000000000..c3069970a012 --- /dev/null +++ b/drivers/ide/arm/palm_bk3710.c | |||
@@ -0,0 +1,395 @@ | |||
1 | /* | ||
2 | * Palmchip bk3710 IDE controller | ||
3 | * | ||
4 | * Copyright (C) 2006 Texas Instruments. | ||
5 | * Copyright (C) 2007 MontaVista Software, Inc., <source@mvista.com> | ||
6 | * | ||
7 | * ---------------------------------------------------------------------------- | ||
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 as published by | ||
11 | * the Free Software Foundation; either version 2 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | * GNU General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License | ||
20 | * along with this program; if not, write to the Free Software | ||
21 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | * ---------------------------------------------------------------------------- | ||
23 | * | ||
24 | */ | ||
25 | |||
26 | #include <linux/types.h> | ||
27 | #include <linux/module.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/hdreg.h> | ||
31 | #include <linux/ide.h> | ||
32 | #include <linux/delay.h> | ||
33 | #include <linux/init.h> | ||
34 | #include <linux/clk.h> | ||
35 | #include <linux/platform_device.h> | ||
36 | |||
37 | /* Offset of the primary interface registers */ | ||
38 | #define IDE_PALM_ATA_PRI_REG_OFFSET 0x1F0 | ||
39 | |||
40 | /* Primary Control Offset */ | ||
41 | #define IDE_PALM_ATA_PRI_CTL_OFFSET 0x3F6 | ||
42 | |||
43 | /* | ||
44 | * PalmChip 3710 IDE Controller UDMA timing structure Definition | ||
45 | */ | ||
46 | struct palm_bk3710_udmatiming { | ||
47 | unsigned int rptime; /* Ready to pause time */ | ||
48 | unsigned int cycletime; /* Cycle Time */ | ||
49 | }; | ||
50 | |||
51 | #define BK3710_BMICP 0x00 | ||
52 | #define BK3710_BMISP 0x02 | ||
53 | #define BK3710_BMIDTP 0x04 | ||
54 | #define BK3710_BMICS 0x08 | ||
55 | #define BK3710_BMISS 0x0A | ||
56 | #define BK3710_BMIDTS 0x0C | ||
57 | #define BK3710_IDETIMP 0x40 | ||
58 | #define BK3710_IDETIMS 0x42 | ||
59 | #define BK3710_SIDETIM 0x44 | ||
60 | #define BK3710_SLEWCTL 0x45 | ||
61 | #define BK3710_IDESTATUS 0x47 | ||
62 | #define BK3710_UDMACTL 0x48 | ||
63 | #define BK3710_UDMATIM 0x4A | ||
64 | #define BK3710_MISCCTL 0x50 | ||
65 | #define BK3710_REGSTB 0x54 | ||
66 | #define BK3710_REGRCVR 0x58 | ||
67 | #define BK3710_DATSTB 0x5C | ||
68 | #define BK3710_DATRCVR 0x60 | ||
69 | #define BK3710_DMASTB 0x64 | ||
70 | #define BK3710_DMARCVR 0x68 | ||
71 | #define BK3710_UDMASTB 0x6C | ||
72 | #define BK3710_UDMATRP 0x70 | ||
73 | #define BK3710_UDMAENV 0x74 | ||
74 | #define BK3710_IORDYTMP 0x78 | ||
75 | #define BK3710_IORDYTMS 0x7C | ||
76 | |||
77 | #include "../ide-timing.h" | ||
78 | |||
79 | static long ide_palm_clk; | ||
80 | |||
81 | static const struct palm_bk3710_udmatiming palm_bk3710_udmatimings[6] = { | ||
82 | {160, 240}, /* UDMA Mode 0 */ | ||
83 | {125, 160}, /* UDMA Mode 1 */ | ||
84 | {100, 120}, /* UDMA Mode 2 */ | ||
85 | {100, 90}, /* UDMA Mode 3 */ | ||
86 | {85, 60}, /* UDMA Mode 4 */ | ||
87 | }; | ||
88 | |||
89 | static struct clk *ideclkp; | ||
90 | |||
91 | static void palm_bk3710_setudmamode(void __iomem *base, unsigned int dev, | ||
92 | unsigned int mode) | ||
93 | { | ||
94 | u8 tenv, trp, t0; | ||
95 | u32 val32; | ||
96 | u16 val16; | ||
97 | |||
98 | /* DMA Data Setup */ | ||
99 | t0 = (palm_bk3710_udmatimings[mode].cycletime + ide_palm_clk - 1) | ||
100 | / ide_palm_clk - 1; | ||
101 | tenv = (20 + ide_palm_clk - 1) / ide_palm_clk - 1; | ||
102 | trp = (palm_bk3710_udmatimings[mode].rptime + ide_palm_clk - 1) | ||
103 | / ide_palm_clk - 1; | ||
104 | |||
105 | /* udmatim Register */ | ||
106 | val16 = readw(base + BK3710_UDMATIM) & (dev ? 0xFF0F : 0xFFF0); | ||
107 | val16 |= (mode << (dev ? 4 : 0)); | ||
108 | writew(val16, base + BK3710_UDMATIM); | ||
109 | |||
110 | /* udmastb Ultra DMA Access Strobe Width */ | ||
111 | val32 = readl(base + BK3710_UDMASTB) & (0xFF << (dev ? 0 : 8)); | ||
112 | val32 |= (t0 << (dev ? 8 : 0)); | ||
113 | writel(val32, base + BK3710_UDMASTB); | ||
114 | |||
115 | /* udmatrp Ultra DMA Ready to Pause Time */ | ||
116 | val32 = readl(base + BK3710_UDMATRP) & (0xFF << (dev ? 0 : 8)); | ||
117 | val32 |= (trp << (dev ? 8 : 0)); | ||
118 | writel(val32, base + BK3710_UDMATRP); | ||
119 | |||
120 | /* udmaenv Ultra DMA envelop Time */ | ||
121 | val32 = readl(base + BK3710_UDMAENV) & (0xFF << (dev ? 0 : 8)); | ||
122 | val32 |= (tenv << (dev ? 8 : 0)); | ||
123 | writel(val32, base + BK3710_UDMAENV); | ||
124 | |||
125 | /* Enable UDMA for Device */ | ||
126 | val16 = readw(base + BK3710_UDMACTL) | (1 << dev); | ||
127 | writew(val16, base + BK3710_UDMACTL); | ||
128 | } | ||
129 | |||
130 | static void palm_bk3710_setdmamode(void __iomem *base, unsigned int dev, | ||
131 | unsigned short min_cycle, | ||
132 | unsigned int mode) | ||
133 | { | ||
134 | u8 td, tkw, t0; | ||
135 | u32 val32; | ||
136 | u16 val16; | ||
137 | struct ide_timing *t; | ||
138 | int cycletime; | ||
139 | |||
140 | t = ide_timing_find_mode(mode); | ||
141 | cycletime = max_t(int, t->cycle, min_cycle); | ||
142 | |||
143 | /* DMA Data Setup */ | ||
144 | t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; | ||
145 | td = (t->active + ide_palm_clk - 1) / ide_palm_clk; | ||
146 | tkw = t0 - td - 1; | ||
147 | td -= 1; | ||
148 | |||
149 | val32 = readl(base + BK3710_DMASTB) & (0xFF << (dev ? 0 : 8)); | ||
150 | val32 |= (td << (dev ? 8 : 0)); | ||
151 | writel(val32, base + BK3710_DMASTB); | ||
152 | |||
153 | val32 = readl(base + BK3710_DMARCVR) & (0xFF << (dev ? 0 : 8)); | ||
154 | val32 |= (tkw << (dev ? 8 : 0)); | ||
155 | writel(val32, base + BK3710_DMARCVR); | ||
156 | |||
157 | /* Disable UDMA for Device */ | ||
158 | val16 = readw(base + BK3710_UDMACTL) & ~(1 << dev); | ||
159 | writew(val16, base + BK3710_UDMACTL); | ||
160 | } | ||
161 | |||
162 | static void palm_bk3710_setpiomode(void __iomem *base, ide_drive_t *mate, | ||
163 | unsigned int dev, unsigned int cycletime, | ||
164 | unsigned int mode) | ||
165 | { | ||
166 | u8 t2, t2i, t0; | ||
167 | u32 val32; | ||
168 | struct ide_timing *t; | ||
169 | |||
170 | /* PIO Data Setup */ | ||
171 | t0 = (cycletime + ide_palm_clk - 1) / ide_palm_clk; | ||
172 | t2 = (ide_timing_find_mode(XFER_PIO_0 + mode)->active + | ||
173 | ide_palm_clk - 1) / ide_palm_clk; | ||
174 | |||
175 | t2i = t0 - t2 - 1; | ||
176 | t2 -= 1; | ||
177 | |||
178 | val32 = readl(base + BK3710_DATSTB) & (0xFF << (dev ? 0 : 8)); | ||
179 | val32 |= (t2 << (dev ? 8 : 0)); | ||
180 | writel(val32, base + BK3710_DATSTB); | ||
181 | |||
182 | val32 = readl(base + BK3710_DATRCVR) & (0xFF << (dev ? 0 : 8)); | ||
183 | val32 |= (t2i << (dev ? 8 : 0)); | ||
184 | writel(val32, base + BK3710_DATRCVR); | ||
185 | |||
186 | if (mate && mate->present) { | ||
187 | u8 mode2 = ide_get_best_pio_mode(mate, 255, 4); | ||
188 | |||
189 | if (mode2 < mode) | ||
190 | mode = mode2; | ||
191 | } | ||
192 | |||
193 | /* TASKFILE Setup */ | ||
194 | t = ide_timing_find_mode(XFER_PIO_0 + mode); | ||
195 | t0 = (t->cyc8b + ide_palm_clk - 1) / ide_palm_clk; | ||
196 | t2 = (t->act8b + ide_palm_clk - 1) / ide_palm_clk; | ||
197 | |||
198 | t2i = t0 - t2 - 1; | ||
199 | t2 -= 1; | ||
200 | |||
201 | val32 = readl(base + BK3710_REGSTB) & (0xFF << (dev ? 0 : 8)); | ||
202 | val32 |= (t2 << (dev ? 8 : 0)); | ||
203 | writel(val32, base + BK3710_REGSTB); | ||
204 | |||
205 | val32 = readl(base + BK3710_REGRCVR) & (0xFF << (dev ? 0 : 8)); | ||
206 | val32 |= (t2i << (dev ? 8 : 0)); | ||
207 | writel(val32, base + BK3710_REGRCVR); | ||
208 | } | ||
209 | |||
210 | static void palm_bk3710_set_dma_mode(ide_drive_t *drive, u8 xferspeed) | ||
211 | { | ||
212 | int is_slave = drive->dn & 1; | ||
213 | void __iomem *base = (void *)drive->hwif->dma_base; | ||
214 | |||
215 | if (xferspeed >= XFER_UDMA_0) { | ||
216 | palm_bk3710_setudmamode(base, is_slave, | ||
217 | xferspeed - XFER_UDMA_0); | ||
218 | } else { | ||
219 | palm_bk3710_setdmamode(base, is_slave, drive->id->eide_dma_min, | ||
220 | xferspeed); | ||
221 | } | ||
222 | } | ||
223 | |||
224 | static void palm_bk3710_set_pio_mode(ide_drive_t *drive, u8 pio) | ||
225 | { | ||
226 | unsigned int cycle_time; | ||
227 | int is_slave = drive->dn & 1; | ||
228 | ide_drive_t *mate; | ||
229 | void __iomem *base = (void *)drive->hwif->dma_base; | ||
230 | |||
231 | /* | ||
232 | * Obtain the drive PIO data for tuning the Palm Chip registers | ||
233 | */ | ||
234 | cycle_time = ide_pio_cycle_time(drive, pio); | ||
235 | mate = ide_get_paired_drive(drive); | ||
236 | palm_bk3710_setpiomode(base, mate, is_slave, cycle_time, pio); | ||
237 | } | ||
238 | |||
239 | static void __devinit palm_bk3710_chipinit(void __iomem *base) | ||
240 | { | ||
241 | /* | ||
242 | * enable the reset_en of ATA controller so that when ata signals | ||
243 | * are brought out, by writing into device config. at that | ||
244 | * time por_n signal should not be 'Z' and have a stable value. | ||
245 | */ | ||
246 | writel(0x0300, base + BK3710_MISCCTL); | ||
247 | |||
248 | /* wait for some time and deassert the reset of ATA Device. */ | ||
249 | mdelay(100); | ||
250 | |||
251 | /* Deassert the Reset */ | ||
252 | writel(0x0200, base + BK3710_MISCCTL); | ||
253 | |||
254 | /* | ||
255 | * Program the IDETIMP Register Value based on the following assumptions | ||
256 | * | ||
257 | * (ATA_IDETIMP_IDEEN , ENABLE ) | | ||
258 | * (ATA_IDETIMP_SLVTIMEN , DISABLE) | | ||
259 | * (ATA_IDETIMP_RDYSMPL , 70NS) | | ||
260 | * (ATA_IDETIMP_RDYRCVRY , 50NS) | | ||
261 | * (ATA_IDETIMP_DMAFTIM1 , PIOCOMP) | | ||
262 | * (ATA_IDETIMP_PREPOST1 , DISABLE) | | ||
263 | * (ATA_IDETIMP_RDYSEN1 , DISABLE) | | ||
264 | * (ATA_IDETIMP_PIOFTIM1 , DISABLE) | | ||
265 | * (ATA_IDETIMP_DMAFTIM0 , PIOCOMP) | | ||
266 | * (ATA_IDETIMP_PREPOST0 , DISABLE) | | ||
267 | * (ATA_IDETIMP_RDYSEN0 , DISABLE) | | ||
268 | * (ATA_IDETIMP_PIOFTIM0 , DISABLE) | ||
269 | */ | ||
270 | writew(0xB388, base + BK3710_IDETIMP); | ||
271 | |||
272 | /* | ||
273 | * Configure SIDETIM Register | ||
274 | * (ATA_SIDETIM_RDYSMPS1 ,120NS ) | | ||
275 | * (ATA_SIDETIM_RDYRCYS1 ,120NS ) | ||
276 | */ | ||
277 | writeb(0, base + BK3710_SIDETIM); | ||
278 | |||
279 | /* | ||
280 | * UDMACTL Ultra-ATA DMA Control | ||
281 | * (ATA_UDMACTL_UDMAP1 , 0 ) | | ||
282 | * (ATA_UDMACTL_UDMAP0 , 0 ) | ||
283 | * | ||
284 | */ | ||
285 | writew(0, base + BK3710_UDMACTL); | ||
286 | |||
287 | /* | ||
288 | * MISCCTL Miscellaneous Conrol Register | ||
289 | * (ATA_MISCCTL_RSTMODEP , 1) | | ||
290 | * (ATA_MISCCTL_RESETP , 0) | | ||
291 | * (ATA_MISCCTL_TIMORIDE , 1) | ||
292 | */ | ||
293 | writel(0x201, base + BK3710_MISCCTL); | ||
294 | |||
295 | /* | ||
296 | * IORDYTMP IORDY Timer for Primary Register | ||
297 | * (ATA_IORDYTMP_IORDYTMP , 0xffff ) | ||
298 | */ | ||
299 | writel(0xFFFF, base + BK3710_IORDYTMP); | ||
300 | |||
301 | /* | ||
302 | * Configure BMISP Register | ||
303 | * (ATA_BMISP_DMAEN1 , DISABLE ) | | ||
304 | * (ATA_BMISP_DMAEN0 , DISABLE ) | | ||
305 | * (ATA_BMISP_IORDYINT , CLEAR) | | ||
306 | * (ATA_BMISP_INTRSTAT , CLEAR) | | ||
307 | * (ATA_BMISP_DMAERROR , CLEAR) | ||
308 | */ | ||
309 | writew(0, base + BK3710_BMISP); | ||
310 | |||
311 | palm_bk3710_setpiomode(base, NULL, 0, 600, 0); | ||
312 | palm_bk3710_setpiomode(base, NULL, 1, 600, 0); | ||
313 | } | ||
314 | static int __devinit palm_bk3710_probe(struct platform_device *pdev) | ||
315 | { | ||
316 | hw_regs_t ide_ctlr_info; | ||
317 | int index = 0; | ||
318 | int pribase; | ||
319 | struct clk *clkp; | ||
320 | struct resource *mem, *irq; | ||
321 | ide_hwif_t *hwif; | ||
322 | void __iomem *base; | ||
323 | |||
324 | clkp = clk_get(NULL, "IDECLK"); | ||
325 | if (IS_ERR(clkp)) | ||
326 | return -ENODEV; | ||
327 | |||
328 | ideclkp = clkp; | ||
329 | clk_enable(ideclkp); | ||
330 | ide_palm_clk = clk_get_rate(ideclkp)/100000; | ||
331 | ide_palm_clk = (10000/ide_palm_clk) + 1; | ||
332 | /* Register the IDE interface with Linux ATA Interface */ | ||
333 | memset(&ide_ctlr_info, 0, sizeof(ide_ctlr_info)); | ||
334 | |||
335 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
336 | if (mem == NULL) { | ||
337 | printk(KERN_ERR "failed to get memory region resource\n"); | ||
338 | return -ENODEV; | ||
339 | } | ||
340 | irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
341 | if (irq == NULL) { | ||
342 | printk(KERN_ERR "failed to get IRQ resource\n"); | ||
343 | return -ENODEV; | ||
344 | } | ||
345 | |||
346 | base = (void *)mem->start; | ||
347 | |||
348 | /* Configure the Palm Chip controller */ | ||
349 | palm_bk3710_chipinit(base); | ||
350 | |||
351 | pribase = mem->start + IDE_PALM_ATA_PRI_REG_OFFSET; | ||
352 | for (index = 0; index < IDE_NR_PORTS - 2; index++) | ||
353 | ide_ctlr_info.io_ports[index] = pribase + index; | ||
354 | ide_ctlr_info.io_ports[IDE_CONTROL_OFFSET] = mem->start + | ||
355 | IDE_PALM_ATA_PRI_CTL_OFFSET; | ||
356 | ide_ctlr_info.irq = irq->start; | ||
357 | ide_ctlr_info.chipset = ide_palm3710; | ||
358 | |||
359 | if (ide_register_hw(&ide_ctlr_info, NULL, &hwif) < 0) { | ||
360 | printk(KERN_WARNING "Palm Chip BK3710 IDE Register Fail\n"); | ||
361 | return -ENODEV; | ||
362 | } | ||
363 | |||
364 | hwif->set_pio_mode = &palm_bk3710_set_pio_mode; | ||
365 | hwif->set_dma_mode = &palm_bk3710_set_dma_mode; | ||
366 | hwif->mmio = 1; | ||
367 | default_hwif_mmiops(hwif); | ||
368 | hwif->cbl = ATA_CBL_PATA80; | ||
369 | hwif->ultra_mask = 0x1f; /* Ultra DMA Mode 4 Max | ||
370 | (input clk 99MHz) */ | ||
371 | hwif->mwdma_mask = 0x7; | ||
372 | hwif->drives[0].autotune = 1; | ||
373 | hwif->drives[1].autotune = 1; | ||
374 | |||
375 | ide_setup_dma(hwif, mem->start); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static struct platform_driver platform_bk_driver = { | ||
381 | .driver = { | ||
382 | .name = "palm_bk3710", | ||
383 | }, | ||
384 | .probe = palm_bk3710_probe, | ||
385 | .remove = NULL, | ||
386 | }; | ||
387 | |||
388 | static int __init palm_bk3710_init(void) | ||
389 | { | ||
390 | return platform_driver_register(&platform_bk_driver); | ||
391 | } | ||
392 | |||
393 | module_init(palm_bk3710_init); | ||
394 | MODULE_LICENSE("GPL"); | ||
395 | |||
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index 00587a8c2ba1..e79bf8f9b7db 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c | |||
@@ -753,6 +753,25 @@ static void cris_set_dma_mode(ide_drive_t *drive, const u8 speed) | |||
753 | cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); | 753 | cris_ide_set_speed(TYPE_DMA, 0, strobe, hold); |
754 | } | 754 | } |
755 | 755 | ||
756 | static void __init cris_setup_ports(hw_regs_t *hw, unsigned long base) | ||
757 | { | ||
758 | int i; | ||
759 | |||
760 | memset(hw, 0, sizeof(*hw)); | ||
761 | |||
762 | for (i = 0; i <= 7; i++) | ||
763 | hw->io_ports[i] = base + cris_ide_reg_addr(i, 0, 1); | ||
764 | |||
765 | /* | ||
766 | * the IDE control register is at ATA address 6, | ||
767 | * with CS1 active instead of CS0 | ||
768 | */ | ||
769 | hw->io_ports[IDE_CONTROL_OFFSET] = base + cris_ide_reg_addr(6, 1, 0); | ||
770 | |||
771 | hw->irq = ide_default_irq(0); | ||
772 | hw->ack_intr = cris_ide_ack_intr; | ||
773 | } | ||
774 | |||
756 | static const struct ide_port_info cris_port_info __initdata = { | 775 | static const struct ide_port_info cris_port_info __initdata = { |
757 | .chipset = ide_etrax100, | 776 | .chipset = ide_etrax100, |
758 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | | 777 | .host_flags = IDE_HFLAG_NO_ATAPI_DMA | |
@@ -765,24 +784,16 @@ static const struct ide_port_info cris_port_info __initdata = { | |||
765 | static int __init init_e100_ide(void) | 784 | static int __init init_e100_ide(void) |
766 | { | 785 | { |
767 | hw_regs_t hw; | 786 | hw_regs_t hw; |
768 | int ide_offsets[IDE_NR_PORTS], h, i; | 787 | int h; |
769 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; | 788 | u8 idx[4] = { 0xff, 0xff, 0xff, 0xff }; |
770 | 789 | ||
771 | printk("ide: ETRAX FS built-in ATA DMA controller\n"); | 790 | printk("ide: ETRAX FS built-in ATA DMA controller\n"); |
772 | 791 | ||
773 | for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) | ||
774 | ide_offsets[i] = cris_ide_reg_addr(i, 0, 1); | ||
775 | |||
776 | /* the IDE control register is at ATA address 6, with CS1 active instead of CS0 */ | ||
777 | ide_offsets[IDE_CONTROL_OFFSET] = cris_ide_reg_addr(6, 1, 0); | ||
778 | |||
779 | for (h = 0; h < 4; h++) { | 792 | for (h = 0; h < 4; h++) { |
780 | ide_hwif_t *hwif = NULL; | 793 | ide_hwif_t *hwif = NULL; |
781 | 794 | ||
782 | ide_setup_ports(&hw, cris_ide_base_address(h), | 795 | cris_setup_ports(&hw, cris_ide_base_address(h)); |
783 | ide_offsets, | 796 | |
784 | 0, 0, cris_ide_ack_intr, | ||
785 | ide_default_irq(0)); | ||
786 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 797 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
787 | if (hwif == NULL) | 798 | if (hwif == NULL) |
788 | continue; | 799 | continue; |
diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index 25aaeae1e830..e07b189f3ec8 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c | |||
@@ -171,7 +171,7 @@ err: | |||
171 | static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) | 171 | static acpi_handle ide_acpi_hwif_get_handle(ide_hwif_t *hwif) |
172 | { | 172 | { |
173 | struct device *dev = hwif->gendev.parent; | 173 | struct device *dev = hwif->gendev.parent; |
174 | acpi_handle dev_handle; | 174 | acpi_handle uninitialized_var(dev_handle); |
175 | acpi_integer pcidevfn; | 175 | acpi_integer pcidevfn; |
176 | acpi_handle chan_handle; | 176 | acpi_handle chan_handle; |
177 | int err; | 177 | int err; |
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c index ee4d458e2bbf..5e42c19a03e3 100644 --- a/drivers/ide/ide-cd.c +++ b/drivers/ide/ide-cd.c | |||
@@ -295,7 +295,8 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
295 | int stat, err, sense_key; | 295 | int stat, err, sense_key; |
296 | 296 | ||
297 | /* Check for errors. */ | 297 | /* Check for errors. */ |
298 | stat = HWIF(drive)->INB(IDE_STATUS_REG); | 298 | stat = ide_read_status(drive); |
299 | |||
299 | if (stat_ret) | 300 | if (stat_ret) |
300 | *stat_ret = stat; | 301 | *stat_ret = stat; |
301 | 302 | ||
@@ -303,7 +304,7 @@ static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) | |||
303 | return 0; | 304 | return 0; |
304 | 305 | ||
305 | /* Get the IDE error register. */ | 306 | /* Get the IDE error register. */ |
306 | err = HWIF(drive)->INB(IDE_ERROR_REG); | 307 | err = ide_read_error(drive); |
307 | sense_key = err >> 4; | 308 | sense_key = err >> 4; |
308 | 309 | ||
309 | if (rq == NULL) { | 310 | if (rq == NULL) { |
@@ -692,7 +693,7 @@ int ide_cd_check_ireason(ide_drive_t *drive, int len, int ireason, int rw) | |||
692 | /* Some drives (ASUS) seem to tell us that status | 693 | /* Some drives (ASUS) seem to tell us that status |
693 | * info is available. just get it and ignore. | 694 | * info is available. just get it and ignore. |
694 | */ | 695 | */ |
695 | (void) HWIF(drive)->INB(IDE_STATUS_REG); | 696 | (void)ide_read_status(drive); |
696 | return 0; | 697 | return 0; |
697 | } else { | 698 | } else { |
698 | /* Drive wants a command packet, or invalid ireason... */ | 699 | /* Drive wants a command packet, or invalid ireason... */ |
@@ -1326,7 +1327,7 @@ ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, sector_t block) | |||
1326 | if (blk_fs_request(rq)) { | 1327 | if (blk_fs_request(rq)) { |
1327 | if (info->cd_flags & IDE_CD_FLAG_SEEKING) { | 1328 | if (info->cd_flags & IDE_CD_FLAG_SEEKING) { |
1328 | unsigned long elapsed = jiffies - info->start_seek; | 1329 | unsigned long elapsed = jiffies - info->start_seek; |
1329 | int stat = HWIF(drive)->INB(IDE_STATUS_REG); | 1330 | int stat = ide_read_status(drive); |
1330 | 1331 | ||
1331 | if ((stat & SEEK_STAT) != SEEK_STAT) { | 1332 | if ((stat & SEEK_STAT) != SEEK_STAT) { |
1332 | if (elapsed < IDECD_SEEK_TIMEOUT) { | 1333 | if (elapsed < IDECD_SEEK_TIMEOUT) { |
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 3cf59f2c3928..a4bb32883c6b 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c | |||
@@ -147,7 +147,8 @@ ide_startstop_t ide_dma_intr (ide_drive_t *drive) | |||
147 | u8 stat = 0, dma_stat = 0; | 147 | u8 stat = 0, dma_stat = 0; |
148 | 148 | ||
149 | dma_stat = HWIF(drive)->ide_dma_end(drive); | 149 | dma_stat = HWIF(drive)->ide_dma_end(drive); |
150 | stat = HWIF(drive)->INB(IDE_STATUS_REG); /* get drive status */ | 150 | stat = ide_read_status(drive); |
151 | |||
151 | if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { | 152 | if (OK_STAT(stat,DRIVE_READY,drive->bad_wstat|DRQ_STAT)) { |
152 | if (!dma_stat) { | 153 | if (!dma_stat) { |
153 | struct request *rq = HWGROUP(drive)->rq; | 154 | struct request *rq = HWGROUP(drive)->rq; |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index f8fe6ee128f3..faf22d716f80 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -465,7 +465,7 @@ static void idefloppy_retry_pc(ide_drive_t *drive) | |||
465 | idefloppy_pc_t *pc; | 465 | idefloppy_pc_t *pc; |
466 | struct request *rq; | 466 | struct request *rq; |
467 | 467 | ||
468 | (void)drive->hwif->INB(IDE_ERROR_REG); | 468 | (void)ide_read_error(drive); |
469 | pc = idefloppy_next_pc_storage(drive); | 469 | pc = idefloppy_next_pc_storage(drive); |
470 | rq = idefloppy_next_rq_storage(drive); | 470 | rq = idefloppy_next_rq_storage(drive); |
471 | idefloppy_create_request_sense_cmd(pc); | 471 | idefloppy_create_request_sense_cmd(pc); |
@@ -501,7 +501,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive) | |||
501 | } | 501 | } |
502 | 502 | ||
503 | /* Clear the interrupt */ | 503 | /* Clear the interrupt */ |
504 | stat = drive->hwif->INB(IDE_STATUS_REG); | 504 | stat = ide_read_status(drive); |
505 | 505 | ||
506 | /* No more interrupts */ | 506 | /* No more interrupts */ |
507 | if ((stat & DRQ_STAT) == 0) { | 507 | if ((stat & DRQ_STAT) == 0) { |
@@ -1246,7 +1246,7 @@ static int idefloppy_get_format_progress(ide_drive_t *drive, int __user *arg) | |||
1246 | u8 stat; | 1246 | u8 stat; |
1247 | 1247 | ||
1248 | local_irq_save(flags); | 1248 | local_irq_save(flags); |
1249 | stat = drive->hwif->INB(IDE_STATUS_REG); | 1249 | stat = ide_read_status(drive); |
1250 | local_irq_restore(flags); | 1250 | local_irq_restore(flags); |
1251 | 1251 | ||
1252 | progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; | 1252 | progress_indication = ((stat & SEEK_STAT) == 0) ? 0 : 0x10000; |
diff --git a/drivers/ide/ide-generic.c b/drivers/ide/ide-generic.c index be469dbbe8fb..709b9e4d2871 100644 --- a/drivers/ide/ide-generic.c +++ b/drivers/ide/ide-generic.c | |||
@@ -20,8 +20,14 @@ static int __init ide_generic_init(void) | |||
20 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) | 20 | if (ide_hwifs[0].io_ports[IDE_DATA_OFFSET]) |
21 | ide_get_lock(NULL, NULL); /* for atari only */ | 21 | ide_get_lock(NULL, NULL); /* for atari only */ |
22 | 22 | ||
23 | for (i = 0; i < MAX_HWIFS; i++) | 23 | for (i = 0; i < MAX_HWIFS; i++) { |
24 | idx[i] = ide_hwifs[i].present ? 0xff : i; | 24 | ide_hwif_t *hwif = &ide_hwifs[i]; |
25 | |||
26 | if (hwif->io_ports[IDE_DATA_OFFSET] && !hwif->present) | ||
27 | idx[i] = i; | ||
28 | else | ||
29 | idx[i] = 0xff; | ||
30 | } | ||
25 | 31 | ||
26 | ide_device_add_all(idx, NULL); | 32 | ide_device_add_all(idx, NULL); |
27 | 33 | ||
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 4bddef0c0b96..3addbe478d26 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -466,7 +466,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 | |||
466 | return ide_stopped; | 466 | return ide_stopped; |
467 | } | 467 | } |
468 | 468 | ||
469 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) | 469 | if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) |
470 | rq->errors |= ERROR_RESET; | 470 | rq->errors |= ERROR_RESET; |
471 | 471 | ||
472 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { | 472 | if ((rq->errors & ERROR_RESET) == ERROR_RESET) { |
@@ -493,7 +493,7 @@ static ide_startstop_t ide_atapi_error(ide_drive_t *drive, struct request *rq, u | |||
493 | /* add decoding error stuff */ | 493 | /* add decoding error stuff */ |
494 | } | 494 | } |
495 | 495 | ||
496 | if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) | 496 | if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) |
497 | /* force an abort */ | 497 | /* force an abort */ |
498 | hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); | 498 | hwif->OUTB(WIN_IDLEIMMEDIATE, IDE_COMMAND_REG); |
499 | 499 | ||
@@ -821,9 +821,8 @@ static ide_startstop_t execute_drive_cmd (ide_drive_t *drive, | |||
821 | #ifdef DEBUG | 821 | #ifdef DEBUG |
822 | printk("%s: DRIVE_CMD (null)\n", drive->name); | 822 | printk("%s: DRIVE_CMD (null)\n", drive->name); |
823 | #endif | 823 | #endif |
824 | ide_end_drive_cmd(drive, | 824 | ide_end_drive_cmd(drive, ide_read_status(drive), ide_read_error(drive)); |
825 | hwif->INB(IDE_STATUS_REG), | 825 | |
826 | hwif->INB(IDE_ERROR_REG)); | ||
827 | return ide_stopped; | 826 | return ide_stopped; |
828 | } | 827 | } |
829 | 828 | ||
@@ -1231,7 +1230,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error) | |||
1231 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); | 1230 | printk(KERN_WARNING "%s: DMA timeout error\n", drive->name); |
1232 | (void)HWIF(drive)->ide_dma_end(drive); | 1231 | (void)HWIF(drive)->ide_dma_end(drive); |
1233 | ret = ide_error(drive, "dma timeout error", | 1232 | ret = ide_error(drive, "dma timeout error", |
1234 | hwif->INB(IDE_STATUS_REG)); | 1233 | ide_read_status(drive)); |
1235 | } else { | 1234 | } else { |
1236 | printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); | 1235 | printk(KERN_WARNING "%s: DMA timeout retry\n", drive->name); |
1237 | hwif->dma_timeout(drive); | 1236 | hwif->dma_timeout(drive); |
@@ -1355,7 +1354,8 @@ void ide_timer_expiry (unsigned long data) | |||
1355 | startstop = ide_dma_timeout_retry(drive, wait); | 1354 | startstop = ide_dma_timeout_retry(drive, wait); |
1356 | } else | 1355 | } else |
1357 | startstop = | 1356 | startstop = |
1358 | ide_error(drive, "irq timeout", hwif->INB(IDE_STATUS_REG)); | 1357 | ide_error(drive, "irq timeout", |
1358 | ide_read_status(drive)); | ||
1359 | } | 1359 | } |
1360 | drive->service_time = jiffies - drive->service_start; | 1360 | drive->service_time = jiffies - drive->service_start; |
1361 | spin_lock_irq(&ide_lock); | 1361 | spin_lock_irq(&ide_lock); |
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index a95178f5e1bb..c32e759df208 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c | |||
@@ -430,10 +430,10 @@ int drive_is_ready (ide_drive_t *drive) | |||
430 | * about possible isa-pnp and pci-pnp issues yet. | 430 | * about possible isa-pnp and pci-pnp issues yet. |
431 | */ | 431 | */ |
432 | if (IDE_CONTROL_REG) | 432 | if (IDE_CONTROL_REG) |
433 | stat = hwif->INB(IDE_ALTSTATUS_REG); | 433 | stat = ide_read_altstatus(drive); |
434 | else | 434 | else |
435 | /* Note: this may clear a pending IRQ!! */ | 435 | /* Note: this may clear a pending IRQ!! */ |
436 | stat = hwif->INB(IDE_STATUS_REG); | 436 | stat = ide_read_status(drive); |
437 | 437 | ||
438 | if (stat & BUSY_STAT) | 438 | if (stat & BUSY_STAT) |
439 | /* drive busy: definitely not interrupting */ | 439 | /* drive busy: definitely not interrupting */ |
@@ -458,23 +458,24 @@ EXPORT_SYMBOL(drive_is_ready); | |||
458 | */ | 458 | */ |
459 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) | 459 | static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat) |
460 | { | 460 | { |
461 | ide_hwif_t *hwif = drive->hwif; | ||
462 | unsigned long flags; | 461 | unsigned long flags; |
463 | int i; | 462 | int i; |
464 | u8 stat; | 463 | u8 stat; |
465 | 464 | ||
466 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ | 465 | udelay(1); /* spec allows drive 400ns to assert "BUSY" */ |
467 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | 466 | stat = ide_read_status(drive); |
467 | |||
468 | if (stat & BUSY_STAT) { | ||
468 | local_irq_set(flags); | 469 | local_irq_set(flags); |
469 | timeout += jiffies; | 470 | timeout += jiffies; |
470 | while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { | 471 | while ((stat = ide_read_status(drive)) & BUSY_STAT) { |
471 | if (time_after(jiffies, timeout)) { | 472 | if (time_after(jiffies, timeout)) { |
472 | /* | 473 | /* |
473 | * One last read after the timeout in case | 474 | * One last read after the timeout in case |
474 | * heavy interrupt load made us not make any | 475 | * heavy interrupt load made us not make any |
475 | * progress during the timeout.. | 476 | * progress during the timeout.. |
476 | */ | 477 | */ |
477 | stat = hwif->INB(IDE_STATUS_REG); | 478 | stat = ide_read_status(drive); |
478 | if (!(stat & BUSY_STAT)) | 479 | if (!(stat & BUSY_STAT)) |
479 | break; | 480 | break; |
480 | 481 | ||
@@ -494,7 +495,9 @@ static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long ti | |||
494 | */ | 495 | */ |
495 | for (i = 0; i < 10; i++) { | 496 | for (i = 0; i < 10; i++) { |
496 | udelay(1); | 497 | udelay(1); |
497 | if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) { | 498 | stat = ide_read_status(drive); |
499 | |||
500 | if (OK_STAT(stat, good, bad)) { | ||
498 | *rstat = stat; | 501 | *rstat = stat; |
499 | return 0; | 502 | return 0; |
500 | } | 503 | } |
@@ -617,6 +620,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
617 | ide_hwif_t *hwif = drive->hwif; | 620 | ide_hwif_t *hwif = drive->hwif; |
618 | struct hd_driveid *id; | 621 | struct hd_driveid *id; |
619 | unsigned long timeout, flags; | 622 | unsigned long timeout, flags; |
623 | u8 stat; | ||
620 | 624 | ||
621 | /* | 625 | /* |
622 | * Re-read drive->id for possible DMA mode | 626 | * Re-read drive->id for possible DMA mode |
@@ -633,10 +637,15 @@ int ide_driveid_update(ide_drive_t *drive) | |||
633 | SELECT_MASK(drive, 0); | 637 | SELECT_MASK(drive, 0); |
634 | return 0; /* drive timed-out */ | 638 | return 0; /* drive timed-out */ |
635 | } | 639 | } |
640 | |||
636 | msleep(50); /* give drive a breather */ | 641 | msleep(50); /* give drive a breather */ |
637 | } while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT); | 642 | stat = ide_read_altstatus(drive); |
643 | } while (stat & BUSY_STAT); | ||
644 | |||
638 | msleep(50); /* wait for IRQ and DRQ_STAT */ | 645 | msleep(50); /* wait for IRQ and DRQ_STAT */ |
639 | if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) { | 646 | stat = ide_read_status(drive); |
647 | |||
648 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | ||
640 | SELECT_MASK(drive, 0); | 649 | SELECT_MASK(drive, 0); |
641 | printk("%s: CHECK for good STATUS\n", drive->name); | 650 | printk("%s: CHECK for good STATUS\n", drive->name); |
642 | return 0; | 651 | return 0; |
@@ -649,7 +658,7 @@ int ide_driveid_update(ide_drive_t *drive) | |||
649 | return 0; | 658 | return 0; |
650 | } | 659 | } |
651 | ata_input_data(drive, id, SECTOR_WORDS); | 660 | ata_input_data(drive, id, SECTOR_WORDS); |
652 | (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ | 661 | (void)ide_read_status(drive); /* clear drive IRQ */ |
653 | local_irq_enable(); | 662 | local_irq_enable(); |
654 | local_irq_restore(flags); | 663 | local_irq_restore(flags); |
655 | ide_fix_driveid(id); | 664 | ide_fix_driveid(id); |
@@ -850,17 +859,16 @@ static ide_startstop_t do_reset1 (ide_drive_t *, int); | |||
850 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) | 859 | static ide_startstop_t atapi_reset_pollfunc (ide_drive_t *drive) |
851 | { | 860 | { |
852 | ide_hwgroup_t *hwgroup = HWGROUP(drive); | 861 | ide_hwgroup_t *hwgroup = HWGROUP(drive); |
853 | ide_hwif_t *hwif = HWIF(drive); | ||
854 | u8 stat; | 862 | u8 stat; |
855 | 863 | ||
856 | SELECT_DRIVE(drive); | 864 | SELECT_DRIVE(drive); |
857 | udelay (10); | 865 | udelay (10); |
866 | stat = ide_read_status(drive); | ||
858 | 867 | ||
859 | if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { | 868 | if (OK_STAT(stat, 0, BUSY_STAT)) |
860 | printk("%s: ATAPI reset complete\n", drive->name); | 869 | printk("%s: ATAPI reset complete\n", drive->name); |
861 | } else { | 870 | else { |
862 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 871 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
863 | BUG_ON(HWGROUP(drive)->handler != NULL); | ||
864 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); | 872 | ide_set_handler(drive, &atapi_reset_pollfunc, HZ/20, NULL); |
865 | /* continue polling */ | 873 | /* continue polling */ |
866 | return ide_started; | 874 | return ide_started; |
@@ -898,9 +906,10 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
898 | } | 906 | } |
899 | } | 907 | } |
900 | 908 | ||
901 | if (!OK_STAT(tmp = hwif->INB(IDE_STATUS_REG), 0, BUSY_STAT)) { | 909 | tmp = ide_read_status(drive); |
910 | |||
911 | if (!OK_STAT(tmp, 0, BUSY_STAT)) { | ||
902 | if (time_before(jiffies, hwgroup->poll_timeout)) { | 912 | if (time_before(jiffies, hwgroup->poll_timeout)) { |
903 | BUG_ON(HWGROUP(drive)->handler != NULL); | ||
904 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); | 913 | ide_set_handler(drive, &reset_pollfunc, HZ/20, NULL); |
905 | /* continue polling */ | 914 | /* continue polling */ |
906 | return ide_started; | 915 | return ide_started; |
@@ -909,7 +918,9 @@ static ide_startstop_t reset_pollfunc (ide_drive_t *drive) | |||
909 | drive->failures++; | 918 | drive->failures++; |
910 | } else { | 919 | } else { |
911 | printk("%s: reset: ", hwif->name); | 920 | printk("%s: reset: ", hwif->name); |
912 | if ((tmp = hwif->INB(IDE_ERROR_REG)) == 1) { | 921 | tmp = ide_read_error(drive); |
922 | |||
923 | if (tmp == 1) { | ||
913 | printk("success\n"); | 924 | printk("success\n"); |
914 | drive->failures = 0; | 925 | drive->failures = 0; |
915 | } else { | 926 | } else { |
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c index b42940d8bf70..1ff676cc6473 100644 --- a/drivers/ide/ide-lib.c +++ b/drivers/ide/ide-lib.c | |||
@@ -578,7 +578,7 @@ u8 ide_dump_status(ide_drive_t *drive, const char *msg, u8 stat) | |||
578 | } | 578 | } |
579 | printk("}\n"); | 579 | printk("}\n"); |
580 | if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { | 580 | if ((stat & (BUSY_STAT|ERR_STAT)) == ERR_STAT) { |
581 | err = drive->hwif->INB(IDE_ERROR_REG); | 581 | err = ide_read_error(drive); |
582 | printk("%s: %s: error=0x%02x ", drive->name, msg, err); | 582 | printk("%s: %s: error=0x%02x ", drive->name, msg, err); |
583 | if (drive->media == ide_disk) | 583 | if (drive->media == ide_disk) |
584 | ide_dump_ata_error(drive, err); | 584 | ide_dump_ata_error(drive, err); |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 9c07bdb68d1a..6daea896c5db 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -264,8 +264,7 @@ err_misc: | |||
264 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | 264 | static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) |
265 | { | 265 | { |
266 | ide_hwif_t *hwif = HWIF(drive); | 266 | ide_hwif_t *hwif = HWIF(drive); |
267 | int rc; | 267 | int use_altstatus = 0, rc; |
268 | unsigned long hd_status; | ||
269 | unsigned long timeout; | 268 | unsigned long timeout; |
270 | u8 s = 0, a = 0; | 269 | u8 s = 0, a = 0; |
271 | 270 | ||
@@ -273,19 +272,17 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
273 | msleep(50); | 272 | msleep(50); |
274 | 273 | ||
275 | if (IDE_CONTROL_REG) { | 274 | if (IDE_CONTROL_REG) { |
276 | a = hwif->INB(IDE_ALTSTATUS_REG); | 275 | a = ide_read_altstatus(drive); |
277 | s = hwif->INB(IDE_STATUS_REG); | 276 | s = ide_read_status(drive); |
278 | if ((a ^ s) & ~INDEX_STAT) { | 277 | if ((a ^ s) & ~INDEX_STAT) |
279 | printk(KERN_INFO "%s: probing with STATUS(0x%02x) instead of " | ||
280 | "ALTSTATUS(0x%02x)\n", drive->name, s, a); | ||
281 | /* ancient Seagate drives, broken interfaces */ | 278 | /* ancient Seagate drives, broken interfaces */ |
282 | hd_status = IDE_STATUS_REG; | 279 | printk(KERN_INFO "%s: probing with STATUS(0x%02x) " |
283 | } else { | 280 | "instead of ALTSTATUS(0x%02x)\n", |
281 | drive->name, s, a); | ||
282 | else | ||
284 | /* use non-intrusive polling */ | 283 | /* use non-intrusive polling */ |
285 | hd_status = IDE_ALTSTATUS_REG; | 284 | use_altstatus = 1; |
286 | } | 285 | } |
287 | } else | ||
288 | hd_status = IDE_STATUS_REG; | ||
289 | 286 | ||
290 | /* set features register for atapi | 287 | /* set features register for atapi |
291 | * identify command to be sure of reply | 288 | * identify command to be sure of reply |
@@ -306,11 +303,15 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
306 | } | 303 | } |
307 | /* give drive a breather */ | 304 | /* give drive a breather */ |
308 | msleep(50); | 305 | msleep(50); |
309 | } while ((hwif->INB(hd_status)) & BUSY_STAT); | 306 | s = use_altstatus ? ide_read_altstatus(drive) |
307 | : ide_read_status(drive); | ||
308 | } while (s & BUSY_STAT); | ||
310 | 309 | ||
311 | /* wait for IRQ and DRQ_STAT */ | 310 | /* wait for IRQ and DRQ_STAT */ |
312 | msleep(50); | 311 | msleep(50); |
313 | if (OK_STAT((hwif->INB(IDE_STATUS_REG)), DRQ_STAT, BAD_R_STAT)) { | 312 | s = ide_read_status(drive); |
313 | |||
314 | if (OK_STAT(s, DRQ_STAT, BAD_R_STAT)) { | ||
314 | unsigned long flags; | 315 | unsigned long flags; |
315 | 316 | ||
316 | /* local CPU only; some systems need this */ | 317 | /* local CPU only; some systems need this */ |
@@ -320,7 +321,7 @@ static int actual_try_to_identify (ide_drive_t *drive, u8 cmd) | |||
320 | /* drive responded with ID */ | 321 | /* drive responded with ID */ |
321 | rc = 0; | 322 | rc = 0; |
322 | /* clear drive IRQ */ | 323 | /* clear drive IRQ */ |
323 | (void) hwif->INB(IDE_STATUS_REG); | 324 | (void)ide_read_status(drive); |
324 | local_irq_restore(flags); | 325 | local_irq_restore(flags); |
325 | } else { | 326 | } else { |
326 | /* drive refused ID */ | 327 | /* drive refused ID */ |
@@ -367,7 +368,7 @@ static int try_to_identify (ide_drive_t *drive, u8 cmd) | |||
367 | 368 | ||
368 | ide_set_irq(drive, 0); | 369 | ide_set_irq(drive, 0); |
369 | /* clear drive IRQ */ | 370 | /* clear drive IRQ */ |
370 | (void) hwif->INB(IDE_STATUS_REG); | 371 | (void)ide_read_status(drive); |
371 | udelay(5); | 372 | udelay(5); |
372 | irq = probe_irq_off(cookie); | 373 | irq = probe_irq_off(cookie); |
373 | if (!hwif->irq) { | 374 | if (!hwif->irq) { |
@@ -455,7 +456,9 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
455 | return 3; | 456 | return 3; |
456 | } | 457 | } |
457 | 458 | ||
458 | if (OK_STAT((hwif->INB(IDE_STATUS_REG)), READY_STAT, BUSY_STAT) || | 459 | stat = ide_read_status(drive); |
460 | |||
461 | if (OK_STAT(stat, READY_STAT, BUSY_STAT) || | ||
459 | drive->present || cmd == WIN_PIDENTIFY) { | 462 | drive->present || cmd == WIN_PIDENTIFY) { |
460 | /* send cmd and wait */ | 463 | /* send cmd and wait */ |
461 | if ((rc = try_to_identify(drive, cmd))) { | 464 | if ((rc = try_to_identify(drive, cmd))) { |
@@ -463,7 +466,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
463 | rc = try_to_identify(drive,cmd); | 466 | rc = try_to_identify(drive,cmd); |
464 | } | 467 | } |
465 | 468 | ||
466 | stat = hwif->INB(IDE_STATUS_REG); | 469 | stat = ide_read_status(drive); |
467 | 470 | ||
468 | if (stat == (BUSY_STAT | READY_STAT)) | 471 | if (stat == (BUSY_STAT | READY_STAT)) |
469 | return 4; | 472 | return 4; |
@@ -482,7 +485,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
482 | } | 485 | } |
483 | 486 | ||
484 | /* ensure drive IRQ is clear */ | 487 | /* ensure drive IRQ is clear */ |
485 | stat = hwif->INB(IDE_STATUS_REG); | 488 | stat = ide_read_status(drive); |
486 | 489 | ||
487 | if (rc == 1) | 490 | if (rc == 1) |
488 | printk(KERN_ERR "%s: no response (status = 0x%02x)\n", | 491 | printk(KERN_ERR "%s: no response (status = 0x%02x)\n", |
@@ -496,7 +499,7 @@ static int do_probe (ide_drive_t *drive, u8 cmd) | |||
496 | SELECT_DRIVE(&hwif->drives[0]); | 499 | SELECT_DRIVE(&hwif->drives[0]); |
497 | msleep(50); | 500 | msleep(50); |
498 | /* ensure drive irq is clear */ | 501 | /* ensure drive irq is clear */ |
499 | (void) hwif->INB(IDE_STATUS_REG); | 502 | (void)ide_read_status(drive); |
500 | } | 503 | } |
501 | return rc; | 504 | return rc; |
502 | } | 505 | } |
@@ -521,7 +524,7 @@ static void enable_nest (ide_drive_t *drive) | |||
521 | 524 | ||
522 | msleep(50); | 525 | msleep(50); |
523 | 526 | ||
524 | stat = hwif->INB(IDE_STATUS_REG); | 527 | stat = ide_read_status(drive); |
525 | 528 | ||
526 | if (!OK_STAT(stat, 0, BAD_STAT)) | 529 | if (!OK_STAT(stat, 0, BAD_STAT)) |
527 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); | 530 | printk(KERN_CONT "failed (status = 0x%02x)\n", stat); |
@@ -1046,7 +1049,7 @@ static int init_irq (ide_hwif_t *hwif) | |||
1046 | */ | 1049 | */ |
1047 | if (!match || match->irq != hwif->irq) { | 1050 | if (!match || match->irq != hwif->irq) { |
1048 | int sa = 0; | 1051 | int sa = 0; |
1049 | #if defined(__mc68000__) || defined(CONFIG_APUS) | 1052 | #if defined(__mc68000__) |
1050 | sa = IRQF_SHARED; | 1053 | sa = IRQF_SHARED; |
1051 | #endif /* __mc68000__ || CONFIG_APUS */ | 1054 | #endif /* __mc68000__ || CONFIG_APUS */ |
1052 | 1055 | ||
@@ -1069,7 +1072,7 @@ static int init_irq (ide_hwif_t *hwif) | |||
1069 | hwif->rqsize = 65536; | 1072 | hwif->rqsize = 65536; |
1070 | } | 1073 | } |
1071 | 1074 | ||
1072 | #if !defined(__mc68000__) && !defined(CONFIG_APUS) | 1075 | #if !defined(__mc68000__) |
1073 | printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, | 1076 | printk("%s at 0x%03lx-0x%03lx,0x%03lx on irq %d", hwif->name, |
1074 | hwif->io_ports[IDE_DATA_OFFSET], | 1077 | hwif->io_ports[IDE_DATA_OFFSET], |
1075 | hwif->io_ports[IDE_DATA_OFFSET]+7, | 1078 | hwif->io_ports[IDE_DATA_OFFSET]+7, |
@@ -1077,7 +1080,7 @@ static int init_irq (ide_hwif_t *hwif) | |||
1077 | #else | 1080 | #else |
1078 | printk("%s at 0x%08lx on irq %d", hwif->name, | 1081 | printk("%s at 0x%08lx on irq %d", hwif->name, |
1079 | hwif->io_ports[IDE_DATA_OFFSET], hwif->irq); | 1082 | hwif->io_ports[IDE_DATA_OFFSET], hwif->irq); |
1080 | #endif /* __mc68000__ && CONFIG_APUS */ | 1083 | #endif /* __mc68000__ */ |
1081 | if (match) | 1084 | if (match) |
1082 | printk(" (%sed with %s)", | 1085 | printk(" (%sed with %s)", |
1083 | hwif->sharing_irq ? "shar" : "serializ", match->name); | 1086 | hwif->sharing_irq ? "shar" : "serializ", match->name); |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index 975c0ff0f438..bab88ca7f7ec 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -65,6 +65,7 @@ static int proc_ide_read_imodel | |||
65 | case ide_4drives: name = "4drives"; break; | 65 | case ide_4drives: name = "4drives"; break; |
66 | case ide_pmac: name = "mac-io"; break; | 66 | case ide_pmac: name = "mac-io"; break; |
67 | case ide_au1xxx: name = "au1xxx"; break; | 67 | case ide_au1xxx: name = "au1xxx"; break; |
68 | case ide_palm3710: name = "palm3710"; break; | ||
68 | case ide_etrax100: name = "etrax100"; break; | 69 | case ide_etrax100: name = "etrax100"; break; |
69 | case ide_acorn: name = "acorn"; break; | 70 | case ide_acorn: name = "acorn"; break; |
70 | default: name = "(unknown)"; break; | 71 | default: name = "(unknown)"; break; |
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index bf40d8c824ad..49dd2e7bae7a 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * Documentation/ide/ChangeLog.ide-tape.1995-2002 | 15 | * Documentation/ide/ChangeLog.ide-tape.1995-2002 |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #define IDETAPE_VERSION "1.19" | 18 | #define IDETAPE_VERSION "1.20" |
19 | 19 | ||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/types.h> | 21 | #include <linux/types.h> |
@@ -39,63 +39,70 @@ | |||
39 | #include <scsi/scsi.h> | 39 | #include <scsi/scsi.h> |
40 | 40 | ||
41 | #include <asm/byteorder.h> | 41 | #include <asm/byteorder.h> |
42 | #include <asm/irq.h> | 42 | #include <linux/irq.h> |
43 | #include <asm/uaccess.h> | 43 | #include <linux/uaccess.h> |
44 | #include <asm/io.h> | 44 | #include <linux/io.h> |
45 | #include <asm/unaligned.h> | 45 | #include <asm/unaligned.h> |
46 | #include <linux/mtio.h> | 46 | #include <linux/mtio.h> |
47 | 47 | ||
48 | enum { | ||
49 | /* output errors only */ | ||
50 | DBG_ERR = (1 << 0), | ||
51 | /* output all sense key/asc */ | ||
52 | DBG_SENSE = (1 << 1), | ||
53 | /* info regarding all chrdev-related procedures */ | ||
54 | DBG_CHRDEV = (1 << 2), | ||
55 | /* all remaining procedures */ | ||
56 | DBG_PROCS = (1 << 3), | ||
57 | /* buffer alloc info (pc_stack & rq_stack) */ | ||
58 | DBG_PCRQ_STACK = (1 << 4), | ||
59 | }; | ||
60 | |||
61 | /* define to see debug info */ | ||
62 | #define IDETAPE_DEBUG_LOG 0 | ||
63 | |||
64 | #if IDETAPE_DEBUG_LOG | ||
65 | #define debug_log(lvl, fmt, args...) \ | ||
66 | { \ | ||
67 | if (tape->debug_mask & lvl) \ | ||
68 | printk(KERN_INFO "ide-tape: " fmt, ## args); \ | ||
69 | } | ||
70 | #else | ||
71 | #define debug_log(lvl, fmt, args...) do {} while (0) | ||
72 | #endif | ||
73 | |||
48 | /**************************** Tunable parameters *****************************/ | 74 | /**************************** Tunable parameters *****************************/ |
49 | 75 | ||
50 | 76 | ||
51 | /* | 77 | /* |
52 | * Pipelined mode parameters. | 78 | * Pipelined mode parameters. |
53 | * | 79 | * |
54 | * We try to use the minimum number of stages which is enough to | 80 | * We try to use the minimum number of stages which is enough to keep the tape |
55 | * keep the tape constantly streaming. To accomplish that, we implement | 81 | * constantly streaming. To accomplish that, we implement a feedback loop around |
56 | * a feedback loop around the maximum number of stages: | 82 | * the maximum number of stages: |
57 | * | 83 | * |
58 | * We start from MIN maximum stages (we will not even use MIN stages | 84 | * We start from MIN maximum stages (we will not even use MIN stages if we don't |
59 | * if we don't need them), increment it by RATE*(MAX-MIN) | 85 | * need them), increment it by RATE*(MAX-MIN) whenever we sense that the |
60 | * whenever we sense that the pipeline is empty, until we reach | 86 | * pipeline is empty, until we reach the optimum value or until we reach MAX. |
61 | * the optimum value or until we reach MAX. | ||
62 | * | 87 | * |
63 | * Setting the following parameter to 0 is illegal: the pipelined mode | 88 | * Setting the following parameter to 0 is illegal: the pipelined mode cannot be |
64 | * cannot be disabled (calculate_speeds() divides by tape->max_stages.) | 89 | * disabled (idetape_calculate_speeds() divides by tape->max_stages.) |
65 | */ | 90 | */ |
66 | #define IDETAPE_MIN_PIPELINE_STAGES 1 | 91 | #define IDETAPE_MIN_PIPELINE_STAGES 1 |
67 | #define IDETAPE_MAX_PIPELINE_STAGES 400 | 92 | #define IDETAPE_MAX_PIPELINE_STAGES 400 |
68 | #define IDETAPE_INCREASE_STAGES_RATE 20 | 93 | #define IDETAPE_INCREASE_STAGES_RATE 20 |
69 | 94 | ||
70 | /* | 95 | /* |
71 | * The following are used to debug the driver: | 96 | * After each failed packet command we issue a request sense command and retry |
72 | * | 97 | * the packet command IDETAPE_MAX_PC_RETRIES times. |
73 | * Setting IDETAPE_DEBUG_LOG to 1 will log driver flow control. | ||
74 | * | 98 | * |
75 | * Setting them to 0 will restore normal operation mode: | 99 | * Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries. |
76 | * | ||
77 | * 1. Disable logging normal successful operations. | ||
78 | * 2. Disable self-sanity checks. | ||
79 | * 3. Errors will still be logged, of course. | ||
80 | * | ||
81 | * All the #if DEBUG code will be removed some day, when the driver | ||
82 | * is verified to be stable enough. This will make it much more | ||
83 | * esthetic. | ||
84 | */ | ||
85 | #define IDETAPE_DEBUG_LOG 0 | ||
86 | |||
87 | /* | ||
88 | * After each failed packet command we issue a request sense command | ||
89 | * and retry the packet command IDETAPE_MAX_PC_RETRIES times. | ||
90 | * | ||
91 | * Setting IDETAPE_MAX_PC_RETRIES to 0 will disable retries. | ||
92 | */ | 100 | */ |
93 | #define IDETAPE_MAX_PC_RETRIES 3 | 101 | #define IDETAPE_MAX_PC_RETRIES 3 |
94 | 102 | ||
95 | /* | 103 | /* |
96 | * With each packet command, we allocate a buffer of | 104 | * With each packet command, we allocate a buffer of IDETAPE_PC_BUFFER_SIZE |
97 | * IDETAPE_PC_BUFFER_SIZE bytes. This is used for several packet | 105 | * bytes. This is used for several packet commands (Not for READ/WRITE commands) |
98 | * commands (Not for READ/WRITE commands). | ||
99 | */ | 106 | */ |
100 | #define IDETAPE_PC_BUFFER_SIZE 256 | 107 | #define IDETAPE_PC_BUFFER_SIZE 256 |
101 | 108 | ||
@@ -114,48 +121,39 @@ | |||
114 | #define IDETAPE_WAIT_CMD (900*HZ) | 121 | #define IDETAPE_WAIT_CMD (900*HZ) |
115 | 122 | ||
116 | /* | 123 | /* |
117 | * The following parameter is used to select the point in the internal | 124 | * The following parameter is used to select the point in the internal tape fifo |
118 | * tape fifo in which we will start to refill the buffer. Decreasing | 125 | * in which we will start to refill the buffer. Decreasing the following |
119 | * the following parameter will improve the system's latency and | 126 | * parameter will improve the system's latency and interactive response, while |
120 | * interactive response, while using a high value might improve system | 127 | * using a high value might improve system throughput. |
121 | * throughput. | ||
122 | */ | 128 | */ |
123 | #define IDETAPE_FIFO_THRESHOLD 2 | 129 | #define IDETAPE_FIFO_THRESHOLD 2 |
124 | 130 | ||
125 | /* | 131 | /* |
126 | * DSC polling parameters. | 132 | * DSC polling parameters. |
127 | * | ||
128 | * Polling for DSC (a single bit in the status register) is a very | ||
129 | * important function in ide-tape. There are two cases in which we | ||
130 | * poll for DSC: | ||
131 | * | 133 | * |
132 | * 1. Before a read/write packet command, to ensure that we | 134 | * Polling for DSC (a single bit in the status register) is a very important |
133 | * can transfer data from/to the tape's data buffers, without | 135 | * function in ide-tape. There are two cases in which we poll for DSC: |
134 | * causing an actual media access. In case the tape is not | ||
135 | * ready yet, we take out our request from the device | ||
136 | * request queue, so that ide.c will service requests from | ||
137 | * the other device on the same interface meanwhile. | ||
138 | * | 136 | * |
139 | * 2. After the successful initialization of a "media access | 137 | * 1. Before a read/write packet command, to ensure that we can transfer data |
140 | * packet command", which is a command which can take a long | 138 | * from/to the tape's data buffers, without causing an actual media access. |
141 | * time to complete (it can be several seconds or even an hour). | 139 | * In case the tape is not ready yet, we take out our request from the device |
140 | * request queue, so that ide.c could service requests from the other device | ||
141 | * on the same interface in the meantime. | ||
142 | * | 142 | * |
143 | * Again, we postpone our request in the middle to free the bus | 143 | * 2. After the successful initialization of a "media access packet command", |
144 | * for the other device. The polling frequency here should be | 144 | * which is a command that can take a long time to complete (the interval can |
145 | * lower than the read/write frequency since those media access | 145 | * range from several seconds to even an hour). Again, we postpone our request |
146 | * commands are slow. We start from a "fast" frequency - | 146 | * in the middle to free the bus for the other device. The polling frequency |
147 | * IDETAPE_DSC_MA_FAST (one second), and if we don't receive DSC | 147 | * here should be lower than the read/write frequency since those media access |
148 | * after IDETAPE_DSC_MA_THRESHOLD (5 minutes), we switch it to a | 148 | * commands are slow. We start from a "fast" frequency - IDETAPE_DSC_MA_FAST |
149 | * lower frequency - IDETAPE_DSC_MA_SLOW (1 minute). | 149 | * (1 second), and if we don't receive DSC after IDETAPE_DSC_MA_THRESHOLD |
150 | * (5 min), we switch it to a lower frequency - IDETAPE_DSC_MA_SLOW (1 min). | ||
150 | * | 151 | * |
151 | * We also set a timeout for the timer, in case something goes wrong. | 152 | * We also set a timeout for the timer, in case something goes wrong. The |
152 | * The timeout should be longer then the maximum execution time of a | 153 | * timeout should be longer then the maximum execution time of a tape operation. |
153 | * tape operation. | ||
154 | */ | ||
155 | |||
156 | /* | ||
157 | * DSC timings. | ||
158 | */ | 154 | */ |
155 | |||
156 | /* DSC timings. */ | ||
159 | #define IDETAPE_DSC_RW_MIN 5*HZ/100 /* 50 msec */ | 157 | #define IDETAPE_DSC_RW_MIN 5*HZ/100 /* 50 msec */ |
160 | #define IDETAPE_DSC_RW_MAX 40*HZ/100 /* 400 msec */ | 158 | #define IDETAPE_DSC_RW_MAX 40*HZ/100 /* 400 msec */ |
161 | #define IDETAPE_DSC_RW_TIMEOUT 2*60*HZ /* 2 minutes */ | 159 | #define IDETAPE_DSC_RW_TIMEOUT 2*60*HZ /* 2 minutes */ |
@@ -166,19 +164,15 @@ | |||
166 | 164 | ||
167 | /*************************** End of tunable parameters ***********************/ | 165 | /*************************** End of tunable parameters ***********************/ |
168 | 166 | ||
169 | /* | 167 | /* Read/Write error simulation */ |
170 | * Read/Write error simulation | ||
171 | */ | ||
172 | #define SIMULATE_ERRORS 0 | 168 | #define SIMULATE_ERRORS 0 |
173 | 169 | ||
174 | /* | 170 | /* tape directions */ |
175 | * For general magnetic tape device compatibility. | 171 | enum { |
176 | */ | 172 | IDETAPE_DIR_NONE = (1 << 0), |
177 | typedef enum { | 173 | IDETAPE_DIR_READ = (1 << 1), |
178 | idetape_direction_none, | 174 | IDETAPE_DIR_WRITE = (1 << 2), |
179 | idetape_direction_read, | 175 | }; |
180 | idetape_direction_write | ||
181 | } idetape_chrdev_direction_t; | ||
182 | 176 | ||
183 | struct idetape_bh { | 177 | struct idetape_bh { |
184 | u32 b_size; | 178 | u32 b_size; |
@@ -187,24 +181,32 @@ struct idetape_bh { | |||
187 | char *b_data; | 181 | char *b_data; |
188 | }; | 182 | }; |
189 | 183 | ||
190 | /* | ||
191 | * Our view of a packet command. | ||
192 | */ | ||
193 | typedef struct idetape_packet_command_s { | 184 | typedef struct idetape_packet_command_s { |
194 | u8 c[12]; /* Actual packet bytes */ | 185 | /* Actual packet bytes */ |
195 | int retries; /* On each retry, we increment retries */ | 186 | u8 c[12]; |
196 | int error; /* Error code */ | 187 | /* On each retry, we increment retries */ |
197 | int request_transfer; /* Bytes to transfer */ | 188 | int retries; |
198 | int actually_transferred; /* Bytes actually transferred */ | 189 | /* Error code */ |
199 | int buffer_size; /* Size of our data buffer */ | 190 | int error; |
191 | /* Bytes to transfer */ | ||
192 | int request_transfer; | ||
193 | /* Bytes actually transferred */ | ||
194 | int actually_transferred; | ||
195 | /* Size of our data buffer */ | ||
196 | int buffer_size; | ||
200 | struct idetape_bh *bh; | 197 | struct idetape_bh *bh; |
201 | char *b_data; | 198 | char *b_data; |
202 | int b_count; | 199 | int b_count; |
203 | u8 *buffer; /* Data buffer */ | 200 | /* Data buffer */ |
204 | u8 *current_position; /* Pointer into the above buffer */ | 201 | u8 *buffer; |
205 | ide_startstop_t (*callback) (ide_drive_t *); /* Called when this packet command is completed */ | 202 | /* Pointer into the above buffer */ |
206 | u8 pc_buffer[IDETAPE_PC_BUFFER_SIZE]; /* Temporary buffer */ | 203 | u8 *current_position; |
207 | unsigned long flags; /* Status/Action bit flags: long for set_bit */ | 204 | /* Called when this packet command is completed */ |
205 | ide_startstop_t (*callback) (ide_drive_t *); | ||
206 | /* Temporary buffer */ | ||
207 | u8 pc_buffer[IDETAPE_PC_BUFFER_SIZE]; | ||
208 | /* Status/Action bit flags: long for set_bit */ | ||
209 | unsigned long flags; | ||
208 | } idetape_pc_t; | 210 | } idetape_pc_t; |
209 | 211 | ||
210 | /* | 212 | /* |
@@ -223,9 +225,7 @@ typedef struct idetape_packet_command_s { | |||
223 | /* Data direction */ | 225 | /* Data direction */ |
224 | #define PC_WRITING 5 | 226 | #define PC_WRITING 5 |
225 | 227 | ||
226 | /* | 228 | /* A pipeline stage. */ |
227 | * A pipeline stage. | ||
228 | */ | ||
229 | typedef struct idetape_stage_s { | 229 | typedef struct idetape_stage_s { |
230 | struct request rq; /* The corresponding request */ | 230 | struct request rq; /* The corresponding request */ |
231 | struct idetape_bh *bh; /* The data buffers */ | 231 | struct idetape_bh *bh; /* The data buffers */ |
@@ -233,9 +233,8 @@ typedef struct idetape_stage_s { | |||
233 | } idetape_stage_t; | 233 | } idetape_stage_t; |
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Most of our global data which we need to save even as we leave the | 236 | * Most of our global data which we need to save even as we leave the driver due |
237 | * driver due to an interrupt or a timer event is stored in a variable | 237 | * to an interrupt or a timer event is stored in the struct defined below. |
238 | * of type idetape_tape_t, defined below. | ||
239 | */ | 238 | */ |
240 | typedef struct ide_tape_obj { | 239 | typedef struct ide_tape_obj { |
241 | ide_drive_t *drive; | 240 | ide_drive_t *drive; |
@@ -271,15 +270,14 @@ typedef struct ide_tape_obj { | |||
271 | int rq_stack_index; | 270 | int rq_stack_index; |
272 | 271 | ||
273 | /* | 272 | /* |
274 | * DSC polling variables. | 273 | * DSC polling variables. |
275 | * | 274 | * |
276 | * While polling for DSC we use postponed_rq to postpone the | 275 | * While polling for DSC we use postponed_rq to postpone the current |
277 | * current request so that ide.c will be able to service | 276 | * request so that ide.c will be able to service pending requests on the |
278 | * pending requests on the other device. Note that at most | 277 | * other device. Note that at most we will have only one DSC (usually |
279 | * we will have only one DSC (usually data transfer) request | 278 | * data transfer) request in the device request queue. Additional |
280 | * in the device request queue. Additional requests can be | 279 | * requests can be queued in our internal pipeline, but they will be |
281 | * queued in our internal pipeline, but they will be visible | 280 | * visible to ide.c only one at a time. |
282 | * to ide.c only one at a time. | ||
283 | */ | 281 | */ |
284 | struct request *postponed_rq; | 282 | struct request *postponed_rq; |
285 | /* The time in which we started polling for DSC */ | 283 | /* The time in which we started polling for DSC */ |
@@ -287,73 +285,57 @@ typedef struct ide_tape_obj { | |||
287 | /* Timer used to poll for dsc */ | 285 | /* Timer used to poll for dsc */ |
288 | struct timer_list dsc_timer; | 286 | struct timer_list dsc_timer; |
289 | /* Read/Write dsc polling frequency */ | 287 | /* Read/Write dsc polling frequency */ |
290 | unsigned long best_dsc_rw_frequency; | 288 | unsigned long best_dsc_rw_freq; |
291 | /* The current polling frequency */ | 289 | unsigned long dsc_poll_freq; |
292 | unsigned long dsc_polling_frequency; | ||
293 | /* Maximum waiting time */ | ||
294 | unsigned long dsc_timeout; | 290 | unsigned long dsc_timeout; |
295 | 291 | ||
296 | /* | 292 | /* Read position information */ |
297 | * Read position information | ||
298 | */ | ||
299 | u8 partition; | 293 | u8 partition; |
300 | /* Current block */ | 294 | /* Current block */ |
301 | unsigned int first_frame_position; | 295 | unsigned int first_frame; |
302 | unsigned int last_frame_position; | ||
303 | unsigned int blocks_in_buffer; | ||
304 | 296 | ||
305 | /* | 297 | /* Last error information */ |
306 | * Last error information | ||
307 | */ | ||
308 | u8 sense_key, asc, ascq; | 298 | u8 sense_key, asc, ascq; |
309 | 299 | ||
310 | /* | 300 | /* Character device operation */ |
311 | * Character device operation | ||
312 | */ | ||
313 | unsigned int minor; | 301 | unsigned int minor; |
314 | /* device name */ | 302 | /* device name */ |
315 | char name[4]; | 303 | char name[4]; |
316 | /* Current character device data transfer direction */ | 304 | /* Current character device data transfer direction */ |
317 | idetape_chrdev_direction_t chrdev_direction; | 305 | u8 chrdev_dir; |
318 | 306 | ||
319 | /* | 307 | /* tape block size, usually 512 or 1024 bytes */ |
320 | * Device information | 308 | unsigned short blk_size; |
321 | */ | ||
322 | /* Usually 512 or 1024 bytes */ | ||
323 | unsigned short tape_block_size; | ||
324 | int user_bs_factor; | 309 | int user_bs_factor; |
325 | 310 | ||
326 | /* Copy of the tape's Capabilities and Mechanical Page */ | 311 | /* Copy of the tape's Capabilities and Mechanical Page */ |
327 | u8 caps[20]; | 312 | u8 caps[20]; |
328 | 313 | ||
329 | /* | 314 | /* |
330 | * Active data transfer request parameters. | 315 | * Active data transfer request parameters. |
331 | * | ||
332 | * At most, there is only one ide-tape originated data transfer | ||
333 | * request in the device request queue. This allows ide.c to | ||
334 | * easily service requests from the other device when we | ||
335 | * postpone our active request. In the pipelined operation | ||
336 | * mode, we use our internal pipeline structure to hold | ||
337 | * more data requests. | ||
338 | * | 316 | * |
339 | * The data buffer size is chosen based on the tape's | 317 | * At most, there is only one ide-tape originated data transfer request |
340 | * recommendation. | 318 | * in the device request queue. This allows ide.c to easily service |
319 | * requests from the other device when we postpone our active request. | ||
320 | * In the pipelined operation mode, we use our internal pipeline | ||
321 | * structure to hold more data requests. The data buffer size is chosen | ||
322 | * based on the tape's recommendation. | ||
341 | */ | 323 | */ |
342 | /* Pointer to the request which is waiting in the device request queue */ | 324 | /* ptr to the request which is waiting in the device request queue */ |
343 | struct request *active_data_request; | 325 | struct request *active_data_rq; |
344 | /* Data buffer size (chosen based on the tape's recommendation */ | 326 | /* Data buffer size chosen based on the tape's recommendation */ |
345 | int stage_size; | 327 | int stage_size; |
346 | idetape_stage_t *merge_stage; | 328 | idetape_stage_t *merge_stage; |
347 | int merge_stage_size; | 329 | int merge_stage_size; |
348 | struct idetape_bh *bh; | 330 | struct idetape_bh *bh; |
349 | char *b_data; | 331 | char *b_data; |
350 | int b_count; | 332 | int b_count; |
351 | 333 | ||
352 | /* | 334 | /* |
353 | * Pipeline parameters. | 335 | * Pipeline parameters. |
354 | * | 336 | * |
355 | * To accomplish non-pipelined mode, we simply set the following | 337 | * To accomplish non-pipelined mode, we simply set the following |
356 | * variables to zero (or NULL, where appropriate). | 338 | * variables to zero (or NULL, where appropriate). |
357 | */ | 339 | */ |
358 | /* Number of currently used stages */ | 340 | /* Number of currently used stages */ |
359 | int nr_stages; | 341 | int nr_stages; |
@@ -378,20 +360,13 @@ typedef struct ide_tape_obj { | |||
378 | /* Status/Action flags: long for set_bit */ | 360 | /* Status/Action flags: long for set_bit */ |
379 | unsigned long flags; | 361 | unsigned long flags; |
380 | /* protects the ide-tape queue */ | 362 | /* protects the ide-tape queue */ |
381 | spinlock_t spinlock; | 363 | spinlock_t lock; |
382 | 364 | ||
383 | /* | 365 | /* Measures average tape speed */ |
384 | * Measures average tape speed | ||
385 | */ | ||
386 | unsigned long avg_time; | 366 | unsigned long avg_time; |
387 | int avg_size; | 367 | int avg_size; |
388 | int avg_speed; | 368 | int avg_speed; |
389 | 369 | ||
390 | char vendor_id[10]; | ||
391 | char product_id[18]; | ||
392 | char firmware_revision[6]; | ||
393 | int firmware_revision_num; | ||
394 | |||
395 | /* the door is currently locked */ | 370 | /* the door is currently locked */ |
396 | int door_locked; | 371 | int door_locked; |
397 | /* the tape hardware is write protected */ | 372 | /* the tape hardware is write protected */ |
@@ -400,11 +375,9 @@ typedef struct ide_tape_obj { | |||
400 | char write_prot; | 375 | char write_prot; |
401 | 376 | ||
402 | /* | 377 | /* |
403 | * Limit the number of times a request can | 378 | * Limit the number of times a request can be postponed, to avoid an |
404 | * be postponed, to avoid an infinite postpone | 379 | * infinite postpone deadlock. |
405 | * deadlock. | ||
406 | */ | 380 | */ |
407 | /* request postpone count limit */ | ||
408 | int postpone_cnt; | 381 | int postpone_cnt; |
409 | 382 | ||
410 | /* | 383 | /* |
@@ -419,30 +392,19 @@ typedef struct ide_tape_obj { | |||
419 | int tape_head; | 392 | int tape_head; |
420 | int last_tape_head; | 393 | int last_tape_head; |
421 | 394 | ||
422 | /* | 395 | /* Speed control at the tape buffers input/output */ |
423 | * Speed control at the tape buffers input/output | ||
424 | */ | ||
425 | unsigned long insert_time; | 396 | unsigned long insert_time; |
426 | int insert_size; | 397 | int insert_size; |
427 | int insert_speed; | 398 | int insert_speed; |
428 | int max_insert_speed; | 399 | int max_insert_speed; |
429 | int measure_insert_time; | 400 | int measure_insert_time; |
430 | 401 | ||
431 | /* | 402 | /* Speed regulation negative feedback loop */ |
432 | * Measure tape still time, in milliseconds | ||
433 | */ | ||
434 | unsigned long tape_still_time_begin; | ||
435 | int tape_still_time; | ||
436 | |||
437 | /* | ||
438 | * Speed regulation negative feedback loop | ||
439 | */ | ||
440 | int speed_control; | 403 | int speed_control; |
441 | int pipeline_head_speed; | 404 | int pipeline_head_speed; |
442 | int controlled_pipeline_head_speed; | 405 | int controlled_pipeline_head_speed; |
443 | int uncontrolled_pipeline_head_speed; | 406 | int uncontrolled_pipeline_head_speed; |
444 | int controlled_last_pipeline_head; | 407 | int controlled_last_pipeline_head; |
445 | int uncontrolled_last_pipeline_head; | ||
446 | unsigned long uncontrolled_pipeline_head_time; | 408 | unsigned long uncontrolled_pipeline_head_time; |
447 | unsigned long controlled_pipeline_head_time; | 409 | unsigned long controlled_pipeline_head_time; |
448 | int controlled_previous_pipeline_head; | 410 | int controlled_previous_pipeline_head; |
@@ -451,18 +413,7 @@ typedef struct ide_tape_obj { | |||
451 | unsigned long uncontrolled_previous_head_time; | 413 | unsigned long uncontrolled_previous_head_time; |
452 | int restart_speed_control_req; | 414 | int restart_speed_control_req; |
453 | 415 | ||
454 | /* | 416 | u32 debug_mask; |
455 | * Debug_level determines amount of debugging output; | ||
456 | * can be changed using /proc/ide/hdx/settings | ||
457 | * 0 : almost no debugging output | ||
458 | * 1 : 0+output errors only | ||
459 | * 2 : 1+output all sensekey/asc | ||
460 | * 3 : 2+follow all chrdev related procedures | ||
461 | * 4 : 3+follow all procedures | ||
462 | * 5 : 4+include pc_stack rq_stack info | ||
463 | * 6 : 5+USE_COUNT updates | ||
464 | */ | ||
465 | int debug_level; | ||
466 | } idetape_tape_t; | 417 | } idetape_tape_t; |
467 | 418 | ||
468 | static DEFINE_MUTEX(idetape_ref_mutex); | 419 | static DEFINE_MUTEX(idetape_ref_mutex); |
@@ -495,9 +446,7 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
495 | mutex_unlock(&idetape_ref_mutex); | 446 | mutex_unlock(&idetape_ref_mutex); |
496 | } | 447 | } |
497 | 448 | ||
498 | /* | 449 | /* Tape door status */ |
499 | * Tape door status | ||
500 | */ | ||
501 | #define DOOR_UNLOCKED 0 | 450 | #define DOOR_UNLOCKED 0 |
502 | #define DOOR_LOCKED 1 | 451 | #define DOOR_LOCKED 1 |
503 | #define DOOR_EXPLICITLY_LOCKED 2 | 452 | #define DOOR_EXPLICITLY_LOCKED 2 |
@@ -517,30 +466,23 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
517 | /* 0 = no tape is loaded, so we don't rewind after ejecting */ | 466 | /* 0 = no tape is loaded, so we don't rewind after ejecting */ |
518 | #define IDETAPE_MEDIUM_PRESENT 9 | 467 | #define IDETAPE_MEDIUM_PRESENT 9 |
519 | 468 | ||
520 | /* | 469 | /* A define for the READ BUFFER command */ |
521 | * Some defines for the READ BUFFER command | ||
522 | */ | ||
523 | #define IDETAPE_RETRIEVE_FAULTY_BLOCK 6 | 470 | #define IDETAPE_RETRIEVE_FAULTY_BLOCK 6 |
524 | 471 | ||
525 | /* | 472 | /* Some defines for the SPACE command */ |
526 | * Some defines for the SPACE command | ||
527 | */ | ||
528 | #define IDETAPE_SPACE_OVER_FILEMARK 1 | 473 | #define IDETAPE_SPACE_OVER_FILEMARK 1 |
529 | #define IDETAPE_SPACE_TO_EOD 3 | 474 | #define IDETAPE_SPACE_TO_EOD 3 |
530 | 475 | ||
531 | /* | 476 | /* Some defines for the LOAD UNLOAD command */ |
532 | * Some defines for the LOAD UNLOAD command | ||
533 | */ | ||
534 | #define IDETAPE_LU_LOAD_MASK 1 | 477 | #define IDETAPE_LU_LOAD_MASK 1 |
535 | #define IDETAPE_LU_RETENSION_MASK 2 | 478 | #define IDETAPE_LU_RETENSION_MASK 2 |
536 | #define IDETAPE_LU_EOT_MASK 4 | 479 | #define IDETAPE_LU_EOT_MASK 4 |
537 | 480 | ||
538 | /* | 481 | /* |
539 | * Special requests for our block device strategy routine. | 482 | * Special requests for our block device strategy routine. |
540 | * | 483 | * |
541 | * In order to service a character device command, we add special | 484 | * In order to service a character device command, we add special requests to |
542 | * requests to the tail of our block device request queue and wait | 485 | * the tail of our block device request queue and wait for their completion. |
543 | * for their completion. | ||
544 | */ | 486 | */ |
545 | 487 | ||
546 | enum { | 488 | enum { |
@@ -551,55 +493,20 @@ enum { | |||
551 | REQ_IDETAPE_READ_BUFFER = (1 << 4), | 493 | REQ_IDETAPE_READ_BUFFER = (1 << 4), |
552 | }; | 494 | }; |
553 | 495 | ||
554 | /* | 496 | /* Error codes returned in rq->errors to the higher part of the driver. */ |
555 | * Error codes which are returned in rq->errors to the higher part | ||
556 | * of the driver. | ||
557 | */ | ||
558 | #define IDETAPE_ERROR_GENERAL 101 | 497 | #define IDETAPE_ERROR_GENERAL 101 |
559 | #define IDETAPE_ERROR_FILEMARK 102 | 498 | #define IDETAPE_ERROR_FILEMARK 102 |
560 | #define IDETAPE_ERROR_EOD 103 | 499 | #define IDETAPE_ERROR_EOD 103 |
561 | 500 | ||
562 | /* | ||
563 | * The following is used to format the general configuration word of | ||
564 | * the ATAPI IDENTIFY DEVICE command. | ||
565 | */ | ||
566 | struct idetape_id_gcw { | ||
567 | unsigned packet_size :2; /* Packet Size */ | ||
568 | unsigned reserved234 :3; /* Reserved */ | ||
569 | unsigned drq_type :2; /* Command packet DRQ type */ | ||
570 | unsigned removable :1; /* Removable media */ | ||
571 | unsigned device_type :5; /* Device type */ | ||
572 | unsigned reserved13 :1; /* Reserved */ | ||
573 | unsigned protocol :2; /* Protocol type */ | ||
574 | }; | ||
575 | |||
576 | /* | ||
577 | * READ POSITION packet command - Data Format (From Table 6-57) | ||
578 | */ | ||
579 | typedef struct { | ||
580 | unsigned reserved0_10 :2; /* Reserved */ | ||
581 | unsigned bpu :1; /* Block Position Unknown */ | ||
582 | unsigned reserved0_543 :3; /* Reserved */ | ||
583 | unsigned eop :1; /* End Of Partition */ | ||
584 | unsigned bop :1; /* Beginning Of Partition */ | ||
585 | u8 partition; /* Partition Number */ | ||
586 | u8 reserved2, reserved3; /* Reserved */ | ||
587 | u32 first_block; /* First Block Location */ | ||
588 | u32 last_block; /* Last Block Location (Optional) */ | ||
589 | u8 reserved12; /* Reserved */ | ||
590 | u8 blocks_in_buffer[3]; /* Blocks In Buffer - (Optional) */ | ||
591 | u32 bytes_in_buffer; /* Bytes In Buffer (Optional) */ | ||
592 | } idetape_read_position_result_t; | ||
593 | |||
594 | /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ | 501 | /* Structures related to the SELECT SENSE / MODE SENSE packet commands. */ |
595 | #define IDETAPE_BLOCK_DESCRIPTOR 0 | 502 | #define IDETAPE_BLOCK_DESCRIPTOR 0 |
596 | #define IDETAPE_CAPABILITIES_PAGE 0x2a | 503 | #define IDETAPE_CAPABILITIES_PAGE 0x2a |
597 | 504 | ||
598 | /* | 505 | /* |
599 | * The variables below are used for the character device interface. | 506 | * The variables below are used for the character device interface. Additional |
600 | * Additional state variables are defined in our ide_drive_t structure. | 507 | * state variables are defined in our ide_drive_t structure. |
601 | */ | 508 | */ |
602 | static struct ide_tape_obj * idetape_devs[MAX_HWIFS * MAX_DRIVES]; | 509 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; |
603 | 510 | ||
604 | #define ide_tape_f(file) ((file)->private_data) | 511 | #define ide_tape_f(file) ((file)->private_data) |
605 | 512 | ||
@@ -616,23 +523,17 @@ static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) | |||
616 | } | 523 | } |
617 | 524 | ||
618 | /* | 525 | /* |
619 | * Function declarations | ||
620 | * | ||
621 | */ | ||
622 | static int idetape_chrdev_release (struct inode *inode, struct file *filp); | ||
623 | static void idetape_write_release (ide_drive_t *drive, unsigned int minor); | ||
624 | |||
625 | /* | ||
626 | * Too bad. The drive wants to send us data which we are not ready to accept. | 526 | * Too bad. The drive wants to send us data which we are not ready to accept. |
627 | * Just throw it away. | 527 | * Just throw it away. |
628 | */ | 528 | */ |
629 | static void idetape_discard_data (ide_drive_t *drive, unsigned int bcount) | 529 | static void idetape_discard_data(ide_drive_t *drive, unsigned int bcount) |
630 | { | 530 | { |
631 | while (bcount--) | 531 | while (bcount--) |
632 | (void) HWIF(drive)->INB(IDE_DATA_REG); | 532 | (void) HWIF(drive)->INB(IDE_DATA_REG); |
633 | } | 533 | } |
634 | 534 | ||
635 | static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount) | 535 | static void idetape_input_buffers(ide_drive_t *drive, idetape_pc_t *pc, |
536 | unsigned int bcount) | ||
636 | { | 537 | { |
637 | struct idetape_bh *bh = pc->bh; | 538 | struct idetape_bh *bh = pc->bh; |
638 | int count; | 539 | int count; |
@@ -644,8 +545,11 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne | |||
644 | idetape_discard_data(drive, bcount); | 545 | idetape_discard_data(drive, bcount); |
645 | return; | 546 | return; |
646 | } | 547 | } |
647 | count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), bcount); | 548 | count = min( |
648 | HWIF(drive)->atapi_input_bytes(drive, bh->b_data + atomic_read(&bh->b_count), count); | 549 | (unsigned int)(bh->b_size - atomic_read(&bh->b_count)), |
550 | bcount); | ||
551 | HWIF(drive)->atapi_input_bytes(drive, bh->b_data + | ||
552 | atomic_read(&bh->b_count), count); | ||
649 | bcount -= count; | 553 | bcount -= count; |
650 | atomic_add(count, &bh->b_count); | 554 | atomic_add(count, &bh->b_count); |
651 | if (atomic_read(&bh->b_count) == bh->b_size) { | 555 | if (atomic_read(&bh->b_count) == bh->b_size) { |
@@ -657,15 +561,16 @@ static void idetape_input_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigne | |||
657 | pc->bh = bh; | 561 | pc->bh = bh; |
658 | } | 562 | } |
659 | 563 | ||
660 | static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsigned int bcount) | 564 | static void idetape_output_buffers(ide_drive_t *drive, idetape_pc_t *pc, |
565 | unsigned int bcount) | ||
661 | { | 566 | { |
662 | struct idetape_bh *bh = pc->bh; | 567 | struct idetape_bh *bh = pc->bh; |
663 | int count; | 568 | int count; |
664 | 569 | ||
665 | while (bcount) { | 570 | while (bcount) { |
666 | if (bh == NULL) { | 571 | if (bh == NULL) { |
667 | printk(KERN_ERR "ide-tape: bh == NULL in " | 572 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", |
668 | "idetape_output_buffers\n"); | 573 | __func__); |
669 | return; | 574 | return; |
670 | } | 575 | } |
671 | count = min((unsigned int)pc->b_count, (unsigned int)bcount); | 576 | count = min((unsigned int)pc->b_count, (unsigned int)bcount); |
@@ -674,7 +579,8 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign | |||
674 | pc->b_data += count; | 579 | pc->b_data += count; |
675 | pc->b_count -= count; | 580 | pc->b_count -= count; |
676 | if (!pc->b_count) { | 581 | if (!pc->b_count) { |
677 | pc->bh = bh = bh->b_reqnext; | 582 | bh = bh->b_reqnext; |
583 | pc->bh = bh; | ||
678 | if (bh) { | 584 | if (bh) { |
679 | pc->b_data = bh->b_data; | 585 | pc->b_data = bh->b_data; |
680 | pc->b_count = atomic_read(&bh->b_count); | 586 | pc->b_count = atomic_read(&bh->b_count); |
@@ -683,7 +589,7 @@ static void idetape_output_buffers (ide_drive_t *drive, idetape_pc_t *pc, unsign | |||
683 | } | 589 | } |
684 | } | 590 | } |
685 | 591 | ||
686 | static void idetape_update_buffers (idetape_pc_t *pc) | 592 | static void idetape_update_buffers(idetape_pc_t *pc) |
687 | { | 593 | { |
688 | struct idetape_bh *bh = pc->bh; | 594 | struct idetape_bh *bh = pc->bh; |
689 | int count; | 595 | int count; |
@@ -693,8 +599,8 @@ static void idetape_update_buffers (idetape_pc_t *pc) | |||
693 | return; | 599 | return; |
694 | while (bcount) { | 600 | while (bcount) { |
695 | if (bh == NULL) { | 601 | if (bh == NULL) { |
696 | printk(KERN_ERR "ide-tape: bh == NULL in " | 602 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", |
697 | "idetape_update_buffers\n"); | 603 | __func__); |
698 | return; | 604 | return; |
699 | } | 605 | } |
700 | count = min((unsigned int)bh->b_size, (unsigned int)bcount); | 606 | count = min((unsigned int)bh->b_size, (unsigned int)bcount); |
@@ -712,17 +618,14 @@ static void idetape_update_buffers (idetape_pc_t *pc) | |||
712 | * driver. A storage space for a maximum of IDETAPE_PC_STACK packet | 618 | * driver. A storage space for a maximum of IDETAPE_PC_STACK packet |
713 | * commands is allocated at initialization time. | 619 | * commands is allocated at initialization time. |
714 | */ | 620 | */ |
715 | static idetape_pc_t *idetape_next_pc_storage (ide_drive_t *drive) | 621 | static idetape_pc_t *idetape_next_pc_storage(ide_drive_t *drive) |
716 | { | 622 | { |
717 | idetape_tape_t *tape = drive->driver_data; | 623 | idetape_tape_t *tape = drive->driver_data; |
718 | 624 | ||
719 | #if IDETAPE_DEBUG_LOG | 625 | debug_log(DBG_PCRQ_STACK, "pc_stack_index=%d\n", tape->pc_stack_index); |
720 | if (tape->debug_level >= 5) | 626 | |
721 | printk(KERN_INFO "ide-tape: pc_stack_index=%d\n", | ||
722 | tape->pc_stack_index); | ||
723 | #endif /* IDETAPE_DEBUG_LOG */ | ||
724 | if (tape->pc_stack_index == IDETAPE_PC_STACK) | 627 | if (tape->pc_stack_index == IDETAPE_PC_STACK) |
725 | tape->pc_stack_index=0; | 628 | tape->pc_stack_index = 0; |
726 | return (&tape->pc_stack[tape->pc_stack_index++]); | 629 | return (&tape->pc_stack[tape->pc_stack_index++]); |
727 | } | 630 | } |
728 | 631 | ||
@@ -731,32 +634,26 @@ static idetape_pc_t *idetape_next_pc_storage (ide_drive_t *drive) | |||
731 | * Since we queue packet commands in the request queue, we need to | 634 | * Since we queue packet commands in the request queue, we need to |
732 | * allocate a request, along with the allocation of a packet command. | 635 | * allocate a request, along with the allocation of a packet command. |
733 | */ | 636 | */ |
734 | 637 | ||
735 | /************************************************************** | 638 | /************************************************************** |
736 | * * | 639 | * * |
737 | * This should get fixed to use kmalloc(.., GFP_ATOMIC) * | 640 | * This should get fixed to use kmalloc(.., GFP_ATOMIC) * |
738 | * followed later on by kfree(). -ml * | 641 | * followed later on by kfree(). -ml * |
739 | * * | 642 | * * |
740 | **************************************************************/ | 643 | **************************************************************/ |
741 | 644 | ||
742 | static struct request *idetape_next_rq_storage (ide_drive_t *drive) | 645 | static struct request *idetape_next_rq_storage(ide_drive_t *drive) |
743 | { | 646 | { |
744 | idetape_tape_t *tape = drive->driver_data; | 647 | idetape_tape_t *tape = drive->driver_data; |
745 | 648 | ||
746 | #if IDETAPE_DEBUG_LOG | 649 | debug_log(DBG_PCRQ_STACK, "rq_stack_index=%d\n", tape->rq_stack_index); |
747 | if (tape->debug_level >= 5) | 650 | |
748 | printk(KERN_INFO "ide-tape: rq_stack_index=%d\n", | ||
749 | tape->rq_stack_index); | ||
750 | #endif /* IDETAPE_DEBUG_LOG */ | ||
751 | if (tape->rq_stack_index == IDETAPE_PC_STACK) | 651 | if (tape->rq_stack_index == IDETAPE_PC_STACK) |
752 | tape->rq_stack_index=0; | 652 | tape->rq_stack_index = 0; |
753 | return (&tape->rq_stack[tape->rq_stack_index++]); | 653 | return (&tape->rq_stack[tape->rq_stack_index++]); |
754 | } | 654 | } |
755 | 655 | ||
756 | /* | 656 | static void idetape_init_pc(idetape_pc_t *pc) |
757 | * idetape_init_pc initializes a packet command. | ||
758 | */ | ||
759 | static void idetape_init_pc (idetape_pc_t *pc) | ||
760 | { | 657 | { |
761 | memset(pc->c, 0, 12); | 658 | memset(pc->c, 0, 12); |
762 | pc->retries = 0; | 659 | pc->retries = 0; |
@@ -780,22 +677,14 @@ static void idetape_analyze_error(ide_drive_t *drive, u8 *sense) | |||
780 | tape->sense_key = sense[2] & 0xF; | 677 | tape->sense_key = sense[2] & 0xF; |
781 | tape->asc = sense[12]; | 678 | tape->asc = sense[12]; |
782 | tape->ascq = sense[13]; | 679 | tape->ascq = sense[13]; |
783 | #if IDETAPE_DEBUG_LOG | 680 | |
784 | /* | 681 | debug_log(DBG_ERR, "pc = %x, sense key = %x, asc = %x, ascq = %x\n", |
785 | * Without debugging, we only log an error if we decided to give up | 682 | pc->c[0], tape->sense_key, tape->asc, tape->ascq); |
786 | * retrying. | ||
787 | */ | ||
788 | if (tape->debug_level >= 1) | ||
789 | printk(KERN_INFO "ide-tape: pc = %x, sense key = %x, " | ||
790 | "asc = %x, ascq = %x\n", | ||
791 | pc->c[0], tape->sense_key, | ||
792 | tape->asc, tape->ascq); | ||
793 | #endif /* IDETAPE_DEBUG_LOG */ | ||
794 | 683 | ||
795 | /* Correct pc->actually_transferred by asking the tape. */ | 684 | /* Correct pc->actually_transferred by asking the tape. */ |
796 | if (test_bit(PC_DMA_ERROR, &pc->flags)) { | 685 | if (test_bit(PC_DMA_ERROR, &pc->flags)) { |
797 | pc->actually_transferred = pc->request_transfer - | 686 | pc->actually_transferred = pc->request_transfer - |
798 | tape->tape_block_size * | 687 | tape->blk_size * |
799 | be32_to_cpu(get_unaligned((u32 *)&sense[3])); | 688 | be32_to_cpu(get_unaligned((u32 *)&sense[3])); |
800 | idetape_update_buffers(pc); | 689 | idetape_update_buffers(pc); |
801 | } | 690 | } |
@@ -843,50 +732,24 @@ static void idetape_activate_next_stage(ide_drive_t *drive) | |||
843 | idetape_stage_t *stage = tape->next_stage; | 732 | idetape_stage_t *stage = tape->next_stage; |
844 | struct request *rq = &stage->rq; | 733 | struct request *rq = &stage->rq; |
845 | 734 | ||
846 | #if IDETAPE_DEBUG_LOG | 735 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
847 | if (tape->debug_level >= 4) | 736 | |
848 | printk(KERN_INFO "ide-tape: Reached idetape_active_next_stage\n"); | ||
849 | #endif /* IDETAPE_DEBUG_LOG */ | ||
850 | if (stage == NULL) { | 737 | if (stage == NULL) { |
851 | printk(KERN_ERR "ide-tape: bug: Trying to activate a non existing stage\n"); | 738 | printk(KERN_ERR "ide-tape: bug: Trying to activate a non" |
739 | " existing stage\n"); | ||
852 | return; | 740 | return; |
853 | } | 741 | } |
854 | 742 | ||
855 | rq->rq_disk = tape->disk; | 743 | rq->rq_disk = tape->disk; |
856 | rq->buffer = NULL; | 744 | rq->buffer = NULL; |
857 | rq->special = (void *)stage->bh; | 745 | rq->special = (void *)stage->bh; |
858 | tape->active_data_request = rq; | 746 | tape->active_data_rq = rq; |
859 | tape->active_stage = stage; | 747 | tape->active_stage = stage; |
860 | tape->next_stage = stage->next; | 748 | tape->next_stage = stage->next; |
861 | } | 749 | } |
862 | 750 | ||
863 | /* | 751 | /* Free a stage along with its related buffers completely. */ |
864 | * idetape_increase_max_pipeline_stages is a part of the feedback | 752 | static void __idetape_kfree_stage(idetape_stage_t *stage) |
865 | * loop which tries to find the optimum number of stages. In the | ||
866 | * feedback loop, we are starting from a minimum maximum number of | ||
867 | * stages, and if we sense that the pipeline is empty, we try to | ||
868 | * increase it, until we reach the user compile time memory limit. | ||
869 | */ | ||
870 | static void idetape_increase_max_pipeline_stages (ide_drive_t *drive) | ||
871 | { | ||
872 | idetape_tape_t *tape = drive->driver_data; | ||
873 | int increase = (tape->max_pipeline - tape->min_pipeline) / 10; | ||
874 | |||
875 | #if IDETAPE_DEBUG_LOG | ||
876 | if (tape->debug_level >= 4) | ||
877 | printk (KERN_INFO "ide-tape: Reached idetape_increase_max_pipeline_stages\n"); | ||
878 | #endif /* IDETAPE_DEBUG_LOG */ | ||
879 | |||
880 | tape->max_stages += max(increase, 1); | ||
881 | tape->max_stages = max(tape->max_stages, tape->min_pipeline); | ||
882 | tape->max_stages = min(tape->max_stages, tape->max_pipeline); | ||
883 | } | ||
884 | |||
885 | /* | ||
886 | * idetape_kfree_stage calls kfree to completely free a stage, along with | ||
887 | * its related buffers. | ||
888 | */ | ||
889 | static void __idetape_kfree_stage (idetape_stage_t *stage) | ||
890 | { | 753 | { |
891 | struct idetape_bh *prev_bh, *bh = stage->bh; | 754 | struct idetape_bh *prev_bh, *bh = stage->bh; |
892 | int size; | 755 | int size; |
@@ -907,30 +770,29 @@ static void __idetape_kfree_stage (idetape_stage_t *stage) | |||
907 | kfree(stage); | 770 | kfree(stage); |
908 | } | 771 | } |
909 | 772 | ||
910 | static void idetape_kfree_stage (idetape_tape_t *tape, idetape_stage_t *stage) | 773 | static void idetape_kfree_stage(idetape_tape_t *tape, idetape_stage_t *stage) |
911 | { | 774 | { |
912 | __idetape_kfree_stage(stage); | 775 | __idetape_kfree_stage(stage); |
913 | } | 776 | } |
914 | 777 | ||
915 | /* | 778 | /* |
916 | * idetape_remove_stage_head removes tape->first_stage from the pipeline. | 779 | * Remove tape->first_stage from the pipeline. The caller should avoid race |
917 | * The caller should avoid race conditions. | 780 | * conditions. |
918 | */ | 781 | */ |
919 | static void idetape_remove_stage_head (ide_drive_t *drive) | 782 | static void idetape_remove_stage_head(ide_drive_t *drive) |
920 | { | 783 | { |
921 | idetape_tape_t *tape = drive->driver_data; | 784 | idetape_tape_t *tape = drive->driver_data; |
922 | idetape_stage_t *stage; | 785 | idetape_stage_t *stage; |
923 | 786 | ||
924 | #if IDETAPE_DEBUG_LOG | 787 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
925 | if (tape->debug_level >= 4) | 788 | |
926 | printk(KERN_INFO "ide-tape: Reached idetape_remove_stage_head\n"); | ||
927 | #endif /* IDETAPE_DEBUG_LOG */ | ||
928 | if (tape->first_stage == NULL) { | 789 | if (tape->first_stage == NULL) { |
929 | printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n"); | 790 | printk(KERN_ERR "ide-tape: bug: tape->first_stage is NULL\n"); |
930 | return; | 791 | return; |
931 | } | 792 | } |
932 | if (tape->active_stage == tape->first_stage) { | 793 | if (tape->active_stage == tape->first_stage) { |
933 | printk(KERN_ERR "ide-tape: bug: Trying to free our active pipeline stage\n"); | 794 | printk(KERN_ERR "ide-tape: bug: Trying to free our active " |
795 | "pipeline stage\n"); | ||
934 | return; | 796 | return; |
935 | } | 797 | } |
936 | stage = tape->first_stage; | 798 | stage = tape->first_stage; |
@@ -940,9 +802,11 @@ static void idetape_remove_stage_head (ide_drive_t *drive) | |||
940 | if (tape->first_stage == NULL) { | 802 | if (tape->first_stage == NULL) { |
941 | tape->last_stage = NULL; | 803 | tape->last_stage = NULL; |
942 | if (tape->next_stage != NULL) | 804 | if (tape->next_stage != NULL) |
943 | printk(KERN_ERR "ide-tape: bug: tape->next_stage != NULL\n"); | 805 | printk(KERN_ERR "ide-tape: bug: tape->next_stage !=" |
806 | " NULL\n"); | ||
944 | if (tape->nr_stages) | 807 | if (tape->nr_stages) |
945 | printk(KERN_ERR "ide-tape: bug: nr_stages should be 0 now\n"); | 808 | printk(KERN_ERR "ide-tape: bug: nr_stages should be 0 " |
809 | "now\n"); | ||
946 | } | 810 | } |
947 | } | 811 | } |
948 | 812 | ||
@@ -957,10 +821,8 @@ static void idetape_abort_pipeline(ide_drive_t *drive, | |||
957 | idetape_stage_t *stage = new_last_stage->next; | 821 | idetape_stage_t *stage = new_last_stage->next; |
958 | idetape_stage_t *nstage; | 822 | idetape_stage_t *nstage; |
959 | 823 | ||
960 | #if IDETAPE_DEBUG_LOG | 824 | debug_log(DBG_PROCS, "%s: Enter %s\n", tape->name, __func__); |
961 | if (tape->debug_level >= 4) | 825 | |
962 | printk(KERN_INFO "ide-tape: %s: idetape_abort_pipeline called\n", tape->name); | ||
963 | #endif | ||
964 | while (stage) { | 826 | while (stage) { |
965 | nstage = stage->next; | 827 | nstage = stage->next; |
966 | idetape_kfree_stage(tape, stage); | 828 | idetape_kfree_stage(tape, stage); |
@@ -975,8 +837,8 @@ static void idetape_abort_pipeline(ide_drive_t *drive, | |||
975 | } | 837 | } |
976 | 838 | ||
977 | /* | 839 | /* |
978 | * idetape_end_request is used to finish servicing a request, and to | 840 | * Finish servicing a request and insert a pending pipeline request into the |
979 | * insert a pending pipeline request into the main device queue. | 841 | * main device queue. |
980 | */ | 842 | */ |
981 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | 843 | static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) |
982 | { | 844 | { |
@@ -987,15 +849,12 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | |||
987 | int remove_stage = 0; | 849 | int remove_stage = 0; |
988 | idetape_stage_t *active_stage; | 850 | idetape_stage_t *active_stage; |
989 | 851 | ||
990 | #if IDETAPE_DEBUG_LOG | 852 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
991 | if (tape->debug_level >= 4) | ||
992 | printk(KERN_INFO "ide-tape: Reached idetape_end_request\n"); | ||
993 | #endif /* IDETAPE_DEBUG_LOG */ | ||
994 | 853 | ||
995 | switch (uptodate) { | 854 | switch (uptodate) { |
996 | case 0: error = IDETAPE_ERROR_GENERAL; break; | 855 | case 0: error = IDETAPE_ERROR_GENERAL; break; |
997 | case 1: error = 0; break; | 856 | case 1: error = 0; break; |
998 | default: error = uptodate; | 857 | default: error = uptodate; |
999 | } | 858 | } |
1000 | rq->errors = error; | 859 | rq->errors = error; |
1001 | if (error) | 860 | if (error) |
@@ -1006,20 +865,21 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | |||
1006 | return 0; | 865 | return 0; |
1007 | } | 866 | } |
1008 | 867 | ||
1009 | spin_lock_irqsave(&tape->spinlock, flags); | 868 | spin_lock_irqsave(&tape->lock, flags); |
1010 | 869 | ||
1011 | /* The request was a pipelined data transfer request */ | 870 | /* The request was a pipelined data transfer request */ |
1012 | if (tape->active_data_request == rq) { | 871 | if (tape->active_data_rq == rq) { |
1013 | active_stage = tape->active_stage; | 872 | active_stage = tape->active_stage; |
1014 | tape->active_stage = NULL; | 873 | tape->active_stage = NULL; |
1015 | tape->active_data_request = NULL; | 874 | tape->active_data_rq = NULL; |
1016 | tape->nr_pending_stages--; | 875 | tape->nr_pending_stages--; |
1017 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { | 876 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { |
1018 | remove_stage = 1; | 877 | remove_stage = 1; |
1019 | if (error) { | 878 | if (error) { |
1020 | set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); | 879 | set_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); |
1021 | if (error == IDETAPE_ERROR_EOD) | 880 | if (error == IDETAPE_ERROR_EOD) |
1022 | idetape_abort_pipeline(drive, active_stage); | 881 | idetape_abort_pipeline(drive, |
882 | active_stage); | ||
1023 | } | 883 | } |
1024 | } else if (rq->cmd[0] & REQ_IDETAPE_READ) { | 884 | } else if (rq->cmd[0] & REQ_IDETAPE_READ) { |
1025 | if (error == IDETAPE_ERROR_EOD) { | 885 | if (error == IDETAPE_ERROR_EOD) { |
@@ -1030,48 +890,57 @@ static int idetape_end_request(ide_drive_t *drive, int uptodate, int nr_sects) | |||
1030 | if (tape->next_stage != NULL) { | 890 | if (tape->next_stage != NULL) { |
1031 | idetape_activate_next_stage(drive); | 891 | idetape_activate_next_stage(drive); |
1032 | 892 | ||
893 | /* Insert the next request into the request queue. */ | ||
894 | (void)ide_do_drive_cmd(drive, tape->active_data_rq, | ||
895 | ide_end); | ||
896 | } else if (!error) { | ||
1033 | /* | 897 | /* |
1034 | * Insert the next request into the request queue. | 898 | * This is a part of the feedback loop which tries to |
899 | * find the optimum number of stages. We are starting | ||
900 | * from a minimum maximum number of stages, and if we | ||
901 | * sense that the pipeline is empty, we try to increase | ||
902 | * it, until we reach the user compile time memory | ||
903 | * limit. | ||
1035 | */ | 904 | */ |
1036 | (void) ide_do_drive_cmd(drive, tape->active_data_request, ide_end); | 905 | int i = (tape->max_pipeline - tape->min_pipeline) / 10; |
1037 | } else if (!error) { | 906 | |
1038 | idetape_increase_max_pipeline_stages(drive); | 907 | tape->max_stages += max(i, 1); |
908 | tape->max_stages = max(tape->max_stages, | ||
909 | tape->min_pipeline); | ||
910 | tape->max_stages = min(tape->max_stages, | ||
911 | tape->max_pipeline); | ||
1039 | } | 912 | } |
1040 | } | 913 | } |
1041 | ide_end_drive_cmd(drive, 0, 0); | 914 | ide_end_drive_cmd(drive, 0, 0); |
1042 | // blkdev_dequeue_request(rq); | ||
1043 | // drive->rq = NULL; | ||
1044 | // end_that_request_last(rq); | ||
1045 | 915 | ||
1046 | if (remove_stage) | 916 | if (remove_stage) |
1047 | idetape_remove_stage_head(drive); | 917 | idetape_remove_stage_head(drive); |
1048 | if (tape->active_data_request == NULL) | 918 | if (tape->active_data_rq == NULL) |
1049 | clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); | 919 | clear_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); |
1050 | spin_unlock_irqrestore(&tape->spinlock, flags); | 920 | spin_unlock_irqrestore(&tape->lock, flags); |
1051 | return 0; | 921 | return 0; |
1052 | } | 922 | } |
1053 | 923 | ||
1054 | static ide_startstop_t idetape_request_sense_callback (ide_drive_t *drive) | 924 | static ide_startstop_t idetape_request_sense_callback(ide_drive_t *drive) |
1055 | { | 925 | { |
1056 | idetape_tape_t *tape = drive->driver_data; | 926 | idetape_tape_t *tape = drive->driver_data; |
1057 | 927 | ||
1058 | #if IDETAPE_DEBUG_LOG | 928 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
1059 | if (tape->debug_level >= 4) | 929 | |
1060 | printk(KERN_INFO "ide-tape: Reached idetape_request_sense_callback\n"); | ||
1061 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1062 | if (!tape->pc->error) { | 930 | if (!tape->pc->error) { |
1063 | idetape_analyze_error(drive, tape->pc->buffer); | 931 | idetape_analyze_error(drive, tape->pc->buffer); |
1064 | idetape_end_request(drive, 1, 0); | 932 | idetape_end_request(drive, 1, 0); |
1065 | } else { | 933 | } else { |
1066 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - Aborting request!\n"); | 934 | printk(KERN_ERR "ide-tape: Error in REQUEST SENSE itself - " |
935 | "Aborting request!\n"); | ||
1067 | idetape_end_request(drive, 0, 0); | 936 | idetape_end_request(drive, 0, 0); |
1068 | } | 937 | } |
1069 | return ide_stopped; | 938 | return ide_stopped; |
1070 | } | 939 | } |
1071 | 940 | ||
1072 | static void idetape_create_request_sense_cmd (idetape_pc_t *pc) | 941 | static void idetape_create_request_sense_cmd(idetape_pc_t *pc) |
1073 | { | 942 | { |
1074 | idetape_init_pc(pc); | 943 | idetape_init_pc(pc); |
1075 | pc->c[0] = REQUEST_SENSE; | 944 | pc->c[0] = REQUEST_SENSE; |
1076 | pc->c[4] = 20; | 945 | pc->c[4] = 20; |
1077 | pc->request_transfer = 20; | 946 | pc->request_transfer = 20; |
@@ -1086,25 +955,22 @@ static void idetape_init_rq(struct request *rq, u8 cmd) | |||
1086 | } | 955 | } |
1087 | 956 | ||
1088 | /* | 957 | /* |
1089 | * idetape_queue_pc_head generates a new packet command request in front | 958 | * Generate a new packet command request in front of the request queue, before |
1090 | * of the request queue, before the current request, so that it will be | 959 | * the current request, so that it will be processed immediately, on the next |
1091 | * processed immediately, on the next pass through the driver. | 960 | * pass through the driver. The function below is called from the request |
1092 | * | 961 | * handling part of the driver (the "bottom" part). Safe storage for the request |
1093 | * idetape_queue_pc_head is called from the request handling part of | 962 | * should be allocated with ide_tape_next_{pc,rq}_storage() prior to that. |
1094 | * the driver (the "bottom" part). Safe storage for the request should | ||
1095 | * be allocated with idetape_next_pc_storage and idetape_next_rq_storage | ||
1096 | * before calling idetape_queue_pc_head. | ||
1097 | * | 963 | * |
1098 | * Memory for those requests is pre-allocated at initialization time, and | 964 | * Memory for those requests is pre-allocated at initialization time, and is |
1099 | * is limited to IDETAPE_PC_STACK requests. We assume that we have enough | 965 | * limited to IDETAPE_PC_STACK requests. We assume that we have enough space for |
1100 | * space for the maximum possible number of inter-dependent packet commands. | 966 | * the maximum possible number of inter-dependent packet commands. |
1101 | * | 967 | * |
1102 | * The higher level of the driver - The ioctl handler and the character | 968 | * The higher level of the driver - The ioctl handler and the character device |
1103 | * device handling functions should queue request to the lower level part | 969 | * handling functions should queue request to the lower level part and wait for |
1104 | * and wait for their completion using idetape_queue_pc_tail or | 970 | * their completion using idetape_queue_pc_tail or idetape_queue_rw_tail. |
1105 | * idetape_queue_rw_tail. | ||
1106 | */ | 971 | */ |
1107 | static void idetape_queue_pc_head (ide_drive_t *drive, idetape_pc_t *pc,struct request *rq) | 972 | static void idetape_queue_pc_head(ide_drive_t *drive, idetape_pc_t *pc, |
973 | struct request *rq) | ||
1108 | { | 974 | { |
1109 | struct ide_tape_obj *tape = drive->driver_data; | 975 | struct ide_tape_obj *tape = drive->driver_data; |
1110 | 976 | ||
@@ -1125,7 +991,7 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) | |||
1125 | idetape_pc_t *pc; | 991 | idetape_pc_t *pc; |
1126 | struct request *rq; | 992 | struct request *rq; |
1127 | 993 | ||
1128 | (void)drive->hwif->INB(IDE_ERROR_REG); | 994 | (void)ide_read_error(drive); |
1129 | pc = idetape_next_pc_storage(drive); | 995 | pc = idetape_next_pc_storage(drive); |
1130 | rq = idetape_next_rq_storage(drive); | 996 | rq = idetape_next_rq_storage(drive); |
1131 | idetape_create_request_sense_cmd(pc); | 997 | idetape_create_request_sense_cmd(pc); |
@@ -1135,50 +1001,46 @@ static ide_startstop_t idetape_retry_pc (ide_drive_t *drive) | |||
1135 | } | 1001 | } |
1136 | 1002 | ||
1137 | /* | 1003 | /* |
1138 | * idetape_postpone_request postpones the current request so that | 1004 | * Postpone the current request so that ide.c will be able to service requests |
1139 | * ide.c will be able to service requests from another device on | 1005 | * from another device on the same hwgroup while we are polling for DSC. |
1140 | * the same hwgroup while we are polling for DSC. | ||
1141 | */ | 1006 | */ |
1142 | static void idetape_postpone_request (ide_drive_t *drive) | 1007 | static void idetape_postpone_request(ide_drive_t *drive) |
1143 | { | 1008 | { |
1144 | idetape_tape_t *tape = drive->driver_data; | 1009 | idetape_tape_t *tape = drive->driver_data; |
1145 | 1010 | ||
1146 | #if IDETAPE_DEBUG_LOG | 1011 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
1147 | if (tape->debug_level >= 4) | 1012 | |
1148 | printk(KERN_INFO "ide-tape: idetape_postpone_request\n"); | ||
1149 | #endif | ||
1150 | tape->postponed_rq = HWGROUP(drive)->rq; | 1013 | tape->postponed_rq = HWGROUP(drive)->rq; |
1151 | ide_stall_queue(drive, tape->dsc_polling_frequency); | 1014 | ide_stall_queue(drive, tape->dsc_poll_freq); |
1152 | } | 1015 | } |
1153 | 1016 | ||
1017 | typedef void idetape_io_buf(ide_drive_t *, idetape_pc_t *, unsigned int); | ||
1018 | |||
1154 | /* | 1019 | /* |
1155 | * idetape_pc_intr is the usual interrupt handler which will be called | 1020 | * This is the usual interrupt handler which will be called during a packet |
1156 | * during a packet command. We will transfer some of the data (as | 1021 | * command. We will transfer some of the data (as requested by the drive) and |
1157 | * requested by the drive) and will re-point interrupt handler to us. | 1022 | * will re-point interrupt handler to us. When data transfer is finished, we |
1158 | * When data transfer is finished, we will act according to the | 1023 | * will act according to the algorithm described before |
1159 | * algorithm described before idetape_issue_packet_command. | 1024 | * idetape_issue_pc. |
1160 | * | ||
1161 | */ | 1025 | */ |
1162 | static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | 1026 | static ide_startstop_t idetape_pc_intr(ide_drive_t *drive) |
1163 | { | 1027 | { |
1164 | ide_hwif_t *hwif = drive->hwif; | 1028 | ide_hwif_t *hwif = drive->hwif; |
1165 | idetape_tape_t *tape = drive->driver_data; | 1029 | idetape_tape_t *tape = drive->driver_data; |
1166 | idetape_pc_t *pc = tape->pc; | 1030 | idetape_pc_t *pc = tape->pc; |
1031 | xfer_func_t *xferfunc; | ||
1032 | idetape_io_buf *iobuf; | ||
1167 | unsigned int temp; | 1033 | unsigned int temp; |
1168 | #if SIMULATE_ERRORS | 1034 | #if SIMULATE_ERRORS |
1169 | static int error_sim_count = 0; | 1035 | static int error_sim_count; |
1170 | #endif | 1036 | #endif |
1171 | u16 bcount; | 1037 | u16 bcount; |
1172 | u8 stat, ireason; | 1038 | u8 stat, ireason; |
1173 | 1039 | ||
1174 | #if IDETAPE_DEBUG_LOG | 1040 | debug_log(DBG_PROCS, "Enter %s - interrupt handler\n", __func__); |
1175 | if (tape->debug_level >= 4) | ||
1176 | printk(KERN_INFO "ide-tape: Reached idetape_pc_intr " | ||
1177 | "interrupt handler\n"); | ||
1178 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1179 | 1041 | ||
1180 | /* Clear the interrupt */ | 1042 | /* Clear the interrupt */ |
1181 | stat = hwif->INB(IDE_STATUS_REG); | 1043 | stat = ide_read_status(drive); |
1182 | 1044 | ||
1183 | if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { | 1045 | if (test_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { |
1184 | if (hwif->ide_dma_end(drive) || (stat & ERR_STAT)) { | 1046 | if (hwif->ide_dma_end(drive) || (stat & ERR_STAT)) { |
@@ -1208,20 +1070,16 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1208 | pc->actually_transferred = pc->request_transfer; | 1070 | pc->actually_transferred = pc->request_transfer; |
1209 | idetape_update_buffers(pc); | 1071 | idetape_update_buffers(pc); |
1210 | } | 1072 | } |
1211 | #if IDETAPE_DEBUG_LOG | 1073 | debug_log(DBG_PROCS, "DMA finished\n"); |
1212 | if (tape->debug_level >= 4) | 1074 | |
1213 | printk(KERN_INFO "ide-tape: DMA finished\n"); | ||
1214 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1215 | } | 1075 | } |
1216 | 1076 | ||
1217 | /* No more interrupts */ | 1077 | /* No more interrupts */ |
1218 | if ((stat & DRQ_STAT) == 0) { | 1078 | if ((stat & DRQ_STAT) == 0) { |
1219 | #if IDETAPE_DEBUG_LOG | 1079 | debug_log(DBG_SENSE, "Packet command completed, %d bytes" |
1220 | if (tape->debug_level >= 2) | 1080 | " transferred\n", pc->actually_transferred); |
1221 | printk(KERN_INFO "ide-tape: Packet command completed, %d bytes transferred\n", pc->actually_transferred); | ||
1222 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1223 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); | ||
1224 | 1081 | ||
1082 | clear_bit(PC_DMA_IN_PROGRESS, &pc->flags); | ||
1225 | local_irq_enable(); | 1083 | local_irq_enable(); |
1226 | 1084 | ||
1227 | #if SIMULATE_ERRORS | 1085 | #if SIMULATE_ERRORS |
@@ -1236,19 +1094,16 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1236 | stat &= ~ERR_STAT; | 1094 | stat &= ~ERR_STAT; |
1237 | if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { | 1095 | if ((stat & ERR_STAT) || test_bit(PC_DMA_ERROR, &pc->flags)) { |
1238 | /* Error detected */ | 1096 | /* Error detected */ |
1239 | #if IDETAPE_DEBUG_LOG | 1097 | debug_log(DBG_ERR, "%s: I/O error\n", tape->name); |
1240 | if (tape->debug_level >= 1) | 1098 | |
1241 | printk(KERN_INFO "ide-tape: %s: I/O error\n", | ||
1242 | tape->name); | ||
1243 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1244 | if (pc->c[0] == REQUEST_SENSE) { | 1099 | if (pc->c[0] == REQUEST_SENSE) { |
1245 | printk(KERN_ERR "ide-tape: I/O error in request sense command\n"); | 1100 | printk(KERN_ERR "ide-tape: I/O error in request" |
1101 | " sense command\n"); | ||
1246 | return ide_do_reset(drive); | 1102 | return ide_do_reset(drive); |
1247 | } | 1103 | } |
1248 | #if IDETAPE_DEBUG_LOG | 1104 | debug_log(DBG_ERR, "[cmd %x]: check condition\n", |
1249 | if (tape->debug_level >= 1) | 1105 | pc->c[0]); |
1250 | printk(KERN_INFO "ide-tape: [cmd %x]: check condition\n", pc->c[0]); | 1106 | |
1251 | #endif | ||
1252 | /* Retry operation */ | 1107 | /* Retry operation */ |
1253 | return idetape_retry_pc(drive); | 1108 | return idetape_retry_pc(drive); |
1254 | } | 1109 | } |
@@ -1257,7 +1112,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1257 | (stat & SEEK_STAT) == 0) { | 1112 | (stat & SEEK_STAT) == 0) { |
1258 | /* Media access command */ | 1113 | /* Media access command */ |
1259 | tape->dsc_polling_start = jiffies; | 1114 | tape->dsc_polling_start = jiffies; |
1260 | tape->dsc_polling_frequency = IDETAPE_DSC_MA_FAST; | 1115 | tape->dsc_poll_freq = IDETAPE_DSC_MA_FAST; |
1261 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; | 1116 | tape->dsc_timeout = jiffies + IDETAPE_DSC_MA_TIMEOUT; |
1262 | /* Allow ide.c to handle other requests */ | 1117 | /* Allow ide.c to handle other requests */ |
1263 | idetape_postpone_request(drive); | 1118 | idetape_postpone_request(drive); |
@@ -1282,7 +1137,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1282 | ireason = hwif->INB(IDE_IREASON_REG); | 1137 | ireason = hwif->INB(IDE_IREASON_REG); |
1283 | 1138 | ||
1284 | if (ireason & CD) { | 1139 | if (ireason & CD) { |
1285 | printk(KERN_ERR "ide-tape: CoD != 0 in idetape_pc_intr\n"); | 1140 | printk(KERN_ERR "ide-tape: CoD != 0 in %s\n", __func__); |
1286 | return ide_do_reset(drive); | 1141 | return ide_do_reset(drive); |
1287 | } | 1142 | } |
1288 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { | 1143 | if (((ireason & IO) == IO) == test_bit(PC_WRITING, &pc->flags)) { |
@@ -1298,86 +1153,76 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive) | |||
1298 | temp = pc->actually_transferred + bcount; | 1153 | temp = pc->actually_transferred + bcount; |
1299 | if (temp > pc->request_transfer) { | 1154 | if (temp > pc->request_transfer) { |
1300 | if (temp > pc->buffer_size) { | 1155 | if (temp > pc->buffer_size) { |
1301 | printk(KERN_ERR "ide-tape: The tape wants to send us more data than expected - discarding data\n"); | 1156 | printk(KERN_ERR "ide-tape: The tape wants to " |
1157 | "send us more data than expected " | ||
1158 | "- discarding data\n"); | ||
1302 | idetape_discard_data(drive, bcount); | 1159 | idetape_discard_data(drive, bcount); |
1303 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 1160 | ide_set_handler(drive, &idetape_pc_intr, |
1161 | IDETAPE_WAIT_CMD, NULL); | ||
1304 | return ide_started; | 1162 | return ide_started; |
1305 | } | 1163 | } |
1306 | #if IDETAPE_DEBUG_LOG | 1164 | debug_log(DBG_SENSE, "The tape wants to send us more " |
1307 | if (tape->debug_level >= 2) | 1165 | "data than expected - allowing transfer\n"); |
1308 | printk(KERN_NOTICE "ide-tape: The tape wants to send us more data than expected - allowing transfer\n"); | ||
1309 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1310 | } | 1166 | } |
1311 | } | 1167 | iobuf = &idetape_input_buffers; |
1312 | if (test_bit(PC_WRITING, &pc->flags)) { | 1168 | xferfunc = hwif->atapi_input_bytes; |
1313 | if (pc->bh != NULL) | ||
1314 | idetape_output_buffers(drive, pc, bcount); | ||
1315 | else | ||
1316 | /* Write the current buffer */ | ||
1317 | hwif->atapi_output_bytes(drive, pc->current_position, | ||
1318 | bcount); | ||
1319 | } else { | 1169 | } else { |
1320 | if (pc->bh != NULL) | 1170 | iobuf = &idetape_output_buffers; |
1321 | idetape_input_buffers(drive, pc, bcount); | 1171 | xferfunc = hwif->atapi_output_bytes; |
1322 | else | ||
1323 | /* Read the current buffer */ | ||
1324 | hwif->atapi_input_bytes(drive, pc->current_position, | ||
1325 | bcount); | ||
1326 | } | 1172 | } |
1173 | |||
1174 | if (pc->bh) | ||
1175 | iobuf(drive, pc, bcount); | ||
1176 | else | ||
1177 | xferfunc(drive, pc->current_position, bcount); | ||
1178 | |||
1327 | /* Update the current position */ | 1179 | /* Update the current position */ |
1328 | pc->actually_transferred += bcount; | 1180 | pc->actually_transferred += bcount; |
1329 | pc->current_position += bcount; | 1181 | pc->current_position += bcount; |
1330 | #if IDETAPE_DEBUG_LOG | 1182 | |
1331 | if (tape->debug_level >= 2) | 1183 | debug_log(DBG_SENSE, "[cmd %x] transferred %d bytes on that intr.\n", |
1332 | printk(KERN_INFO "ide-tape: [cmd %x] transferred %d bytes " | 1184 | pc->c[0], bcount); |
1333 | "on that interrupt\n", pc->c[0], bcount); | 1185 | |
1334 | #endif | ||
1335 | /* And set the interrupt handler again */ | 1186 | /* And set the interrupt handler again */ |
1336 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); | 1187 | ide_set_handler(drive, &idetape_pc_intr, IDETAPE_WAIT_CMD, NULL); |
1337 | return ide_started; | 1188 | return ide_started; |
1338 | } | 1189 | } |
1339 | 1190 | ||
1340 | /* | 1191 | /* |
1341 | * Packet Command Interface | 1192 | * Packet Command Interface |
1342 | * | ||
1343 | * The current Packet Command is available in tape->pc, and will not | ||
1344 | * change until we finish handling it. Each packet command is associated | ||
1345 | * with a callback function that will be called when the command is | ||
1346 | * finished. | ||
1347 | * | 1193 | * |
1348 | * The handling will be done in three stages: | 1194 | * The current Packet Command is available in tape->pc, and will not change |
1195 | * until we finish handling it. Each packet command is associated with a | ||
1196 | * callback function that will be called when the command is finished. | ||
1349 | * | 1197 | * |
1350 | * 1. idetape_issue_packet_command will send the packet command to the | 1198 | * The handling will be done in three stages: |
1351 | * drive, and will set the interrupt handler to idetape_pc_intr. | ||
1352 | * | 1199 | * |
1353 | * 2. On each interrupt, idetape_pc_intr will be called. This step | 1200 | * 1. idetape_issue_pc will send the packet command to the drive, and will set |
1354 | * will be repeated until the device signals us that no more | 1201 | * the interrupt handler to idetape_pc_intr. |
1355 | * interrupts will be issued. | ||
1356 | * | 1202 | * |
1357 | * 3. ATAPI Tape media access commands have immediate status with a | 1203 | * 2. On each interrupt, idetape_pc_intr will be called. This step will be |
1358 | * delayed process. In case of a successful initiation of a | 1204 | * repeated until the device signals us that no more interrupts will be issued. |
1359 | * media access packet command, the DSC bit will be set when the | ||
1360 | * actual execution of the command is finished. | ||
1361 | * Since the tape drive will not issue an interrupt, we have to | ||
1362 | * poll for this event. In this case, we define the request as | ||
1363 | * "low priority request" by setting rq_status to | ||
1364 | * IDETAPE_RQ_POSTPONED, set a timer to poll for DSC and exit | ||
1365 | * the driver. | ||
1366 | * | 1205 | * |
1367 | * ide.c will then give higher priority to requests which | 1206 | * 3. ATAPI Tape media access commands have immediate status with a delayed |
1368 | * originate from the other device, until will change rq_status | 1207 | * process. In case of a successful initiation of a media access packet command, |
1369 | * to RQ_ACTIVE. | 1208 | * the DSC bit will be set when the actual execution of the command is finished. |
1209 | * Since the tape drive will not issue an interrupt, we have to poll for this | ||
1210 | * event. In this case, we define the request as "low priority request" by | ||
1211 | * setting rq_status to IDETAPE_RQ_POSTPONED, set a timer to poll for DSC and | ||
1212 | * exit the driver. | ||
1370 | * | 1213 | * |
1371 | * 4. When the packet command is finished, it will be checked for errors. | 1214 | * ide.c will then give higher priority to requests which originate from the |
1215 | * other device, until will change rq_status to RQ_ACTIVE. | ||
1372 | * | 1216 | * |
1373 | * 5. In case an error was found, we queue a request sense packet | 1217 | * 4. When the packet command is finished, it will be checked for errors. |
1374 | * command in front of the request queue and retry the operation | ||
1375 | * up to IDETAPE_MAX_PC_RETRIES times. | ||
1376 | * | 1218 | * |
1377 | * 6. In case no error was found, or we decided to give up and not | 1219 | * 5. In case an error was found, we queue a request sense packet command in |
1378 | * to retry again, the callback function will be called and then | 1220 | * front of the request queue and retry the operation up to |
1379 | * we will handle the next request. | 1221 | * IDETAPE_MAX_PC_RETRIES times. |
1380 | * | 1222 | * |
1223 | * 6. In case no error was found, or we decided to give up and not to retry | ||
1224 | * again, the callback function will be called and then we will handle the next | ||
1225 | * request. | ||
1381 | */ | 1226 | */ |
1382 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | 1227 | static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) |
1383 | { | 1228 | { |
@@ -1388,8 +1233,9 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | |||
1388 | ide_startstop_t startstop; | 1233 | ide_startstop_t startstop; |
1389 | u8 ireason; | 1234 | u8 ireason; |
1390 | 1235 | ||
1391 | if (ide_wait_stat(&startstop,drive,DRQ_STAT,BUSY_STAT,WAIT_READY)) { | 1236 | if (ide_wait_stat(&startstop, drive, DRQ_STAT, BUSY_STAT, WAIT_READY)) { |
1392 | printk(KERN_ERR "ide-tape: Strange, packet command initiated yet DRQ isn't asserted\n"); | 1237 | printk(KERN_ERR "ide-tape: Strange, packet command initiated " |
1238 | "yet DRQ isn't asserted\n"); | ||
1393 | return startstop; | 1239 | return startstop; |
1394 | } | 1240 | } |
1395 | ireason = hwif->INB(IDE_IREASON_REG); | 1241 | ireason = hwif->INB(IDE_IREASON_REG); |
@@ -1422,7 +1268,7 @@ static ide_startstop_t idetape_transfer_pc(ide_drive_t *drive) | |||
1422 | return ide_started; | 1268 | return ide_started; |
1423 | } | 1269 | } |
1424 | 1270 | ||
1425 | static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape_pc_t *pc) | 1271 | static ide_startstop_t idetape_issue_pc(ide_drive_t *drive, idetape_pc_t *pc) |
1426 | { | 1272 | { |
1427 | ide_hwif_t *hwif = drive->hwif; | 1273 | ide_hwif_t *hwif = drive->hwif; |
1428 | idetape_tape_t *tape = drive->driver_data; | 1274 | idetape_tape_t *tape = drive->driver_data; |
@@ -1443,9 +1289,9 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
1443 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || | 1289 | if (pc->retries > IDETAPE_MAX_PC_RETRIES || |
1444 | test_bit(PC_ABORT, &pc->flags)) { | 1290 | test_bit(PC_ABORT, &pc->flags)) { |
1445 | /* | 1291 | /* |
1446 | * We will "abort" retrying a packet command in case | 1292 | * We will "abort" retrying a packet command in case legitimate |
1447 | * a legitimate error code was received (crossing a | 1293 | * error code was received (crossing a filemark, or end of the |
1448 | * filemark, or end of the media, for example). | 1294 | * media, for example). |
1449 | */ | 1295 | */ |
1450 | if (!test_bit(PC_ABORT, &pc->flags)) { | 1296 | if (!test_bit(PC_ABORT, &pc->flags)) { |
1451 | if (!(pc->c[0] == TEST_UNIT_READY && | 1297 | if (!(pc->c[0] == TEST_UNIT_READY && |
@@ -1464,10 +1310,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
1464 | tape->failed_pc = NULL; | 1310 | tape->failed_pc = NULL; |
1465 | return pc->callback(drive); | 1311 | return pc->callback(drive); |
1466 | } | 1312 | } |
1467 | #if IDETAPE_DEBUG_LOG | 1313 | debug_log(DBG_SENSE, "Retry #%d, cmd = %02X\n", pc->retries, pc->c[0]); |
1468 | if (tape->debug_level >= 2) | ||
1469 | printk(KERN_INFO "ide-tape: Retry number - %d, cmd = %02X\n", pc->retries, pc->c[0]); | ||
1470 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1471 | 1314 | ||
1472 | pc->retries++; | 1315 | pc->retries++; |
1473 | /* We haven't transferred any data yet */ | 1316 | /* We haven't transferred any data yet */ |
@@ -1499,31 +1342,24 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape | |||
1499 | } | 1342 | } |
1500 | } | 1343 | } |
1501 | 1344 | ||
1502 | /* | 1345 | static ide_startstop_t idetape_pc_callback(ide_drive_t *drive) |
1503 | * General packet command callback function. | ||
1504 | */ | ||
1505 | static ide_startstop_t idetape_pc_callback (ide_drive_t *drive) | ||
1506 | { | 1346 | { |
1507 | idetape_tape_t *tape = drive->driver_data; | 1347 | idetape_tape_t *tape = drive->driver_data; |
1508 | 1348 | ||
1509 | #if IDETAPE_DEBUG_LOG | 1349 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
1510 | if (tape->debug_level >= 4) | ||
1511 | printk(KERN_INFO "ide-tape: Reached idetape_pc_callback\n"); | ||
1512 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1513 | 1350 | ||
1514 | idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); | 1351 | idetape_end_request(drive, tape->pc->error ? 0 : 1, 0); |
1515 | return ide_stopped; | 1352 | return ide_stopped; |
1516 | } | 1353 | } |
1517 | 1354 | ||
1518 | /* | 1355 | /* A mode sense command is used to "sense" tape parameters. */ |
1519 | * A mode sense command is used to "sense" tape parameters. | 1356 | static void idetape_create_mode_sense_cmd(idetape_pc_t *pc, u8 page_code) |
1520 | */ | ||
1521 | static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, u8 page_code) | ||
1522 | { | 1357 | { |
1523 | idetape_init_pc(pc); | 1358 | idetape_init_pc(pc); |
1524 | pc->c[0] = MODE_SENSE; | 1359 | pc->c[0] = MODE_SENSE; |
1525 | if (page_code != IDETAPE_BLOCK_DESCRIPTOR) | 1360 | if (page_code != IDETAPE_BLOCK_DESCRIPTOR) |
1526 | pc->c[1] = 8; /* DBD = 1 - Don't return block descriptors */ | 1361 | /* DBD = 1 - Don't return block descriptors */ |
1362 | pc->c[1] = 8; | ||
1527 | pc->c[2] = page_code; | 1363 | pc->c[2] = page_code; |
1528 | /* | 1364 | /* |
1529 | * Changed pc->c[3] to 0 (255 will at best return unused info). | 1365 | * Changed pc->c[3] to 0 (255 will at best return unused info). |
@@ -1533,7 +1369,8 @@ static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, u8 page_code) | |||
1533 | * and return an error when 255 is used. | 1369 | * and return an error when 255 is used. |
1534 | */ | 1370 | */ |
1535 | pc->c[3] = 0; | 1371 | pc->c[3] = 0; |
1536 | pc->c[4] = 255; /* (We will just discard data in that case) */ | 1372 | /* We will just discard data in that case */ |
1373 | pc->c[4] = 255; | ||
1537 | if (page_code == IDETAPE_BLOCK_DESCRIPTOR) | 1374 | if (page_code == IDETAPE_BLOCK_DESCRIPTOR) |
1538 | pc->request_transfer = 12; | 1375 | pc->request_transfer = 12; |
1539 | else if (page_code == IDETAPE_CAPABILITIES_PAGE) | 1376 | else if (page_code == IDETAPE_CAPABILITIES_PAGE) |
@@ -1543,62 +1380,77 @@ static void idetape_create_mode_sense_cmd (idetape_pc_t *pc, u8 page_code) | |||
1543 | pc->callback = &idetape_pc_callback; | 1380 | pc->callback = &idetape_pc_callback; |
1544 | } | 1381 | } |
1545 | 1382 | ||
1546 | static void calculate_speeds(ide_drive_t *drive) | 1383 | static void idetape_calculate_speeds(ide_drive_t *drive) |
1547 | { | 1384 | { |
1548 | idetape_tape_t *tape = drive->driver_data; | 1385 | idetape_tape_t *tape = drive->driver_data; |
1549 | int full = 125, empty = 75; | ||
1550 | 1386 | ||
1551 | if (time_after(jiffies, tape->controlled_pipeline_head_time + 120 * HZ)) { | 1387 | if (time_after(jiffies, |
1552 | tape->controlled_previous_pipeline_head = tape->controlled_last_pipeline_head; | 1388 | tape->controlled_pipeline_head_time + 120 * HZ)) { |
1553 | tape->controlled_previous_head_time = tape->controlled_pipeline_head_time; | 1389 | tape->controlled_previous_pipeline_head = |
1390 | tape->controlled_last_pipeline_head; | ||
1391 | tape->controlled_previous_head_time = | ||
1392 | tape->controlled_pipeline_head_time; | ||
1554 | tape->controlled_last_pipeline_head = tape->pipeline_head; | 1393 | tape->controlled_last_pipeline_head = tape->pipeline_head; |
1555 | tape->controlled_pipeline_head_time = jiffies; | 1394 | tape->controlled_pipeline_head_time = jiffies; |
1556 | } | 1395 | } |
1557 | if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ)) | 1396 | if (time_after(jiffies, tape->controlled_pipeline_head_time + 60 * HZ)) |
1558 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_last_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_pipeline_head_time); | 1397 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - |
1398 | tape->controlled_last_pipeline_head) * 32 * HZ / | ||
1399 | (jiffies - tape->controlled_pipeline_head_time); | ||
1559 | else if (time_after(jiffies, tape->controlled_previous_head_time)) | 1400 | else if (time_after(jiffies, tape->controlled_previous_head_time)) |
1560 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - tape->controlled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->controlled_previous_head_time); | 1401 | tape->controlled_pipeline_head_speed = (tape->pipeline_head - |
1402 | tape->controlled_previous_pipeline_head) * 32 * | ||
1403 | HZ / (jiffies - tape->controlled_previous_head_time); | ||
1561 | 1404 | ||
1562 | if (tape->nr_pending_stages < tape->max_stages /*- 1 */) { | 1405 | if (tape->nr_pending_stages < tape->max_stages/*- 1 */) { |
1563 | /* -1 for read mode error recovery */ | 1406 | /* -1 for read mode error recovery */ |
1564 | if (time_after(jiffies, tape->uncontrolled_previous_head_time + 10 * HZ)) { | 1407 | if (time_after(jiffies, tape->uncontrolled_previous_head_time + |
1408 | 10 * HZ)) { | ||
1565 | tape->uncontrolled_pipeline_head_time = jiffies; | 1409 | tape->uncontrolled_pipeline_head_time = jiffies; |
1566 | tape->uncontrolled_pipeline_head_speed = (tape->pipeline_head - tape->uncontrolled_previous_pipeline_head) * 32 * HZ / (jiffies - tape->uncontrolled_previous_head_time); | 1410 | tape->uncontrolled_pipeline_head_speed = |
1411 | (tape->pipeline_head - | ||
1412 | tape->uncontrolled_previous_pipeline_head) * | ||
1413 | 32 * HZ / (jiffies - | ||
1414 | tape->uncontrolled_previous_head_time); | ||
1567 | } | 1415 | } |
1568 | } else { | 1416 | } else { |
1569 | tape->uncontrolled_previous_head_time = jiffies; | 1417 | tape->uncontrolled_previous_head_time = jiffies; |
1570 | tape->uncontrolled_previous_pipeline_head = tape->pipeline_head; | 1418 | tape->uncontrolled_previous_pipeline_head = tape->pipeline_head; |
1571 | if (time_after(jiffies, tape->uncontrolled_pipeline_head_time + 30 * HZ)) { | 1419 | if (time_after(jiffies, tape->uncontrolled_pipeline_head_time + |
1420 | 30 * HZ)) | ||
1572 | tape->uncontrolled_pipeline_head_time = jiffies; | 1421 | tape->uncontrolled_pipeline_head_time = jiffies; |
1573 | } | 1422 | |
1574 | } | 1423 | } |
1575 | tape->pipeline_head_speed = max(tape->uncontrolled_pipeline_head_speed, tape->controlled_pipeline_head_speed); | 1424 | tape->pipeline_head_speed = max(tape->uncontrolled_pipeline_head_speed, |
1576 | if (tape->speed_control == 0) { | 1425 | tape->controlled_pipeline_head_speed); |
1577 | tape->max_insert_speed = 5000; | 1426 | |
1578 | } else if (tape->speed_control == 1) { | 1427 | if (tape->speed_control == 1) { |
1579 | if (tape->nr_pending_stages >= tape->max_stages / 2) | 1428 | if (tape->nr_pending_stages >= tape->max_stages / 2) |
1580 | tape->max_insert_speed = tape->pipeline_head_speed + | 1429 | tape->max_insert_speed = tape->pipeline_head_speed + |
1581 | (1100 - tape->pipeline_head_speed) * 2 * (tape->nr_pending_stages - tape->max_stages / 2) / tape->max_stages; | 1430 | (1100 - tape->pipeline_head_speed) * 2 * |
1431 | (tape->nr_pending_stages - tape->max_stages / 2) | ||
1432 | / tape->max_stages; | ||
1582 | else | 1433 | else |
1583 | tape->max_insert_speed = 500 + | 1434 | tape->max_insert_speed = 500 + |
1584 | (tape->pipeline_head_speed - 500) * 2 * tape->nr_pending_stages / tape->max_stages; | 1435 | (tape->pipeline_head_speed - 500) * 2 * |
1436 | tape->nr_pending_stages / tape->max_stages; | ||
1437 | |||
1585 | if (tape->nr_pending_stages >= tape->max_stages * 99 / 100) | 1438 | if (tape->nr_pending_stages >= tape->max_stages * 99 / 100) |
1586 | tape->max_insert_speed = 5000; | 1439 | tape->max_insert_speed = 5000; |
1587 | } else if (tape->speed_control == 2) { | ||
1588 | tape->max_insert_speed = tape->pipeline_head_speed * empty / 100 + | ||
1589 | (tape->pipeline_head_speed * full / 100 - tape->pipeline_head_speed * empty / 100) * tape->nr_pending_stages / tape->max_stages; | ||
1590 | } else | 1440 | } else |
1591 | tape->max_insert_speed = tape->speed_control; | 1441 | tape->max_insert_speed = tape->speed_control; |
1442 | |||
1592 | tape->max_insert_speed = max(tape->max_insert_speed, 500); | 1443 | tape->max_insert_speed = max(tape->max_insert_speed, 500); |
1593 | } | 1444 | } |
1594 | 1445 | ||
1595 | static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive) | 1446 | static ide_startstop_t idetape_media_access_finished(ide_drive_t *drive) |
1596 | { | 1447 | { |
1597 | idetape_tape_t *tape = drive->driver_data; | 1448 | idetape_tape_t *tape = drive->driver_data; |
1598 | idetape_pc_t *pc = tape->pc; | 1449 | idetape_pc_t *pc = tape->pc; |
1599 | u8 stat; | 1450 | u8 stat; |
1600 | 1451 | ||
1601 | stat = drive->hwif->INB(IDE_STATUS_REG); | 1452 | stat = ide_read_status(drive); |
1453 | |||
1602 | if (stat & SEEK_STAT) { | 1454 | if (stat & SEEK_STAT) { |
1603 | if (stat & ERR_STAT) { | 1455 | if (stat & ERR_STAT) { |
1604 | /* Error detected */ | 1456 | /* Error detected */ |
@@ -1618,14 +1470,14 @@ static ide_startstop_t idetape_media_access_finished (ide_drive_t *drive) | |||
1618 | return pc->callback(drive); | 1470 | return pc->callback(drive); |
1619 | } | 1471 | } |
1620 | 1472 | ||
1621 | static ide_startstop_t idetape_rw_callback (ide_drive_t *drive) | 1473 | static ide_startstop_t idetape_rw_callback(ide_drive_t *drive) |
1622 | { | 1474 | { |
1623 | idetape_tape_t *tape = drive->driver_data; | 1475 | idetape_tape_t *tape = drive->driver_data; |
1624 | struct request *rq = HWGROUP(drive)->rq; | 1476 | struct request *rq = HWGROUP(drive)->rq; |
1625 | int blocks = tape->pc->actually_transferred / tape->tape_block_size; | 1477 | int blocks = tape->pc->actually_transferred / tape->blk_size; |
1626 | 1478 | ||
1627 | tape->avg_size += blocks * tape->tape_block_size; | 1479 | tape->avg_size += blocks * tape->blk_size; |
1628 | tape->insert_size += blocks * tape->tape_block_size; | 1480 | tape->insert_size += blocks * tape->blk_size; |
1629 | if (tape->insert_size > 1024 * 1024) | 1481 | if (tape->insert_size > 1024 * 1024) |
1630 | tape->measure_insert_time = 1; | 1482 | tape->measure_insert_time = 1; |
1631 | if (tape->measure_insert_time) { | 1483 | if (tape->measure_insert_time) { |
@@ -1634,19 +1486,17 @@ static ide_startstop_t idetape_rw_callback (ide_drive_t *drive) | |||
1634 | tape->insert_size = 0; | 1486 | tape->insert_size = 0; |
1635 | } | 1487 | } |
1636 | if (time_after(jiffies, tape->insert_time)) | 1488 | if (time_after(jiffies, tape->insert_time)) |
1637 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | 1489 | tape->insert_speed = tape->insert_size / 1024 * HZ / |
1490 | (jiffies - tape->insert_time); | ||
1638 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { | 1491 | if (time_after_eq(jiffies, tape->avg_time + HZ)) { |
1639 | tape->avg_speed = tape->avg_size * HZ / (jiffies - tape->avg_time) / 1024; | 1492 | tape->avg_speed = tape->avg_size * HZ / |
1493 | (jiffies - tape->avg_time) / 1024; | ||
1640 | tape->avg_size = 0; | 1494 | tape->avg_size = 0; |
1641 | tape->avg_time = jiffies; | 1495 | tape->avg_time = jiffies; |
1642 | } | 1496 | } |
1497 | debug_log(DBG_PROCS, "Enter %s\n", __func__); | ||
1643 | 1498 | ||
1644 | #if IDETAPE_DEBUG_LOG | 1499 | tape->first_frame += blocks; |
1645 | if (tape->debug_level >= 4) | ||
1646 | printk(KERN_INFO "ide-tape: Reached idetape_rw_callback\n"); | ||
1647 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1648 | |||
1649 | tape->first_frame_position += blocks; | ||
1650 | rq->current_nr_sectors -= blocks; | 1500 | rq->current_nr_sectors -= blocks; |
1651 | 1501 | ||
1652 | if (!tape->pc->error) | 1502 | if (!tape->pc->error) |
@@ -1656,7 +1506,8 @@ static ide_startstop_t idetape_rw_callback (ide_drive_t *drive) | |||
1656 | return ide_stopped; | 1506 | return ide_stopped; |
1657 | } | 1507 | } |
1658 | 1508 | ||
1659 | static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) | 1509 | static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc, |
1510 | unsigned int length, struct idetape_bh *bh) | ||
1660 | { | 1511 | { |
1661 | idetape_init_pc(pc); | 1512 | idetape_init_pc(pc); |
1662 | pc->c[0] = READ_6; | 1513 | pc->c[0] = READ_6; |
@@ -1666,12 +1517,14 @@ static void idetape_create_read_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsi | |||
1666 | pc->bh = bh; | 1517 | pc->bh = bh; |
1667 | atomic_set(&bh->b_count, 0); | 1518 | atomic_set(&bh->b_count, 0); |
1668 | pc->buffer = NULL; | 1519 | pc->buffer = NULL; |
1669 | pc->request_transfer = pc->buffer_size = length * tape->tape_block_size; | 1520 | pc->buffer_size = length * tape->blk_size; |
1521 | pc->request_transfer = pc->buffer_size; | ||
1670 | if (pc->request_transfer == tape->stage_size) | 1522 | if (pc->request_transfer == tape->stage_size) |
1671 | set_bit(PC_DMA_RECOMMENDED, &pc->flags); | 1523 | set_bit(PC_DMA_RECOMMENDED, &pc->flags); |
1672 | } | 1524 | } |
1673 | 1525 | ||
1674 | static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) | 1526 | static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, |
1527 | idetape_pc_t *pc, struct idetape_bh *bh) | ||
1675 | { | 1528 | { |
1676 | int size = 32768; | 1529 | int size = 32768; |
1677 | struct idetape_bh *p = bh; | 1530 | struct idetape_bh *p = bh; |
@@ -1689,10 +1542,12 @@ static void idetape_create_read_buffer_cmd(idetape_tape_t *tape, idetape_pc_t *p | |||
1689 | atomic_set(&p->b_count, 0); | 1542 | atomic_set(&p->b_count, 0); |
1690 | p = p->b_reqnext; | 1543 | p = p->b_reqnext; |
1691 | } | 1544 | } |
1692 | pc->request_transfer = pc->buffer_size = size; | 1545 | pc->request_transfer = size; |
1546 | pc->buffer_size = size; | ||
1693 | } | 1547 | } |
1694 | 1548 | ||
1695 | static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc, unsigned int length, struct idetape_bh *bh) | 1549 | static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc, |
1550 | unsigned int length, struct idetape_bh *bh) | ||
1696 | { | 1551 | { |
1697 | idetape_init_pc(pc); | 1552 | idetape_init_pc(pc); |
1698 | pc->c[0] = WRITE_6; | 1553 | pc->c[0] = WRITE_6; |
@@ -1704,14 +1559,12 @@ static void idetape_create_write_cmd(idetape_tape_t *tape, idetape_pc_t *pc, uns | |||
1704 | pc->b_data = bh->b_data; | 1559 | pc->b_data = bh->b_data; |
1705 | pc->b_count = atomic_read(&bh->b_count); | 1560 | pc->b_count = atomic_read(&bh->b_count); |
1706 | pc->buffer = NULL; | 1561 | pc->buffer = NULL; |
1707 | pc->request_transfer = pc->buffer_size = length * tape->tape_block_size; | 1562 | pc->buffer_size = length * tape->blk_size; |
1563 | pc->request_transfer = pc->buffer_size; | ||
1708 | if (pc->request_transfer == tape->stage_size) | 1564 | if (pc->request_transfer == tape->stage_size) |
1709 | set_bit(PC_DMA_RECOMMENDED, &pc->flags); | 1565 | set_bit(PC_DMA_RECOMMENDED, &pc->flags); |
1710 | } | 1566 | } |
1711 | 1567 | ||
1712 | /* | ||
1713 | * idetape_do_request is our request handling function. | ||
1714 | */ | ||
1715 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, | 1568 | static ide_startstop_t idetape_do_request(ide_drive_t *drive, |
1716 | struct request *rq, sector_t block) | 1569 | struct request *rq, sector_t block) |
1717 | { | 1570 | { |
@@ -1720,30 +1573,22 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1720 | struct request *postponed_rq = tape->postponed_rq; | 1573 | struct request *postponed_rq = tape->postponed_rq; |
1721 | u8 stat; | 1574 | u8 stat; |
1722 | 1575 | ||
1723 | #if IDETAPE_DEBUG_LOG | 1576 | debug_log(DBG_SENSE, "sector: %ld, nr_sectors: %ld," |
1724 | if (tape->debug_level >= 2) | 1577 | " current_nr_sectors: %d\n", |
1725 | printk(KERN_INFO "ide-tape: sector: %ld, " | ||
1726 | "nr_sectors: %ld, current_nr_sectors: %d\n", | ||
1727 | rq->sector, rq->nr_sectors, rq->current_nr_sectors); | 1578 | rq->sector, rq->nr_sectors, rq->current_nr_sectors); |
1728 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1729 | 1579 | ||
1730 | if (!blk_special_request(rq)) { | 1580 | if (!blk_special_request(rq)) { |
1731 | /* | 1581 | /* We do not support buffer cache originated requests. */ |
1732 | * We do not support buffer cache originated requests. | ||
1733 | */ | ||
1734 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " | 1582 | printk(KERN_NOTICE "ide-tape: %s: Unsupported request in " |
1735 | "request queue (%d)\n", drive->name, rq->cmd_type); | 1583 | "request queue (%d)\n", drive->name, rq->cmd_type); |
1736 | ide_end_request(drive, 0, 0); | 1584 | ide_end_request(drive, 0, 0); |
1737 | return ide_stopped; | 1585 | return ide_stopped; |
1738 | } | 1586 | } |
1739 | 1587 | ||
1740 | /* | 1588 | /* Retry a failed packet command */ |
1741 | * Retry a failed packet command | 1589 | if (tape->failed_pc && tape->pc->c[0] == REQUEST_SENSE) |
1742 | */ | 1590 | return idetape_issue_pc(drive, tape->failed_pc); |
1743 | if (tape->failed_pc != NULL && | 1591 | |
1744 | tape->pc->c[0] == REQUEST_SENSE) { | ||
1745 | return idetape_issue_packet_command(drive, tape->failed_pc); | ||
1746 | } | ||
1747 | if (postponed_rq != NULL) | 1592 | if (postponed_rq != NULL) |
1748 | if (rq != postponed_rq) { | 1593 | if (rq != postponed_rq) { |
1749 | printk(KERN_ERR "ide-tape: ide-tape.c bug - " | 1594 | printk(KERN_ERR "ide-tape: ide-tape.c bug - " |
@@ -1758,7 +1603,7 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1758 | * If the tape is still busy, postpone our request and service | 1603 | * If the tape is still busy, postpone our request and service |
1759 | * the other device meanwhile. | 1604 | * the other device meanwhile. |
1760 | */ | 1605 | */ |
1761 | stat = drive->hwif->INB(IDE_STATUS_REG); | 1606 | stat = ide_read_status(drive); |
1762 | 1607 | ||
1763 | if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2)) | 1608 | if (!drive->dsc_overlap && !(rq->cmd[0] & REQ_IDETAPE_PC2)) |
1764 | set_bit(IDETAPE_IGNORE_DSC, &tape->flags); | 1609 | set_bit(IDETAPE_IGNORE_DSC, &tape->flags); |
@@ -1768,16 +1613,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1768 | drive->post_reset = 0; | 1613 | drive->post_reset = 0; |
1769 | } | 1614 | } |
1770 | 1615 | ||
1771 | if (tape->tape_still_time > 100 && tape->tape_still_time < 200) | ||
1772 | tape->measure_insert_time = 1; | ||
1773 | if (time_after(jiffies, tape->insert_time)) | 1616 | if (time_after(jiffies, tape->insert_time)) |
1774 | tape->insert_speed = tape->insert_size / 1024 * HZ / (jiffies - tape->insert_time); | 1617 | tape->insert_speed = tape->insert_size / 1024 * HZ / |
1775 | calculate_speeds(drive); | 1618 | (jiffies - tape->insert_time); |
1619 | idetape_calculate_speeds(drive); | ||
1776 | if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && | 1620 | if (!test_and_clear_bit(IDETAPE_IGNORE_DSC, &tape->flags) && |
1777 | (stat & SEEK_STAT) == 0) { | 1621 | (stat & SEEK_STAT) == 0) { |
1778 | if (postponed_rq == NULL) { | 1622 | if (postponed_rq == NULL) { |
1779 | tape->dsc_polling_start = jiffies; | 1623 | tape->dsc_polling_start = jiffies; |
1780 | tape->dsc_polling_frequency = tape->best_dsc_rw_frequency; | 1624 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; |
1781 | tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; | 1625 | tape->dsc_timeout = jiffies + IDETAPE_DSC_RW_TIMEOUT; |
1782 | } else if (time_after(jiffies, tape->dsc_timeout)) { | 1626 | } else if (time_after(jiffies, tape->dsc_timeout)) { |
1783 | printk(KERN_ERR "ide-tape: %s: DSC timeout\n", | 1627 | printk(KERN_ERR "ide-tape: %s: DSC timeout\n", |
@@ -1788,8 +1632,10 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1788 | } else { | 1632 | } else { |
1789 | return ide_do_reset(drive); | 1633 | return ide_do_reset(drive); |
1790 | } | 1634 | } |
1791 | } else if (time_after(jiffies, tape->dsc_polling_start + IDETAPE_DSC_MA_THRESHOLD)) | 1635 | } else if (time_after(jiffies, |
1792 | tape->dsc_polling_frequency = IDETAPE_DSC_MA_SLOW; | 1636 | tape->dsc_polling_start + |
1637 | IDETAPE_DSC_MA_THRESHOLD)) | ||
1638 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; | ||
1793 | idetape_postpone_request(drive); | 1639 | idetape_postpone_request(drive); |
1794 | return ide_stopped; | 1640 | return ide_stopped; |
1795 | } | 1641 | } |
@@ -1797,20 +1643,23 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1797 | tape->buffer_head++; | 1643 | tape->buffer_head++; |
1798 | tape->postpone_cnt = 0; | 1644 | tape->postpone_cnt = 0; |
1799 | pc = idetape_next_pc_storage(drive); | 1645 | pc = idetape_next_pc_storage(drive); |
1800 | idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); | 1646 | idetape_create_read_cmd(tape, pc, rq->current_nr_sectors, |
1647 | (struct idetape_bh *)rq->special); | ||
1801 | goto out; | 1648 | goto out; |
1802 | } | 1649 | } |
1803 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { | 1650 | if (rq->cmd[0] & REQ_IDETAPE_WRITE) { |
1804 | tape->buffer_head++; | 1651 | tape->buffer_head++; |
1805 | tape->postpone_cnt = 0; | 1652 | tape->postpone_cnt = 0; |
1806 | pc = idetape_next_pc_storage(drive); | 1653 | pc = idetape_next_pc_storage(drive); |
1807 | idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); | 1654 | idetape_create_write_cmd(tape, pc, rq->current_nr_sectors, |
1655 | (struct idetape_bh *)rq->special); | ||
1808 | goto out; | 1656 | goto out; |
1809 | } | 1657 | } |
1810 | if (rq->cmd[0] & REQ_IDETAPE_READ_BUFFER) { | 1658 | if (rq->cmd[0] & REQ_IDETAPE_READ_BUFFER) { |
1811 | tape->postpone_cnt = 0; | 1659 | tape->postpone_cnt = 0; |
1812 | pc = idetape_next_pc_storage(drive); | 1660 | pc = idetape_next_pc_storage(drive); |
1813 | idetape_create_read_buffer_cmd(tape, pc, rq->current_nr_sectors, (struct idetape_bh *)rq->special); | 1661 | idetape_create_read_buffer_cmd(tape, pc, |
1662 | (struct idetape_bh *)rq->special); | ||
1814 | goto out; | 1663 | goto out; |
1815 | } | 1664 | } |
1816 | if (rq->cmd[0] & REQ_IDETAPE_PC1) { | 1665 | if (rq->cmd[0] & REQ_IDETAPE_PC1) { |
@@ -1825,49 +1674,51 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
1825 | } | 1674 | } |
1826 | BUG(); | 1675 | BUG(); |
1827 | out: | 1676 | out: |
1828 | return idetape_issue_packet_command(drive, pc); | 1677 | return idetape_issue_pc(drive, pc); |
1829 | } | 1678 | } |
1830 | 1679 | ||
1831 | /* | 1680 | /* Pipeline related functions */ |
1832 | * Pipeline related functions | 1681 | static inline int idetape_pipeline_active(idetape_tape_t *tape) |
1833 | */ | ||
1834 | static inline int idetape_pipeline_active (idetape_tape_t *tape) | ||
1835 | { | 1682 | { |
1836 | int rc1, rc2; | 1683 | int rc1, rc2; |
1837 | 1684 | ||
1838 | rc1 = test_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); | 1685 | rc1 = test_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); |
1839 | rc2 = (tape->active_data_request != NULL); | 1686 | rc2 = (tape->active_data_rq != NULL); |
1840 | return rc1; | 1687 | return rc1; |
1841 | } | 1688 | } |
1842 | 1689 | ||
1843 | /* | 1690 | /* |
1844 | * idetape_kmalloc_stage uses __get_free_page to allocate a pipeline | 1691 | * The function below uses __get_free_page to allocate a pipeline stage, along |
1845 | * stage, along with all the necessary small buffers which together make | 1692 | * with all the necessary small buffers which together make a buffer of size |
1846 | * a buffer of size tape->stage_size (or a bit more). We attempt to | 1693 | * tape->stage_size (or a bit more). We attempt to combine sequential pages as |
1847 | * combine sequential pages as much as possible. | 1694 | * much as possible. |
1848 | * | 1695 | * |
1849 | * Returns a pointer to the new allocated stage, or NULL if we | 1696 | * It returns a pointer to the new allocated stage, or NULL if we can't (or |
1850 | * can't (or don't want to) allocate a stage. | 1697 | * don't want to) allocate a stage. |
1851 | * | 1698 | * |
1852 | * Pipeline stages are optional and are used to increase performance. | 1699 | * Pipeline stages are optional and are used to increase performance. If we |
1853 | * If we can't allocate them, we'll manage without them. | 1700 | * can't allocate them, we'll manage without them. |
1854 | */ | 1701 | */ |
1855 | static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, int clear) | 1702 | static idetape_stage_t *__idetape_kmalloc_stage(idetape_tape_t *tape, int full, |
1703 | int clear) | ||
1856 | { | 1704 | { |
1857 | idetape_stage_t *stage; | 1705 | idetape_stage_t *stage; |
1858 | struct idetape_bh *prev_bh, *bh; | 1706 | struct idetape_bh *prev_bh, *bh; |
1859 | int pages = tape->pages_per_stage; | 1707 | int pages = tape->pages_per_stage; |
1860 | char *b_data = NULL; | 1708 | char *b_data = NULL; |
1861 | 1709 | ||
1862 | if ((stage = kmalloc(sizeof (idetape_stage_t),GFP_KERNEL)) == NULL) | 1710 | stage = kmalloc(sizeof(idetape_stage_t), GFP_KERNEL); |
1711 | if (!stage) | ||
1863 | return NULL; | 1712 | return NULL; |
1864 | stage->next = NULL; | 1713 | stage->next = NULL; |
1865 | 1714 | ||
1866 | bh = stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); | 1715 | stage->bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); |
1716 | bh = stage->bh; | ||
1867 | if (bh == NULL) | 1717 | if (bh == NULL) |
1868 | goto abort; | 1718 | goto abort; |
1869 | bh->b_reqnext = NULL; | 1719 | bh->b_reqnext = NULL; |
1870 | if ((bh->b_data = (char *) __get_free_page (GFP_KERNEL)) == NULL) | 1720 | bh->b_data = (char *) __get_free_page(GFP_KERNEL); |
1721 | if (!bh->b_data) | ||
1871 | goto abort; | 1722 | goto abort; |
1872 | if (clear) | 1723 | if (clear) |
1873 | memset(bh->b_data, 0, PAGE_SIZE); | 1724 | memset(bh->b_data, 0, PAGE_SIZE); |
@@ -1875,7 +1726,8 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, | |||
1875 | atomic_set(&bh->b_count, full ? bh->b_size : 0); | 1726 | atomic_set(&bh->b_count, full ? bh->b_size : 0); |
1876 | 1727 | ||
1877 | while (--pages) { | 1728 | while (--pages) { |
1878 | if ((b_data = (char *) __get_free_page (GFP_KERNEL)) == NULL) | 1729 | b_data = (char *) __get_free_page(GFP_KERNEL); |
1730 | if (!b_data) | ||
1879 | goto abort; | 1731 | goto abort; |
1880 | if (clear) | 1732 | if (clear) |
1881 | memset(b_data, 0, PAGE_SIZE); | 1733 | memset(b_data, 0, PAGE_SIZE); |
@@ -1893,7 +1745,8 @@ static idetape_stage_t *__idetape_kmalloc_stage (idetape_tape_t *tape, int full, | |||
1893 | continue; | 1745 | continue; |
1894 | } | 1746 | } |
1895 | prev_bh = bh; | 1747 | prev_bh = bh; |
1896 | if ((bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL)) == NULL) { | 1748 | bh = kmalloc(sizeof(struct idetape_bh), GFP_KERNEL); |
1749 | if (!bh) { | ||
1897 | free_page((unsigned long) b_data); | 1750 | free_page((unsigned long) b_data); |
1898 | goto abort; | 1751 | goto abort; |
1899 | } | 1752 | } |
@@ -1912,14 +1765,11 @@ abort: | |||
1912 | return NULL; | 1765 | return NULL; |
1913 | } | 1766 | } |
1914 | 1767 | ||
1915 | static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape) | 1768 | static idetape_stage_t *idetape_kmalloc_stage(idetape_tape_t *tape) |
1916 | { | 1769 | { |
1917 | idetape_stage_t *cache_stage = tape->cache_stage; | 1770 | idetape_stage_t *cache_stage = tape->cache_stage; |
1918 | 1771 | ||
1919 | #if IDETAPE_DEBUG_LOG | 1772 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
1920 | if (tape->debug_level >= 4) | ||
1921 | printk(KERN_INFO "ide-tape: Reached idetape_kmalloc_stage\n"); | ||
1922 | #endif /* IDETAPE_DEBUG_LOG */ | ||
1923 | 1773 | ||
1924 | if (tape->nr_stages >= tape->max_stages) | 1774 | if (tape->nr_stages >= tape->max_stages) |
1925 | return NULL; | 1775 | return NULL; |
@@ -1930,7 +1780,8 @@ static idetape_stage_t *idetape_kmalloc_stage (idetape_tape_t *tape) | |||
1930 | return __idetape_kmalloc_stage(tape, 0, 0); | 1780 | return __idetape_kmalloc_stage(tape, 0, 0); |
1931 | } | 1781 | } |
1932 | 1782 | ||
1933 | static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t *stage, const char __user *buf, int n) | 1783 | static int idetape_copy_stage_from_user(idetape_tape_t *tape, |
1784 | idetape_stage_t *stage, const char __user *buf, int n) | ||
1934 | { | 1785 | { |
1935 | struct idetape_bh *bh = tape->bh; | 1786 | struct idetape_bh *bh = tape->bh; |
1936 | int count; | 1787 | int count; |
@@ -1938,12 +1789,15 @@ static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t * | |||
1938 | 1789 | ||
1939 | while (n) { | 1790 | while (n) { |
1940 | if (bh == NULL) { | 1791 | if (bh == NULL) { |
1941 | printk(KERN_ERR "ide-tape: bh == NULL in " | 1792 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", |
1942 | "idetape_copy_stage_from_user\n"); | 1793 | __func__); |
1943 | return 1; | 1794 | return 1; |
1944 | } | 1795 | } |
1945 | count = min((unsigned int)(bh->b_size - atomic_read(&bh->b_count)), (unsigned int)n); | 1796 | count = min((unsigned int) |
1946 | if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, count)) | 1797 | (bh->b_size - atomic_read(&bh->b_count)), |
1798 | (unsigned int)n); | ||
1799 | if (copy_from_user(bh->b_data + atomic_read(&bh->b_count), buf, | ||
1800 | count)) | ||
1947 | ret = 1; | 1801 | ret = 1; |
1948 | n -= count; | 1802 | n -= count; |
1949 | atomic_add(count, &bh->b_count); | 1803 | atomic_add(count, &bh->b_count); |
@@ -1958,7 +1812,8 @@ static int idetape_copy_stage_from_user (idetape_tape_t *tape, idetape_stage_t * | |||
1958 | return ret; | 1812 | return ret; |
1959 | } | 1813 | } |
1960 | 1814 | ||
1961 | static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, idetape_stage_t *stage, int n) | 1815 | static int idetape_copy_stage_to_user(idetape_tape_t *tape, char __user *buf, |
1816 | idetape_stage_t *stage, int n) | ||
1962 | { | 1817 | { |
1963 | struct idetape_bh *bh = tape->bh; | 1818 | struct idetape_bh *bh = tape->bh; |
1964 | int count; | 1819 | int count; |
@@ -1966,8 +1821,8 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i | |||
1966 | 1821 | ||
1967 | while (n) { | 1822 | while (n) { |
1968 | if (bh == NULL) { | 1823 | if (bh == NULL) { |
1969 | printk(KERN_ERR "ide-tape: bh == NULL in " | 1824 | printk(KERN_ERR "ide-tape: bh == NULL in %s\n", |
1970 | "idetape_copy_stage_to_user\n"); | 1825 | __func__); |
1971 | return 1; | 1826 | return 1; |
1972 | } | 1827 | } |
1973 | count = min(tape->b_count, n); | 1828 | count = min(tape->b_count, n); |
@@ -1978,7 +1833,8 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i | |||
1978 | tape->b_count -= count; | 1833 | tape->b_count -= count; |
1979 | buf += count; | 1834 | buf += count; |
1980 | if (!tape->b_count) { | 1835 | if (!tape->b_count) { |
1981 | tape->bh = bh = bh->b_reqnext; | 1836 | bh = bh->b_reqnext; |
1837 | tape->bh = bh; | ||
1982 | if (bh) { | 1838 | if (bh) { |
1983 | tape->b_data = bh->b_data; | 1839 | tape->b_data = bh->b_data; |
1984 | tape->b_count = atomic_read(&bh->b_count); | 1840 | tape->b_count = atomic_read(&bh->b_count); |
@@ -1988,12 +1844,12 @@ static int idetape_copy_stage_to_user (idetape_tape_t *tape, char __user *buf, i | |||
1988 | return ret; | 1844 | return ret; |
1989 | } | 1845 | } |
1990 | 1846 | ||
1991 | static void idetape_init_merge_stage (idetape_tape_t *tape) | 1847 | static void idetape_init_merge_stage(idetape_tape_t *tape) |
1992 | { | 1848 | { |
1993 | struct idetape_bh *bh = tape->merge_stage->bh; | 1849 | struct idetape_bh *bh = tape->merge_stage->bh; |
1994 | 1850 | ||
1995 | tape->bh = bh; | 1851 | tape->bh = bh; |
1996 | if (tape->chrdev_direction == idetape_direction_write) | 1852 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) |
1997 | atomic_set(&bh->b_count, 0); | 1853 | atomic_set(&bh->b_count, 0); |
1998 | else { | 1854 | else { |
1999 | tape->b_data = bh->b_data; | 1855 | tape->b_data = bh->b_data; |
@@ -2001,7 +1857,7 @@ static void idetape_init_merge_stage (idetape_tape_t *tape) | |||
2001 | } | 1857 | } |
2002 | } | 1858 | } |
2003 | 1859 | ||
2004 | static void idetape_switch_buffers (idetape_tape_t *tape, idetape_stage_t *stage) | 1860 | static void idetape_switch_buffers(idetape_tape_t *tape, idetape_stage_t *stage) |
2005 | { | 1861 | { |
2006 | struct idetape_bh *tmp; | 1862 | struct idetape_bh *tmp; |
2007 | 1863 | ||
@@ -2011,87 +1867,76 @@ static void idetape_switch_buffers (idetape_tape_t *tape, idetape_stage_t *stage | |||
2011 | idetape_init_merge_stage(tape); | 1867 | idetape_init_merge_stage(tape); |
2012 | } | 1868 | } |
2013 | 1869 | ||
2014 | /* | 1870 | /* Add a new stage at the end of the pipeline. */ |
2015 | * idetape_add_stage_tail adds a new stage at the end of the pipeline. | 1871 | static void idetape_add_stage_tail(ide_drive_t *drive, idetape_stage_t *stage) |
2016 | */ | ||
2017 | static void idetape_add_stage_tail (ide_drive_t *drive,idetape_stage_t *stage) | ||
2018 | { | 1872 | { |
2019 | idetape_tape_t *tape = drive->driver_data; | 1873 | idetape_tape_t *tape = drive->driver_data; |
2020 | unsigned long flags; | 1874 | unsigned long flags; |
2021 | 1875 | ||
2022 | #if IDETAPE_DEBUG_LOG | 1876 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
2023 | if (tape->debug_level >= 4) | 1877 | |
2024 | printk (KERN_INFO "ide-tape: Reached idetape_add_stage_tail\n"); | 1878 | spin_lock_irqsave(&tape->lock, flags); |
2025 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2026 | spin_lock_irqsave(&tape->spinlock, flags); | ||
2027 | stage->next = NULL; | 1879 | stage->next = NULL; |
2028 | if (tape->last_stage != NULL) | 1880 | if (tape->last_stage != NULL) |
2029 | tape->last_stage->next=stage; | 1881 | tape->last_stage->next = stage; |
2030 | else | 1882 | else |
2031 | tape->first_stage = tape->next_stage=stage; | 1883 | tape->first_stage = stage; |
1884 | tape->next_stage = stage; | ||
2032 | tape->last_stage = stage; | 1885 | tape->last_stage = stage; |
2033 | if (tape->next_stage == NULL) | 1886 | if (tape->next_stage == NULL) |
2034 | tape->next_stage = tape->last_stage; | 1887 | tape->next_stage = tape->last_stage; |
2035 | tape->nr_stages++; | 1888 | tape->nr_stages++; |
2036 | tape->nr_pending_stages++; | 1889 | tape->nr_pending_stages++; |
2037 | spin_unlock_irqrestore(&tape->spinlock, flags); | 1890 | spin_unlock_irqrestore(&tape->lock, flags); |
2038 | } | 1891 | } |
2039 | 1892 | ||
2040 | /* | 1893 | /* Install a completion in a pending request and sleep until it is serviced. The |
2041 | * idetape_wait_for_request installs a completion in a pending request | 1894 | * caller should ensure that the request will not be serviced before we install |
2042 | * and sleeps until it is serviced. | 1895 | * the completion (usually by disabling interrupts). |
2043 | * | ||
2044 | * The caller should ensure that the request will not be serviced | ||
2045 | * before we install the completion (usually by disabling interrupts). | ||
2046 | */ | 1896 | */ |
2047 | static void idetape_wait_for_request (ide_drive_t *drive, struct request *rq) | 1897 | static void idetape_wait_for_request(ide_drive_t *drive, struct request *rq) |
2048 | { | 1898 | { |
2049 | DECLARE_COMPLETION_ONSTACK(wait); | 1899 | DECLARE_COMPLETION_ONSTACK(wait); |
2050 | idetape_tape_t *tape = drive->driver_data; | 1900 | idetape_tape_t *tape = drive->driver_data; |
2051 | 1901 | ||
2052 | if (rq == NULL || !blk_special_request(rq)) { | 1902 | if (rq == NULL || !blk_special_request(rq)) { |
2053 | printk (KERN_ERR "ide-tape: bug: Trying to sleep on non-valid request\n"); | 1903 | printk(KERN_ERR "ide-tape: bug: Trying to sleep on non-valid" |
1904 | " request\n"); | ||
2054 | return; | 1905 | return; |
2055 | } | 1906 | } |
2056 | rq->end_io_data = &wait; | 1907 | rq->end_io_data = &wait; |
2057 | rq->end_io = blk_end_sync_rq; | 1908 | rq->end_io = blk_end_sync_rq; |
2058 | spin_unlock_irq(&tape->spinlock); | 1909 | spin_unlock_irq(&tape->lock); |
2059 | wait_for_completion(&wait); | 1910 | wait_for_completion(&wait); |
2060 | /* The stage and its struct request have been deallocated */ | 1911 | /* The stage and its struct request have been deallocated */ |
2061 | spin_lock_irq(&tape->spinlock); | 1912 | spin_lock_irq(&tape->lock); |
2062 | } | 1913 | } |
2063 | 1914 | ||
2064 | static ide_startstop_t idetape_read_position_callback (ide_drive_t *drive) | 1915 | static ide_startstop_t idetape_read_position_callback(ide_drive_t *drive) |
2065 | { | 1916 | { |
2066 | idetape_tape_t *tape = drive->driver_data; | 1917 | idetape_tape_t *tape = drive->driver_data; |
2067 | idetape_read_position_result_t *result; | 1918 | u8 *readpos = tape->pc->buffer; |
2068 | 1919 | ||
2069 | #if IDETAPE_DEBUG_LOG | 1920 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
2070 | if (tape->debug_level >= 4) | ||
2071 | printk(KERN_INFO "ide-tape: Reached idetape_read_position_callback\n"); | ||
2072 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2073 | 1921 | ||
2074 | if (!tape->pc->error) { | 1922 | if (!tape->pc->error) { |
2075 | result = (idetape_read_position_result_t *) tape->pc->buffer; | 1923 | debug_log(DBG_SENSE, "BOP - %s\n", |
2076 | #if IDETAPE_DEBUG_LOG | 1924 | (readpos[0] & 0x80) ? "Yes" : "No"); |
2077 | if (tape->debug_level >= 2) | 1925 | debug_log(DBG_SENSE, "EOP - %s\n", |
2078 | printk(KERN_INFO "ide-tape: BOP - %s\n",result->bop ? "Yes":"No"); | 1926 | (readpos[0] & 0x40) ? "Yes" : "No"); |
2079 | if (tape->debug_level >= 2) | 1927 | |
2080 | printk(KERN_INFO "ide-tape: EOP - %s\n",result->eop ? "Yes":"No"); | 1928 | if (readpos[0] & 0x4) { |
2081 | #endif /* IDETAPE_DEBUG_LOG */ | 1929 | printk(KERN_INFO "ide-tape: Block location is unknown" |
2082 | if (result->bpu) { | 1930 | "to the tape\n"); |
2083 | printk(KERN_INFO "ide-tape: Block location is unknown to the tape\n"); | ||
2084 | clear_bit(IDETAPE_ADDRESS_VALID, &tape->flags); | 1931 | clear_bit(IDETAPE_ADDRESS_VALID, &tape->flags); |
2085 | idetape_end_request(drive, 0, 0); | 1932 | idetape_end_request(drive, 0, 0); |
2086 | } else { | 1933 | } else { |
2087 | #if IDETAPE_DEBUG_LOG | 1934 | debug_log(DBG_SENSE, "Block Location - %u\n", |
2088 | if (tape->debug_level >= 2) | 1935 | be32_to_cpu(*(u32 *)&readpos[4])); |
2089 | printk(KERN_INFO "ide-tape: Block Location - %u\n", ntohl(result->first_block)); | 1936 | |
2090 | #endif /* IDETAPE_DEBUG_LOG */ | 1937 | tape->partition = readpos[1]; |
2091 | tape->partition = result->partition; | 1938 | tape->first_frame = |
2092 | tape->first_frame_position = ntohl(result->first_block); | 1939 | be32_to_cpu(*(u32 *)&readpos[4]); |
2093 | tape->last_frame_position = ntohl(result->last_block); | ||
2094 | tape->blocks_in_buffer = result->blocks_in_buffer[2]; | ||
2095 | set_bit(IDETAPE_ADDRESS_VALID, &tape->flags); | 1940 | set_bit(IDETAPE_ADDRESS_VALID, &tape->flags); |
2096 | idetape_end_request(drive, 1, 0); | 1941 | idetape_end_request(drive, 1, 0); |
2097 | } | 1942 | } |
@@ -2102,14 +1947,11 @@ static ide_startstop_t idetape_read_position_callback (ide_drive_t *drive) | |||
2102 | } | 1947 | } |
2103 | 1948 | ||
2104 | /* | 1949 | /* |
2105 | * idetape_create_write_filemark_cmd will: | 1950 | * Write a filemark if write_filemark=1. Flush the device buffers without |
2106 | * | 1951 | * writing a filemark otherwise. |
2107 | * 1. Write a filemark if write_filemark=1. | ||
2108 | * 2. Flush the device buffers without writing a filemark | ||
2109 | * if write_filemark=0. | ||
2110 | * | ||
2111 | */ | 1952 | */ |
2112 | static void idetape_create_write_filemark_cmd (ide_drive_t *drive, idetape_pc_t *pc,int write_filemark) | 1953 | static void idetape_create_write_filemark_cmd(ide_drive_t *drive, |
1954 | idetape_pc_t *pc, int write_filemark) | ||
2113 | { | 1955 | { |
2114 | idetape_init_pc(pc); | 1956 | idetape_init_pc(pc); |
2115 | pc->c[0] = WRITE_FILEMARKS; | 1957 | pc->c[0] = WRITE_FILEMARKS; |
@@ -2126,26 +1968,19 @@ static void idetape_create_test_unit_ready_cmd(idetape_pc_t *pc) | |||
2126 | } | 1968 | } |
2127 | 1969 | ||
2128 | /* | 1970 | /* |
2129 | * idetape_queue_pc_tail is based on the following functions: | 1971 | * We add a special packet command request to the tail of the request queue, and |
2130 | * | 1972 | * wait for it to be serviced. This is not to be called from within the request |
2131 | * ide_do_drive_cmd from ide.c | 1973 | * handling part of the driver! We allocate here data on the stack and it is |
2132 | * cdrom_queue_request and cdrom_queue_packet_command from ide-cd.c | 1974 | * valid until the request is finished. This is not the case for the bottom part |
1975 | * of the driver, where we are always leaving the functions to wait for an | ||
1976 | * interrupt or a timer event. | ||
2133 | * | 1977 | * |
2134 | * We add a special packet command request to the tail of the request | 1978 | * From the bottom part of the driver, we should allocate safe memory using |
2135 | * queue, and wait for it to be serviced. | 1979 | * idetape_next_pc_storage() and ide_tape_next_rq_storage(), and add the request |
2136 | * | 1980 | * to the request list without waiting for it to be serviced! In that case, we |
2137 | * This is not to be called from within the request handling part | 1981 | * usually use idetape_queue_pc_head(). |
2138 | * of the driver ! We allocate here data in the stack, and it is valid | ||
2139 | * until the request is finished. This is not the case for the bottom | ||
2140 | * part of the driver, where we are always leaving the functions to wait | ||
2141 | * for an interrupt or a timer event. | ||
2142 | * | ||
2143 | * From the bottom part of the driver, we should allocate safe memory | ||
2144 | * using idetape_next_pc_storage and idetape_next_rq_storage, and add | ||
2145 | * the request to the request list without waiting for it to be serviced ! | ||
2146 | * In that case, we usually use idetape_queue_pc_head. | ||
2147 | */ | 1982 | */ |
2148 | static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc) | 1983 | static int __idetape_queue_pc_tail(ide_drive_t *drive, idetape_pc_t *pc) |
2149 | { | 1984 | { |
2150 | struct ide_tape_obj *tape = drive->driver_data; | 1985 | struct ide_tape_obj *tape = drive->driver_data; |
2151 | struct request rq; | 1986 | struct request rq; |
@@ -2156,7 +1991,8 @@ static int __idetape_queue_pc_tail (ide_drive_t *drive, idetape_pc_t *pc) | |||
2156 | return ide_do_drive_cmd(drive, &rq, ide_wait); | 1991 | return ide_do_drive_cmd(drive, &rq, ide_wait); |
2157 | } | 1992 | } |
2158 | 1993 | ||
2159 | static void idetape_create_load_unload_cmd (ide_drive_t *drive, idetape_pc_t *pc,int cmd) | 1994 | static void idetape_create_load_unload_cmd(ide_drive_t *drive, idetape_pc_t *pc, |
1995 | int cmd) | ||
2160 | { | 1996 | { |
2161 | idetape_init_pc(pc); | 1997 | idetape_init_pc(pc); |
2162 | pc->c[0] = START_STOP; | 1998 | pc->c[0] = START_STOP; |
@@ -2171,9 +2007,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | |||
2171 | idetape_pc_t pc; | 2007 | idetape_pc_t pc; |
2172 | int load_attempted = 0; | 2008 | int load_attempted = 0; |
2173 | 2009 | ||
2174 | /* | 2010 | /* Wait for the tape to become ready */ |
2175 | * Wait for the tape to become ready | ||
2176 | */ | ||
2177 | set_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); | 2011 | set_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); |
2178 | timeout += jiffies; | 2012 | timeout += jiffies; |
2179 | while (time_before(jiffies, timeout)) { | 2013 | while (time_before(jiffies, timeout)) { |
@@ -2181,10 +2015,12 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | |||
2181 | if (!__idetape_queue_pc_tail(drive, &pc)) | 2015 | if (!__idetape_queue_pc_tail(drive, &pc)) |
2182 | return 0; | 2016 | return 0; |
2183 | if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) | 2017 | if ((tape->sense_key == 2 && tape->asc == 4 && tape->ascq == 2) |
2184 | || (tape->asc == 0x3A)) { /* no media */ | 2018 | || (tape->asc == 0x3A)) { |
2019 | /* no media */ | ||
2185 | if (load_attempted) | 2020 | if (load_attempted) |
2186 | return -ENOMEDIUM; | 2021 | return -ENOMEDIUM; |
2187 | idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK); | 2022 | idetape_create_load_unload_cmd(drive, &pc, |
2023 | IDETAPE_LU_LOAD_MASK); | ||
2188 | __idetape_queue_pc_tail(drive, &pc); | 2024 | __idetape_queue_pc_tail(drive, &pc); |
2189 | load_attempted = 1; | 2025 | load_attempted = 1; |
2190 | /* not about to be ready */ | 2026 | /* not about to be ready */ |
@@ -2196,24 +2032,25 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | |||
2196 | return -EIO; | 2032 | return -EIO; |
2197 | } | 2033 | } |
2198 | 2034 | ||
2199 | static int idetape_queue_pc_tail (ide_drive_t *drive,idetape_pc_t *pc) | 2035 | static int idetape_queue_pc_tail(ide_drive_t *drive, idetape_pc_t *pc) |
2200 | { | 2036 | { |
2201 | return __idetape_queue_pc_tail(drive, pc); | 2037 | return __idetape_queue_pc_tail(drive, pc); |
2202 | } | 2038 | } |
2203 | 2039 | ||
2204 | static int idetape_flush_tape_buffers (ide_drive_t *drive) | 2040 | static int idetape_flush_tape_buffers(ide_drive_t *drive) |
2205 | { | 2041 | { |
2206 | idetape_pc_t pc; | 2042 | idetape_pc_t pc; |
2207 | int rc; | 2043 | int rc; |
2208 | 2044 | ||
2209 | idetape_create_write_filemark_cmd(drive, &pc, 0); | 2045 | idetape_create_write_filemark_cmd(drive, &pc, 0); |
2210 | if ((rc = idetape_queue_pc_tail(drive, &pc))) | 2046 | rc = idetape_queue_pc_tail(drive, &pc); |
2047 | if (rc) | ||
2211 | return rc; | 2048 | return rc; |
2212 | idetape_wait_ready(drive, 60 * 5 * HZ); | 2049 | idetape_wait_ready(drive, 60 * 5 * HZ); |
2213 | return 0; | 2050 | return 0; |
2214 | } | 2051 | } |
2215 | 2052 | ||
2216 | static void idetape_create_read_position_cmd (idetape_pc_t *pc) | 2053 | static void idetape_create_read_position_cmd(idetape_pc_t *pc) |
2217 | { | 2054 | { |
2218 | idetape_init_pc(pc); | 2055 | idetape_init_pc(pc); |
2219 | pc->c[0] = READ_POSITION; | 2056 | pc->c[0] = READ_POSITION; |
@@ -2221,25 +2058,23 @@ static void idetape_create_read_position_cmd (idetape_pc_t *pc) | |||
2221 | pc->callback = &idetape_read_position_callback; | 2058 | pc->callback = &idetape_read_position_callback; |
2222 | } | 2059 | } |
2223 | 2060 | ||
2224 | static int idetape_read_position (ide_drive_t *drive) | 2061 | static int idetape_read_position(ide_drive_t *drive) |
2225 | { | 2062 | { |
2226 | idetape_tape_t *tape = drive->driver_data; | 2063 | idetape_tape_t *tape = drive->driver_data; |
2227 | idetape_pc_t pc; | 2064 | idetape_pc_t pc; |
2228 | int position; | 2065 | int position; |
2229 | 2066 | ||
2230 | #if IDETAPE_DEBUG_LOG | 2067 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
2231 | if (tape->debug_level >= 4) | ||
2232 | printk(KERN_INFO "ide-tape: Reached idetape_read_position\n"); | ||
2233 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2234 | 2068 | ||
2235 | idetape_create_read_position_cmd(&pc); | 2069 | idetape_create_read_position_cmd(&pc); |
2236 | if (idetape_queue_pc_tail(drive, &pc)) | 2070 | if (idetape_queue_pc_tail(drive, &pc)) |
2237 | return -1; | 2071 | return -1; |
2238 | position = tape->first_frame_position; | 2072 | position = tape->first_frame; |
2239 | return position; | 2073 | return position; |
2240 | } | 2074 | } |
2241 | 2075 | ||
2242 | static void idetape_create_locate_cmd (ide_drive_t *drive, idetape_pc_t *pc, unsigned int block, u8 partition, int skip) | 2076 | static void idetape_create_locate_cmd(ide_drive_t *drive, idetape_pc_t *pc, |
2077 | unsigned int block, u8 partition, int skip) | ||
2243 | { | 2078 | { |
2244 | idetape_init_pc(pc); | 2079 | idetape_init_pc(pc); |
2245 | pc->c[0] = POSITION_TO_ELEMENT; | 2080 | pc->c[0] = POSITION_TO_ELEMENT; |
@@ -2250,7 +2085,8 @@ static void idetape_create_locate_cmd (ide_drive_t *drive, idetape_pc_t *pc, uns | |||
2250 | pc->callback = &idetape_pc_callback; | 2085 | pc->callback = &idetape_pc_callback; |
2251 | } | 2086 | } |
2252 | 2087 | ||
2253 | static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int prevent) | 2088 | static int idetape_create_prevent_cmd(ide_drive_t *drive, idetape_pc_t *pc, |
2089 | int prevent) | ||
2254 | { | 2090 | { |
2255 | idetape_tape_t *tape = drive->driver_data; | 2091 | idetape_tape_t *tape = drive->driver_data; |
2256 | 2092 | ||
@@ -2265,17 +2101,17 @@ static int idetape_create_prevent_cmd (ide_drive_t *drive, idetape_pc_t *pc, int | |||
2265 | return 1; | 2101 | return 1; |
2266 | } | 2102 | } |
2267 | 2103 | ||
2268 | static int __idetape_discard_read_pipeline (ide_drive_t *drive) | 2104 | static int __idetape_discard_read_pipeline(ide_drive_t *drive) |
2269 | { | 2105 | { |
2270 | idetape_tape_t *tape = drive->driver_data; | 2106 | idetape_tape_t *tape = drive->driver_data; |
2271 | unsigned long flags; | 2107 | unsigned long flags; |
2272 | int cnt; | 2108 | int cnt; |
2273 | 2109 | ||
2274 | if (tape->chrdev_direction != idetape_direction_read) | 2110 | if (tape->chrdev_dir != IDETAPE_DIR_READ) |
2275 | return 0; | 2111 | return 0; |
2276 | 2112 | ||
2277 | /* Remove merge stage. */ | 2113 | /* Remove merge stage. */ |
2278 | cnt = tape->merge_stage_size / tape->tape_block_size; | 2114 | cnt = tape->merge_stage_size / tape->blk_size; |
2279 | if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags)) | 2115 | if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags)) |
2280 | ++cnt; /* Filemarks count as 1 sector */ | 2116 | ++cnt; /* Filemarks count as 1 sector */ |
2281 | tape->merge_stage_size = 0; | 2117 | tape->merge_stage_size = 0; |
@@ -2286,22 +2122,22 @@ static int __idetape_discard_read_pipeline (ide_drive_t *drive) | |||
2286 | 2122 | ||
2287 | /* Clear pipeline flags. */ | 2123 | /* Clear pipeline flags. */ |
2288 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); | 2124 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); |
2289 | tape->chrdev_direction = idetape_direction_none; | 2125 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
2290 | 2126 | ||
2291 | /* Remove pipeline stages. */ | 2127 | /* Remove pipeline stages. */ |
2292 | if (tape->first_stage == NULL) | 2128 | if (tape->first_stage == NULL) |
2293 | return 0; | 2129 | return 0; |
2294 | 2130 | ||
2295 | spin_lock_irqsave(&tape->spinlock, flags); | 2131 | spin_lock_irqsave(&tape->lock, flags); |
2296 | tape->next_stage = NULL; | 2132 | tape->next_stage = NULL; |
2297 | if (idetape_pipeline_active(tape)) | 2133 | if (idetape_pipeline_active(tape)) |
2298 | idetape_wait_for_request(drive, tape->active_data_request); | 2134 | idetape_wait_for_request(drive, tape->active_data_rq); |
2299 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2135 | spin_unlock_irqrestore(&tape->lock, flags); |
2300 | 2136 | ||
2301 | while (tape->first_stage != NULL) { | 2137 | while (tape->first_stage != NULL) { |
2302 | struct request *rq_ptr = &tape->first_stage->rq; | 2138 | struct request *rq_ptr = &tape->first_stage->rq; |
2303 | 2139 | ||
2304 | cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors; | 2140 | cnt += rq_ptr->nr_sectors - rq_ptr->current_nr_sectors; |
2305 | if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) | 2141 | if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) |
2306 | ++cnt; | 2142 | ++cnt; |
2307 | idetape_remove_stage_head(drive); | 2143 | idetape_remove_stage_head(drive); |
@@ -2312,21 +2148,19 @@ static int __idetape_discard_read_pipeline (ide_drive_t *drive) | |||
2312 | } | 2148 | } |
2313 | 2149 | ||
2314 | /* | 2150 | /* |
2315 | * idetape_position_tape positions the tape to the requested block | 2151 | * Position the tape to the requested block using the LOCATE packet command. |
2316 | * using the LOCATE packet command. A READ POSITION command is then | 2152 | * A READ POSITION command is then issued to check where we are positioned. Like |
2317 | * issued to check where we are positioned. | 2153 | * all higher level operations, we queue the commands at the tail of the request |
2318 | * | 2154 | * queue and wait for their completion. |
2319 | * Like all higher level operations, we queue the commands at the tail | ||
2320 | * of the request queue and wait for their completion. | ||
2321 | * | ||
2322 | */ | 2155 | */ |
2323 | static int idetape_position_tape (ide_drive_t *drive, unsigned int block, u8 partition, int skip) | 2156 | static int idetape_position_tape(ide_drive_t *drive, unsigned int block, |
2157 | u8 partition, int skip) | ||
2324 | { | 2158 | { |
2325 | idetape_tape_t *tape = drive->driver_data; | 2159 | idetape_tape_t *tape = drive->driver_data; |
2326 | int retval; | 2160 | int retval; |
2327 | idetape_pc_t pc; | 2161 | idetape_pc_t pc; |
2328 | 2162 | ||
2329 | if (tape->chrdev_direction == idetape_direction_read) | 2163 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
2330 | __idetape_discard_read_pipeline(drive); | 2164 | __idetape_discard_read_pipeline(drive); |
2331 | idetape_wait_ready(drive, 60 * 5 * HZ); | 2165 | idetape_wait_ready(drive, 60 * 5 * HZ); |
2332 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); | 2166 | idetape_create_locate_cmd(drive, &pc, block, partition, skip); |
@@ -2338,7 +2172,8 @@ static int idetape_position_tape (ide_drive_t *drive, unsigned int block, u8 par | |||
2338 | return (idetape_queue_pc_tail(drive, &pc)); | 2172 | return (idetape_queue_pc_tail(drive, &pc)); |
2339 | } | 2173 | } |
2340 | 2174 | ||
2341 | static void idetape_discard_read_pipeline (ide_drive_t *drive, int restore_position) | 2175 | static void idetape_discard_read_pipeline(ide_drive_t *drive, |
2176 | int restore_position) | ||
2342 | { | 2177 | { |
2343 | idetape_tape_t *tape = drive->driver_data; | 2178 | idetape_tape_t *tape = drive->driver_data; |
2344 | int cnt; | 2179 | int cnt; |
@@ -2349,35 +2184,37 @@ static void idetape_discard_read_pipeline (ide_drive_t *drive, int restore_posit | |||
2349 | position = idetape_read_position(drive); | 2184 | position = idetape_read_position(drive); |
2350 | seek = position > cnt ? position - cnt : 0; | 2185 | seek = position > cnt ? position - cnt : 0; |
2351 | if (idetape_position_tape(drive, seek, 0, 0)) { | 2186 | if (idetape_position_tape(drive, seek, 0, 0)) { |
2352 | printk(KERN_INFO "ide-tape: %s: position_tape failed in discard_pipeline()\n", tape->name); | 2187 | printk(KERN_INFO "ide-tape: %s: position_tape failed in" |
2188 | " discard_pipeline()\n", tape->name); | ||
2353 | return; | 2189 | return; |
2354 | } | 2190 | } |
2355 | } | 2191 | } |
2356 | } | 2192 | } |
2357 | 2193 | ||
2358 | /* | 2194 | /* |
2359 | * idetape_queue_rw_tail generates a read/write request for the block | 2195 | * Generate a read/write request for the block device interface and wait for it |
2360 | * device interface and wait for it to be serviced. | 2196 | * to be serviced. |
2361 | */ | 2197 | */ |
2362 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct idetape_bh *bh) | 2198 | static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, |
2199 | struct idetape_bh *bh) | ||
2363 | { | 2200 | { |
2364 | idetape_tape_t *tape = drive->driver_data; | 2201 | idetape_tape_t *tape = drive->driver_data; |
2365 | struct request rq; | 2202 | struct request rq; |
2366 | 2203 | ||
2367 | #if IDETAPE_DEBUG_LOG | 2204 | debug_log(DBG_SENSE, "%s: cmd=%d\n", __func__, cmd); |
2368 | if (tape->debug_level >= 2) | 2205 | |
2369 | printk(KERN_INFO "ide-tape: idetape_queue_rw_tail: cmd=%d\n",cmd); | ||
2370 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2371 | if (idetape_pipeline_active(tape)) { | 2206 | if (idetape_pipeline_active(tape)) { |
2372 | printk(KERN_ERR "ide-tape: bug: the pipeline is active in idetape_queue_rw_tail\n"); | 2207 | printk(KERN_ERR "ide-tape: bug: the pipeline is active in %s\n", |
2208 | __func__); | ||
2373 | return (0); | 2209 | return (0); |
2374 | } | 2210 | } |
2375 | 2211 | ||
2376 | idetape_init_rq(&rq, cmd); | 2212 | idetape_init_rq(&rq, cmd); |
2377 | rq.rq_disk = tape->disk; | 2213 | rq.rq_disk = tape->disk; |
2378 | rq.special = (void *)bh; | 2214 | rq.special = (void *)bh; |
2379 | rq.sector = tape->first_frame_position; | 2215 | rq.sector = tape->first_frame; |
2380 | rq.nr_sectors = rq.current_nr_sectors = blocks; | 2216 | rq.nr_sectors = blocks; |
2217 | rq.current_nr_sectors = blocks; | ||
2381 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); | 2218 | (void) ide_do_drive_cmd(drive, &rq, ide_wait); |
2382 | 2219 | ||
2383 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) | 2220 | if ((cmd & (REQ_IDETAPE_READ | REQ_IDETAPE_WRITE)) == 0) |
@@ -2387,14 +2224,11 @@ static int idetape_queue_rw_tail(ide_drive_t *drive, int cmd, int blocks, struct | |||
2387 | idetape_init_merge_stage(tape); | 2224 | idetape_init_merge_stage(tape); |
2388 | if (rq.errors == IDETAPE_ERROR_GENERAL) | 2225 | if (rq.errors == IDETAPE_ERROR_GENERAL) |
2389 | return -EIO; | 2226 | return -EIO; |
2390 | return (tape->tape_block_size * (blocks-rq.current_nr_sectors)); | 2227 | return (tape->blk_size * (blocks-rq.current_nr_sectors)); |
2391 | } | 2228 | } |
2392 | 2229 | ||
2393 | /* | 2230 | /* start servicing the pipeline stages, starting from tape->next_stage. */ |
2394 | * idetape_insert_pipeline_into_queue is used to start servicing the | 2231 | static void idetape_plug_pipeline(ide_drive_t *drive) |
2395 | * pipeline stages, starting from tape->next_stage. | ||
2396 | */ | ||
2397 | static void idetape_insert_pipeline_into_queue (ide_drive_t *drive) | ||
2398 | { | 2232 | { |
2399 | idetape_tape_t *tape = drive->driver_data; | 2233 | idetape_tape_t *tape = drive->driver_data; |
2400 | 2234 | ||
@@ -2403,19 +2237,20 @@ static void idetape_insert_pipeline_into_queue (ide_drive_t *drive) | |||
2403 | if (!idetape_pipeline_active(tape)) { | 2237 | if (!idetape_pipeline_active(tape)) { |
2404 | set_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); | 2238 | set_bit(IDETAPE_PIPELINE_ACTIVE, &tape->flags); |
2405 | idetape_activate_next_stage(drive); | 2239 | idetape_activate_next_stage(drive); |
2406 | (void) ide_do_drive_cmd(drive, tape->active_data_request, ide_end); | 2240 | (void) ide_do_drive_cmd(drive, tape->active_data_rq, ide_end); |
2407 | } | 2241 | } |
2408 | } | 2242 | } |
2409 | 2243 | ||
2410 | static void idetape_create_inquiry_cmd (idetape_pc_t *pc) | 2244 | static void idetape_create_inquiry_cmd(idetape_pc_t *pc) |
2411 | { | 2245 | { |
2412 | idetape_init_pc(pc); | 2246 | idetape_init_pc(pc); |
2413 | pc->c[0] = INQUIRY; | 2247 | pc->c[0] = INQUIRY; |
2414 | pc->c[4] = pc->request_transfer = 254; | 2248 | pc->c[4] = 254; |
2249 | pc->request_transfer = 254; | ||
2415 | pc->callback = &idetape_pc_callback; | 2250 | pc->callback = &idetape_pc_callback; |
2416 | } | 2251 | } |
2417 | 2252 | ||
2418 | static void idetape_create_rewind_cmd (ide_drive_t *drive, idetape_pc_t *pc) | 2253 | static void idetape_create_rewind_cmd(ide_drive_t *drive, idetape_pc_t *pc) |
2419 | { | 2254 | { |
2420 | idetape_init_pc(pc); | 2255 | idetape_init_pc(pc); |
2421 | pc->c[0] = REZERO_UNIT; | 2256 | pc->c[0] = REZERO_UNIT; |
@@ -2423,7 +2258,7 @@ static void idetape_create_rewind_cmd (ide_drive_t *drive, idetape_pc_t *pc) | |||
2423 | pc->callback = &idetape_pc_callback; | 2258 | pc->callback = &idetape_pc_callback; |
2424 | } | 2259 | } |
2425 | 2260 | ||
2426 | static void idetape_create_erase_cmd (idetape_pc_t *pc) | 2261 | static void idetape_create_erase_cmd(idetape_pc_t *pc) |
2427 | { | 2262 | { |
2428 | idetape_init_pc(pc); | 2263 | idetape_init_pc(pc); |
2429 | pc->c[0] = ERASE; | 2264 | pc->c[0] = ERASE; |
@@ -2432,7 +2267,7 @@ static void idetape_create_erase_cmd (idetape_pc_t *pc) | |||
2432 | pc->callback = &idetape_pc_callback; | 2267 | pc->callback = &idetape_pc_callback; |
2433 | } | 2268 | } |
2434 | 2269 | ||
2435 | static void idetape_create_space_cmd (idetape_pc_t *pc,int count, u8 cmd) | 2270 | static void idetape_create_space_cmd(idetape_pc_t *pc, int count, u8 cmd) |
2436 | { | 2271 | { |
2437 | idetape_init_pc(pc); | 2272 | idetape_init_pc(pc); |
2438 | pc->c[0] = SPACE; | 2273 | pc->c[0] = SPACE; |
@@ -2442,89 +2277,87 @@ static void idetape_create_space_cmd (idetape_pc_t *pc,int count, u8 cmd) | |||
2442 | pc->callback = &idetape_pc_callback; | 2277 | pc->callback = &idetape_pc_callback; |
2443 | } | 2278 | } |
2444 | 2279 | ||
2445 | static void idetape_wait_first_stage (ide_drive_t *drive) | 2280 | static void idetape_wait_first_stage(ide_drive_t *drive) |
2446 | { | 2281 | { |
2447 | idetape_tape_t *tape = drive->driver_data; | 2282 | idetape_tape_t *tape = drive->driver_data; |
2448 | unsigned long flags; | 2283 | unsigned long flags; |
2449 | 2284 | ||
2450 | if (tape->first_stage == NULL) | 2285 | if (tape->first_stage == NULL) |
2451 | return; | 2286 | return; |
2452 | spin_lock_irqsave(&tape->spinlock, flags); | 2287 | spin_lock_irqsave(&tape->lock, flags); |
2453 | if (tape->active_stage == tape->first_stage) | 2288 | if (tape->active_stage == tape->first_stage) |
2454 | idetape_wait_for_request(drive, tape->active_data_request); | 2289 | idetape_wait_for_request(drive, tape->active_data_rq); |
2455 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2290 | spin_unlock_irqrestore(&tape->lock, flags); |
2456 | } | 2291 | } |
2457 | 2292 | ||
2458 | /* | 2293 | /* |
2459 | * idetape_add_chrdev_write_request tries to add a character device | 2294 | * Try to add a character device originated write request to our pipeline. In |
2460 | * originated write request to our pipeline. In case we don't succeed, | 2295 | * case we don't succeed, we revert to non-pipelined operation mode for this |
2461 | * we revert to non-pipelined operation mode for this request. | 2296 | * request. In order to accomplish that, we |
2462 | * | 2297 | * |
2463 | * 1. Try to allocate a new pipeline stage. | 2298 | * 1. Try to allocate a new pipeline stage. |
2464 | * 2. If we can't, wait for more and more requests to be serviced | 2299 | * 2. If we can't, wait for more and more requests to be serviced and try again |
2465 | * and try again each time. | 2300 | * each time. |
2466 | * 3. If we still can't allocate a stage, fallback to | 2301 | * 3. If we still can't allocate a stage, fallback to non-pipelined operation |
2467 | * non-pipelined operation mode for this request. | 2302 | * mode for this request. |
2468 | */ | 2303 | */ |
2469 | static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks) | 2304 | static int idetape_add_chrdev_write_request(ide_drive_t *drive, int blocks) |
2470 | { | 2305 | { |
2471 | idetape_tape_t *tape = drive->driver_data; | 2306 | idetape_tape_t *tape = drive->driver_data; |
2472 | idetape_stage_t *new_stage; | 2307 | idetape_stage_t *new_stage; |
2473 | unsigned long flags; | 2308 | unsigned long flags; |
2474 | struct request *rq; | 2309 | struct request *rq; |
2475 | 2310 | ||
2476 | #if IDETAPE_DEBUG_LOG | 2311 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
2477 | if (tape->debug_level >= 3) | ||
2478 | printk(KERN_INFO "ide-tape: Reached idetape_add_chrdev_write_request\n"); | ||
2479 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2480 | 2312 | ||
2481 | /* | 2313 | /* Attempt to allocate a new stage. Beware possible race conditions. */ |
2482 | * Attempt to allocate a new stage. | ||
2483 | * Pay special attention to possible race conditions. | ||
2484 | */ | ||
2485 | while ((new_stage = idetape_kmalloc_stage(tape)) == NULL) { | 2314 | while ((new_stage = idetape_kmalloc_stage(tape)) == NULL) { |
2486 | spin_lock_irqsave(&tape->spinlock, flags); | 2315 | spin_lock_irqsave(&tape->lock, flags); |
2487 | if (idetape_pipeline_active(tape)) { | 2316 | if (idetape_pipeline_active(tape)) { |
2488 | idetape_wait_for_request(drive, tape->active_data_request); | 2317 | idetape_wait_for_request(drive, tape->active_data_rq); |
2489 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2318 | spin_unlock_irqrestore(&tape->lock, flags); |
2490 | } else { | 2319 | } else { |
2491 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2320 | spin_unlock_irqrestore(&tape->lock, flags); |
2492 | idetape_insert_pipeline_into_queue(drive); | 2321 | idetape_plug_pipeline(drive); |
2493 | if (idetape_pipeline_active(tape)) | 2322 | if (idetape_pipeline_active(tape)) |
2494 | continue; | 2323 | continue; |
2495 | /* | 2324 | /* |
2496 | * Linux is short on memory. Fallback to | 2325 | * The machine is short on memory. Fallback to non- |
2497 | * non-pipelined operation mode for this request. | 2326 | * pipelined operation mode for this request. |
2498 | */ | 2327 | */ |
2499 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_stage->bh); | 2328 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, |
2329 | blocks, tape->merge_stage->bh); | ||
2500 | } | 2330 | } |
2501 | } | 2331 | } |
2502 | rq = &new_stage->rq; | 2332 | rq = &new_stage->rq; |
2503 | idetape_init_rq(rq, REQ_IDETAPE_WRITE); | 2333 | idetape_init_rq(rq, REQ_IDETAPE_WRITE); |
2504 | /* Doesn't actually matter - We always assume sequential access */ | 2334 | /* Doesn't actually matter - We always assume sequential access */ |
2505 | rq->sector = tape->first_frame_position; | 2335 | rq->sector = tape->first_frame; |
2506 | rq->nr_sectors = rq->current_nr_sectors = blocks; | 2336 | rq->current_nr_sectors = blocks; |
2337 | rq->nr_sectors = blocks; | ||
2507 | 2338 | ||
2508 | idetape_switch_buffers(tape, new_stage); | 2339 | idetape_switch_buffers(tape, new_stage); |
2509 | idetape_add_stage_tail(drive, new_stage); | 2340 | idetape_add_stage_tail(drive, new_stage); |
2510 | tape->pipeline_head++; | 2341 | tape->pipeline_head++; |
2511 | calculate_speeds(drive); | 2342 | idetape_calculate_speeds(drive); |
2512 | 2343 | ||
2513 | /* | 2344 | /* |
2514 | * Estimate whether the tape has stopped writing by checking | 2345 | * Estimate whether the tape has stopped writing by checking if our |
2515 | * if our write pipeline is currently empty. If we are not | 2346 | * write pipeline is currently empty. If we are not writing anymore, |
2516 | * writing anymore, wait for the pipeline to be full enough | 2347 | * wait for the pipeline to be almost completely full (90%) before |
2517 | * (90%) before starting to service requests, so that we will | 2348 | * starting to service requests, so that we will be able to keep up with |
2518 | * be able to keep up with the higher speeds of the tape. | 2349 | * the higher speeds of the tape. |
2519 | */ | 2350 | */ |
2520 | if (!idetape_pipeline_active(tape)) { | 2351 | if (!idetape_pipeline_active(tape)) { |
2521 | if (tape->nr_stages >= tape->max_stages * 9 / 10 || | 2352 | if (tape->nr_stages >= tape->max_stages * 9 / 10 || |
2522 | tape->nr_stages >= tape->max_stages - tape->uncontrolled_pipeline_head_speed * 3 * 1024 / tape->tape_block_size) { | 2353 | tape->nr_stages >= tape->max_stages - |
2354 | tape->uncontrolled_pipeline_head_speed * 3 * 1024 / | ||
2355 | tape->blk_size) { | ||
2523 | tape->measure_insert_time = 1; | 2356 | tape->measure_insert_time = 1; |
2524 | tape->insert_time = jiffies; | 2357 | tape->insert_time = jiffies; |
2525 | tape->insert_size = 0; | 2358 | tape->insert_size = 0; |
2526 | tape->insert_speed = 0; | 2359 | tape->insert_speed = 0; |
2527 | idetape_insert_pipeline_into_queue(drive); | 2360 | idetape_plug_pipeline(drive); |
2528 | } | 2361 | } |
2529 | } | 2362 | } |
2530 | if (test_and_clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) | 2363 | if (test_and_clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) |
@@ -2534,31 +2367,32 @@ static int idetape_add_chrdev_write_request (ide_drive_t *drive, int blocks) | |||
2534 | } | 2367 | } |
2535 | 2368 | ||
2536 | /* | 2369 | /* |
2537 | * idetape_wait_for_pipeline will wait until all pending pipeline | 2370 | * Wait until all pending pipeline requests are serviced. Typically called on |
2538 | * requests are serviced. Typically called on device close. | 2371 | * device close. |
2539 | */ | 2372 | */ |
2540 | static void idetape_wait_for_pipeline (ide_drive_t *drive) | 2373 | static void idetape_wait_for_pipeline(ide_drive_t *drive) |
2541 | { | 2374 | { |
2542 | idetape_tape_t *tape = drive->driver_data; | 2375 | idetape_tape_t *tape = drive->driver_data; |
2543 | unsigned long flags; | 2376 | unsigned long flags; |
2544 | 2377 | ||
2545 | while (tape->next_stage || idetape_pipeline_active(tape)) { | 2378 | while (tape->next_stage || idetape_pipeline_active(tape)) { |
2546 | idetape_insert_pipeline_into_queue(drive); | 2379 | idetape_plug_pipeline(drive); |
2547 | spin_lock_irqsave(&tape->spinlock, flags); | 2380 | spin_lock_irqsave(&tape->lock, flags); |
2548 | if (idetape_pipeline_active(tape)) | 2381 | if (idetape_pipeline_active(tape)) |
2549 | idetape_wait_for_request(drive, tape->active_data_request); | 2382 | idetape_wait_for_request(drive, tape->active_data_rq); |
2550 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2383 | spin_unlock_irqrestore(&tape->lock, flags); |
2551 | } | 2384 | } |
2552 | } | 2385 | } |
2553 | 2386 | ||
2554 | static void idetape_empty_write_pipeline (ide_drive_t *drive) | 2387 | static void idetape_empty_write_pipeline(ide_drive_t *drive) |
2555 | { | 2388 | { |
2556 | idetape_tape_t *tape = drive->driver_data; | 2389 | idetape_tape_t *tape = drive->driver_data; |
2557 | int blocks, min; | 2390 | int blocks, min; |
2558 | struct idetape_bh *bh; | 2391 | struct idetape_bh *bh; |
2559 | 2392 | ||
2560 | if (tape->chrdev_direction != idetape_direction_write) { | 2393 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
2561 | printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline, but we are not writing.\n"); | 2394 | printk(KERN_ERR "ide-tape: bug: Trying to empty write pipeline," |
2395 | " but we are not writing.\n"); | ||
2562 | return; | 2396 | return; |
2563 | } | 2397 | } |
2564 | if (tape->merge_stage_size > tape->stage_size) { | 2398 | if (tape->merge_stage_size > tape->stage_size) { |
@@ -2566,12 +2400,13 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive) | |||
2566 | tape->merge_stage_size = tape->stage_size; | 2400 | tape->merge_stage_size = tape->stage_size; |
2567 | } | 2401 | } |
2568 | if (tape->merge_stage_size) { | 2402 | if (tape->merge_stage_size) { |
2569 | blocks = tape->merge_stage_size / tape->tape_block_size; | 2403 | blocks = tape->merge_stage_size / tape->blk_size; |
2570 | if (tape->merge_stage_size % tape->tape_block_size) { | 2404 | if (tape->merge_stage_size % tape->blk_size) { |
2571 | unsigned int i; | 2405 | unsigned int i; |
2572 | 2406 | ||
2573 | blocks++; | 2407 | blocks++; |
2574 | i = tape->tape_block_size - tape->merge_stage_size % tape->tape_block_size; | 2408 | i = tape->blk_size - tape->merge_stage_size % |
2409 | tape->blk_size; | ||
2575 | bh = tape->bh->b_reqnext; | 2410 | bh = tape->bh->b_reqnext; |
2576 | while (bh) { | 2411 | while (bh) { |
2577 | atomic_set(&bh->b_count, 0); | 2412 | atomic_set(&bh->b_count, 0); |
@@ -2580,12 +2415,14 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive) | |||
2580 | bh = tape->bh; | 2415 | bh = tape->bh; |
2581 | while (i) { | 2416 | while (i) { |
2582 | if (bh == NULL) { | 2417 | if (bh == NULL) { |
2583 | 2418 | printk(KERN_INFO "ide-tape: bug," | |
2584 | printk(KERN_INFO "ide-tape: bug, bh NULL\n"); | 2419 | " bh NULL\n"); |
2585 | break; | 2420 | break; |
2586 | } | 2421 | } |
2587 | min = min(i, (unsigned int)(bh->b_size - atomic_read(&bh->b_count))); | 2422 | min = min(i, (unsigned int)(bh->b_size - |
2588 | memset(bh->b_data + atomic_read(&bh->b_count), 0, min); | 2423 | atomic_read(&bh->b_count))); |
2424 | memset(bh->b_data + atomic_read(&bh->b_count), | ||
2425 | 0, min); | ||
2589 | atomic_add(min, &bh->b_count); | 2426 | atomic_add(min, &bh->b_count); |
2590 | i -= min; | 2427 | i -= min; |
2591 | bh = bh->b_reqnext; | 2428 | bh = bh->b_reqnext; |
@@ -2600,13 +2437,13 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive) | |||
2600 | tape->merge_stage = NULL; | 2437 | tape->merge_stage = NULL; |
2601 | } | 2438 | } |
2602 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); | 2439 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); |
2603 | tape->chrdev_direction = idetape_direction_none; | 2440 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
2604 | 2441 | ||
2605 | /* | 2442 | /* |
2606 | * On the next backup, perform the feedback loop again. | 2443 | * On the next backup, perform the feedback loop again. (I don't want to |
2607 | * (I don't want to keep sense information between backups, | 2444 | * keep sense information between backups, as some systems are |
2608 | * as some systems are constantly on, and the system load | 2445 | * constantly on, and the system load can be totally different on the |
2609 | * can be totally different on the next backup). | 2446 | * next backup). |
2610 | */ | 2447 | */ |
2611 | tape->max_stages = tape->min_pipeline; | 2448 | tape->max_stages = tape->min_pipeline; |
2612 | if (tape->first_stage != NULL || | 2449 | if (tape->first_stage != NULL || |
@@ -2621,21 +2458,25 @@ static void idetape_empty_write_pipeline (ide_drive_t *drive) | |||
2621 | } | 2458 | } |
2622 | } | 2459 | } |
2623 | 2460 | ||
2624 | static void idetape_restart_speed_control (ide_drive_t *drive) | 2461 | static void idetape_restart_speed_control(ide_drive_t *drive) |
2625 | { | 2462 | { |
2626 | idetape_tape_t *tape = drive->driver_data; | 2463 | idetape_tape_t *tape = drive->driver_data; |
2627 | 2464 | ||
2628 | tape->restart_speed_control_req = 0; | 2465 | tape->restart_speed_control_req = 0; |
2629 | tape->pipeline_head = 0; | 2466 | tape->pipeline_head = 0; |
2630 | tape->controlled_last_pipeline_head = tape->uncontrolled_last_pipeline_head = 0; | 2467 | tape->controlled_last_pipeline_head = 0; |
2631 | tape->controlled_previous_pipeline_head = tape->uncontrolled_previous_pipeline_head = 0; | 2468 | tape->controlled_previous_pipeline_head = 0; |
2632 | tape->pipeline_head_speed = tape->controlled_pipeline_head_speed = 5000; | 2469 | tape->uncontrolled_previous_pipeline_head = 0; |
2470 | tape->controlled_pipeline_head_speed = 5000; | ||
2471 | tape->pipeline_head_speed = 5000; | ||
2633 | tape->uncontrolled_pipeline_head_speed = 0; | 2472 | tape->uncontrolled_pipeline_head_speed = 0; |
2634 | tape->controlled_pipeline_head_time = tape->uncontrolled_pipeline_head_time = jiffies; | 2473 | tape->controlled_pipeline_head_time = |
2635 | tape->controlled_previous_head_time = tape->uncontrolled_previous_head_time = jiffies; | 2474 | tape->uncontrolled_pipeline_head_time = jiffies; |
2475 | tape->controlled_previous_head_time = | ||
2476 | tape->uncontrolled_previous_head_time = jiffies; | ||
2636 | } | 2477 | } |
2637 | 2478 | ||
2638 | static int idetape_initiate_read (ide_drive_t *drive, int max_stages) | 2479 | static int idetape_init_read(ide_drive_t *drive, int max_stages) |
2639 | { | 2480 | { |
2640 | idetape_tape_t *tape = drive->driver_data; | 2481 | idetape_tape_t *tape = drive->driver_data; |
2641 | idetape_stage_t *new_stage; | 2482 | idetape_stage_t *new_stage; |
@@ -2644,32 +2485,35 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages) | |||
2644 | u16 blocks = *(u16 *)&tape->caps[12]; | 2485 | u16 blocks = *(u16 *)&tape->caps[12]; |
2645 | 2486 | ||
2646 | /* Initialize read operation */ | 2487 | /* Initialize read operation */ |
2647 | if (tape->chrdev_direction != idetape_direction_read) { | 2488 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
2648 | if (tape->chrdev_direction == idetape_direction_write) { | 2489 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { |
2649 | idetape_empty_write_pipeline(drive); | 2490 | idetape_empty_write_pipeline(drive); |
2650 | idetape_flush_tape_buffers(drive); | 2491 | idetape_flush_tape_buffers(drive); |
2651 | } | 2492 | } |
2652 | if (tape->merge_stage || tape->merge_stage_size) { | 2493 | if (tape->merge_stage || tape->merge_stage_size) { |
2653 | printk (KERN_ERR "ide-tape: merge_stage_size should be 0 now\n"); | 2494 | printk(KERN_ERR "ide-tape: merge_stage_size should be" |
2495 | " 0 now\n"); | ||
2654 | tape->merge_stage_size = 0; | 2496 | tape->merge_stage_size = 0; |
2655 | } | 2497 | } |
2656 | if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL) | 2498 | tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0); |
2499 | if (!tape->merge_stage) | ||
2657 | return -ENOMEM; | 2500 | return -ENOMEM; |
2658 | tape->chrdev_direction = idetape_direction_read; | 2501 | tape->chrdev_dir = IDETAPE_DIR_READ; |
2659 | 2502 | ||
2660 | /* | 2503 | /* |
2661 | * Issue a read 0 command to ensure that DSC handshake | 2504 | * Issue a read 0 command to ensure that DSC handshake is |
2662 | * is switched from completion mode to buffer available | 2505 | * switched from completion mode to buffer available mode. |
2663 | * mode. | 2506 | * No point in issuing this if DSC overlap isn't supported, some |
2664 | * No point in issuing this if DSC overlap isn't supported, | 2507 | * drives (Seagate STT3401A) will return an error. |
2665 | * some drives (Seagate STT3401A) will return an error. | ||
2666 | */ | 2508 | */ |
2667 | if (drive->dsc_overlap) { | 2509 | if (drive->dsc_overlap) { |
2668 | bytes_read = idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, 0, tape->merge_stage->bh); | 2510 | bytes_read = idetape_queue_rw_tail(drive, |
2511 | REQ_IDETAPE_READ, 0, | ||
2512 | tape->merge_stage->bh); | ||
2669 | if (bytes_read < 0) { | 2513 | if (bytes_read < 0) { |
2670 | __idetape_kfree_stage(tape->merge_stage); | 2514 | __idetape_kfree_stage(tape->merge_stage); |
2671 | tape->merge_stage = NULL; | 2515 | tape->merge_stage = NULL; |
2672 | tape->chrdev_direction = idetape_direction_none; | 2516 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
2673 | return bytes_read; | 2517 | return bytes_read; |
2674 | } | 2518 | } |
2675 | } | 2519 | } |
@@ -2677,8 +2521,9 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages) | |||
2677 | if (tape->restart_speed_control_req) | 2521 | if (tape->restart_speed_control_req) |
2678 | idetape_restart_speed_control(drive); | 2522 | idetape_restart_speed_control(drive); |
2679 | idetape_init_rq(&rq, REQ_IDETAPE_READ); | 2523 | idetape_init_rq(&rq, REQ_IDETAPE_READ); |
2680 | rq.sector = tape->first_frame_position; | 2524 | rq.sector = tape->first_frame; |
2681 | rq.nr_sectors = rq.current_nr_sectors = blocks; | 2525 | rq.nr_sectors = blocks; |
2526 | rq.current_nr_sectors = blocks; | ||
2682 | if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) && | 2527 | if (!test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags) && |
2683 | tape->nr_stages < max_stages) { | 2528 | tape->nr_stages < max_stages) { |
2684 | new_stage = idetape_kmalloc_stage(tape); | 2529 | new_stage = idetape_kmalloc_stage(tape); |
@@ -2696,50 +2541,43 @@ static int idetape_initiate_read (ide_drive_t *drive, int max_stages) | |||
2696 | tape->insert_time = jiffies; | 2541 | tape->insert_time = jiffies; |
2697 | tape->insert_size = 0; | 2542 | tape->insert_size = 0; |
2698 | tape->insert_speed = 0; | 2543 | tape->insert_speed = 0; |
2699 | idetape_insert_pipeline_into_queue(drive); | 2544 | idetape_plug_pipeline(drive); |
2700 | } | 2545 | } |
2701 | } | 2546 | } |
2702 | return 0; | 2547 | return 0; |
2703 | } | 2548 | } |
2704 | 2549 | ||
2705 | /* | 2550 | /* |
2706 | * idetape_add_chrdev_read_request is called from idetape_chrdev_read | 2551 | * Called from idetape_chrdev_read() to service a character device read request |
2707 | * to service a character device read request and add read-ahead | 2552 | * and add read-ahead requests to our pipeline. |
2708 | * requests to our pipeline. | ||
2709 | */ | 2553 | */ |
2710 | static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks) | 2554 | static int idetape_add_chrdev_read_request(ide_drive_t *drive, int blocks) |
2711 | { | 2555 | { |
2712 | idetape_tape_t *tape = drive->driver_data; | 2556 | idetape_tape_t *tape = drive->driver_data; |
2713 | unsigned long flags; | 2557 | unsigned long flags; |
2714 | struct request *rq_ptr; | 2558 | struct request *rq_ptr; |
2715 | int bytes_read; | 2559 | int bytes_read; |
2716 | 2560 | ||
2717 | #if IDETAPE_DEBUG_LOG | 2561 | debug_log(DBG_PROCS, "Enter %s, %d blocks\n", __func__, blocks); |
2718 | if (tape->debug_level >= 4) | ||
2719 | printk(KERN_INFO "ide-tape: Reached idetape_add_chrdev_read_request, %d blocks\n", blocks); | ||
2720 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2721 | 2562 | ||
2722 | /* | 2563 | /* If we are at a filemark, return a read length of 0 */ |
2723 | * If we are at a filemark, return a read length of 0 | ||
2724 | */ | ||
2725 | if (test_bit(IDETAPE_FILEMARK, &tape->flags)) | 2564 | if (test_bit(IDETAPE_FILEMARK, &tape->flags)) |
2726 | return 0; | 2565 | return 0; |
2727 | 2566 | ||
2728 | /* | 2567 | /* Wait for the next block to reach the head of the pipeline. */ |
2729 | * Wait for the next block to be available at the head | 2568 | idetape_init_read(drive, tape->max_stages); |
2730 | * of the pipeline | ||
2731 | */ | ||
2732 | idetape_initiate_read(drive, tape->max_stages); | ||
2733 | if (tape->first_stage == NULL) { | 2569 | if (tape->first_stage == NULL) { |
2734 | if (test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) | 2570 | if (test_bit(IDETAPE_PIPELINE_ERROR, &tape->flags)) |
2735 | return 0; | 2571 | return 0; |
2736 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, tape->merge_stage->bh); | 2572 | return idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, blocks, |
2573 | tape->merge_stage->bh); | ||
2737 | } | 2574 | } |
2738 | idetape_wait_first_stage(drive); | 2575 | idetape_wait_first_stage(drive); |
2739 | rq_ptr = &tape->first_stage->rq; | 2576 | rq_ptr = &tape->first_stage->rq; |
2740 | bytes_read = tape->tape_block_size * (rq_ptr->nr_sectors - rq_ptr->current_nr_sectors); | 2577 | bytes_read = tape->blk_size * (rq_ptr->nr_sectors - |
2741 | rq_ptr->nr_sectors = rq_ptr->current_nr_sectors = 0; | 2578 | rq_ptr->current_nr_sectors); |
2742 | 2579 | rq_ptr->nr_sectors = 0; | |
2580 | rq_ptr->current_nr_sectors = 0; | ||
2743 | 2581 | ||
2744 | if (rq_ptr->errors == IDETAPE_ERROR_EOD) | 2582 | if (rq_ptr->errors == IDETAPE_ERROR_EOD) |
2745 | return 0; | 2583 | return 0; |
@@ -2747,43 +2585,46 @@ static int idetape_add_chrdev_read_request (ide_drive_t *drive,int blocks) | |||
2747 | idetape_switch_buffers(tape, tape->first_stage); | 2585 | idetape_switch_buffers(tape, tape->first_stage); |
2748 | if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) | 2586 | if (rq_ptr->errors == IDETAPE_ERROR_FILEMARK) |
2749 | set_bit(IDETAPE_FILEMARK, &tape->flags); | 2587 | set_bit(IDETAPE_FILEMARK, &tape->flags); |
2750 | spin_lock_irqsave(&tape->spinlock, flags); | 2588 | spin_lock_irqsave(&tape->lock, flags); |
2751 | idetape_remove_stage_head(drive); | 2589 | idetape_remove_stage_head(drive); |
2752 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2590 | spin_unlock_irqrestore(&tape->lock, flags); |
2753 | tape->pipeline_head++; | 2591 | tape->pipeline_head++; |
2754 | calculate_speeds(drive); | 2592 | idetape_calculate_speeds(drive); |
2755 | } | 2593 | } |
2756 | if (bytes_read > blocks * tape->tape_block_size) { | 2594 | if (bytes_read > blocks * tape->blk_size) { |
2757 | printk(KERN_ERR "ide-tape: bug: trying to return more bytes than requested\n"); | 2595 | printk(KERN_ERR "ide-tape: bug: trying to return more bytes" |
2758 | bytes_read = blocks * tape->tape_block_size; | 2596 | " than requested\n"); |
2597 | bytes_read = blocks * tape->blk_size; | ||
2759 | } | 2598 | } |
2760 | return (bytes_read); | 2599 | return (bytes_read); |
2761 | } | 2600 | } |
2762 | 2601 | ||
2763 | static void idetape_pad_zeros (ide_drive_t *drive, int bcount) | 2602 | static void idetape_pad_zeros(ide_drive_t *drive, int bcount) |
2764 | { | 2603 | { |
2765 | idetape_tape_t *tape = drive->driver_data; | 2604 | idetape_tape_t *tape = drive->driver_data; |
2766 | struct idetape_bh *bh; | 2605 | struct idetape_bh *bh; |
2767 | int blocks; | 2606 | int blocks; |
2768 | 2607 | ||
2769 | while (bcount) { | 2608 | while (bcount) { |
2770 | unsigned int count; | 2609 | unsigned int count; |
2771 | 2610 | ||
2772 | bh = tape->merge_stage->bh; | 2611 | bh = tape->merge_stage->bh; |
2773 | count = min(tape->stage_size, bcount); | 2612 | count = min(tape->stage_size, bcount); |
2774 | bcount -= count; | 2613 | bcount -= count; |
2775 | blocks = count / tape->tape_block_size; | 2614 | blocks = count / tape->blk_size; |
2776 | while (count) { | 2615 | while (count) { |
2777 | atomic_set(&bh->b_count, min(count, (unsigned int)bh->b_size)); | 2616 | atomic_set(&bh->b_count, |
2617 | min(count, (unsigned int)bh->b_size)); | ||
2778 | memset(bh->b_data, 0, atomic_read(&bh->b_count)); | 2618 | memset(bh->b_data, 0, atomic_read(&bh->b_count)); |
2779 | count -= atomic_read(&bh->b_count); | 2619 | count -= atomic_read(&bh->b_count); |
2780 | bh = bh->b_reqnext; | 2620 | bh = bh->b_reqnext; |
2781 | } | 2621 | } |
2782 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, tape->merge_stage->bh); | 2622 | idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, blocks, |
2623 | tape->merge_stage->bh); | ||
2783 | } | 2624 | } |
2784 | } | 2625 | } |
2785 | 2626 | ||
2786 | static int idetape_pipeline_size (ide_drive_t *drive) | 2627 | static int idetape_pipeline_size(ide_drive_t *drive) |
2787 | { | 2628 | { |
2788 | idetape_tape_t *tape = drive->driver_data; | 2629 | idetape_tape_t *tape = drive->driver_data; |
2789 | idetape_stage_t *stage; | 2630 | idetape_stage_t *stage; |
@@ -2794,9 +2635,10 @@ static int idetape_pipeline_size (ide_drive_t *drive) | |||
2794 | stage = tape->first_stage; | 2635 | stage = tape->first_stage; |
2795 | while (stage != NULL) { | 2636 | while (stage != NULL) { |
2796 | rq = &stage->rq; | 2637 | rq = &stage->rq; |
2797 | size += tape->tape_block_size * (rq->nr_sectors-rq->current_nr_sectors); | 2638 | size += tape->blk_size * (rq->nr_sectors - |
2639 | rq->current_nr_sectors); | ||
2798 | if (rq->errors == IDETAPE_ERROR_FILEMARK) | 2640 | if (rq->errors == IDETAPE_ERROR_FILEMARK) |
2799 | size += tape->tape_block_size; | 2641 | size += tape->blk_size; |
2800 | stage = stage->next; | 2642 | stage = stage->next; |
2801 | } | 2643 | } |
2802 | size += tape->merge_stage_size; | 2644 | size += tape->merge_stage_size; |
@@ -2804,20 +2646,18 @@ static int idetape_pipeline_size (ide_drive_t *drive) | |||
2804 | } | 2646 | } |
2805 | 2647 | ||
2806 | /* | 2648 | /* |
2807 | * Rewinds the tape to the Beginning Of the current Partition (BOP). | 2649 | * Rewinds the tape to the Beginning Of the current Partition (BOP). We |
2808 | * | 2650 | * currently support only one partition. |
2809 | * We currently support only one partition. | 2651 | */ |
2810 | */ | 2652 | static int idetape_rewind_tape(ide_drive_t *drive) |
2811 | static int idetape_rewind_tape (ide_drive_t *drive) | ||
2812 | { | 2653 | { |
2813 | int retval; | 2654 | int retval; |
2814 | idetape_pc_t pc; | 2655 | idetape_pc_t pc; |
2815 | #if IDETAPE_DEBUG_LOG | 2656 | idetape_tape_t *tape; |
2816 | idetape_tape_t *tape = drive->driver_data; | 2657 | tape = drive->driver_data; |
2817 | if (tape->debug_level >= 2) | 2658 | |
2818 | printk(KERN_INFO "ide-tape: Reached idetape_rewind_tape\n"); | 2659 | debug_log(DBG_SENSE, "Enter %s\n", __func__); |
2819 | #endif /* IDETAPE_DEBUG_LOG */ | 2660 | |
2820 | |||
2821 | idetape_create_rewind_cmd(drive, &pc); | 2661 | idetape_create_rewind_cmd(drive, &pc); |
2822 | retval = idetape_queue_pc_tail(drive, &pc); | 2662 | retval = idetape_queue_pc_tail(drive, &pc); |
2823 | if (retval) | 2663 | if (retval) |
@@ -2830,14 +2670,9 @@ static int idetape_rewind_tape (ide_drive_t *drive) | |||
2830 | return 0; | 2670 | return 0; |
2831 | } | 2671 | } |
2832 | 2672 | ||
2833 | /* | 2673 | /* mtio.h compatible commands should be issued to the chrdev interface. */ |
2834 | * Our special ide-tape ioctl's. | 2674 | static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, |
2835 | * | 2675 | unsigned long arg) |
2836 | * Currently there aren't any ioctl's. | ||
2837 | * mtio.h compatible commands should be issued to the character device | ||
2838 | * interface. | ||
2839 | */ | ||
2840 | static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned long arg) | ||
2841 | { | 2676 | { |
2842 | idetape_tape_t *tape = drive->driver_data; | 2677 | idetape_tape_t *tape = drive->driver_data; |
2843 | void __user *argp = (void __user *)arg; | 2678 | void __user *argp = (void __user *)arg; |
@@ -2848,44 +2683,41 @@ static int idetape_blkdev_ioctl(ide_drive_t *drive, unsigned int cmd, unsigned l | |||
2848 | int nr_stages; | 2683 | int nr_stages; |
2849 | } config; | 2684 | } config; |
2850 | 2685 | ||
2851 | #if IDETAPE_DEBUG_LOG | 2686 | debug_log(DBG_PROCS, "Enter %s\n", __func__); |
2852 | if (tape->debug_level >= 4) | 2687 | |
2853 | printk(KERN_INFO "ide-tape: Reached idetape_blkdev_ioctl\n"); | ||
2854 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2855 | switch (cmd) { | 2688 | switch (cmd) { |
2856 | case 0x0340: | 2689 | case 0x0340: |
2857 | if (copy_from_user(&config, argp, sizeof(config))) | 2690 | if (copy_from_user(&config, argp, sizeof(config))) |
2858 | return -EFAULT; | 2691 | return -EFAULT; |
2859 | tape->best_dsc_rw_frequency = config.dsc_rw_frequency; | 2692 | tape->best_dsc_rw_freq = config.dsc_rw_frequency; |
2860 | tape->max_stages = config.nr_stages; | 2693 | tape->max_stages = config.nr_stages; |
2861 | break; | 2694 | break; |
2862 | case 0x0350: | 2695 | case 0x0350: |
2863 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_frequency; | 2696 | config.dsc_rw_frequency = (int) tape->best_dsc_rw_freq; |
2864 | config.nr_stages = tape->max_stages; | 2697 | config.nr_stages = tape->max_stages; |
2865 | if (copy_to_user(argp, &config, sizeof(config))) | 2698 | if (copy_to_user(argp, &config, sizeof(config))) |
2866 | return -EFAULT; | 2699 | return -EFAULT; |
2867 | break; | 2700 | break; |
2868 | default: | 2701 | default: |
2869 | return -EIO; | 2702 | return -EIO; |
2870 | } | 2703 | } |
2871 | return 0; | 2704 | return 0; |
2872 | } | 2705 | } |
2873 | 2706 | ||
2874 | /* | 2707 | /* |
2875 | * idetape_space_over_filemarks is now a bit more complicated than just | 2708 | * The function below is now a bit more complicated than just passing the |
2876 | * passing the command to the tape since we may have crossed some | 2709 | * command to the tape since we may have crossed some filemarks during our |
2877 | * filemarks during our pipelined read-ahead mode. | 2710 | * pipelined read-ahead mode. As a minor side effect, the pipeline enables us to |
2878 | * | 2711 | * support MTFSFM when the filemark is in our internal pipeline even if the tape |
2879 | * As a minor side effect, the pipeline enables us to support MTFSFM when | 2712 | * doesn't support spacing over filemarks in the reverse direction. |
2880 | * the filemark is in our internal pipeline even if the tape doesn't | ||
2881 | * support spacing over filemarks in the reverse direction. | ||
2882 | */ | 2713 | */ |
2883 | static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_count) | 2714 | static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, |
2715 | int mt_count) | ||
2884 | { | 2716 | { |
2885 | idetape_tape_t *tape = drive->driver_data; | 2717 | idetape_tape_t *tape = drive->driver_data; |
2886 | idetape_pc_t pc; | 2718 | idetape_pc_t pc; |
2887 | unsigned long flags; | 2719 | unsigned long flags; |
2888 | int retval,count=0; | 2720 | int retval, count = 0; |
2889 | int sprev = !!(tape->caps[4] & 0x20); | 2721 | int sprev = !!(tape->caps[4] & 0x20); |
2890 | 2722 | ||
2891 | if (mt_count == 0) | 2723 | if (mt_count == 0) |
@@ -2893,14 +2725,11 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c | |||
2893 | if (MTBSF == mt_op || MTBSFM == mt_op) { | 2725 | if (MTBSF == mt_op || MTBSFM == mt_op) { |
2894 | if (!sprev) | 2726 | if (!sprev) |
2895 | return -EIO; | 2727 | return -EIO; |
2896 | mt_count = - mt_count; | 2728 | mt_count = -mt_count; |
2897 | } | 2729 | } |
2898 | 2730 | ||
2899 | if (tape->chrdev_direction == idetape_direction_read) { | 2731 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
2900 | /* | 2732 | /* its a read-ahead buffer, scan it for crossed filemarks. */ |
2901 | * We have a read-ahead buffer. Scan it for crossed | ||
2902 | * filemarks. | ||
2903 | */ | ||
2904 | tape->merge_stage_size = 0; | 2733 | tape->merge_stage_size = 0; |
2905 | if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags)) | 2734 | if (test_and_clear_bit(IDETAPE_FILEMARK, &tape->flags)) |
2906 | ++count; | 2735 | ++count; |
@@ -2910,24 +2739,27 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c | |||
2910 | set_bit(IDETAPE_FILEMARK, &tape->flags); | 2739 | set_bit(IDETAPE_FILEMARK, &tape->flags); |
2911 | return 0; | 2740 | return 0; |
2912 | } | 2741 | } |
2913 | spin_lock_irqsave(&tape->spinlock, flags); | 2742 | spin_lock_irqsave(&tape->lock, flags); |
2914 | if (tape->first_stage == tape->active_stage) { | 2743 | if (tape->first_stage == tape->active_stage) { |
2915 | /* | 2744 | /* |
2916 | * We have reached the active stage in the read pipeline. | 2745 | * We have reached the active stage in the read |
2917 | * There is no point in allowing the drive to continue | 2746 | * pipeline. There is no point in allowing the |
2918 | * reading any farther, so we stop the pipeline. | 2747 | * drive to continue reading any farther, so we |
2748 | * stop the pipeline. | ||
2919 | * | 2749 | * |
2920 | * This section should be moved to a separate subroutine, | 2750 | * This section should be moved to a separate |
2921 | * because a similar function is performed in | 2751 | * subroutine because similar operations are |
2922 | * __idetape_discard_read_pipeline(), for example. | 2752 | * done in __idetape_discard_read_pipeline(), |
2753 | * for example. | ||
2923 | */ | 2754 | */ |
2924 | tape->next_stage = NULL; | 2755 | tape->next_stage = NULL; |
2925 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2756 | spin_unlock_irqrestore(&tape->lock, flags); |
2926 | idetape_wait_first_stage(drive); | 2757 | idetape_wait_first_stage(drive); |
2927 | tape->next_stage = tape->first_stage->next; | 2758 | tape->next_stage = tape->first_stage->next; |
2928 | } else | 2759 | } else |
2929 | spin_unlock_irqrestore(&tape->spinlock, flags); | 2760 | spin_unlock_irqrestore(&tape->lock, flags); |
2930 | if (tape->first_stage->rq.errors == IDETAPE_ERROR_FILEMARK) | 2761 | if (tape->first_stage->rq.errors == |
2762 | IDETAPE_ERROR_FILEMARK) | ||
2931 | ++count; | 2763 | ++count; |
2932 | idetape_remove_stage_head(drive); | 2764 | idetape_remove_stage_head(drive); |
2933 | } | 2765 | } |
@@ -2935,73 +2767,74 @@ static int idetape_space_over_filemarks (ide_drive_t *drive,short mt_op,int mt_c | |||
2935 | } | 2767 | } |
2936 | 2768 | ||
2937 | /* | 2769 | /* |
2938 | * The filemark was not found in our internal pipeline. | 2770 | * The filemark was not found in our internal pipeline; now we can issue |
2939 | * Now we can issue the space command. | 2771 | * the space command. |
2940 | */ | 2772 | */ |
2941 | switch (mt_op) { | 2773 | switch (mt_op) { |
2942 | case MTFSF: | 2774 | case MTFSF: |
2943 | case MTBSF: | 2775 | case MTBSF: |
2944 | idetape_create_space_cmd(&pc,mt_count-count,IDETAPE_SPACE_OVER_FILEMARK); | 2776 | idetape_create_space_cmd(&pc, mt_count - count, |
2945 | return (idetape_queue_pc_tail(drive, &pc)); | 2777 | IDETAPE_SPACE_OVER_FILEMARK); |
2946 | case MTFSFM: | 2778 | return idetape_queue_pc_tail(drive, &pc); |
2947 | case MTBSFM: | 2779 | case MTFSFM: |
2948 | if (!sprev) | 2780 | case MTBSFM: |
2949 | return (-EIO); | 2781 | if (!sprev) |
2950 | retval = idetape_space_over_filemarks(drive, MTFSF, mt_count-count); | 2782 | return -EIO; |
2951 | if (retval) return (retval); | 2783 | retval = idetape_space_over_filemarks(drive, MTFSF, |
2952 | count = (MTBSFM == mt_op ? 1 : -1); | 2784 | mt_count - count); |
2953 | return (idetape_space_over_filemarks(drive, MTFSF, count)); | 2785 | if (retval) |
2954 | default: | 2786 | return retval; |
2955 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n",mt_op); | 2787 | count = (MTBSFM == mt_op ? 1 : -1); |
2956 | return (-EIO); | 2788 | return idetape_space_over_filemarks(drive, MTFSF, count); |
2789 | default: | ||
2790 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", | ||
2791 | mt_op); | ||
2792 | return -EIO; | ||
2957 | } | 2793 | } |
2958 | } | 2794 | } |
2959 | 2795 | ||
2960 | |||
2961 | /* | 2796 | /* |
2962 | * Our character device read / write functions. | 2797 | * Our character device read / write functions. |
2963 | * | 2798 | * |
2964 | * The tape is optimized to maximize throughput when it is transferring | 2799 | * The tape is optimized to maximize throughput when it is transferring an |
2965 | * an integral number of the "continuous transfer limit", which is | 2800 | * integral number of the "continuous transfer limit", which is a parameter of |
2966 | * a parameter of the specific tape (26 KB on my particular tape). | 2801 | * the specific tape (26kB on my particular tape, 32kB for Onstream). |
2967 | * (32 kB for Onstream) | ||
2968 | * | 2802 | * |
2969 | * As of version 1.3 of the driver, the character device provides an | 2803 | * As of version 1.3 of the driver, the character device provides an abstract |
2970 | * abstract continuous view of the media - any mix of block sizes (even 1 | 2804 | * continuous view of the media - any mix of block sizes (even 1 byte) on the |
2971 | * byte) on the same backup/restore procedure is supported. The driver | 2805 | * same backup/restore procedure is supported. The driver will internally |
2972 | * will internally convert the requests to the recommended transfer unit, | 2806 | * convert the requests to the recommended transfer unit, so that an unmatch |
2973 | * so that an unmatch between the user's block size to the recommended | 2807 | * between the user's block size to the recommended size will only result in a |
2974 | * size will only result in a (slightly) increased driver overhead, but | 2808 | * (slightly) increased driver overhead, but will no longer hit performance. |
2975 | * will no longer hit performance. | 2809 | * This is not applicable to Onstream. |
2976 | * This is not applicable to Onstream. | ||
2977 | */ | 2810 | */ |
2978 | static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, | 2811 | static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, |
2979 | size_t count, loff_t *ppos) | 2812 | size_t count, loff_t *ppos) |
2980 | { | 2813 | { |
2981 | struct ide_tape_obj *tape = ide_tape_f(file); | 2814 | struct ide_tape_obj *tape = ide_tape_f(file); |
2982 | ide_drive_t *drive = tape->drive; | 2815 | ide_drive_t *drive = tape->drive; |
2983 | ssize_t bytes_read,temp, actually_read = 0, rc; | 2816 | ssize_t bytes_read, temp, actually_read = 0, rc; |
2984 | ssize_t ret = 0; | 2817 | ssize_t ret = 0; |
2985 | u16 ctl = *(u16 *)&tape->caps[12]; | 2818 | u16 ctl = *(u16 *)&tape->caps[12]; |
2986 | 2819 | ||
2987 | #if IDETAPE_DEBUG_LOG | 2820 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
2988 | if (tape->debug_level >= 3) | ||
2989 | printk(KERN_INFO "ide-tape: Reached idetape_chrdev_read, count %Zd\n", count); | ||
2990 | #endif /* IDETAPE_DEBUG_LOG */ | ||
2991 | 2821 | ||
2992 | if (tape->chrdev_direction != idetape_direction_read) { | 2822 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
2993 | if (test_bit(IDETAPE_DETECT_BS, &tape->flags)) | 2823 | if (test_bit(IDETAPE_DETECT_BS, &tape->flags)) |
2994 | if (count > tape->tape_block_size && | 2824 | if (count > tape->blk_size && |
2995 | (count % tape->tape_block_size) == 0) | 2825 | (count % tape->blk_size) == 0) |
2996 | tape->user_bs_factor = count / tape->tape_block_size; | 2826 | tape->user_bs_factor = count / tape->blk_size; |
2997 | } | 2827 | } |
2998 | if ((rc = idetape_initiate_read(drive, tape->max_stages)) < 0) | 2828 | rc = idetape_init_read(drive, tape->max_stages); |
2829 | if (rc < 0) | ||
2999 | return rc; | 2830 | return rc; |
3000 | if (count == 0) | 2831 | if (count == 0) |
3001 | return (0); | 2832 | return (0); |
3002 | if (tape->merge_stage_size) { | 2833 | if (tape->merge_stage_size) { |
3003 | actually_read = min((unsigned int)(tape->merge_stage_size), (unsigned int)count); | 2834 | actually_read = min((unsigned int)(tape->merge_stage_size), |
3004 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, actually_read)) | 2835 | (unsigned int)count); |
2836 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, | ||
2837 | actually_read)) | ||
3005 | ret = -EFAULT; | 2838 | ret = -EFAULT; |
3006 | buf += actually_read; | 2839 | buf += actually_read; |
3007 | tape->merge_stage_size -= actually_read; | 2840 | tape->merge_stage_size -= actually_read; |
@@ -3011,7 +2844,8 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, | |||
3011 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); | 2844 | bytes_read = idetape_add_chrdev_read_request(drive, ctl); |
3012 | if (bytes_read <= 0) | 2845 | if (bytes_read <= 0) |
3013 | goto finish; | 2846 | goto finish; |
3014 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, bytes_read)) | 2847 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, |
2848 | bytes_read)) | ||
3015 | ret = -EFAULT; | 2849 | ret = -EFAULT; |
3016 | buf += bytes_read; | 2850 | buf += bytes_read; |
3017 | count -= bytes_read; | 2851 | count -= bytes_read; |
@@ -3022,25 +2856,24 @@ static ssize_t idetape_chrdev_read (struct file *file, char __user *buf, | |||
3022 | if (bytes_read <= 0) | 2856 | if (bytes_read <= 0) |
3023 | goto finish; | 2857 | goto finish; |
3024 | temp = min((unsigned long)count, (unsigned long)bytes_read); | 2858 | temp = min((unsigned long)count, (unsigned long)bytes_read); |
3025 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, temp)) | 2859 | if (idetape_copy_stage_to_user(tape, buf, tape->merge_stage, |
2860 | temp)) | ||
3026 | ret = -EFAULT; | 2861 | ret = -EFAULT; |
3027 | actually_read += temp; | 2862 | actually_read += temp; |
3028 | tape->merge_stage_size = bytes_read-temp; | 2863 | tape->merge_stage_size = bytes_read-temp; |
3029 | } | 2864 | } |
3030 | finish: | 2865 | finish: |
3031 | if (!actually_read && test_bit(IDETAPE_FILEMARK, &tape->flags)) { | 2866 | if (!actually_read && test_bit(IDETAPE_FILEMARK, &tape->flags)) { |
3032 | #if IDETAPE_DEBUG_LOG | 2867 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); |
3033 | if (tape->debug_level >= 2) | 2868 | |
3034 | printk(KERN_INFO "ide-tape: %s: spacing over filemark\n", tape->name); | ||
3035 | #endif | ||
3036 | idetape_space_over_filemarks(drive, MTFSF, 1); | 2869 | idetape_space_over_filemarks(drive, MTFSF, 1); |
3037 | return 0; | 2870 | return 0; |
3038 | } | 2871 | } |
3039 | 2872 | ||
3040 | return (ret) ? ret : actually_read; | 2873 | return ret ? ret : actually_read; |
3041 | } | 2874 | } |
3042 | 2875 | ||
3043 | static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, | 2876 | static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, |
3044 | size_t count, loff_t *ppos) | 2877 | size_t count, loff_t *ppos) |
3045 | { | 2878 | { |
3046 | struct ide_tape_obj *tape = ide_tape_f(file); | 2879 | struct ide_tape_obj *tape = ide_tape_f(file); |
@@ -3053,39 +2886,37 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, | |||
3053 | if (tape->write_prot) | 2886 | if (tape->write_prot) |
3054 | return -EACCES; | 2887 | return -EACCES; |
3055 | 2888 | ||
3056 | #if IDETAPE_DEBUG_LOG | 2889 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
3057 | if (tape->debug_level >= 3) | ||
3058 | printk(KERN_INFO "ide-tape: Reached idetape_chrdev_write, " | ||
3059 | "count %Zd\n", count); | ||
3060 | #endif /* IDETAPE_DEBUG_LOG */ | ||
3061 | 2890 | ||
3062 | /* Initialize write operation */ | 2891 | /* Initialize write operation */ |
3063 | if (tape->chrdev_direction != idetape_direction_write) { | 2892 | if (tape->chrdev_dir != IDETAPE_DIR_WRITE) { |
3064 | if (tape->chrdev_direction == idetape_direction_read) | 2893 | if (tape->chrdev_dir == IDETAPE_DIR_READ) |
3065 | idetape_discard_read_pipeline(drive, 1); | 2894 | idetape_discard_read_pipeline(drive, 1); |
3066 | if (tape->merge_stage || tape->merge_stage_size) { | 2895 | if (tape->merge_stage || tape->merge_stage_size) { |
3067 | printk(KERN_ERR "ide-tape: merge_stage_size " | 2896 | printk(KERN_ERR "ide-tape: merge_stage_size " |
3068 | "should be 0 now\n"); | 2897 | "should be 0 now\n"); |
3069 | tape->merge_stage_size = 0; | 2898 | tape->merge_stage_size = 0; |
3070 | } | 2899 | } |
3071 | if ((tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0)) == NULL) | 2900 | tape->merge_stage = __idetape_kmalloc_stage(tape, 0, 0); |
2901 | if (!tape->merge_stage) | ||
3072 | return -ENOMEM; | 2902 | return -ENOMEM; |
3073 | tape->chrdev_direction = idetape_direction_write; | 2903 | tape->chrdev_dir = IDETAPE_DIR_WRITE; |
3074 | idetape_init_merge_stage(tape); | 2904 | idetape_init_merge_stage(tape); |
3075 | 2905 | ||
3076 | /* | 2906 | /* |
3077 | * Issue a write 0 command to ensure that DSC handshake | 2907 | * Issue a write 0 command to ensure that DSC handshake is |
3078 | * is switched from completion mode to buffer available | 2908 | * switched from completion mode to buffer available mode. No |
3079 | * mode. | 2909 | * point in issuing this if DSC overlap isn't supported, some |
3080 | * No point in issuing this if DSC overlap isn't supported, | 2910 | * drives (Seagate STT3401A) will return an error. |
3081 | * some drives (Seagate STT3401A) will return an error. | ||
3082 | */ | 2911 | */ |
3083 | if (drive->dsc_overlap) { | 2912 | if (drive->dsc_overlap) { |
3084 | ssize_t retval = idetape_queue_rw_tail(drive, REQ_IDETAPE_WRITE, 0, tape->merge_stage->bh); | 2913 | ssize_t retval = idetape_queue_rw_tail(drive, |
2914 | REQ_IDETAPE_WRITE, 0, | ||
2915 | tape->merge_stage->bh); | ||
3085 | if (retval < 0) { | 2916 | if (retval < 0) { |
3086 | __idetape_kfree_stage(tape->merge_stage); | 2917 | __idetape_kfree_stage(tape->merge_stage); |
3087 | tape->merge_stage = NULL; | 2918 | tape->merge_stage = NULL; |
3088 | tape->chrdev_direction = idetape_direction_none; | 2919 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
3089 | return retval; | 2920 | return retval; |
3090 | } | 2921 | } |
3091 | } | 2922 | } |
@@ -3096,11 +2927,14 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, | |||
3096 | idetape_restart_speed_control(drive); | 2927 | idetape_restart_speed_control(drive); |
3097 | if (tape->merge_stage_size) { | 2928 | if (tape->merge_stage_size) { |
3098 | if (tape->merge_stage_size >= tape->stage_size) { | 2929 | if (tape->merge_stage_size >= tape->stage_size) { |
3099 | printk(KERN_ERR "ide-tape: bug: merge buffer too big\n"); | 2930 | printk(KERN_ERR "ide-tape: bug: merge buf too big\n"); |
3100 | tape->merge_stage_size = 0; | 2931 | tape->merge_stage_size = 0; |
3101 | } | 2932 | } |
3102 | actually_written = min((unsigned int)(tape->stage_size - tape->merge_stage_size), (unsigned int)count); | 2933 | actually_written = min((unsigned int) |
3103 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, actually_written)) | 2934 | (tape->stage_size - tape->merge_stage_size), |
2935 | (unsigned int)count); | ||
2936 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, | ||
2937 | actually_written)) | ||
3104 | ret = -EFAULT; | 2938 | ret = -EFAULT; |
3105 | buf += actually_written; | 2939 | buf += actually_written; |
3106 | tape->merge_stage_size += actually_written; | 2940 | tape->merge_stage_size += actually_written; |
@@ -3116,7 +2950,8 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, | |||
3116 | } | 2950 | } |
3117 | while (count >= tape->stage_size) { | 2951 | while (count >= tape->stage_size) { |
3118 | ssize_t retval; | 2952 | ssize_t retval; |
3119 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, tape->stage_size)) | 2953 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, |
2954 | tape->stage_size)) | ||
3120 | ret = -EFAULT; | 2955 | ret = -EFAULT; |
3121 | buf += tape->stage_size; | 2956 | buf += tape->stage_size; |
3122 | count -= tape->stage_size; | 2957 | count -= tape->stage_size; |
@@ -3127,14 +2962,15 @@ static ssize_t idetape_chrdev_write (struct file *file, const char __user *buf, | |||
3127 | } | 2962 | } |
3128 | if (count) { | 2963 | if (count) { |
3129 | actually_written += count; | 2964 | actually_written += count; |
3130 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, count)) | 2965 | if (idetape_copy_stage_from_user(tape, tape->merge_stage, buf, |
2966 | count)) | ||
3131 | ret = -EFAULT; | 2967 | ret = -EFAULT; |
3132 | tape->merge_stage_size += count; | 2968 | tape->merge_stage_size += count; |
3133 | } | 2969 | } |
3134 | return (ret) ? ret : actually_written; | 2970 | return ret ? ret : actually_written; |
3135 | } | 2971 | } |
3136 | 2972 | ||
3137 | static int idetape_write_filemark (ide_drive_t *drive) | 2973 | static int idetape_write_filemark(ide_drive_t *drive) |
3138 | { | 2974 | { |
3139 | idetape_pc_t pc; | 2975 | idetape_pc_t pc; |
3140 | 2976 | ||
@@ -3165,113 +3001,117 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
3165 | { | 3001 | { |
3166 | idetape_tape_t *tape = drive->driver_data; | 3002 | idetape_tape_t *tape = drive->driver_data; |
3167 | idetape_pc_t pc; | 3003 | idetape_pc_t pc; |
3168 | int i,retval; | 3004 | int i, retval; |
3169 | 3005 | ||
3170 | #if IDETAPE_DEBUG_LOG | 3006 | debug_log(DBG_ERR, "Handling MTIOCTOP ioctl: mt_op=%d, mt_count=%d\n", |
3171 | if (tape->debug_level >= 1) | 3007 | mt_op, mt_count); |
3172 | printk(KERN_INFO "ide-tape: Handling MTIOCTOP ioctl: " | 3008 | |
3173 | "mt_op=%d, mt_count=%d\n", mt_op, mt_count); | 3009 | /* Commands which need our pipelined read-ahead stages. */ |
3174 | #endif /* IDETAPE_DEBUG_LOG */ | ||
3175 | /* | ||
3176 | * Commands which need our pipelined read-ahead stages. | ||
3177 | */ | ||
3178 | switch (mt_op) { | 3010 | switch (mt_op) { |
3179 | case MTFSF: | 3011 | case MTFSF: |
3180 | case MTFSFM: | 3012 | case MTFSFM: |
3181 | case MTBSF: | 3013 | case MTBSF: |
3182 | case MTBSFM: | 3014 | case MTBSFM: |
3183 | if (!mt_count) | 3015 | if (!mt_count) |
3184 | return (0); | 3016 | return 0; |
3185 | return (idetape_space_over_filemarks(drive,mt_op,mt_count)); | 3017 | return idetape_space_over_filemarks(drive, mt_op, mt_count); |
3186 | default: | 3018 | default: |
3187 | break; | 3019 | break; |
3188 | } | 3020 | } |
3021 | |||
3189 | switch (mt_op) { | 3022 | switch (mt_op) { |
3190 | case MTWEOF: | 3023 | case MTWEOF: |
3191 | if (tape->write_prot) | 3024 | if (tape->write_prot) |
3192 | return -EACCES; | 3025 | return -EACCES; |
3193 | idetape_discard_read_pipeline(drive, 1); | 3026 | idetape_discard_read_pipeline(drive, 1); |
3194 | for (i = 0; i < mt_count; i++) { | 3027 | for (i = 0; i < mt_count; i++) { |
3195 | retval = idetape_write_filemark(drive); | 3028 | retval = idetape_write_filemark(drive); |
3196 | if (retval) | 3029 | if (retval) |
3197 | return retval; | 3030 | return retval; |
3198 | } | 3031 | } |
3199 | return (0); | 3032 | return 0; |
3200 | case MTREW: | 3033 | case MTREW: |
3201 | idetape_discard_read_pipeline(drive, 0); | 3034 | idetape_discard_read_pipeline(drive, 0); |
3202 | if (idetape_rewind_tape(drive)) | 3035 | if (idetape_rewind_tape(drive)) |
3036 | return -EIO; | ||
3037 | return 0; | ||
3038 | case MTLOAD: | ||
3039 | idetape_discard_read_pipeline(drive, 0); | ||
3040 | idetape_create_load_unload_cmd(drive, &pc, | ||
3041 | IDETAPE_LU_LOAD_MASK); | ||
3042 | return idetape_queue_pc_tail(drive, &pc); | ||
3043 | case MTUNLOAD: | ||
3044 | case MTOFFL: | ||
3045 | /* | ||
3046 | * If door is locked, attempt to unlock before | ||
3047 | * attempting to eject. | ||
3048 | */ | ||
3049 | if (tape->door_locked) { | ||
3050 | if (idetape_create_prevent_cmd(drive, &pc, 0)) | ||
3051 | if (!idetape_queue_pc_tail(drive, &pc)) | ||
3052 | tape->door_locked = DOOR_UNLOCKED; | ||
3053 | } | ||
3054 | idetape_discard_read_pipeline(drive, 0); | ||
3055 | idetape_create_load_unload_cmd(drive, &pc, | ||
3056 | !IDETAPE_LU_LOAD_MASK); | ||
3057 | retval = idetape_queue_pc_tail(drive, &pc); | ||
3058 | if (!retval) | ||
3059 | clear_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); | ||
3060 | return retval; | ||
3061 | case MTNOP: | ||
3062 | idetape_discard_read_pipeline(drive, 0); | ||
3063 | return idetape_flush_tape_buffers(drive); | ||
3064 | case MTRETEN: | ||
3065 | idetape_discard_read_pipeline(drive, 0); | ||
3066 | idetape_create_load_unload_cmd(drive, &pc, | ||
3067 | IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); | ||
3068 | return idetape_queue_pc_tail(drive, &pc); | ||
3069 | case MTEOM: | ||
3070 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); | ||
3071 | return idetape_queue_pc_tail(drive, &pc); | ||
3072 | case MTERASE: | ||
3073 | (void)idetape_rewind_tape(drive); | ||
3074 | idetape_create_erase_cmd(&pc); | ||
3075 | return idetape_queue_pc_tail(drive, &pc); | ||
3076 | case MTSETBLK: | ||
3077 | if (mt_count) { | ||
3078 | if (mt_count < tape->blk_size || | ||
3079 | mt_count % tape->blk_size) | ||
3203 | return -EIO; | 3080 | return -EIO; |
3081 | tape->user_bs_factor = mt_count / tape->blk_size; | ||
3082 | clear_bit(IDETAPE_DETECT_BS, &tape->flags); | ||
3083 | } else | ||
3084 | set_bit(IDETAPE_DETECT_BS, &tape->flags); | ||
3085 | return 0; | ||
3086 | case MTSEEK: | ||
3087 | idetape_discard_read_pipeline(drive, 0); | ||
3088 | return idetape_position_tape(drive, | ||
3089 | mt_count * tape->user_bs_factor, tape->partition, 0); | ||
3090 | case MTSETPART: | ||
3091 | idetape_discard_read_pipeline(drive, 0); | ||
3092 | return idetape_position_tape(drive, 0, mt_count, 0); | ||
3093 | case MTFSR: | ||
3094 | case MTBSR: | ||
3095 | case MTLOCK: | ||
3096 | if (!idetape_create_prevent_cmd(drive, &pc, 1)) | ||
3204 | return 0; | 3097 | return 0; |
3205 | case MTLOAD: | 3098 | retval = idetape_queue_pc_tail(drive, &pc); |
3206 | idetape_discard_read_pipeline(drive, 0); | 3099 | if (retval) |
3207 | idetape_create_load_unload_cmd(drive, &pc, IDETAPE_LU_LOAD_MASK); | ||
3208 | return (idetape_queue_pc_tail(drive, &pc)); | ||
3209 | case MTUNLOAD: | ||
3210 | case MTOFFL: | ||
3211 | /* | ||
3212 | * If door is locked, attempt to unlock before | ||
3213 | * attempting to eject. | ||
3214 | */ | ||
3215 | if (tape->door_locked) { | ||
3216 | if (idetape_create_prevent_cmd(drive, &pc, 0)) | ||
3217 | if (!idetape_queue_pc_tail(drive, &pc)) | ||
3218 | tape->door_locked = DOOR_UNLOCKED; | ||
3219 | } | ||
3220 | idetape_discard_read_pipeline(drive, 0); | ||
3221 | idetape_create_load_unload_cmd(drive, &pc,!IDETAPE_LU_LOAD_MASK); | ||
3222 | retval = idetape_queue_pc_tail(drive, &pc); | ||
3223 | if (!retval) | ||
3224 | clear_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags); | ||
3225 | return retval; | 3100 | return retval; |
3226 | case MTNOP: | 3101 | tape->door_locked = DOOR_EXPLICITLY_LOCKED; |
3227 | idetape_discard_read_pipeline(drive, 0); | 3102 | return 0; |
3228 | return (idetape_flush_tape_buffers(drive)); | 3103 | case MTUNLOCK: |
3229 | case MTRETEN: | 3104 | if (!idetape_create_prevent_cmd(drive, &pc, 0)) |
3230 | idetape_discard_read_pipeline(drive, 0); | ||
3231 | idetape_create_load_unload_cmd(drive, &pc,IDETAPE_LU_RETENSION_MASK | IDETAPE_LU_LOAD_MASK); | ||
3232 | return (idetape_queue_pc_tail(drive, &pc)); | ||
3233 | case MTEOM: | ||
3234 | idetape_create_space_cmd(&pc, 0, IDETAPE_SPACE_TO_EOD); | ||
3235 | return (idetape_queue_pc_tail(drive, &pc)); | ||
3236 | case MTERASE: | ||
3237 | (void) idetape_rewind_tape(drive); | ||
3238 | idetape_create_erase_cmd(&pc); | ||
3239 | return (idetape_queue_pc_tail(drive, &pc)); | ||
3240 | case MTSETBLK: | ||
3241 | if (mt_count) { | ||
3242 | if (mt_count < tape->tape_block_size || mt_count % tape->tape_block_size) | ||
3243 | return -EIO; | ||
3244 | tape->user_bs_factor = mt_count / tape->tape_block_size; | ||
3245 | clear_bit(IDETAPE_DETECT_BS, &tape->flags); | ||
3246 | } else | ||
3247 | set_bit(IDETAPE_DETECT_BS, &tape->flags); | ||
3248 | return 0; | ||
3249 | case MTSEEK: | ||
3250 | idetape_discard_read_pipeline(drive, 0); | ||
3251 | return idetape_position_tape(drive, mt_count * tape->user_bs_factor, tape->partition, 0); | ||
3252 | case MTSETPART: | ||
3253 | idetape_discard_read_pipeline(drive, 0); | ||
3254 | return (idetape_position_tape(drive, 0, mt_count, 0)); | ||
3255 | case MTFSR: | ||
3256 | case MTBSR: | ||
3257 | case MTLOCK: | ||
3258 | if (!idetape_create_prevent_cmd(drive, &pc, 1)) | ||
3259 | return 0; | ||
3260 | retval = idetape_queue_pc_tail(drive, &pc); | ||
3261 | if (retval) return retval; | ||
3262 | tape->door_locked = DOOR_EXPLICITLY_LOCKED; | ||
3263 | return 0; | ||
3264 | case MTUNLOCK: | ||
3265 | if (!idetape_create_prevent_cmd(drive, &pc, 0)) | ||
3266 | return 0; | ||
3267 | retval = idetape_queue_pc_tail(drive, &pc); | ||
3268 | if (retval) return retval; | ||
3269 | tape->door_locked = DOOR_UNLOCKED; | ||
3270 | return 0; | 3105 | return 0; |
3271 | default: | 3106 | retval = idetape_queue_pc_tail(drive, &pc); |
3272 | printk(KERN_ERR "ide-tape: MTIO operation %d not " | 3107 | if (retval) |
3273 | "supported\n", mt_op); | 3108 | return retval; |
3274 | return (-EIO); | 3109 | tape->door_locked = DOOR_UNLOCKED; |
3110 | return 0; | ||
3111 | default: | ||
3112 | printk(KERN_ERR "ide-tape: MTIO operation %d not supported\n", | ||
3113 | mt_op); | ||
3114 | return -EIO; | ||
3275 | } | 3115 | } |
3276 | } | 3116 | } |
3277 | 3117 | ||
@@ -3288,50 +3128,51 @@ static int idetape_chrdev_ioctl(struct inode *inode, struct file *file, | |||
3288 | struct mtop mtop; | 3128 | struct mtop mtop; |
3289 | struct mtget mtget; | 3129 | struct mtget mtget; |
3290 | struct mtpos mtpos; | 3130 | struct mtpos mtpos; |
3291 | int block_offset = 0, position = tape->first_frame_position; | 3131 | int block_offset = 0, position = tape->first_frame; |
3292 | void __user *argp = (void __user *)arg; | 3132 | void __user *argp = (void __user *)arg; |
3293 | 3133 | ||
3294 | #if IDETAPE_DEBUG_LOG | 3134 | debug_log(DBG_CHRDEV, "Enter %s, cmd=%u\n", __func__, cmd); |
3295 | if (tape->debug_level >= 3) | ||
3296 | printk(KERN_INFO "ide-tape: Reached idetape_chrdev_ioctl, " | ||
3297 | "cmd=%u\n", cmd); | ||
3298 | #endif /* IDETAPE_DEBUG_LOG */ | ||
3299 | 3135 | ||
3300 | tape->restart_speed_control_req = 1; | 3136 | tape->restart_speed_control_req = 1; |
3301 | if (tape->chrdev_direction == idetape_direction_write) { | 3137 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) { |
3302 | idetape_empty_write_pipeline(drive); | 3138 | idetape_empty_write_pipeline(drive); |
3303 | idetape_flush_tape_buffers(drive); | 3139 | idetape_flush_tape_buffers(drive); |
3304 | } | 3140 | } |
3305 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { | 3141 | if (cmd == MTIOCGET || cmd == MTIOCPOS) { |
3306 | block_offset = idetape_pipeline_size(drive) / (tape->tape_block_size * tape->user_bs_factor); | 3142 | block_offset = idetape_pipeline_size(drive) / |
3307 | if ((position = idetape_read_position(drive)) < 0) | 3143 | (tape->blk_size * tape->user_bs_factor); |
3144 | position = idetape_read_position(drive); | ||
3145 | if (position < 0) | ||
3308 | return -EIO; | 3146 | return -EIO; |
3309 | } | 3147 | } |
3310 | switch (cmd) { | 3148 | switch (cmd) { |
3311 | case MTIOCTOP: | 3149 | case MTIOCTOP: |
3312 | if (copy_from_user(&mtop, argp, sizeof (struct mtop))) | 3150 | if (copy_from_user(&mtop, argp, sizeof(struct mtop))) |
3313 | return -EFAULT; | 3151 | return -EFAULT; |
3314 | return (idetape_mtioctop(drive,mtop.mt_op,mtop.mt_count)); | 3152 | return idetape_mtioctop(drive, mtop.mt_op, mtop.mt_count); |
3315 | case MTIOCGET: | 3153 | case MTIOCGET: |
3316 | memset(&mtget, 0, sizeof (struct mtget)); | 3154 | memset(&mtget, 0, sizeof(struct mtget)); |
3317 | mtget.mt_type = MT_ISSCSI2; | 3155 | mtget.mt_type = MT_ISSCSI2; |
3318 | mtget.mt_blkno = position / tape->user_bs_factor - block_offset; | 3156 | mtget.mt_blkno = position / tape->user_bs_factor - block_offset; |
3319 | mtget.mt_dsreg = ((tape->tape_block_size * tape->user_bs_factor) << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; | 3157 | mtget.mt_dsreg = |
3320 | if (tape->drv_write_prot) { | 3158 | ((tape->blk_size * tape->user_bs_factor) |
3321 | mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); | 3159 | << MT_ST_BLKSIZE_SHIFT) & MT_ST_BLKSIZE_MASK; |
3322 | } | 3160 | |
3323 | if (copy_to_user(argp, &mtget, sizeof(struct mtget))) | 3161 | if (tape->drv_write_prot) |
3324 | return -EFAULT; | 3162 | mtget.mt_gstat |= GMT_WR_PROT(0xffffffff); |
3325 | return 0; | 3163 | |
3326 | case MTIOCPOS: | 3164 | if (copy_to_user(argp, &mtget, sizeof(struct mtget))) |
3327 | mtpos.mt_blkno = position / tape->user_bs_factor - block_offset; | 3165 | return -EFAULT; |
3328 | if (copy_to_user(argp, &mtpos, sizeof(struct mtpos))) | 3166 | return 0; |
3329 | return -EFAULT; | 3167 | case MTIOCPOS: |
3330 | return 0; | 3168 | mtpos.mt_blkno = position / tape->user_bs_factor - block_offset; |
3331 | default: | 3169 | if (copy_to_user(argp, &mtpos, sizeof(struct mtpos))) |
3332 | if (tape->chrdev_direction == idetape_direction_read) | 3170 | return -EFAULT; |
3333 | idetape_discard_read_pipeline(drive, 1); | 3171 | return 0; |
3334 | return idetape_blkdev_ioctl(drive, cmd, arg); | 3172 | default: |
3173 | if (tape->chrdev_dir == IDETAPE_DIR_READ) | ||
3174 | idetape_discard_read_pipeline(drive, 1); | ||
3175 | return idetape_blkdev_ioctl(drive, cmd, arg); | ||
3335 | } | 3176 | } |
3336 | } | 3177 | } |
3337 | 3178 | ||
@@ -3347,23 +3188,20 @@ static void ide_tape_get_bsize_from_bdesc(ide_drive_t *drive) | |||
3347 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); | 3188 | idetape_create_mode_sense_cmd(&pc, IDETAPE_BLOCK_DESCRIPTOR); |
3348 | if (idetape_queue_pc_tail(drive, &pc)) { | 3189 | if (idetape_queue_pc_tail(drive, &pc)) { |
3349 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); | 3190 | printk(KERN_ERR "ide-tape: Can't get block descriptor\n"); |
3350 | if (tape->tape_block_size == 0) { | 3191 | if (tape->blk_size == 0) { |
3351 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " | 3192 | printk(KERN_WARNING "ide-tape: Cannot deal with zero " |
3352 | "block size, assuming 32k\n"); | 3193 | "block size, assuming 32k\n"); |
3353 | tape->tape_block_size = 32768; | 3194 | tape->blk_size = 32768; |
3354 | } | 3195 | } |
3355 | return; | 3196 | return; |
3356 | } | 3197 | } |
3357 | tape->tape_block_size = (pc.buffer[4 + 5] << 16) + | 3198 | tape->blk_size = (pc.buffer[4 + 5] << 16) + |
3358 | (pc.buffer[4 + 6] << 8) + | 3199 | (pc.buffer[4 + 6] << 8) + |
3359 | pc.buffer[4 + 7]; | 3200 | pc.buffer[4 + 7]; |
3360 | tape->drv_write_prot = (pc.buffer[2] & 0x80) >> 7; | 3201 | tape->drv_write_prot = (pc.buffer[2] & 0x80) >> 7; |
3361 | } | 3202 | } |
3362 | 3203 | ||
3363 | /* | 3204 | static int idetape_chrdev_open(struct inode *inode, struct file *filp) |
3364 | * Our character device open function. | ||
3365 | */ | ||
3366 | static int idetape_chrdev_open (struct inode *inode, struct file *filp) | ||
3367 | { | 3205 | { |
3368 | unsigned int minor = iminor(inode), i = minor & ~0xc0; | 3206 | unsigned int minor = iminor(inode), i = minor & ~0xc0; |
3369 | ide_drive_t *drive; | 3207 | ide_drive_t *drive; |
@@ -3371,6 +3209,15 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) | |||
3371 | idetape_pc_t pc; | 3209 | idetape_pc_t pc; |
3372 | int retval; | 3210 | int retval; |
3373 | 3211 | ||
3212 | if (i >= MAX_HWIFS * MAX_DRIVES) | ||
3213 | return -ENXIO; | ||
3214 | |||
3215 | tape = ide_tape_chrdev_get(i); | ||
3216 | if (!tape) | ||
3217 | return -ENXIO; | ||
3218 | |||
3219 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); | ||
3220 | |||
3374 | /* | 3221 | /* |
3375 | * We really want to do nonseekable_open(inode, filp); here, but some | 3222 | * We really want to do nonseekable_open(inode, filp); here, but some |
3376 | * versions of tar incorrectly call lseek on tapes and bail out if that | 3223 | * versions of tar incorrectly call lseek on tapes and bail out if that |
@@ -3378,16 +3225,6 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) | |||
3378 | */ | 3225 | */ |
3379 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); | 3226 | filp->f_mode &= ~(FMODE_PREAD | FMODE_PWRITE); |
3380 | 3227 | ||
3381 | #if IDETAPE_DEBUG_LOG | ||
3382 | printk(KERN_INFO "ide-tape: Reached idetape_chrdev_open\n"); | ||
3383 | #endif /* IDETAPE_DEBUG_LOG */ | ||
3384 | |||
3385 | if (i >= MAX_HWIFS * MAX_DRIVES) | ||
3386 | return -ENXIO; | ||
3387 | |||
3388 | if (!(tape = ide_tape_chrdev_get(i))) | ||
3389 | return -ENXIO; | ||
3390 | |||
3391 | drive = tape->drive; | 3228 | drive = tape->drive; |
3392 | 3229 | ||
3393 | filp->private_data = tape; | 3230 | filp->private_data = tape; |
@@ -3408,7 +3245,7 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) | |||
3408 | if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags)) | 3245 | if (!test_bit(IDETAPE_ADDRESS_VALID, &tape->flags)) |
3409 | (void)idetape_rewind_tape(drive); | 3246 | (void)idetape_rewind_tape(drive); |
3410 | 3247 | ||
3411 | if (tape->chrdev_direction != idetape_direction_read) | 3248 | if (tape->chrdev_dir != IDETAPE_DIR_READ) |
3412 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); | 3249 | clear_bit(IDETAPE_PIPELINE_ERROR, &tape->flags); |
3413 | 3250 | ||
3414 | /* Read block size and write protect status from drive. */ | 3251 | /* Read block size and write protect status from drive. */ |
@@ -3430,10 +3267,8 @@ static int idetape_chrdev_open (struct inode *inode, struct file *filp) | |||
3430 | } | 3267 | } |
3431 | } | 3268 | } |
3432 | 3269 | ||
3433 | /* | 3270 | /* Lock the tape drive door so user can't eject. */ |
3434 | * Lock the tape drive door so user can't eject. | 3271 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
3435 | */ | ||
3436 | if (tape->chrdev_direction == idetape_direction_none) { | ||
3437 | if (idetape_create_prevent_cmd(drive, &pc, 1)) { | 3272 | if (idetape_create_prevent_cmd(drive, &pc, 1)) { |
3438 | if (!idetape_queue_pc_tail(drive, &pc)) { | 3273 | if (!idetape_queue_pc_tail(drive, &pc)) { |
3439 | if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) | 3274 | if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) |
@@ -3450,14 +3285,15 @@ out_put_tape: | |||
3450 | return retval; | 3285 | return retval; |
3451 | } | 3286 | } |
3452 | 3287 | ||
3453 | static void idetape_write_release (ide_drive_t *drive, unsigned int minor) | 3288 | static void idetape_write_release(ide_drive_t *drive, unsigned int minor) |
3454 | { | 3289 | { |
3455 | idetape_tape_t *tape = drive->driver_data; | 3290 | idetape_tape_t *tape = drive->driver_data; |
3456 | 3291 | ||
3457 | idetape_empty_write_pipeline(drive); | 3292 | idetape_empty_write_pipeline(drive); |
3458 | tape->merge_stage = __idetape_kmalloc_stage(tape, 1, 0); | 3293 | tape->merge_stage = __idetape_kmalloc_stage(tape, 1, 0); |
3459 | if (tape->merge_stage != NULL) { | 3294 | if (tape->merge_stage != NULL) { |
3460 | idetape_pad_zeros(drive, tape->tape_block_size * (tape->user_bs_factor - 1)); | 3295 | idetape_pad_zeros(drive, tape->blk_size * |
3296 | (tape->user_bs_factor - 1)); | ||
3461 | __idetape_kfree_stage(tape->merge_stage); | 3297 | __idetape_kfree_stage(tape->merge_stage); |
3462 | tape->merge_stage = NULL; | 3298 | tape->merge_stage = NULL; |
3463 | } | 3299 | } |
@@ -3466,10 +3302,7 @@ static void idetape_write_release (ide_drive_t *drive, unsigned int minor) | |||
3466 | idetape_flush_tape_buffers(drive); | 3302 | idetape_flush_tape_buffers(drive); |
3467 | } | 3303 | } |
3468 | 3304 | ||
3469 | /* | 3305 | static int idetape_chrdev_release(struct inode *inode, struct file *filp) |
3470 | * Our character device release function. | ||
3471 | */ | ||
3472 | static int idetape_chrdev_release (struct inode *inode, struct file *filp) | ||
3473 | { | 3306 | { |
3474 | struct ide_tape_obj *tape = ide_tape_f(filp); | 3307 | struct ide_tape_obj *tape = ide_tape_f(filp); |
3475 | ide_drive_t *drive = tape->drive; | 3308 | ide_drive_t *drive = tape->drive; |
@@ -3478,14 +3311,12 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) | |||
3478 | 3311 | ||
3479 | lock_kernel(); | 3312 | lock_kernel(); |
3480 | tape = drive->driver_data; | 3313 | tape = drive->driver_data; |
3481 | #if IDETAPE_DEBUG_LOG | ||
3482 | if (tape->debug_level >= 3) | ||
3483 | printk(KERN_INFO "ide-tape: Reached idetape_chrdev_release\n"); | ||
3484 | #endif /* IDETAPE_DEBUG_LOG */ | ||
3485 | 3314 | ||
3486 | if (tape->chrdev_direction == idetape_direction_write) | 3315 | debug_log(DBG_CHRDEV, "Enter %s\n", __func__); |
3316 | |||
3317 | if (tape->chrdev_dir == IDETAPE_DIR_WRITE) | ||
3487 | idetape_write_release(drive, minor); | 3318 | idetape_write_release(drive, minor); |
3488 | if (tape->chrdev_direction == idetape_direction_read) { | 3319 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
3489 | if (minor < 128) | 3320 | if (minor < 128) |
3490 | idetape_discard_read_pipeline(drive, 1); | 3321 | idetape_discard_read_pipeline(drive, 1); |
3491 | else | 3322 | else |
@@ -3497,7 +3328,7 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) | |||
3497 | } | 3328 | } |
3498 | if (minor < 128 && test_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags)) | 3329 | if (minor < 128 && test_bit(IDETAPE_MEDIUM_PRESENT, &tape->flags)) |
3499 | (void) idetape_rewind_tape(drive); | 3330 | (void) idetape_rewind_tape(drive); |
3500 | if (tape->chrdev_direction == idetape_direction_none) { | 3331 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
3501 | if (tape->door_locked == DOOR_LOCKED) { | 3332 | if (tape->door_locked == DOOR_LOCKED) { |
3502 | if (idetape_create_prevent_cmd(drive, &pc, 0)) { | 3333 | if (idetape_create_prevent_cmd(drive, &pc, 0)) { |
3503 | if (!idetape_queue_pc_tail(drive, &pc)) | 3334 | if (!idetape_queue_pc_tail(drive, &pc)) |
@@ -3512,37 +3343,39 @@ static int idetape_chrdev_release (struct inode *inode, struct file *filp) | |||
3512 | } | 3343 | } |
3513 | 3344 | ||
3514 | /* | 3345 | /* |
3515 | * idetape_identify_device is called to check the contents of the | 3346 | * check the contents of the ATAPI IDENTIFY command results. We return: |
3516 | * ATAPI IDENTIFY command results. We return: | ||
3517 | * | 3347 | * |
3518 | * 1 If the tape can be supported by us, based on the information | 3348 | * 1 - If the tape can be supported by us, based on the information we have so |
3519 | * we have so far. | 3349 | * far. |
3520 | * | 3350 | * |
3521 | * 0 If this tape driver is not currently supported by us. | 3351 | * 0 - If this tape driver is not currently supported by us. |
3522 | */ | 3352 | */ |
3523 | static int idetape_identify_device (ide_drive_t *drive) | 3353 | static int idetape_identify_device(ide_drive_t *drive) |
3524 | { | 3354 | { |
3525 | struct idetape_id_gcw gcw; | 3355 | u8 gcw[2], protocol, device_type, removable, packet_size; |
3526 | struct hd_driveid *id = drive->id; | ||
3527 | 3356 | ||
3528 | if (drive->id_read == 0) | 3357 | if (drive->id_read == 0) |
3529 | return 1; | 3358 | return 1; |
3530 | 3359 | ||
3531 | *((unsigned short *) &gcw) = id->config; | 3360 | *((unsigned short *) &gcw) = drive->id->config; |
3361 | |||
3362 | protocol = (gcw[1] & 0xC0) >> 6; | ||
3363 | device_type = gcw[1] & 0x1F; | ||
3364 | removable = !!(gcw[0] & 0x80); | ||
3365 | packet_size = gcw[0] & 0x3; | ||
3532 | 3366 | ||
3533 | /* Check that we can support this device */ | 3367 | /* Check that we can support this device */ |
3534 | 3368 | if (protocol != 2) | |
3535 | if (gcw.protocol != 2) | ||
3536 | printk(KERN_ERR "ide-tape: Protocol (0x%02x) is not ATAPI\n", | 3369 | printk(KERN_ERR "ide-tape: Protocol (0x%02x) is not ATAPI\n", |
3537 | gcw.protocol); | 3370 | protocol); |
3538 | else if (gcw.device_type != 1) | 3371 | else if (device_type != 1) |
3539 | printk(KERN_ERR "ide-tape: Device type (0x%02x) is not set " | 3372 | printk(KERN_ERR "ide-tape: Device type (0x%02x) is not set " |
3540 | "to tape\n", gcw.device_type); | 3373 | "to tape\n", device_type); |
3541 | else if (!gcw.removable) | 3374 | else if (!removable) |
3542 | printk(KERN_ERR "ide-tape: The removable flag is not set\n"); | 3375 | printk(KERN_ERR "ide-tape: The removable flag is not set\n"); |
3543 | else if (gcw.packet_size != 0) { | 3376 | else if (packet_size != 0) { |
3544 | printk(KERN_ERR "ide-tape: Packet size (0x%02x) is not 12 " | 3377 | printk(KERN_ERR "ide-tape: Packet size (0x%02x) is not 12" |
3545 | "bytes long\n", gcw.packet_size); | 3378 | " bytes\n", packet_size); |
3546 | } else | 3379 | } else |
3547 | return 1; | 3380 | return 1; |
3548 | return 0; | 3381 | return 0; |
@@ -3550,9 +3383,9 @@ static int idetape_identify_device (ide_drive_t *drive) | |||
3550 | 3383 | ||
3551 | static void idetape_get_inquiry_results(ide_drive_t *drive) | 3384 | static void idetape_get_inquiry_results(ide_drive_t *drive) |
3552 | { | 3385 | { |
3553 | char *r; | ||
3554 | idetape_tape_t *tape = drive->driver_data; | 3386 | idetape_tape_t *tape = drive->driver_data; |
3555 | idetape_pc_t pc; | 3387 | idetape_pc_t pc; |
3388 | char fw_rev[6], vendor_id[10], product_id[18]; | ||
3556 | 3389 | ||
3557 | idetape_create_inquiry_cmd(&pc); | 3390 | idetape_create_inquiry_cmd(&pc); |
3558 | if (idetape_queue_pc_tail(drive, &pc)) { | 3391 | if (idetape_queue_pc_tail(drive, &pc)) { |
@@ -3560,27 +3393,23 @@ static void idetape_get_inquiry_results(ide_drive_t *drive) | |||
3560 | tape->name); | 3393 | tape->name); |
3561 | return; | 3394 | return; |
3562 | } | 3395 | } |
3563 | memcpy(tape->vendor_id, &pc.buffer[8], 8); | 3396 | memcpy(vendor_id, &pc.buffer[8], 8); |
3564 | memcpy(tape->product_id, &pc.buffer[16], 16); | 3397 | memcpy(product_id, &pc.buffer[16], 16); |
3565 | memcpy(tape->firmware_revision, &pc.buffer[32], 4); | 3398 | memcpy(fw_rev, &pc.buffer[32], 4); |
3566 | 3399 | ||
3567 | ide_fixstring(tape->vendor_id, 10, 0); | 3400 | ide_fixstring(vendor_id, 10, 0); |
3568 | ide_fixstring(tape->product_id, 18, 0); | 3401 | ide_fixstring(product_id, 18, 0); |
3569 | ide_fixstring(tape->firmware_revision, 6, 0); | 3402 | ide_fixstring(fw_rev, 6, 0); |
3570 | r = tape->firmware_revision; | 3403 | |
3571 | if (*(r + 1) == '.') | ||
3572 | tape->firmware_revision_num = (*r - '0') * 100 + | ||
3573 | (*(r + 2) - '0') * 10 + *(r + 3) - '0'; | ||
3574 | printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", | 3404 | printk(KERN_INFO "ide-tape: %s <-> %s: %s %s rev %s\n", |
3575 | drive->name, tape->name, tape->vendor_id, | 3405 | drive->name, tape->name, vendor_id, product_id, fw_rev); |
3576 | tape->product_id, tape->firmware_revision); | ||
3577 | } | 3406 | } |
3578 | 3407 | ||
3579 | /* | 3408 | /* |
3580 | * Ask the tape about its various parameters. In particular, we will adjust our | 3409 | * Ask the tape about its various parameters. In particular, we will adjust our |
3581 | * data transfer buffer size to the recommended value as returned by the tape. | 3410 | * data transfer buffer size to the recommended value as returned by the tape. |
3582 | */ | 3411 | */ |
3583 | static void idetape_get_mode_sense_results (ide_drive_t *drive) | 3412 | static void idetape_get_mode_sense_results(ide_drive_t *drive) |
3584 | { | 3413 | { |
3585 | idetape_tape_t *tape = drive->driver_data; | 3414 | idetape_tape_t *tape = drive->driver_data; |
3586 | idetape_pc_t pc; | 3415 | idetape_pc_t pc; |
@@ -3591,7 +3420,7 @@ static void idetape_get_mode_sense_results (ide_drive_t *drive) | |||
3591 | if (idetape_queue_pc_tail(drive, &pc)) { | 3420 | if (idetape_queue_pc_tail(drive, &pc)) { |
3592 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" | 3421 | printk(KERN_ERR "ide-tape: Can't get tape parameters - assuming" |
3593 | " some default values\n"); | 3422 | " some default values\n"); |
3594 | tape->tape_block_size = 512; | 3423 | tape->blk_size = 512; |
3595 | put_unaligned(52, (u16 *)&tape->caps[12]); | 3424 | put_unaligned(52, (u16 *)&tape->caps[12]); |
3596 | put_unaligned(540, (u16 *)&tape->caps[14]); | 3425 | put_unaligned(540, (u16 *)&tape->caps[14]); |
3597 | put_unaligned(6*52, (u16 *)&tape->caps[16]); | 3426 | put_unaligned(6*52, (u16 *)&tape->caps[16]); |
@@ -3621,62 +3450,75 @@ static void idetape_get_mode_sense_results (ide_drive_t *drive) | |||
3621 | 3450 | ||
3622 | memcpy(&tape->caps, caps, 20); | 3451 | memcpy(&tape->caps, caps, 20); |
3623 | if (caps[7] & 0x02) | 3452 | if (caps[7] & 0x02) |
3624 | tape->tape_block_size = 512; | 3453 | tape->blk_size = 512; |
3625 | else if (caps[7] & 0x04) | 3454 | else if (caps[7] & 0x04) |
3626 | tape->tape_block_size = 1024; | 3455 | tape->blk_size = 1024; |
3627 | } | 3456 | } |
3628 | 3457 | ||
3629 | #ifdef CONFIG_IDE_PROC_FS | 3458 | #ifdef CONFIG_IDE_PROC_FS |
3630 | static void idetape_add_settings (ide_drive_t *drive) | 3459 | static void idetape_add_settings(ide_drive_t *drive) |
3631 | { | 3460 | { |
3632 | idetape_tape_t *tape = drive->driver_data; | 3461 | idetape_tape_t *tape = drive->driver_data; |
3633 | 3462 | ||
3634 | /* | ||
3635 | * drive setting name read/write data type min max mul_factor div_factor data pointer set function | ||
3636 | */ | ||
3637 | ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff, | 3463 | ide_add_setting(drive, "buffer", SETTING_READ, TYPE_SHORT, 0, 0xffff, |
3638 | 1, 2, (u16 *)&tape->caps[16], NULL); | 3464 | 1, 2, (u16 *)&tape->caps[16], NULL); |
3639 | ide_add_setting(drive, "pipeline_min", SETTING_RW, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->min_pipeline, NULL); | 3465 | ide_add_setting(drive, "pipeline_min", SETTING_RW, TYPE_INT, 1, 0xffff, |
3640 | ide_add_setting(drive, "pipeline", SETTING_RW, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->max_stages, NULL); | 3466 | tape->stage_size / 1024, 1, &tape->min_pipeline, NULL); |
3641 | ide_add_setting(drive, "pipeline_max", SETTING_RW, TYPE_INT, 1, 0xffff, tape->stage_size / 1024, 1, &tape->max_pipeline, NULL); | 3467 | ide_add_setting(drive, "pipeline", SETTING_RW, TYPE_INT, 1, 0xffff, |
3642 | ide_add_setting(drive, "pipeline_used", SETTING_READ, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_stages, NULL); | 3468 | tape->stage_size / 1024, 1, &tape->max_stages, NULL); |
3643 | ide_add_setting(drive, "pipeline_pending", SETTING_READ, TYPE_INT, 0, 0xffff, tape->stage_size / 1024, 1, &tape->nr_pending_stages, NULL); | 3469 | ide_add_setting(drive, "pipeline_max", SETTING_RW, TYPE_INT, 1, 0xffff, |
3470 | tape->stage_size / 1024, 1, &tape->max_pipeline, NULL); | ||
3471 | ide_add_setting(drive, "pipeline_used", SETTING_READ, TYPE_INT, 0, | ||
3472 | 0xffff, tape->stage_size / 1024, 1, &tape->nr_stages, | ||
3473 | NULL); | ||
3474 | ide_add_setting(drive, "pipeline_pending", SETTING_READ, TYPE_INT, 0, | ||
3475 | 0xffff, tape->stage_size / 1024, 1, | ||
3476 | &tape->nr_pending_stages, NULL); | ||
3644 | ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff, | 3477 | ide_add_setting(drive, "speed", SETTING_READ, TYPE_SHORT, 0, 0xffff, |
3645 | 1, 1, (u16 *)&tape->caps[14], NULL); | 3478 | 1, 1, (u16 *)&tape->caps[14], NULL); |
3646 | ide_add_setting(drive, "stage", SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1024, &tape->stage_size, NULL); | 3479 | ide_add_setting(drive, "stage", SETTING_READ, TYPE_INT, 0, 0xffff, 1, |
3647 | ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN, IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_frequency, NULL); | 3480 | 1024, &tape->stage_size, NULL); |
3648 | ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, 1, &drive->dsc_overlap, NULL); | 3481 | ide_add_setting(drive, "tdsc", SETTING_RW, TYPE_INT, IDETAPE_DSC_RW_MIN, |
3649 | ide_add_setting(drive, "pipeline_head_speed_c",SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1, &tape->controlled_pipeline_head_speed, NULL); | 3482 | IDETAPE_DSC_RW_MAX, 1000, HZ, &tape->best_dsc_rw_freq, |
3650 | ide_add_setting(drive, "pipeline_head_speed_u",SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1, &tape->uncontrolled_pipeline_head_speed,NULL); | 3483 | NULL); |
3651 | ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff, 1, 1, &tape->avg_speed, NULL); | 3484 | ide_add_setting(drive, "dsc_overlap", SETTING_RW, TYPE_BYTE, 0, 1, 1, |
3652 | ide_add_setting(drive, "debug_level", SETTING_RW, TYPE_INT, 0, 0xffff, 1, 1, &tape->debug_level, NULL); | 3485 | 1, &drive->dsc_overlap, NULL); |
3486 | ide_add_setting(drive, "pipeline_head_speed_c", SETTING_READ, TYPE_INT, | ||
3487 | 0, 0xffff, 1, 1, &tape->controlled_pipeline_head_speed, | ||
3488 | NULL); | ||
3489 | ide_add_setting(drive, "pipeline_head_speed_u", SETTING_READ, TYPE_INT, | ||
3490 | 0, 0xffff, 1, 1, | ||
3491 | &tape->uncontrolled_pipeline_head_speed, NULL); | ||
3492 | ide_add_setting(drive, "avg_speed", SETTING_READ, TYPE_INT, 0, 0xffff, | ||
3493 | 1, 1, &tape->avg_speed, NULL); | ||
3494 | ide_add_setting(drive, "debug_mask", SETTING_RW, TYPE_INT, 0, 0xffff, 1, | ||
3495 | 1, &tape->debug_mask, NULL); | ||
3653 | } | 3496 | } |
3654 | #else | 3497 | #else |
3655 | static inline void idetape_add_settings(ide_drive_t *drive) { ; } | 3498 | static inline void idetape_add_settings(ide_drive_t *drive) { ; } |
3656 | #endif | 3499 | #endif |
3657 | 3500 | ||
3658 | /* | 3501 | /* |
3659 | * ide_setup is called to: | 3502 | * The function below is called to: |
3660 | * | 3503 | * |
3661 | * 1. Initialize our various state variables. | 3504 | * 1. Initialize our various state variables. |
3662 | * 2. Ask the tape for its capabilities. | 3505 | * 2. Ask the tape for its capabilities. |
3663 | * 3. Allocate a buffer which will be used for data | 3506 | * 3. Allocate a buffer which will be used for data transfer. The buffer size |
3664 | * transfer. The buffer size is chosen based on | 3507 | * is chosen based on the recommendation which we received in step 2. |
3665 | * the recommendation which we received in step (2). | ||
3666 | * | 3508 | * |
3667 | * Note that at this point ide.c already assigned us an irq, so that | 3509 | * Note that at this point ide.c already assigned us an irq, so that we can |
3668 | * we can queue requests here and wait for their completion. | 3510 | * queue requests here and wait for their completion. |
3669 | */ | 3511 | */ |
3670 | static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) | 3512 | static void idetape_setup(ide_drive_t *drive, idetape_tape_t *tape, int minor) |
3671 | { | 3513 | { |
3672 | unsigned long t1, tmid, tn, t; | 3514 | unsigned long t1, tmid, tn, t; |
3673 | int speed; | 3515 | int speed; |
3674 | struct idetape_id_gcw gcw; | ||
3675 | int stage_size; | 3516 | int stage_size; |
3517 | u8 gcw[2]; | ||
3676 | struct sysinfo si; | 3518 | struct sysinfo si; |
3677 | u16 *ctl = (u16 *)&tape->caps[12]; | 3519 | u16 *ctl = (u16 *)&tape->caps[12]; |
3678 | 3520 | ||
3679 | spin_lock_init(&tape->spinlock); | 3521 | spin_lock_init(&tape->lock); |
3680 | drive->dsc_overlap = 1; | 3522 | drive->dsc_overlap = 1; |
3681 | if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { | 3523 | if (drive->hwif->host_flags & IDE_HFLAG_NO_DSC) { |
3682 | printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", | 3524 | printk(KERN_INFO "ide-tape: %s: disabling DSC overlap\n", |
@@ -3690,25 +3532,29 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
3690 | tape->name[0] = 'h'; | 3532 | tape->name[0] = 'h'; |
3691 | tape->name[1] = 't'; | 3533 | tape->name[1] = 't'; |
3692 | tape->name[2] = '0' + minor; | 3534 | tape->name[2] = '0' + minor; |
3693 | tape->chrdev_direction = idetape_direction_none; | 3535 | tape->chrdev_dir = IDETAPE_DIR_NONE; |
3694 | tape->pc = tape->pc_stack; | 3536 | tape->pc = tape->pc_stack; |
3695 | tape->max_insert_speed = 10000; | 3537 | tape->max_insert_speed = 10000; |
3696 | tape->speed_control = 1; | 3538 | tape->speed_control = 1; |
3697 | *((unsigned short *) &gcw) = drive->id->config; | 3539 | *((unsigned short *) &gcw) = drive->id->config; |
3698 | if (gcw.drq_type == 1) | 3540 | |
3541 | /* Command packet DRQ type */ | ||
3542 | if (((gcw[0] & 0x60) >> 5) == 1) | ||
3699 | set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags); | 3543 | set_bit(IDETAPE_DRQ_INTERRUPT, &tape->flags); |
3700 | 3544 | ||
3701 | tape->min_pipeline = tape->max_pipeline = tape->max_stages = 10; | 3545 | tape->min_pipeline = 10; |
3702 | 3546 | tape->max_pipeline = 10; | |
3547 | tape->max_stages = 10; | ||
3548 | |||
3703 | idetape_get_inquiry_results(drive); | 3549 | idetape_get_inquiry_results(drive); |
3704 | idetape_get_mode_sense_results(drive); | 3550 | idetape_get_mode_sense_results(drive); |
3705 | ide_tape_get_bsize_from_bdesc(drive); | 3551 | ide_tape_get_bsize_from_bdesc(drive); |
3706 | tape->user_bs_factor = 1; | 3552 | tape->user_bs_factor = 1; |
3707 | tape->stage_size = *ctl * tape->tape_block_size; | 3553 | tape->stage_size = *ctl * tape->blk_size; |
3708 | while (tape->stage_size > 0xffff) { | 3554 | while (tape->stage_size > 0xffff) { |
3709 | printk(KERN_NOTICE "ide-tape: decreasing stage size\n"); | 3555 | printk(KERN_NOTICE "ide-tape: decreasing stage size\n"); |
3710 | *ctl /= 2; | 3556 | *ctl /= 2; |
3711 | tape->stage_size = *ctl * tape->tape_block_size; | 3557 | tape->stage_size = *ctl * tape->blk_size; |
3712 | } | 3558 | } |
3713 | stage_size = tape->stage_size; | 3559 | stage_size = tape->stage_size; |
3714 | tape->pages_per_stage = stage_size / PAGE_SIZE; | 3560 | tape->pages_per_stage = stage_size / PAGE_SIZE; |
@@ -3722,17 +3568,22 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
3722 | 3568 | ||
3723 | tape->max_stages = speed * 1000 * 10 / tape->stage_size; | 3569 | tape->max_stages = speed * 1000 * 10 / tape->stage_size; |
3724 | 3570 | ||
3725 | /* | 3571 | /* Limit memory use for pipeline to 10% of physical memory */ |
3726 | * Limit memory use for pipeline to 10% of physical memory | ||
3727 | */ | ||
3728 | si_meminfo(&si); | 3572 | si_meminfo(&si); |
3729 | if (tape->max_stages * tape->stage_size > si.totalram * si.mem_unit / 10) | 3573 | if (tape->max_stages * tape->stage_size > |
3730 | tape->max_stages = si.totalram * si.mem_unit / (10 * tape->stage_size); | 3574 | si.totalram * si.mem_unit / 10) |
3575 | tape->max_stages = | ||
3576 | si.totalram * si.mem_unit / (10 * tape->stage_size); | ||
3577 | |||
3731 | tape->max_stages = min(tape->max_stages, IDETAPE_MAX_PIPELINE_STAGES); | 3578 | tape->max_stages = min(tape->max_stages, IDETAPE_MAX_PIPELINE_STAGES); |
3732 | tape->min_pipeline = min(tape->max_stages, IDETAPE_MIN_PIPELINE_STAGES); | 3579 | tape->min_pipeline = min(tape->max_stages, IDETAPE_MIN_PIPELINE_STAGES); |
3733 | tape->max_pipeline = min(tape->max_stages * 2, IDETAPE_MAX_PIPELINE_STAGES); | 3580 | tape->max_pipeline = |
3734 | if (tape->max_stages == 0) | 3581 | min(tape->max_stages * 2, IDETAPE_MAX_PIPELINE_STAGES); |
3735 | tape->max_stages = tape->min_pipeline = tape->max_pipeline = 1; | 3582 | if (tape->max_stages == 0) { |
3583 | tape->max_stages = 1; | ||
3584 | tape->min_pipeline = 1; | ||
3585 | tape->max_pipeline = 1; | ||
3586 | } | ||
3736 | 3587 | ||
3737 | t1 = (tape->stage_size * HZ) / (speed * 1000); | 3588 | t1 = (tape->stage_size * HZ) / (speed * 1000); |
3738 | tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125); | 3589 | tmid = (*(u16 *)&tape->caps[16] * 32 * HZ) / (speed * 125); |
@@ -3744,17 +3595,19 @@ static void idetape_setup (ide_drive_t *drive, idetape_tape_t *tape, int minor) | |||
3744 | t = t1; | 3595 | t = t1; |
3745 | 3596 | ||
3746 | /* | 3597 | /* |
3747 | * Ensure that the number we got makes sense; limit | 3598 | * Ensure that the number we got makes sense; limit it within |
3748 | * it within IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. | 3599 | * IDETAPE_DSC_RW_MIN and IDETAPE_DSC_RW_MAX. |
3749 | */ | 3600 | */ |
3750 | tape->best_dsc_rw_frequency = max_t(unsigned long, min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), IDETAPE_DSC_RW_MIN); | 3601 | tape->best_dsc_rw_freq = max_t(unsigned long, |
3602 | min_t(unsigned long, t, IDETAPE_DSC_RW_MAX), | ||
3603 | IDETAPE_DSC_RW_MIN); | ||
3751 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " | 3604 | printk(KERN_INFO "ide-tape: %s <-> %s: %dKBps, %d*%dkB buffer, " |
3752 | "%dkB pipeline, %lums tDSC%s\n", | 3605 | "%dkB pipeline, %lums tDSC%s\n", |
3753 | drive->name, tape->name, *(u16 *)&tape->caps[14], | 3606 | drive->name, tape->name, *(u16 *)&tape->caps[14], |
3754 | (*(u16 *)&tape->caps[16] * 512) / tape->stage_size, | 3607 | (*(u16 *)&tape->caps[16] * 512) / tape->stage_size, |
3755 | tape->stage_size / 1024, | 3608 | tape->stage_size / 1024, |
3756 | tape->max_stages * tape->stage_size / 1024, | 3609 | tape->max_stages * tape->stage_size / 1024, |
3757 | tape->best_dsc_rw_frequency * 1000 / HZ, | 3610 | tape->best_dsc_rw_freq * 1000 / HZ, |
3758 | drive->using_dma ? ", DMA":""); | 3611 | drive->using_dma ? ", DMA":""); |
3759 | 3612 | ||
3760 | idetape_add_settings(drive); | 3613 | idetape_add_settings(drive); |
@@ -3782,7 +3635,8 @@ static void ide_tape_release(struct kref *kref) | |||
3782 | drive->dsc_overlap = 0; | 3635 | drive->dsc_overlap = 0; |
3783 | drive->driver_data = NULL; | 3636 | drive->driver_data = NULL; |
3784 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); | 3637 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor)); |
3785 | device_destroy(idetape_sysfs_class, MKDEV(IDETAPE_MAJOR, tape->minor + 128)); | 3638 | device_destroy(idetape_sysfs_class, |
3639 | MKDEV(IDETAPE_MAJOR, tape->minor + 128)); | ||
3786 | idetape_devs[tape->minor] = NULL; | 3640 | idetape_devs[tape->minor] = NULL; |
3787 | g->private_data = NULL; | 3641 | g->private_data = NULL; |
3788 | put_disk(g); | 3642 | put_disk(g); |
@@ -3831,9 +3685,7 @@ static ide_driver_t idetape_driver = { | |||
3831 | #endif | 3685 | #endif |
3832 | }; | 3686 | }; |
3833 | 3687 | ||
3834 | /* | 3688 | /* Our character device supporting functions, passed to register_chrdev. */ |
3835 | * Our character device supporting functions, passed to register_chrdev. | ||
3836 | */ | ||
3837 | static const struct file_operations idetape_fops = { | 3689 | static const struct file_operations idetape_fops = { |
3838 | .owner = THIS_MODULE, | 3690 | .owner = THIS_MODULE, |
3839 | .read = idetape_chrdev_read, | 3691 | .read = idetape_chrdev_read, |
@@ -3848,7 +3700,8 @@ static int idetape_open(struct inode *inode, struct file *filp) | |||
3848 | struct gendisk *disk = inode->i_bdev->bd_disk; | 3700 | struct gendisk *disk = inode->i_bdev->bd_disk; |
3849 | struct ide_tape_obj *tape; | 3701 | struct ide_tape_obj *tape; |
3850 | 3702 | ||
3851 | if (!(tape = ide_tape_get(disk))) | 3703 | tape = ide_tape_get(disk); |
3704 | if (!tape) | ||
3852 | return -ENXIO; | 3705 | return -ENXIO; |
3853 | 3706 | ||
3854 | return 0; | 3707 | return 0; |
@@ -3895,21 +3748,20 @@ static int ide_tape_probe(ide_drive_t *drive) | |||
3895 | goto failed; | 3748 | goto failed; |
3896 | if (drive->media != ide_tape) | 3749 | if (drive->media != ide_tape) |
3897 | goto failed; | 3750 | goto failed; |
3898 | if (!idetape_identify_device (drive)) { | 3751 | if (!idetape_identify_device(drive)) { |
3899 | printk(KERN_ERR "ide-tape: %s: not supported by this version of ide-tape\n", drive->name); | 3752 | printk(KERN_ERR "ide-tape: %s: not supported by this version of" |
3753 | " the driver\n", drive->name); | ||
3900 | goto failed; | 3754 | goto failed; |
3901 | } | 3755 | } |
3902 | if (drive->scsi) { | 3756 | if (drive->scsi) { |
3903 | printk("ide-tape: passing drive %s to ide-scsi emulation.\n", drive->name); | 3757 | printk(KERN_INFO "ide-tape: passing drive %s to ide-scsi" |
3758 | " emulation.\n", drive->name); | ||
3904 | goto failed; | 3759 | goto failed; |
3905 | } | 3760 | } |
3906 | if (strstr(drive->id->model, "OnStream DI-")) { | 3761 | tape = kzalloc(sizeof(idetape_tape_t), GFP_KERNEL); |
3907 | printk(KERN_WARNING "ide-tape: Use drive %s with ide-scsi emulation and osst.\n", drive->name); | ||
3908 | printk(KERN_WARNING "ide-tape: OnStream support will be removed soon from ide-tape!\n"); | ||
3909 | } | ||
3910 | tape = kzalloc(sizeof (idetape_tape_t), GFP_KERNEL); | ||
3911 | if (tape == NULL) { | 3762 | if (tape == NULL) { |
3912 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape structure\n", drive->name); | 3763 | printk(KERN_ERR "ide-tape: %s: Can't allocate a tape struct\n", |
3764 | drive->name); | ||
3913 | goto failed; | 3765 | goto failed; |
3914 | } | 3766 | } |
3915 | 3767 | ||
@@ -3955,10 +3807,7 @@ failed: | |||
3955 | return -ENODEV; | 3807 | return -ENODEV; |
3956 | } | 3808 | } |
3957 | 3809 | ||
3958 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); | 3810 | static void __exit idetape_exit(void) |
3959 | MODULE_LICENSE("GPL"); | ||
3960 | |||
3961 | static void __exit idetape_exit (void) | ||
3962 | { | 3811 | { |
3963 | driver_unregister(&idetape_driver.gen_driver); | 3812 | driver_unregister(&idetape_driver.gen_driver); |
3964 | class_destroy(idetape_sysfs_class); | 3813 | class_destroy(idetape_sysfs_class); |
@@ -3977,7 +3826,8 @@ static int __init idetape_init(void) | |||
3977 | } | 3826 | } |
3978 | 3827 | ||
3979 | if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { | 3828 | if (register_chrdev(IDETAPE_MAJOR, "ht", &idetape_fops)) { |
3980 | printk(KERN_ERR "ide-tape: Failed to register character device interface\n"); | 3829 | printk(KERN_ERR "ide-tape: Failed to register chrdev" |
3830 | " interface\n"); | ||
3981 | error = -EBUSY; | 3831 | error = -EBUSY; |
3982 | goto out_free_class; | 3832 | goto out_free_class; |
3983 | } | 3833 | } |
@@ -4000,3 +3850,5 @@ MODULE_ALIAS("ide:*m-tape*"); | |||
4000 | module_init(idetape_init); | 3850 | module_init(idetape_init); |
4001 | module_exit(idetape_exit); | 3851 | module_exit(idetape_exit); |
4002 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); | 3852 | MODULE_ALIAS_CHARDEV_MAJOR(IDETAPE_MAJOR); |
3853 | MODULE_DESCRIPTION("ATAPI Streaming TAPE Driver"); | ||
3854 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c index 4e1da1c78cb5..0518a2e948cf 100644 --- a/drivers/ide/ide-taskfile.c +++ b/drivers/ide/ide-taskfile.c | |||
@@ -189,12 +189,11 @@ EXPORT_SYMBOL_GPL(do_rw_taskfile); | |||
189 | */ | 189 | */ |
190 | static ide_startstop_t set_multmode_intr(ide_drive_t *drive) | 190 | static ide_startstop_t set_multmode_intr(ide_drive_t *drive) |
191 | { | 191 | { |
192 | ide_hwif_t *hwif = HWIF(drive); | 192 | u8 stat = ide_read_status(drive); |
193 | u8 stat; | ||
194 | 193 | ||
195 | if (OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { | 194 | if (OK_STAT(stat, READY_STAT, BAD_STAT)) |
196 | drive->mult_count = drive->mult_req; | 195 | drive->mult_count = drive->mult_req; |
197 | } else { | 196 | else { |
198 | drive->mult_req = drive->mult_count = 0; | 197 | drive->mult_req = drive->mult_count = 0; |
199 | drive->special.b.recalibrate = 1; | 198 | drive->special.b.recalibrate = 1; |
200 | (void) ide_dump_status(drive, "set_multmode", stat); | 199 | (void) ide_dump_status(drive, "set_multmode", stat); |
@@ -207,11 +206,10 @@ static ide_startstop_t set_multmode_intr(ide_drive_t *drive) | |||
207 | */ | 206 | */ |
208 | static ide_startstop_t set_geometry_intr(ide_drive_t *drive) | 207 | static ide_startstop_t set_geometry_intr(ide_drive_t *drive) |
209 | { | 208 | { |
210 | ide_hwif_t *hwif = HWIF(drive); | ||
211 | int retries = 5; | 209 | int retries = 5; |
212 | u8 stat; | 210 | u8 stat; |
213 | 211 | ||
214 | while (((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) && retries--) | 212 | while (((stat = ide_read_status(drive)) & BUSY_STAT) && retries--) |
215 | udelay(10); | 213 | udelay(10); |
216 | 214 | ||
217 | if (OK_STAT(stat, READY_STAT, BAD_STAT)) | 215 | if (OK_STAT(stat, READY_STAT, BAD_STAT)) |
@@ -230,10 +228,9 @@ static ide_startstop_t set_geometry_intr(ide_drive_t *drive) | |||
230 | */ | 228 | */ |
231 | static ide_startstop_t recal_intr(ide_drive_t *drive) | 229 | static ide_startstop_t recal_intr(ide_drive_t *drive) |
232 | { | 230 | { |
233 | ide_hwif_t *hwif = HWIF(drive); | 231 | u8 stat = ide_read_status(drive); |
234 | u8 stat; | ||
235 | 232 | ||
236 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG), READY_STAT, BAD_STAT)) | 233 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) |
237 | return ide_error(drive, "recal_intr", stat); | 234 | return ide_error(drive, "recal_intr", stat); |
238 | return ide_stopped; | 235 | return ide_stopped; |
239 | } | 236 | } |
@@ -244,23 +241,23 @@ static ide_startstop_t recal_intr(ide_drive_t *drive) | |||
244 | static ide_startstop_t task_no_data_intr(ide_drive_t *drive) | 241 | static ide_startstop_t task_no_data_intr(ide_drive_t *drive) |
245 | { | 242 | { |
246 | ide_task_t *args = HWGROUP(drive)->rq->special; | 243 | ide_task_t *args = HWGROUP(drive)->rq->special; |
247 | ide_hwif_t *hwif = HWIF(drive); | ||
248 | u8 stat; | 244 | u8 stat; |
249 | 245 | ||
250 | local_irq_enable_in_hardirq(); | 246 | local_irq_enable_in_hardirq(); |
251 | if (!OK_STAT(stat = hwif->INB(IDE_STATUS_REG),READY_STAT,BAD_STAT)) { | 247 | stat = ide_read_status(drive); |
248 | |||
249 | if (!OK_STAT(stat, READY_STAT, BAD_STAT)) | ||
252 | return ide_error(drive, "task_no_data_intr", stat); | 250 | return ide_error(drive, "task_no_data_intr", stat); |
253 | /* calls ide_end_drive_cmd */ | 251 | /* calls ide_end_drive_cmd */ |
254 | } | 252 | |
255 | if (args) | 253 | if (args) |
256 | ide_end_drive_cmd(drive, stat, hwif->INB(IDE_ERROR_REG)); | 254 | ide_end_drive_cmd(drive, stat, ide_read_error(drive)); |
257 | 255 | ||
258 | return ide_stopped; | 256 | return ide_stopped; |
259 | } | 257 | } |
260 | 258 | ||
261 | static u8 wait_drive_not_busy(ide_drive_t *drive) | 259 | static u8 wait_drive_not_busy(ide_drive_t *drive) |
262 | { | 260 | { |
263 | ide_hwif_t *hwif = HWIF(drive); | ||
264 | int retries; | 261 | int retries; |
265 | u8 stat; | 262 | u8 stat; |
266 | 263 | ||
@@ -269,7 +266,9 @@ static u8 wait_drive_not_busy(ide_drive_t *drive) | |||
269 | * This can take up to 10 usec, but we will wait max 1 ms. | 266 | * This can take up to 10 usec, but we will wait max 1 ms. |
270 | */ | 267 | */ |
271 | for (retries = 0; retries < 100; retries++) { | 268 | for (retries = 0; retries < 100; retries++) { |
272 | if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) | 269 | stat = ide_read_status(drive); |
270 | |||
271 | if (stat & BUSY_STAT) | ||
273 | udelay(10); | 272 | udelay(10); |
274 | else | 273 | else |
275 | break; | 274 | break; |
@@ -408,7 +407,7 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq, | |||
408 | void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) | 407 | void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) |
409 | { | 408 | { |
410 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { | 409 | if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { |
411 | u8 err = drive->hwif->INB(IDE_ERROR_REG); | 410 | u8 err = ide_read_error(drive); |
412 | 411 | ||
413 | ide_end_drive_cmd(drive, stat, err); | 412 | ide_end_drive_cmd(drive, stat, err); |
414 | return; | 413 | return; |
@@ -430,7 +429,7 @@ static ide_startstop_t task_in_intr(ide_drive_t *drive) | |||
430 | { | 429 | { |
431 | ide_hwif_t *hwif = drive->hwif; | 430 | ide_hwif_t *hwif = drive->hwif; |
432 | struct request *rq = HWGROUP(drive)->rq; | 431 | struct request *rq = HWGROUP(drive)->rq; |
433 | u8 stat = hwif->INB(IDE_STATUS_REG); | 432 | u8 stat = ide_read_status(drive); |
434 | 433 | ||
435 | /* new way for dealing with premature shared PCI interrupts */ | 434 | /* new way for dealing with premature shared PCI interrupts */ |
436 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { | 435 | if (!OK_STAT(stat, DRQ_STAT, BAD_R_STAT)) { |
@@ -465,7 +464,7 @@ static ide_startstop_t task_out_intr (ide_drive_t *drive) | |||
465 | { | 464 | { |
466 | ide_hwif_t *hwif = drive->hwif; | 465 | ide_hwif_t *hwif = drive->hwif; |
467 | struct request *rq = HWGROUP(drive)->rq; | 466 | struct request *rq = HWGROUP(drive)->rq; |
468 | u8 stat = hwif->INB(IDE_STATUS_REG); | 467 | u8 stat = ide_read_status(drive); |
469 | 468 | ||
470 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) | 469 | if (!OK_STAT(stat, DRIVE_READY, drive->bad_wstat)) |
471 | return task_error(drive, rq, __FUNCTION__, stat); | 470 | return task_error(drive, rq, __FUNCTION__, stat); |
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index ac6136001615..ad0e9955f73c 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c | |||
@@ -618,60 +618,6 @@ abort: | |||
618 | 618 | ||
619 | EXPORT_SYMBOL(ide_unregister); | 619 | EXPORT_SYMBOL(ide_unregister); |
620 | 620 | ||
621 | |||
622 | /** | ||
623 | * ide_setup_ports - set up IDE interface ports | ||
624 | * @hw: register descriptions | ||
625 | * @base: base register | ||
626 | * @offsets: table of register offsets | ||
627 | * @ctrl: control register | ||
628 | * @ack_irq: IRQ ack | ||
629 | * @irq: interrupt lie | ||
630 | * | ||
631 | * Setup hw_regs_t structure described by parameters. You | ||
632 | * may set up the hw structure yourself OR use this routine to | ||
633 | * do it for you. This is basically a helper | ||
634 | * | ||
635 | */ | ||
636 | |||
637 | void ide_setup_ports ( hw_regs_t *hw, | ||
638 | unsigned long base, int *offsets, | ||
639 | unsigned long ctrl, unsigned long intr, | ||
640 | ide_ack_intr_t *ack_intr, | ||
641 | /* | ||
642 | * ide_io_ops_t *iops, | ||
643 | */ | ||
644 | int irq) | ||
645 | { | ||
646 | int i; | ||
647 | |||
648 | memset(hw, 0, sizeof(hw_regs_t)); | ||
649 | for (i = 0; i < IDE_NR_PORTS; i++) { | ||
650 | if (offsets[i] == -1) { | ||
651 | switch(i) { | ||
652 | case IDE_CONTROL_OFFSET: | ||
653 | hw->io_ports[i] = ctrl; | ||
654 | break; | ||
655 | #if defined(CONFIG_AMIGA) || defined(CONFIG_MAC) | ||
656 | case IDE_IRQ_OFFSET: | ||
657 | hw->io_ports[i] = intr; | ||
658 | break; | ||
659 | #endif /* (CONFIG_AMIGA) || (CONFIG_MAC) */ | ||
660 | default: | ||
661 | hw->io_ports[i] = 0; | ||
662 | break; | ||
663 | } | ||
664 | } else { | ||
665 | hw->io_ports[i] = base + offsets[i]; | ||
666 | } | ||
667 | } | ||
668 | hw->irq = irq; | ||
669 | hw->ack_intr = ack_intr; | ||
670 | /* | ||
671 | * hw->iops = iops; | ||
672 | */ | ||
673 | } | ||
674 | |||
675 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) | 621 | void ide_init_port_hw(ide_hwif_t *hwif, hw_regs_t *hw) |
676 | { | 622 | { |
677 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); | 623 | memcpy(hwif->io_ports, hw->io_ports, sizeof(hwif->io_ports)); |
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c index 8bdb79da17e8..50ffa871d5e9 100644 --- a/drivers/ide/legacy/buddha.c +++ b/drivers/ide/legacy/buddha.c | |||
@@ -56,31 +56,11 @@ static u_int xsurf_bases[XSURF_NUM_HWIFS] __initdata = { | |||
56 | XSURF_BASE1, XSURF_BASE2 | 56 | XSURF_BASE1, XSURF_BASE2 |
57 | }; | 57 | }; |
58 | 58 | ||
59 | |||
60 | /* | 59 | /* |
61 | * Offsets from one of the above bases | 60 | * Offsets from one of the above bases |
62 | */ | 61 | */ |
63 | 62 | ||
64 | #define BUDDHA_DATA 0x00 | ||
65 | #define BUDDHA_ERROR 0x06 /* see err-bits */ | ||
66 | #define BUDDHA_NSECTOR 0x0a /* nr of sectors to read/write */ | ||
67 | #define BUDDHA_SECTOR 0x0e /* starting sector */ | ||
68 | #define BUDDHA_LCYL 0x12 /* starting cylinder */ | ||
69 | #define BUDDHA_HCYL 0x16 /* high byte of starting cyl */ | ||
70 | #define BUDDHA_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ | ||
71 | #define BUDDHA_STATUS 0x1e /* see status-bits */ | ||
72 | #define BUDDHA_CONTROL 0x11a | 63 | #define BUDDHA_CONTROL 0x11a |
73 | #define XSURF_CONTROL -1 /* X-Surf has no CS1* (Control/AltStat) */ | ||
74 | |||
75 | static int buddha_offsets[IDE_NR_PORTS] __initdata = { | ||
76 | BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, | ||
77 | BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, BUDDHA_CONTROL, -1 | ||
78 | }; | ||
79 | |||
80 | static int xsurf_offsets[IDE_NR_PORTS] __initdata = { | ||
81 | BUDDHA_DATA, BUDDHA_ERROR, BUDDHA_NSECTOR, BUDDHA_SECTOR, BUDDHA_LCYL, | ||
82 | BUDDHA_HCYL, BUDDHA_SELECT, BUDDHA_STATUS, XSURF_CONTROL, -1 | ||
83 | }; | ||
84 | 64 | ||
85 | /* | 65 | /* |
86 | * Other registers | 66 | * Other registers |
@@ -140,6 +120,26 @@ static int xsurf_ack_intr(ide_hwif_t *hwif) | |||
140 | return 1; | 120 | return 1; |
141 | } | 121 | } |
142 | 122 | ||
123 | static void __init buddha_setup_ports(hw_regs_t *hw, unsigned long base, | ||
124 | unsigned long ctl, unsigned long irq_port, | ||
125 | ide_ack_intr_t *ack_intr) | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | memset(hw, 0, sizeof(*hw)); | ||
130 | |||
131 | hw->io_ports[IDE_DATA_OFFSET] = base; | ||
132 | |||
133 | for (i = 1; i < 8; i++) | ||
134 | hw->io_ports[i] = base + 2 + i * 4; | ||
135 | |||
136 | hw->io_ports[IDE_CONTROL_OFFSET] = ctl; | ||
137 | hw->io_ports[IDE_IRQ_OFFSET] = irq_port; | ||
138 | |||
139 | hw->irq = IRQ_AMIGA_PORTS; | ||
140 | hw->ack_intr = ack_intr; | ||
141 | } | ||
142 | |||
143 | /* | 143 | /* |
144 | * Probe for a Buddha or Catweasel IDE interface | 144 | * Probe for a Buddha or Catweasel IDE interface |
145 | */ | 145 | */ |
@@ -202,22 +202,24 @@ fail_base2: | |||
202 | printk(KERN_INFO "ide: %s IDE controller\n", | 202 | printk(KERN_INFO "ide: %s IDE controller\n", |
203 | buddha_board_name[type]); | 203 | buddha_board_name[type]); |
204 | 204 | ||
205 | for(i=0;i<buddha_num_hwifs;i++) { | 205 | for (i = 0; i < buddha_num_hwifs; i++) { |
206 | if(type != BOARD_XSURF) { | 206 | unsigned long base, ctl, irq_port; |
207 | ide_setup_ports(&hw, (buddha_board+buddha_bases[i]), | 207 | ide_ack_intr_t *ack_intr; |
208 | buddha_offsets, 0, | 208 | |
209 | (buddha_board+buddha_irqports[i]), | 209 | if (type != BOARD_XSURF) { |
210 | buddha_ack_intr, | 210 | base = buddha_board + buddha_bases[i]; |
211 | // budda_iops, | 211 | ctl = base + BUDDHA_CONTROL; |
212 | IRQ_AMIGA_PORTS); | 212 | irq_port = buddha_board + buddha_irqports[i]; |
213 | ack_intr = buddha_ack_intr; | ||
213 | } else { | 214 | } else { |
214 | ide_setup_ports(&hw, (buddha_board+xsurf_bases[i]), | 215 | base = buddha_board + xsurf_bases[i]; |
215 | xsurf_offsets, 0, | 216 | /* X-Surf has no CS1* (Control/AltStat) */ |
216 | (buddha_board+xsurf_irqports[i]), | 217 | ctl = 0; |
217 | xsurf_ack_intr, | 218 | irq_port = buddha_board + xsurf_irqports[i]; |
218 | // xsurf_iops, | 219 | ack_intr = xsurf_ack_intr; |
219 | IRQ_AMIGA_PORTS); | 220 | } |
220 | } | 221 | |
222 | buddha_setup_ports(&hw, base, ctl, irq_port, ack_intr); | ||
221 | 223 | ||
222 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 224 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
223 | if (hwif) { | 225 | if (hwif) { |
diff --git a/drivers/ide/legacy/falconide.c b/drivers/ide/legacy/falconide.c index 85b69a82825f..f044048903b3 100644 --- a/drivers/ide/legacy/falconide.c +++ b/drivers/ide/legacy/falconide.c | |||
@@ -33,22 +33,8 @@ | |||
33 | * Offsets from the above base | 33 | * Offsets from the above base |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #define ATA_HD_DATA 0x00 | ||
37 | #define ATA_HD_ERROR 0x05 /* see err-bits */ | ||
38 | #define ATA_HD_NSECTOR 0x09 /* nr of sectors to read/write */ | ||
39 | #define ATA_HD_SECTOR 0x0d /* starting sector */ | ||
40 | #define ATA_HD_LCYL 0x11 /* starting cylinder */ | ||
41 | #define ATA_HD_HCYL 0x15 /* high byte of starting cyl */ | ||
42 | #define ATA_HD_SELECT 0x19 /* 101dhhhh , d=drive, hhhh=head */ | ||
43 | #define ATA_HD_STATUS 0x1d /* see status-bits */ | ||
44 | #define ATA_HD_CONTROL 0x39 | 36 | #define ATA_HD_CONTROL 0x39 |
45 | 37 | ||
46 | static int falconide_offsets[IDE_NR_PORTS] __initdata = { | ||
47 | ATA_HD_DATA, ATA_HD_ERROR, ATA_HD_NSECTOR, ATA_HD_SECTOR, ATA_HD_LCYL, | ||
48 | ATA_HD_HCYL, ATA_HD_SELECT, ATA_HD_STATUS, ATA_HD_CONTROL, -1 | ||
49 | }; | ||
50 | |||
51 | |||
52 | /* | 38 | /* |
53 | * falconide_intr_lock is used to obtain access to the IDE interrupt, | 39 | * falconide_intr_lock is used to obtain access to the IDE interrupt, |
54 | * which is shared between several drivers. | 40 | * which is shared between several drivers. |
@@ -57,6 +43,22 @@ static int falconide_offsets[IDE_NR_PORTS] __initdata = { | |||
57 | int falconide_intr_lock; | 43 | int falconide_intr_lock; |
58 | EXPORT_SYMBOL(falconide_intr_lock); | 44 | EXPORT_SYMBOL(falconide_intr_lock); |
59 | 45 | ||
46 | static void __init falconide_setup_ports(hw_regs_t *hw) | ||
47 | { | ||
48 | int i; | ||
49 | |||
50 | memset(hw, 0, sizeof(*hw)); | ||
51 | |||
52 | hw->io_ports[IDE_DATA_OFFSET] = ATA_HD_BASE; | ||
53 | |||
54 | for (i = 1; i < 8; i++) | ||
55 | hw->io_ports[i] = ATA_HD_BASE + 1 + i * 4; | ||
56 | |||
57 | hw->io_ports[IDE_CONTROL_OFFSET] = ATA_HD_CONTROL; | ||
58 | |||
59 | hw->irq = IRQ_MFP_IDE; | ||
60 | hw->ack_intr = NULL; | ||
61 | } | ||
60 | 62 | ||
61 | /* | 63 | /* |
62 | * Probe for a Falcon IDE interface | 64 | * Probe for a Falcon IDE interface |
@@ -64,16 +66,15 @@ EXPORT_SYMBOL(falconide_intr_lock); | |||
64 | 66 | ||
65 | static int __init falconide_init(void) | 67 | static int __init falconide_init(void) |
66 | { | 68 | { |
67 | if (MACH_IS_ATARI && ATARIHW_PRESENT(IDE)) { | ||
68 | hw_regs_t hw; | 69 | hw_regs_t hw; |
69 | ide_hwif_t *hwif; | 70 | ide_hwif_t *hwif; |
70 | 71 | ||
72 | if (!MACH_IS_ATARI || !ATARIHW_PRESENT(IDE)) | ||
73 | return 0; | ||
74 | |||
71 | printk(KERN_INFO "ide: Falcon IDE controller\n"); | 75 | printk(KERN_INFO "ide: Falcon IDE controller\n"); |
72 | 76 | ||
73 | ide_setup_ports(&hw, ATA_HD_BASE, falconide_offsets, | 77 | falconide_setup_ports(&hw); |
74 | 0, 0, NULL, | ||
75 | // falconide_iops, | ||
76 | IRQ_MFP_IDE); | ||
77 | 78 | ||
78 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 79 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
79 | if (hwif) { | 80 | if (hwif) { |
@@ -85,9 +86,8 @@ static int __init falconide_init(void) | |||
85 | 86 | ||
86 | ide_device_add(idx, NULL); | 87 | ide_device_add(idx, NULL); |
87 | } | 88 | } |
88 | } | ||
89 | 89 | ||
90 | return 0; | 90 | return 0; |
91 | } | 91 | } |
92 | 92 | ||
93 | module_init(falconide_init); | 93 | module_init(falconide_init); |
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c index fc29ce75aff1..9d3851d27677 100644 --- a/drivers/ide/legacy/gayle.c +++ b/drivers/ide/legacy/gayle.c | |||
@@ -34,22 +34,8 @@ | |||
34 | * Offsets from one of the above bases | 34 | * Offsets from one of the above bases |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define GAYLE_DATA 0x00 | ||
38 | #define GAYLE_ERROR 0x06 /* see err-bits */ | ||
39 | #define GAYLE_NSECTOR 0x0a /* nr of sectors to read/write */ | ||
40 | #define GAYLE_SECTOR 0x0e /* starting sector */ | ||
41 | #define GAYLE_LCYL 0x12 /* starting cylinder */ | ||
42 | #define GAYLE_HCYL 0x16 /* high byte of starting cyl */ | ||
43 | #define GAYLE_SELECT 0x1a /* 101dhhhh , d=drive, hhhh=head */ | ||
44 | #define GAYLE_STATUS 0x1e /* see status-bits */ | ||
45 | #define GAYLE_CONTROL 0x101a | 37 | #define GAYLE_CONTROL 0x101a |
46 | 38 | ||
47 | static int gayle_offsets[IDE_NR_PORTS] __initdata = { | ||
48 | GAYLE_DATA, GAYLE_ERROR, GAYLE_NSECTOR, GAYLE_SECTOR, GAYLE_LCYL, | ||
49 | GAYLE_HCYL, GAYLE_SELECT, GAYLE_STATUS, -1, -1 | ||
50 | }; | ||
51 | |||
52 | |||
53 | /* | 39 | /* |
54 | * These are at different offsets from the base | 40 | * These are at different offsets from the base |
55 | */ | 41 | */ |
@@ -106,6 +92,26 @@ static int gayle_ack_intr_a1200(ide_hwif_t *hwif) | |||
106 | return 1; | 92 | return 1; |
107 | } | 93 | } |
108 | 94 | ||
95 | static void __init gayle_setup_ports(hw_regs_t *hw, unsigned long base, | ||
96 | unsigned long ctl, unsigned long irq_port, | ||
97 | ide_ack_intr_t *ack_intr); | ||
98 | { | ||
99 | int i; | ||
100 | |||
101 | memset(hw, 0, sizeof(*hw)); | ||
102 | |||
103 | hw->io_ports[IDE_DATA_OFFSET] = base; | ||
104 | |||
105 | for (i = 1; i < 8; i++) | ||
106 | hw->io_ports[i] = base + 2 + i * 4; | ||
107 | |||
108 | hw->io_ports[IDE_CONTROL_OFFSET] = ctl; | ||
109 | hw->io_ports[IDE_IRQ_OFFSET] = irq_port; | ||
110 | |||
111 | hw->irq = IRQ_AMIGA_PORTS; | ||
112 | hw->ack_intr = ack_intr; | ||
113 | } | ||
114 | |||
109 | /* | 115 | /* |
110 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) | 116 | * Probe for a Gayle IDE interface (and optionally for an IDE doubler) |
111 | */ | 117 | */ |
@@ -167,10 +173,7 @@ found: | |||
167 | base = (unsigned long)ZTWO_VADDR(phys_base); | 173 | base = (unsigned long)ZTWO_VADDR(phys_base); |
168 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; | 174 | ctrlport = GAYLE_HAS_CONTROL_REG ? (base + GAYLE_CONTROL) : 0; |
169 | 175 | ||
170 | ide_setup_ports(&hw, base, gayle_offsets, | 176 | gayle_setup_ports(&hw, base, ctrlport, irqport, ack_intr); |
171 | ctrlport, irqport, ack_intr, | ||
172 | // &gayle_iops, | ||
173 | IRQ_AMIGA_PORTS); | ||
174 | 177 | ||
175 | hwif = ide_find_port(base); | 178 | hwif = ide_find_port(base); |
176 | if (hwif) { | 179 | if (hwif) { |
diff --git a/drivers/ide/legacy/hd.c b/drivers/ide/legacy/hd.c index 8e05d88e81ba..0b0d86731927 100644 --- a/drivers/ide/legacy/hd.c +++ b/drivers/ide/legacy/hd.c | |||
@@ -421,11 +421,14 @@ static void bad_rw_intr(void) | |||
421 | 421 | ||
422 | static inline int wait_DRQ(void) | 422 | static inline int wait_DRQ(void) |
423 | { | 423 | { |
424 | int retries = 100000, stat; | 424 | int retries; |
425 | int stat; | ||
425 | 426 | ||
426 | while (--retries > 0) | 427 | for (retries = 0; retries < 100000; retries++) { |
427 | if ((stat = inb_p(HD_STATUS)) & DRQ_STAT) | 428 | stat = inb_p(HD_STATUS); |
429 | if (stat & DRQ_STAT) | ||
428 | return 0; | 430 | return 0; |
431 | } | ||
429 | dump_status("wait_DRQ", stat); | 432 | dump_status("wait_DRQ", stat); |
430 | return -1; | 433 | return -1; |
431 | } | 434 | } |
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c index 06df8df857a3..a61e60737dc7 100644 --- a/drivers/ide/legacy/macide.c +++ b/drivers/ide/legacy/macide.c | |||
@@ -31,14 +31,6 @@ | |||
31 | * These match MkLinux so they should be correct. | 31 | * These match MkLinux so they should be correct. |
32 | */ | 32 | */ |
33 | 33 | ||
34 | #define IDE_DATA 0x00 | ||
35 | #define IDE_ERROR 0x04 /* see err-bits */ | ||
36 | #define IDE_NSECTOR 0x08 /* nr of sectors to read/write */ | ||
37 | #define IDE_SECTOR 0x0c /* starting sector */ | ||
38 | #define IDE_LCYL 0x10 /* starting cylinder */ | ||
39 | #define IDE_HCYL 0x14 /* high byte of starting cyl */ | ||
40 | #define IDE_SELECT 0x18 /* 101dhhhh , d=drive, hhhh=head */ | ||
41 | #define IDE_STATUS 0x1c /* see status-bits */ | ||
42 | #define IDE_CONTROL 0x38 /* control/altstatus */ | 34 | #define IDE_CONTROL 0x38 /* control/altstatus */ |
43 | 35 | ||
44 | /* | 36 | /* |
@@ -63,11 +55,6 @@ | |||
63 | 55 | ||
64 | volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR); | 56 | volatile unsigned char *ide_ifr = (unsigned char *) (IDE_BASE + IDE_IFR); |
65 | 57 | ||
66 | static int macide_offsets[IDE_NR_PORTS] = { | ||
67 | IDE_DATA, IDE_ERROR, IDE_NSECTOR, IDE_SECTOR, IDE_LCYL, | ||
68 | IDE_HCYL, IDE_SELECT, IDE_STATUS, IDE_CONTROL | ||
69 | }; | ||
70 | |||
71 | int macide_ack_intr(ide_hwif_t* hwif) | 58 | int macide_ack_intr(ide_hwif_t* hwif) |
72 | { | 59 | { |
73 | if (*ide_ifr & 0x20) { | 60 | if (*ide_ifr & 0x20) { |
@@ -77,6 +64,22 @@ int macide_ack_intr(ide_hwif_t* hwif) | |||
77 | return 0; | 64 | return 0; |
78 | } | 65 | } |
79 | 66 | ||
67 | static void __init macide_setup_ports(hw_regs_t *hw, unsigned long base, | ||
68 | int irq, ide_ack_intr_t *ack_intr) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | memset(hw, 0, sizeof(*hw)); | ||
73 | |||
74 | for (i = 0; i < 8; i++) | ||
75 | hw->io_ports[i] = base + i * 4; | ||
76 | |||
77 | hw->io_ports[IDE_CONTROL_OFFSET] = IDE_CONTROL; | ||
78 | |||
79 | hw->irq = irq; | ||
80 | hw->ack_intr = ack_intr; | ||
81 | } | ||
82 | |||
80 | static const char *mac_ide_name[] = | 83 | static const char *mac_ide_name[] = |
81 | { "Quadra", "Powerbook", "Powerbook Baboon" }; | 84 | { "Quadra", "Powerbook", "Powerbook Baboon" }; |
82 | 85 | ||
@@ -86,27 +89,27 @@ static const char *mac_ide_name[] = | |||
86 | 89 | ||
87 | static int __init macide_init(void) | 90 | static int __init macide_init(void) |
88 | { | 91 | { |
89 | hw_regs_t hw; | ||
90 | ide_hwif_t *hwif; | 92 | ide_hwif_t *hwif; |
93 | ide_ack_intr_t *ack_intr; | ||
94 | unsigned long base; | ||
95 | int irq; | ||
96 | hw_regs_t hw; | ||
91 | 97 | ||
92 | switch (macintosh_config->ide_type) { | 98 | switch (macintosh_config->ide_type) { |
93 | case MAC_IDE_QUADRA: | 99 | case MAC_IDE_QUADRA: |
94 | ide_setup_ports(&hw, IDE_BASE, macide_offsets, | 100 | base = IDE_BASE; |
95 | 0, 0, macide_ack_intr, | 101 | ack_intr = macide_ack_intr; |
96 | // quadra_ide_iops, | 102 | irq = IRQ_NUBUS_F; |
97 | IRQ_NUBUS_F); | ||
98 | break; | 103 | break; |
99 | case MAC_IDE_PB: | 104 | case MAC_IDE_PB: |
100 | ide_setup_ports(&hw, IDE_BASE, macide_offsets, | 105 | base = IDE_BASE; |
101 | 0, 0, macide_ack_intr, | 106 | ack_intr = macide_ack_intr; |
102 | // macide_pb_iops, | 107 | irq = IRQ_NUBUS_C; |
103 | IRQ_NUBUS_C); | ||
104 | break; | 108 | break; |
105 | case MAC_IDE_BABOON: | 109 | case MAC_IDE_BABOON: |
106 | ide_setup_ports(&hw, BABOON_BASE, macide_offsets, | 110 | base = BABOON_BASE; |
107 | 0, 0, NULL, | 111 | ack_intr = NULL; |
108 | // macide_baboon_iops, | 112 | irq = IRQ_BABOON_1; |
109 | IRQ_BABOON_1); | ||
110 | break; | 113 | break; |
111 | default: | 114 | default: |
112 | return -ENODEV; | 115 | return -ENODEV; |
@@ -115,6 +118,8 @@ static int __init macide_init(void) | |||
115 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", | 118 | printk(KERN_INFO "ide: Macintosh %s IDE controller\n", |
116 | mac_ide_name[macintosh_config->ide_type - 1]); | 119 | mac_ide_name[macintosh_config->ide_type - 1]); |
117 | 120 | ||
121 | macide_setup_ports(&hw, base, irq, ack_intr); | ||
122 | |||
118 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); | 123 | hwif = ide_find_port(hw.io_ports[IDE_DATA_OFFSET]); |
119 | if (hwif) { | 124 | if (hwif) { |
120 | u8 index = hwif->index; | 125 | u8 index = hwif->index; |
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c index 2f0b34d892a1..1381b91bc316 100644 --- a/drivers/ide/legacy/q40ide.c +++ b/drivers/ide/legacy/q40ide.c | |||
@@ -66,16 +66,12 @@ static int q40ide_default_irq(unsigned long base) | |||
66 | 66 | ||
67 | 67 | ||
68 | /* | 68 | /* |
69 | * This is very similar to ide_setup_ports except that addresses | 69 | * Addresses are pretranslated for Q40 ISA access. |
70 | * are pretranslated for q40 ISA access | ||
71 | */ | 70 | */ |
72 | void q40_ide_setup_ports ( hw_regs_t *hw, | 71 | void q40_ide_setup_ports ( hw_regs_t *hw, |
73 | unsigned long base, int *offsets, | 72 | unsigned long base, int *offsets, |
74 | unsigned long ctrl, unsigned long intr, | 73 | unsigned long ctrl, unsigned long intr, |
75 | ide_ack_intr_t *ack_intr, | 74 | ide_ack_intr_t *ack_intr, |
76 | /* | ||
77 | * ide_io_ops_t *iops, | ||
78 | */ | ||
79 | int irq) | 75 | int irq) |
80 | { | 76 | { |
81 | int i; | 77 | int i; |
@@ -92,9 +88,6 @@ void q40_ide_setup_ports ( hw_regs_t *hw, | |||
92 | 88 | ||
93 | hw->irq = irq; | 89 | hw->irq = irq; |
94 | hw->ack_intr = ack_intr; | 90 | hw->ack_intr = ack_intr; |
95 | /* | ||
96 | * hw->iops = iops; | ||
97 | */ | ||
98 | } | 91 | } |
99 | 92 | ||
100 | 93 | ||
diff --git a/drivers/ide/pci/Makefile b/drivers/ide/pci/Makefile index 94803253e8af..02e6ee7d751d 100644 --- a/drivers/ide/pci/Makefile +++ b/drivers/ide/pci/Makefile | |||
@@ -34,7 +34,8 @@ obj-$(CONFIG_BLK_DEV_TRM290) += trm290.o | |||
34 | obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o | 34 | obj-$(CONFIG_BLK_DEV_VIA82CXXX) += via82cxxx.o |
35 | 35 | ||
36 | # Must appear at the end of the block | 36 | # Must appear at the end of the block |
37 | obj-$(CONFIG_BLK_DEV_GENERIC) += generic.o | 37 | obj-$(CONFIG_BLK_DEV_GENERIC) += ide-pci-generic.o |
38 | ide-pci-generic-y += generic.o | ||
38 | 39 | ||
39 | ifeq ($(CONFIG_BLK_DEV_CMD640), m) | 40 | ifeq ($(CONFIG_BLK_DEV_CMD640), m) |
40 | obj-m += cmd640.o | 41 | obj-m += cmd640.o |
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index 9262a9174b4e..7fd83a9d4dee 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -29,19 +29,6 @@ | |||
29 | 29 | ||
30 | static int ide_generic_all; /* Set to claim all devices */ | 30 | static int ide_generic_all; /* Set to claim all devices */ |
31 | 31 | ||
32 | /* | ||
33 | * the module_param_named() was added for the modular case | ||
34 | * the __setup() is left as compatibility for existing setups | ||
35 | */ | ||
36 | #ifndef MODULE | ||
37 | static int __init ide_generic_all_on(char *unused) | ||
38 | { | ||
39 | ide_generic_all = 1; | ||
40 | printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n"); | ||
41 | return 1; | ||
42 | } | ||
43 | const __setup("all-generic-ide", ide_generic_all_on); | ||
44 | #endif | ||
45 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); | 32 | module_param_named(all_generic_ide, ide_generic_all, bool, 0444); |
46 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); | 33 | MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers."); |
47 | 34 | ||
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c index ef5b39fa042b..cc4be9621bc0 100644 --- a/drivers/ide/pci/siimage.c +++ b/drivers/ide/pci/siimage.c | |||
@@ -704,9 +704,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) | |||
704 | hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; | 704 | hwif->sata_scr[SATA_STATUS_OFFSET] = base + 0x104; |
705 | hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; | 705 | hwif->sata_scr[SATA_ERROR_OFFSET] = base + 0x108; |
706 | hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; | 706 | hwif->sata_scr[SATA_CONTROL_OFFSET] = base + 0x100; |
707 | hwif->sata_misc[SATA_MISC_OFFSET] = base + 0x140; | ||
708 | hwif->sata_misc[SATA_PHY_OFFSET] = base + 0x144; | ||
709 | hwif->sata_misc[SATA_IEN_OFFSET] = base + 0x148; | ||
710 | } | 707 | } |
711 | 708 | ||
712 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); | 709 | memcpy(hwif->io_ports, hw.io_ports, sizeof(hwif->io_ports)); |
diff --git a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c index 2ae6c6016a86..28ae15ed12c5 100644 --- a/drivers/input/touchscreen/h3600_ts_input.c +++ b/drivers/input/touchscreen/h3600_ts_input.c | |||
@@ -109,7 +109,7 @@ struct h3600_dev { | |||
109 | static irqreturn_t action_button_handler(int irq, void *dev_id) | 109 | static irqreturn_t action_button_handler(int irq, void *dev_id) |
110 | { | 110 | { |
111 | int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; | 111 | int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1; |
112 | struct input_dev *dev = (struct input_dev *) dev_id; | 112 | struct input_dev *dev = dev_id; |
113 | 113 | ||
114 | input_report_key(dev, KEY_ENTER, down); | 114 | input_report_key(dev, KEY_ENTER, down); |
115 | input_sync(dev); | 115 | input_sync(dev); |
@@ -120,7 +120,7 @@ static irqreturn_t action_button_handler(int irq, void *dev_id) | |||
120 | static irqreturn_t npower_button_handler(int irq, void *dev_id) | 120 | static irqreturn_t npower_button_handler(int irq, void *dev_id) |
121 | { | 121 | { |
122 | int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; | 122 | int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1; |
123 | struct input_dev *dev = (struct input_dev *) dev_id; | 123 | struct input_dev *dev = dev_id; |
124 | 124 | ||
125 | /* | 125 | /* |
126 | * This interrupt is only called when we release the key. So we have | 126 | * This interrupt is only called when we release the key. So we have |
diff --git a/drivers/isdn/act2000/module.c b/drivers/isdn/act2000/module.c index ee2b0b9f8f46..8325022e2bed 100644 --- a/drivers/isdn/act2000/module.c +++ b/drivers/isdn/act2000/module.c | |||
@@ -310,7 +310,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
310 | } | 310 | } |
311 | break; | 311 | break; |
312 | case ISDN_CMD_DIAL: | 312 | case ISDN_CMD_DIAL: |
313 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 313 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
314 | return -ENODEV; | 314 | return -ENODEV; |
315 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 315 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
316 | break; | 316 | break; |
@@ -339,7 +339,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
339 | } | 339 | } |
340 | return ret; | 340 | return ret; |
341 | case ISDN_CMD_ACCEPTD: | 341 | case ISDN_CMD_ACCEPTD: |
342 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 342 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
343 | return -ENODEV; | 343 | return -ENODEV; |
344 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 344 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
345 | break; | 345 | break; |
@@ -347,11 +347,11 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
347 | actcapi_select_b2_protocol_req(card, chan); | 347 | actcapi_select_b2_protocol_req(card, chan); |
348 | return 0; | 348 | return 0; |
349 | case ISDN_CMD_ACCEPTB: | 349 | case ISDN_CMD_ACCEPTB: |
350 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 350 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
351 | return -ENODEV; | 351 | return -ENODEV; |
352 | return 0; | 352 | return 0; |
353 | case ISDN_CMD_HANGUP: | 353 | case ISDN_CMD_HANGUP: |
354 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 354 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
355 | return -ENODEV; | 355 | return -ENODEV; |
356 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 356 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
357 | break; | 357 | break; |
@@ -366,7 +366,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
366 | } | 366 | } |
367 | return 0; | 367 | return 0; |
368 | case ISDN_CMD_SETEAZ: | 368 | case ISDN_CMD_SETEAZ: |
369 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 369 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
370 | return -ENODEV; | 370 | return -ENODEV; |
371 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 371 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
372 | break; | 372 | break; |
@@ -386,7 +386,7 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
386 | actcapi_listen_req(card); | 386 | actcapi_listen_req(card); |
387 | return 0; | 387 | return 0; |
388 | case ISDN_CMD_CLREAZ: | 388 | case ISDN_CMD_CLREAZ: |
389 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 389 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
390 | return -ENODEV; | 390 | return -ENODEV; |
391 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 391 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
392 | break; | 392 | break; |
@@ -394,14 +394,14 @@ act2000_command(act2000_card * card, isdn_ctrl * c) | |||
394 | actcapi_listen_req(card); | 394 | actcapi_listen_req(card); |
395 | return 0; | 395 | return 0; |
396 | case ISDN_CMD_SETL2: | 396 | case ISDN_CMD_SETL2: |
397 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 397 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
398 | return -ENODEV; | 398 | return -ENODEV; |
399 | if (!(chan = find_channel(card, c->arg & 0x0f))) | 399 | if (!(chan = find_channel(card, c->arg & 0x0f))) |
400 | break; | 400 | break; |
401 | chan->l2prot = (c->arg >> 8); | 401 | chan->l2prot = (c->arg >> 8); |
402 | return 0; | 402 | return 0; |
403 | case ISDN_CMD_SETL3: | 403 | case ISDN_CMD_SETL3: |
404 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 404 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
405 | return -ENODEV; | 405 | return -ENODEV; |
406 | if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { | 406 | if ((c->arg >> 8) != ISDN_PROTO_L3_TRANS) { |
407 | printk(KERN_WARNING "L3 protocol unknown\n"); | 407 | printk(KERN_WARNING "L3 protocol unknown\n"); |
@@ -524,7 +524,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel) | |||
524 | act2000_card *card = act2000_findcard(id); | 524 | act2000_card *card = act2000_findcard(id); |
525 | 525 | ||
526 | if (card) { | 526 | if (card) { |
527 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 527 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
528 | return -ENODEV; | 528 | return -ENODEV; |
529 | return (len); | 529 | return (len); |
530 | } | 530 | } |
@@ -539,7 +539,7 @@ if_readstatus(u_char __user * buf, int len, int id, int channel) | |||
539 | act2000_card *card = act2000_findcard(id); | 539 | act2000_card *card = act2000_findcard(id); |
540 | 540 | ||
541 | if (card) { | 541 | if (card) { |
542 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 542 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
543 | return -ENODEV; | 543 | return -ENODEV; |
544 | return (act2000_readstatus(buf, len, card)); | 544 | return (act2000_readstatus(buf, len, card)); |
545 | } | 545 | } |
@@ -554,7 +554,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) | |||
554 | act2000_card *card = act2000_findcard(id); | 554 | act2000_card *card = act2000_findcard(id); |
555 | 555 | ||
556 | if (card) { | 556 | if (card) { |
557 | if (!card->flags & ACT2000_FLAGS_RUNNING) | 557 | if (!(card->flags & ACT2000_FLAGS_RUNNING)) |
558 | return -ENODEV; | 558 | return -ENODEV; |
559 | return (act2000_sendbuf(card, channel, ack, skb)); | 559 | return (act2000_sendbuf(card, channel, ack, skb)); |
560 | } | 560 | } |
diff --git a/drivers/isdn/gigaset/asyncdata.c b/drivers/isdn/gigaset/asyncdata.c index 00a3be5b862b..091deb9d1c47 100644 --- a/drivers/isdn/gigaset/asyncdata.c +++ b/drivers/isdn/gigaset/asyncdata.c | |||
@@ -350,8 +350,8 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
350 | unsigned char *src, c; | 350 | unsigned char *src, c; |
351 | int procbytes; | 351 | int procbytes; |
352 | 352 | ||
353 | head = atomic_read(&inbuf->head); | 353 | head = inbuf->head; |
354 | tail = atomic_read(&inbuf->tail); | 354 | tail = inbuf->tail; |
355 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 355 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
356 | 356 | ||
357 | if (head != tail) { | 357 | if (head != tail) { |
@@ -361,7 +361,7 @@ void gigaset_m10x_input(struct inbuf_t *inbuf) | |||
361 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 361 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
362 | 362 | ||
363 | while (numbytes) { | 363 | while (numbytes) { |
364 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 364 | if (cs->mstate == MS_LOCKED) { |
365 | procbytes = lock_loop(src, numbytes, inbuf); | 365 | procbytes = lock_loop(src, numbytes, inbuf); |
366 | src += procbytes; | 366 | src += procbytes; |
367 | numbytes -= procbytes; | 367 | numbytes -= procbytes; |
@@ -436,7 +436,7 @@ nextbyte: | |||
436 | } | 436 | } |
437 | 437 | ||
438 | gig_dbg(DEBUG_INTR, "setting head to %u", head); | 438 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
439 | atomic_set(&inbuf->head, head); | 439 | inbuf->head = head; |
440 | } | 440 | } |
441 | } | 441 | } |
442 | EXPORT_SYMBOL_GPL(gigaset_m10x_input); | 442 | EXPORT_SYMBOL_GPL(gigaset_m10x_input); |
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index af7648274b38..5255b5e20e13 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -73,6 +73,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
73 | /* Function will be called if the device is unplugged */ | 73 | /* Function will be called if the device is unplugged */ |
74 | static void gigaset_disconnect(struct usb_interface *interface); | 74 | static void gigaset_disconnect(struct usb_interface *interface); |
75 | 75 | ||
76 | /* functions called before/after suspend */ | ||
77 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message); | ||
78 | static int gigaset_resume(struct usb_interface *intf); | ||
79 | |||
80 | /* functions called before/after device reset */ | ||
81 | static int gigaset_pre_reset(struct usb_interface *intf); | ||
82 | static int gigaset_post_reset(struct usb_interface *intf); | ||
83 | |||
76 | static int atread_submit(struct cardstate *, int); | 84 | static int atread_submit(struct cardstate *, int); |
77 | static void stopurbs(struct bas_bc_state *); | 85 | static void stopurbs(struct bas_bc_state *); |
78 | static int req_submit(struct bc_state *, int, int, int); | 86 | static int req_submit(struct bc_state *, int, int, int); |
@@ -105,8 +113,9 @@ struct bas_cardstate { | |||
105 | unsigned char int_in_buf[3]; | 113 | unsigned char int_in_buf[3]; |
106 | 114 | ||
107 | spinlock_t lock; /* locks all following */ | 115 | spinlock_t lock; /* locks all following */ |
108 | atomic_t basstate; /* bitmap (BS_*) */ | 116 | int basstate; /* bitmap (BS_*) */ |
109 | int pending; /* uncompleted base request */ | 117 | int pending; /* uncompleted base request */ |
118 | wait_queue_head_t waitqueue; | ||
110 | int rcvbuf_size; /* size of AT receive buffer */ | 119 | int rcvbuf_size; /* size of AT receive buffer */ |
111 | /* 0: no receive in progress */ | 120 | /* 0: no receive in progress */ |
112 | int retry_cmd_in; /* receive req retry count */ | 121 | int retry_cmd_in; /* receive req retry count */ |
@@ -121,10 +130,10 @@ struct bas_cardstate { | |||
121 | #define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */ | 130 | #define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */ |
122 | #define BS_ATRDPEND 0x040 /* urb_cmd_in in use */ | 131 | #define BS_ATRDPEND 0x040 /* urb_cmd_in in use */ |
123 | #define BS_ATWRPEND 0x080 /* urb_cmd_out in use */ | 132 | #define BS_ATWRPEND 0x080 /* urb_cmd_out in use */ |
133 | #define BS_SUSPEND 0x100 /* USB port suspended */ | ||
124 | 134 | ||
125 | 135 | ||
126 | static struct gigaset_driver *driver = NULL; | 136 | static struct gigaset_driver *driver = NULL; |
127 | static struct cardstate *cardstate = NULL; | ||
128 | 137 | ||
129 | /* usb specific object needed to register this driver with the usb subsystem */ | 138 | /* usb specific object needed to register this driver with the usb subsystem */ |
130 | static struct usb_driver gigaset_usb_driver = { | 139 | static struct usb_driver gigaset_usb_driver = { |
@@ -132,6 +141,11 @@ static struct usb_driver gigaset_usb_driver = { | |||
132 | .probe = gigaset_probe, | 141 | .probe = gigaset_probe, |
133 | .disconnect = gigaset_disconnect, | 142 | .disconnect = gigaset_disconnect, |
134 | .id_table = gigaset_table, | 143 | .id_table = gigaset_table, |
144 | .suspend = gigaset_suspend, | ||
145 | .resume = gigaset_resume, | ||
146 | .reset_resume = gigaset_post_reset, | ||
147 | .pre_reset = gigaset_pre_reset, | ||
148 | .post_reset = gigaset_post_reset, | ||
135 | }; | 149 | }; |
136 | 150 | ||
137 | /* get message text for usb_submit_urb return code | 151 | /* get message text for usb_submit_urb return code |
@@ -248,12 +262,12 @@ static inline void dump_urb(enum debuglevel level, const char *tag, | |||
248 | if (urb) { | 262 | if (urb) { |
249 | gig_dbg(level, | 263 | gig_dbg(level, |
250 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " | 264 | " dev=0x%08lx, pipe=%s:EP%d/DV%d:%s, " |
251 | "status=%d, hcpriv=0x%08lx, transfer_flags=0x%x,", | 265 | "hcpriv=0x%08lx, transfer_flags=0x%x,", |
252 | (unsigned long) urb->dev, | 266 | (unsigned long) urb->dev, |
253 | usb_pipetype_str(urb->pipe), | 267 | usb_pipetype_str(urb->pipe), |
254 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), | 268 | usb_pipeendpoint(urb->pipe), usb_pipedevice(urb->pipe), |
255 | usb_pipein(urb->pipe) ? "in" : "out", | 269 | usb_pipein(urb->pipe) ? "in" : "out", |
256 | urb->status, (unsigned long) urb->hcpriv, | 270 | (unsigned long) urb->hcpriv, |
257 | urb->transfer_flags); | 271 | urb->transfer_flags); |
258 | gig_dbg(level, | 272 | gig_dbg(level, |
259 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " | 273 | " transfer_buffer=0x%08lx[%d], actual_length=%d, " |
@@ -355,27 +369,27 @@ static void check_pending(struct bas_cardstate *ucs) | |||
355 | case 0: | 369 | case 0: |
356 | break; | 370 | break; |
357 | case HD_OPEN_ATCHANNEL: | 371 | case HD_OPEN_ATCHANNEL: |
358 | if (atomic_read(&ucs->basstate) & BS_ATOPEN) | 372 | if (ucs->basstate & BS_ATOPEN) |
359 | ucs->pending = 0; | 373 | ucs->pending = 0; |
360 | break; | 374 | break; |
361 | case HD_OPEN_B1CHANNEL: | 375 | case HD_OPEN_B1CHANNEL: |
362 | if (atomic_read(&ucs->basstate) & BS_B1OPEN) | 376 | if (ucs->basstate & BS_B1OPEN) |
363 | ucs->pending = 0; | 377 | ucs->pending = 0; |
364 | break; | 378 | break; |
365 | case HD_OPEN_B2CHANNEL: | 379 | case HD_OPEN_B2CHANNEL: |
366 | if (atomic_read(&ucs->basstate) & BS_B2OPEN) | 380 | if (ucs->basstate & BS_B2OPEN) |
367 | ucs->pending = 0; | 381 | ucs->pending = 0; |
368 | break; | 382 | break; |
369 | case HD_CLOSE_ATCHANNEL: | 383 | case HD_CLOSE_ATCHANNEL: |
370 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) | 384 | if (!(ucs->basstate & BS_ATOPEN)) |
371 | ucs->pending = 0; | 385 | ucs->pending = 0; |
372 | break; | 386 | break; |
373 | case HD_CLOSE_B1CHANNEL: | 387 | case HD_CLOSE_B1CHANNEL: |
374 | if (!(atomic_read(&ucs->basstate) & BS_B1OPEN)) | 388 | if (!(ucs->basstate & BS_B1OPEN)) |
375 | ucs->pending = 0; | 389 | ucs->pending = 0; |
376 | break; | 390 | break; |
377 | case HD_CLOSE_B2CHANNEL: | 391 | case HD_CLOSE_B2CHANNEL: |
378 | if (!(atomic_read(&ucs->basstate) & BS_B2OPEN)) | 392 | if (!(ucs->basstate & BS_B2OPEN)) |
379 | ucs->pending = 0; | 393 | ucs->pending = 0; |
380 | break; | 394 | break; |
381 | case HD_DEVICE_INIT_ACK: /* no reply expected */ | 395 | case HD_DEVICE_INIT_ACK: /* no reply expected */ |
@@ -441,8 +455,8 @@ inline static int update_basstate(struct bas_cardstate *ucs, | |||
441 | int state; | 455 | int state; |
442 | 456 | ||
443 | spin_lock_irqsave(&ucs->lock, flags); | 457 | spin_lock_irqsave(&ucs->lock, flags); |
444 | state = atomic_read(&ucs->basstate); | 458 | state = ucs->basstate; |
445 | atomic_set(&ucs->basstate, (state & ~clear) | set); | 459 | ucs->basstate = (state & ~clear) | set; |
446 | spin_unlock_irqrestore(&ucs->lock, flags); | 460 | spin_unlock_irqrestore(&ucs->lock, flags); |
447 | return state; | 461 | return state; |
448 | } | 462 | } |
@@ -459,11 +473,13 @@ static void read_ctrl_callback(struct urb *urb) | |||
459 | struct inbuf_t *inbuf = urb->context; | 473 | struct inbuf_t *inbuf = urb->context; |
460 | struct cardstate *cs = inbuf->cs; | 474 | struct cardstate *cs = inbuf->cs; |
461 | struct bas_cardstate *ucs = cs->hw.bas; | 475 | struct bas_cardstate *ucs = cs->hw.bas; |
476 | int status = urb->status; | ||
462 | int have_data = 0; | 477 | int have_data = 0; |
463 | unsigned numbytes; | 478 | unsigned numbytes; |
464 | int rc; | 479 | int rc; |
465 | 480 | ||
466 | update_basstate(ucs, 0, BS_ATRDPEND); | 481 | update_basstate(ucs, 0, BS_ATRDPEND); |
482 | wake_up(&ucs->waitqueue); | ||
467 | 483 | ||
468 | if (!ucs->rcvbuf_size) { | 484 | if (!ucs->rcvbuf_size) { |
469 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); | 485 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); |
@@ -472,7 +488,7 @@ static void read_ctrl_callback(struct urb *urb) | |||
472 | 488 | ||
473 | del_timer(&ucs->timer_cmd_in); | 489 | del_timer(&ucs->timer_cmd_in); |
474 | 490 | ||
475 | switch (urb->status) { | 491 | switch (status) { |
476 | case 0: /* normal completion */ | 492 | case 0: /* normal completion */ |
477 | numbytes = urb->actual_length; | 493 | numbytes = urb->actual_length; |
478 | if (unlikely(numbytes != ucs->rcvbuf_size)) { | 494 | if (unlikely(numbytes != ucs->rcvbuf_size)) { |
@@ -506,12 +522,12 @@ static void read_ctrl_callback(struct urb *urb) | |||
506 | case -ESHUTDOWN: /* device shut down */ | 522 | case -ESHUTDOWN: /* device shut down */ |
507 | /* no action necessary */ | 523 | /* no action necessary */ |
508 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 524 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
509 | __func__, get_usb_statmsg(urb->status)); | 525 | __func__, get_usb_statmsg(status)); |
510 | break; | 526 | break; |
511 | 527 | ||
512 | default: /* severe trouble */ | 528 | default: /* severe trouble */ |
513 | dev_warn(cs->dev, "control read: %s\n", | 529 | dev_warn(cs->dev, "control read: %s\n", |
514 | get_usb_statmsg(urb->status)); | 530 | get_usb_statmsg(status)); |
515 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 531 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
516 | dev_notice(cs->dev, "control read: retry %d\n", | 532 | dev_notice(cs->dev, "control read: retry %d\n", |
517 | ucs->retry_cmd_in); | 533 | ucs->retry_cmd_in); |
@@ -550,17 +566,28 @@ static void read_ctrl_callback(struct urb *urb) | |||
550 | static int atread_submit(struct cardstate *cs, int timeout) | 566 | static int atread_submit(struct cardstate *cs, int timeout) |
551 | { | 567 | { |
552 | struct bas_cardstate *ucs = cs->hw.bas; | 568 | struct bas_cardstate *ucs = cs->hw.bas; |
569 | int basstate; | ||
553 | int ret; | 570 | int ret; |
554 | 571 | ||
555 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", | 572 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", |
556 | ucs->rcvbuf_size); | 573 | ucs->rcvbuf_size); |
557 | 574 | ||
558 | if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) { | 575 | basstate = update_basstate(ucs, BS_ATRDPEND, 0); |
576 | if (basstate & BS_ATRDPEND) { | ||
559 | dev_err(cs->dev, | 577 | dev_err(cs->dev, |
560 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); | 578 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); |
561 | return -EBUSY; | 579 | return -EBUSY; |
562 | } | 580 | } |
563 | 581 | ||
582 | if (basstate & BS_SUSPEND) { | ||
583 | dev_notice(cs->dev, | ||
584 | "HD_READ_ATMESSAGE not submitted, " | ||
585 | "suspend in progress\n"); | ||
586 | update_basstate(ucs, 0, BS_ATRDPEND); | ||
587 | /* treat like disconnect */ | ||
588 | return -ENODEV; | ||
589 | } | ||
590 | |||
564 | ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ; | 591 | ucs->dr_cmd_in.bRequestType = IN_VENDOR_REQ; |
565 | ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE; | 592 | ucs->dr_cmd_in.bRequest = HD_READ_ATMESSAGE; |
566 | ucs->dr_cmd_in.wValue = 0; | 593 | ucs->dr_cmd_in.wValue = 0; |
@@ -601,12 +628,13 @@ static void read_int_callback(struct urb *urb) | |||
601 | struct cardstate *cs = urb->context; | 628 | struct cardstate *cs = urb->context; |
602 | struct bas_cardstate *ucs = cs->hw.bas; | 629 | struct bas_cardstate *ucs = cs->hw.bas; |
603 | struct bc_state *bcs; | 630 | struct bc_state *bcs; |
631 | int status = urb->status; | ||
604 | unsigned long flags; | 632 | unsigned long flags; |
605 | int rc; | 633 | int rc; |
606 | unsigned l; | 634 | unsigned l; |
607 | int channel; | 635 | int channel; |
608 | 636 | ||
609 | switch (urb->status) { | 637 | switch (status) { |
610 | case 0: /* success */ | 638 | case 0: /* success */ |
611 | break; | 639 | break; |
612 | case -ENOENT: /* cancelled */ | 640 | case -ENOENT: /* cancelled */ |
@@ -614,7 +642,7 @@ static void read_int_callback(struct urb *urb) | |||
614 | case -EINPROGRESS: /* pending */ | 642 | case -EINPROGRESS: /* pending */ |
615 | /* ignore silently */ | 643 | /* ignore silently */ |
616 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 644 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
617 | __func__, get_usb_statmsg(urb->status)); | 645 | __func__, get_usb_statmsg(status)); |
618 | return; | 646 | return; |
619 | case -ENODEV: /* device removed */ | 647 | case -ENODEV: /* device removed */ |
620 | case -ESHUTDOWN: /* device shut down */ | 648 | case -ESHUTDOWN: /* device shut down */ |
@@ -623,7 +651,7 @@ static void read_int_callback(struct urb *urb) | |||
623 | return; | 651 | return; |
624 | default: /* severe trouble */ | 652 | default: /* severe trouble */ |
625 | dev_warn(cs->dev, "interrupt read: %s\n", | 653 | dev_warn(cs->dev, "interrupt read: %s\n", |
626 | get_usb_statmsg(urb->status)); | 654 | get_usb_statmsg(status)); |
627 | //FIXME corrective action? resubmission always ok? | 655 | //FIXME corrective action? resubmission always ok? |
628 | goto resubmit; | 656 | goto resubmit; |
629 | } | 657 | } |
@@ -745,6 +773,7 @@ static void read_int_callback(struct urb *urb) | |||
745 | } | 773 | } |
746 | 774 | ||
747 | check_pending(ucs); | 775 | check_pending(ucs); |
776 | wake_up(&ucs->waitqueue); | ||
748 | 777 | ||
749 | resubmit: | 778 | resubmit: |
750 | rc = usb_submit_urb(urb, GFP_ATOMIC); | 779 | rc = usb_submit_urb(urb, GFP_ATOMIC); |
@@ -766,17 +795,18 @@ static void read_iso_callback(struct urb *urb) | |||
766 | { | 795 | { |
767 | struct bc_state *bcs; | 796 | struct bc_state *bcs; |
768 | struct bas_bc_state *ubc; | 797 | struct bas_bc_state *ubc; |
798 | int status = urb->status; | ||
769 | unsigned long flags; | 799 | unsigned long flags; |
770 | int i, rc; | 800 | int i, rc; |
771 | 801 | ||
772 | /* status codes not worth bothering the tasklet with */ | 802 | /* status codes not worth bothering the tasklet with */ |
773 | if (unlikely(urb->status == -ENOENT || | 803 | if (unlikely(status == -ENOENT || |
774 | urb->status == -ECONNRESET || | 804 | status == -ECONNRESET || |
775 | urb->status == -EINPROGRESS || | 805 | status == -EINPROGRESS || |
776 | urb->status == -ENODEV || | 806 | status == -ENODEV || |
777 | urb->status == -ESHUTDOWN)) { | 807 | status == -ESHUTDOWN)) { |
778 | gig_dbg(DEBUG_ISO, "%s: %s", | 808 | gig_dbg(DEBUG_ISO, "%s: %s", |
779 | __func__, get_usb_statmsg(urb->status)); | 809 | __func__, get_usb_statmsg(status)); |
780 | return; | 810 | return; |
781 | } | 811 | } |
782 | 812 | ||
@@ -787,10 +817,11 @@ static void read_iso_callback(struct urb *urb) | |||
787 | if (likely(ubc->isoindone == NULL)) { | 817 | if (likely(ubc->isoindone == NULL)) { |
788 | /* pass URB to tasklet */ | 818 | /* pass URB to tasklet */ |
789 | ubc->isoindone = urb; | 819 | ubc->isoindone = urb; |
820 | ubc->isoinstatus = status; | ||
790 | tasklet_schedule(&ubc->rcvd_tasklet); | 821 | tasklet_schedule(&ubc->rcvd_tasklet); |
791 | } else { | 822 | } else { |
792 | /* tasklet still busy, drop data and resubmit URB */ | 823 | /* tasklet still busy, drop data and resubmit URB */ |
793 | ubc->loststatus = urb->status; | 824 | ubc->loststatus = status; |
794 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 825 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
795 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; | 826 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; |
796 | if (unlikely(urb->iso_frame_desc[i].status != 0 && | 827 | if (unlikely(urb->iso_frame_desc[i].status != 0 && |
@@ -800,7 +831,7 @@ static void read_iso_callback(struct urb *urb) | |||
800 | urb->iso_frame_desc[i].status = 0; | 831 | urb->iso_frame_desc[i].status = 0; |
801 | urb->iso_frame_desc[i].actual_length = 0; | 832 | urb->iso_frame_desc[i].actual_length = 0; |
802 | } | 833 | } |
803 | if (likely(atomic_read(&ubc->running))) { | 834 | if (likely(ubc->running)) { |
804 | /* urb->dev is clobbered by USB subsystem */ | 835 | /* urb->dev is clobbered by USB subsystem */ |
805 | urb->dev = bcs->cs->hw.bas->udev; | 836 | urb->dev = bcs->cs->hw.bas->udev; |
806 | urb->transfer_flags = URB_ISO_ASAP; | 837 | urb->transfer_flags = URB_ISO_ASAP; |
@@ -831,22 +862,24 @@ static void write_iso_callback(struct urb *urb) | |||
831 | { | 862 | { |
832 | struct isow_urbctx_t *ucx; | 863 | struct isow_urbctx_t *ucx; |
833 | struct bas_bc_state *ubc; | 864 | struct bas_bc_state *ubc; |
865 | int status = urb->status; | ||
834 | unsigned long flags; | 866 | unsigned long flags; |
835 | 867 | ||
836 | /* status codes not worth bothering the tasklet with */ | 868 | /* status codes not worth bothering the tasklet with */ |
837 | if (unlikely(urb->status == -ENOENT || | 869 | if (unlikely(status == -ENOENT || |
838 | urb->status == -ECONNRESET || | 870 | status == -ECONNRESET || |
839 | urb->status == -EINPROGRESS || | 871 | status == -EINPROGRESS || |
840 | urb->status == -ENODEV || | 872 | status == -ENODEV || |
841 | urb->status == -ESHUTDOWN)) { | 873 | status == -ESHUTDOWN)) { |
842 | gig_dbg(DEBUG_ISO, "%s: %s", | 874 | gig_dbg(DEBUG_ISO, "%s: %s", |
843 | __func__, get_usb_statmsg(urb->status)); | 875 | __func__, get_usb_statmsg(status)); |
844 | return; | 876 | return; |
845 | } | 877 | } |
846 | 878 | ||
847 | /* pass URB context to tasklet */ | 879 | /* pass URB context to tasklet */ |
848 | ucx = urb->context; | 880 | ucx = urb->context; |
849 | ubc = ucx->bcs->hw.bas; | 881 | ubc = ucx->bcs->hw.bas; |
882 | ucx->status = status; | ||
850 | 883 | ||
851 | spin_lock_irqsave(&ubc->isooutlock, flags); | 884 | spin_lock_irqsave(&ubc->isooutlock, flags); |
852 | ubc->isooutovfl = ubc->isooutdone; | 885 | ubc->isooutovfl = ubc->isooutdone; |
@@ -875,7 +908,7 @@ static int starturbs(struct bc_state *bcs) | |||
875 | bcs->inputstate |= INS_flag_hunt; | 908 | bcs->inputstate |= INS_flag_hunt; |
876 | 909 | ||
877 | /* submit all isochronous input URBs */ | 910 | /* submit all isochronous input URBs */ |
878 | atomic_set(&ubc->running, 1); | 911 | ubc->running = 1; |
879 | for (k = 0; k < BAS_INURBS; k++) { | 912 | for (k = 0; k < BAS_INURBS; k++) { |
880 | urb = ubc->isoinurbs[k]; | 913 | urb = ubc->isoinurbs[k]; |
881 | if (!urb) { | 914 | if (!urb) { |
@@ -932,15 +965,15 @@ static int starturbs(struct bc_state *bcs) | |||
932 | ubc->isoouturbs[k].limit = -1; | 965 | ubc->isoouturbs[k].limit = -1; |
933 | } | 966 | } |
934 | 967 | ||
935 | /* submit two URBs, keep third one */ | 968 | /* keep one URB free, submit the others */ |
936 | for (k = 0; k < 2; ++k) { | 969 | for (k = 0; k < BAS_OUTURBS-1; ++k) { |
937 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); | 970 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); |
938 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC); | 971 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, GFP_ATOMIC); |
939 | if (rc != 0) | 972 | if (rc != 0) |
940 | goto error; | 973 | goto error; |
941 | } | 974 | } |
942 | dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); | 975 | dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); |
943 | ubc->isooutfree = &ubc->isoouturbs[2]; | 976 | ubc->isooutfree = &ubc->isoouturbs[BAS_OUTURBS-1]; |
944 | ubc->isooutdone = ubc->isooutovfl = NULL; | 977 | ubc->isooutdone = ubc->isooutovfl = NULL; |
945 | return 0; | 978 | return 0; |
946 | error: | 979 | error: |
@@ -958,7 +991,7 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
958 | { | 991 | { |
959 | int k, rc; | 992 | int k, rc; |
960 | 993 | ||
961 | atomic_set(&ubc->running, 0); | 994 | ubc->running = 0; |
962 | 995 | ||
963 | for (k = 0; k < BAS_INURBS; ++k) { | 996 | for (k = 0; k < BAS_INURBS; ++k) { |
964 | rc = usb_unlink_urb(ubc->isoinurbs[k]); | 997 | rc = usb_unlink_urb(ubc->isoinurbs[k]); |
@@ -1034,7 +1067,7 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
1034 | } | 1067 | } |
1035 | break; | 1068 | break; |
1036 | } | 1069 | } |
1037 | ucx->limit = atomic_read(&ubc->isooutbuf->nextread); | 1070 | ucx->limit = ubc->isooutbuf->nextread; |
1038 | ifd->status = 0; | 1071 | ifd->status = 0; |
1039 | ifd->actual_length = 0; | 1072 | ifd->actual_length = 0; |
1040 | } | 1073 | } |
@@ -1070,6 +1103,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1070 | struct cardstate *cs = bcs->cs; | 1103 | struct cardstate *cs = bcs->cs; |
1071 | struct isow_urbctx_t *done, *next, *ovfl; | 1104 | struct isow_urbctx_t *done, *next, *ovfl; |
1072 | struct urb *urb; | 1105 | struct urb *urb; |
1106 | int status; | ||
1073 | struct usb_iso_packet_descriptor *ifd; | 1107 | struct usb_iso_packet_descriptor *ifd; |
1074 | int offset; | 1108 | int offset; |
1075 | unsigned long flags; | 1109 | unsigned long flags; |
@@ -1080,7 +1114,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1080 | 1114 | ||
1081 | /* loop while completed URBs arrive in time */ | 1115 | /* loop while completed URBs arrive in time */ |
1082 | for (;;) { | 1116 | for (;;) { |
1083 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1117 | if (unlikely(!(ubc->running))) { |
1084 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); | 1118 | gig_dbg(DEBUG_ISO, "%s: not running", __func__); |
1085 | return; | 1119 | return; |
1086 | } | 1120 | } |
@@ -1126,7 +1160,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1126 | 1160 | ||
1127 | /* process completed URB */ | 1161 | /* process completed URB */ |
1128 | urb = done->urb; | 1162 | urb = done->urb; |
1129 | switch (urb->status) { | 1163 | status = done->status; |
1164 | switch (status) { | ||
1130 | case -EXDEV: /* partial completion */ | 1165 | case -EXDEV: /* partial completion */ |
1131 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", | 1166 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", |
1132 | __func__); | 1167 | __func__); |
@@ -1179,12 +1214,12 @@ static void write_iso_tasklet(unsigned long data) | |||
1179 | break; | 1214 | break; |
1180 | default: /* severe trouble */ | 1215 | default: /* severe trouble */ |
1181 | dev_warn(cs->dev, "isochronous write: %s\n", | 1216 | dev_warn(cs->dev, "isochronous write: %s\n", |
1182 | get_usb_statmsg(urb->status)); | 1217 | get_usb_statmsg(status)); |
1183 | } | 1218 | } |
1184 | 1219 | ||
1185 | /* mark the write buffer area covered by this URB as free */ | 1220 | /* mark the write buffer area covered by this URB as free */ |
1186 | if (done->limit >= 0) | 1221 | if (done->limit >= 0) |
1187 | atomic_set(&ubc->isooutbuf->read, done->limit); | 1222 | ubc->isooutbuf->read = done->limit; |
1188 | 1223 | ||
1189 | /* mark URB as free */ | 1224 | /* mark URB as free */ |
1190 | spin_lock_irqsave(&ubc->isooutlock, flags); | 1225 | spin_lock_irqsave(&ubc->isooutlock, flags); |
@@ -1233,6 +1268,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1233 | struct bas_bc_state *ubc = bcs->hw.bas; | 1268 | struct bas_bc_state *ubc = bcs->hw.bas; |
1234 | struct cardstate *cs = bcs->cs; | 1269 | struct cardstate *cs = bcs->cs; |
1235 | struct urb *urb; | 1270 | struct urb *urb; |
1271 | int status; | ||
1236 | char *rcvbuf; | 1272 | char *rcvbuf; |
1237 | unsigned long flags; | 1273 | unsigned long flags; |
1238 | int totleft, numbytes, offset, frame, rc; | 1274 | int totleft, numbytes, offset, frame, rc; |
@@ -1245,6 +1281,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1245 | spin_unlock_irqrestore(&ubc->isoinlock, flags); | 1281 | spin_unlock_irqrestore(&ubc->isoinlock, flags); |
1246 | return; | 1282 | return; |
1247 | } | 1283 | } |
1284 | status = ubc->isoinstatus; | ||
1248 | ubc->isoindone = NULL; | 1285 | ubc->isoindone = NULL; |
1249 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { | 1286 | if (unlikely(ubc->loststatus != -EINPROGRESS)) { |
1250 | dev_warn(cs->dev, | 1287 | dev_warn(cs->dev, |
@@ -1256,15 +1293,15 @@ static void read_iso_tasklet(unsigned long data) | |||
1256 | } | 1293 | } |
1257 | spin_unlock_irqrestore(&ubc->isoinlock, flags); | 1294 | spin_unlock_irqrestore(&ubc->isoinlock, flags); |
1258 | 1295 | ||
1259 | if (unlikely(!(atomic_read(&ubc->running)))) { | 1296 | if (unlikely(!(ubc->running))) { |
1260 | gig_dbg(DEBUG_ISO, | 1297 | gig_dbg(DEBUG_ISO, |
1261 | "%s: channel not running, " | 1298 | "%s: channel not running, " |
1262 | "dropped URB with status: %s", | 1299 | "dropped URB with status: %s", |
1263 | __func__, get_usb_statmsg(urb->status)); | 1300 | __func__, get_usb_statmsg(status)); |
1264 | return; | 1301 | return; |
1265 | } | 1302 | } |
1266 | 1303 | ||
1267 | switch (urb->status) { | 1304 | switch (status) { |
1268 | case 0: /* normal completion */ | 1305 | case 0: /* normal completion */ |
1269 | break; | 1306 | break; |
1270 | case -EXDEV: /* inspect individual frames | 1307 | case -EXDEV: /* inspect individual frames |
@@ -1276,7 +1313,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1276 | case -ECONNRESET: | 1313 | case -ECONNRESET: |
1277 | case -EINPROGRESS: | 1314 | case -EINPROGRESS: |
1278 | gig_dbg(DEBUG_ISO, "%s: %s", | 1315 | gig_dbg(DEBUG_ISO, "%s: %s", |
1279 | __func__, get_usb_statmsg(urb->status)); | 1316 | __func__, get_usb_statmsg(status)); |
1280 | continue; /* -> skip */ | 1317 | continue; /* -> skip */ |
1281 | case -EPIPE: | 1318 | case -EPIPE: |
1282 | dev_err(cs->dev, "isochronous read stalled\n"); | 1319 | dev_err(cs->dev, "isochronous read stalled\n"); |
@@ -1284,7 +1321,7 @@ static void read_iso_tasklet(unsigned long data) | |||
1284 | continue; /* -> skip */ | 1321 | continue; /* -> skip */ |
1285 | default: /* severe trouble */ | 1322 | default: /* severe trouble */ |
1286 | dev_warn(cs->dev, "isochronous read: %s\n", | 1323 | dev_warn(cs->dev, "isochronous read: %s\n", |
1287 | get_usb_statmsg(urb->status)); | 1324 | get_usb_statmsg(status)); |
1288 | goto error; | 1325 | goto error; |
1289 | } | 1326 | } |
1290 | 1327 | ||
@@ -1406,6 +1443,8 @@ static void req_timeout(unsigned long data) | |||
1406 | dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", | 1443 | dev_warn(bcs->cs->dev, "request 0x%02x timed out, clearing\n", |
1407 | pending); | 1444 | pending); |
1408 | } | 1445 | } |
1446 | |||
1447 | wake_up(&ucs->waitqueue); | ||
1409 | } | 1448 | } |
1410 | 1449 | ||
1411 | /* write_ctrl_callback | 1450 | /* write_ctrl_callback |
@@ -1418,11 +1457,12 @@ static void req_timeout(unsigned long data) | |||
1418 | static void write_ctrl_callback(struct urb *urb) | 1457 | static void write_ctrl_callback(struct urb *urb) |
1419 | { | 1458 | { |
1420 | struct bas_cardstate *ucs = urb->context; | 1459 | struct bas_cardstate *ucs = urb->context; |
1460 | int status = urb->status; | ||
1421 | int rc; | 1461 | int rc; |
1422 | unsigned long flags; | 1462 | unsigned long flags; |
1423 | 1463 | ||
1424 | /* check status */ | 1464 | /* check status */ |
1425 | switch (urb->status) { | 1465 | switch (status) { |
1426 | case 0: /* normal completion */ | 1466 | case 0: /* normal completion */ |
1427 | spin_lock_irqsave(&ucs->lock, flags); | 1467 | spin_lock_irqsave(&ucs->lock, flags); |
1428 | switch (ucs->pending) { | 1468 | switch (ucs->pending) { |
@@ -1441,20 +1481,22 @@ static void write_ctrl_callback(struct urb *urb) | |||
1441 | case -ESHUTDOWN: /* device shut down */ | 1481 | case -ESHUTDOWN: /* device shut down */ |
1442 | /* ignore silently */ | 1482 | /* ignore silently */ |
1443 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 1483 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
1444 | __func__, get_usb_statmsg(urb->status)); | 1484 | __func__, get_usb_statmsg(status)); |
1445 | break; | 1485 | break; |
1446 | 1486 | ||
1447 | default: /* any failure */ | 1487 | default: /* any failure */ |
1448 | if (++ucs->retry_ctrl > BAS_RETRY) { | 1488 | /* don't retry if suspend requested */ |
1489 | if (++ucs->retry_ctrl > BAS_RETRY || | ||
1490 | (ucs->basstate & BS_SUSPEND)) { | ||
1449 | dev_err(&ucs->interface->dev, | 1491 | dev_err(&ucs->interface->dev, |
1450 | "control request 0x%02x failed: %s\n", | 1492 | "control request 0x%02x failed: %s\n", |
1451 | ucs->dr_ctrl.bRequest, | 1493 | ucs->dr_ctrl.bRequest, |
1452 | get_usb_statmsg(urb->status)); | 1494 | get_usb_statmsg(status)); |
1453 | break; /* give up */ | 1495 | break; /* give up */ |
1454 | } | 1496 | } |
1455 | dev_notice(&ucs->interface->dev, | 1497 | dev_notice(&ucs->interface->dev, |
1456 | "control request 0x%02x: %s, retry %d\n", | 1498 | "control request 0x%02x: %s, retry %d\n", |
1457 | ucs->dr_ctrl.bRequest, get_usb_statmsg(urb->status), | 1499 | ucs->dr_ctrl.bRequest, get_usb_statmsg(status), |
1458 | ucs->retry_ctrl); | 1500 | ucs->retry_ctrl); |
1459 | /* urb->dev is clobbered by USB subsystem */ | 1501 | /* urb->dev is clobbered by USB subsystem */ |
1460 | urb->dev = ucs->udev; | 1502 | urb->dev = ucs->udev; |
@@ -1474,6 +1516,7 @@ static void write_ctrl_callback(struct urb *urb) | |||
1474 | del_timer(&ucs->timer_ctrl); | 1516 | del_timer(&ucs->timer_ctrl); |
1475 | ucs->pending = 0; | 1517 | ucs->pending = 0; |
1476 | spin_unlock_irqrestore(&ucs->lock, flags); | 1518 | spin_unlock_irqrestore(&ucs->lock, flags); |
1519 | wake_up(&ucs->waitqueue); | ||
1477 | } | 1520 | } |
1478 | 1521 | ||
1479 | /* req_submit | 1522 | /* req_submit |
@@ -1548,37 +1591,46 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1548 | */ | 1591 | */ |
1549 | static int gigaset_init_bchannel(struct bc_state *bcs) | 1592 | static int gigaset_init_bchannel(struct bc_state *bcs) |
1550 | { | 1593 | { |
1594 | struct cardstate *cs = bcs->cs; | ||
1551 | int req, ret; | 1595 | int req, ret; |
1552 | unsigned long flags; | 1596 | unsigned long flags; |
1553 | 1597 | ||
1554 | spin_lock_irqsave(&bcs->cs->lock, flags); | 1598 | spin_lock_irqsave(&cs->lock, flags); |
1555 | if (unlikely(!bcs->cs->connected)) { | 1599 | if (unlikely(!cs->connected)) { |
1556 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | 1600 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); |
1557 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1601 | spin_unlock_irqrestore(&cs->lock, flags); |
1558 | return -ENODEV; | 1602 | return -ENODEV; |
1559 | } | 1603 | } |
1560 | 1604 | ||
1605 | if (cs->hw.bas->basstate & BS_SUSPEND) { | ||
1606 | dev_notice(cs->dev, | ||
1607 | "not starting isochronous I/O, " | ||
1608 | "suspend in progress\n"); | ||
1609 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1610 | return -EHOSTUNREACH; | ||
1611 | } | ||
1612 | |||
1561 | if ((ret = starturbs(bcs)) < 0) { | 1613 | if ((ret = starturbs(bcs)) < 0) { |
1562 | dev_err(bcs->cs->dev, | 1614 | dev_err(cs->dev, |
1563 | "could not start isochronous I/O for channel B%d: %s\n", | 1615 | "could not start isochronous I/O for channel B%d: %s\n", |
1564 | bcs->channel + 1, | 1616 | bcs->channel + 1, |
1565 | ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); | 1617 | ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); |
1566 | if (ret != -ENODEV) | 1618 | if (ret != -ENODEV) |
1567 | error_hangup(bcs); | 1619 | error_hangup(bcs); |
1568 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1620 | spin_unlock_irqrestore(&cs->lock, flags); |
1569 | return ret; | 1621 | return ret; |
1570 | } | 1622 | } |
1571 | 1623 | ||
1572 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; | 1624 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; |
1573 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { | 1625 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { |
1574 | dev_err(bcs->cs->dev, "could not open channel B%d\n", | 1626 | dev_err(cs->dev, "could not open channel B%d\n", |
1575 | bcs->channel + 1); | 1627 | bcs->channel + 1); |
1576 | stopurbs(bcs->hw.bas); | 1628 | stopurbs(bcs->hw.bas); |
1577 | if (ret != -ENODEV) | 1629 | if (ret != -ENODEV) |
1578 | error_hangup(bcs); | 1630 | error_hangup(bcs); |
1579 | } | 1631 | } |
1580 | 1632 | ||
1581 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1633 | spin_unlock_irqrestore(&cs->lock, flags); |
1582 | return ret; | 1634 | return ret; |
1583 | } | 1635 | } |
1584 | 1636 | ||
@@ -1594,20 +1646,20 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1594 | */ | 1646 | */ |
1595 | static int gigaset_close_bchannel(struct bc_state *bcs) | 1647 | static int gigaset_close_bchannel(struct bc_state *bcs) |
1596 | { | 1648 | { |
1649 | struct cardstate *cs = bcs->cs; | ||
1597 | int req, ret; | 1650 | int req, ret; |
1598 | unsigned long flags; | 1651 | unsigned long flags; |
1599 | 1652 | ||
1600 | spin_lock_irqsave(&bcs->cs->lock, flags); | 1653 | spin_lock_irqsave(&cs->lock, flags); |
1601 | if (unlikely(!bcs->cs->connected)) { | 1654 | if (unlikely(!cs->connected)) { |
1602 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1655 | spin_unlock_irqrestore(&cs->lock, flags); |
1603 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | 1656 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); |
1604 | return -ENODEV; | 1657 | return -ENODEV; |
1605 | } | 1658 | } |
1606 | 1659 | ||
1607 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & | 1660 | if (!(cs->hw.bas->basstate & (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { |
1608 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { | ||
1609 | /* channel not running: just signal common.c */ | 1661 | /* channel not running: just signal common.c */ |
1610 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1662 | spin_unlock_irqrestore(&cs->lock, flags); |
1611 | gigaset_bchannel_down(bcs); | 1663 | gigaset_bchannel_down(bcs); |
1612 | return 0; | 1664 | return 0; |
1613 | } | 1665 | } |
@@ -1615,10 +1667,10 @@ static int gigaset_close_bchannel(struct bc_state *bcs) | |||
1615 | /* channel running: tell device to close it */ | 1667 | /* channel running: tell device to close it */ |
1616 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; | 1668 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; |
1617 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) | 1669 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) |
1618 | dev_err(bcs->cs->dev, "closing channel B%d failed\n", | 1670 | dev_err(cs->dev, "closing channel B%d failed\n", |
1619 | bcs->channel + 1); | 1671 | bcs->channel + 1); |
1620 | 1672 | ||
1621 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1673 | spin_unlock_irqrestore(&cs->lock, flags); |
1622 | return ret; | 1674 | return ret; |
1623 | } | 1675 | } |
1624 | 1676 | ||
@@ -1665,12 +1717,14 @@ static void write_command_callback(struct urb *urb) | |||
1665 | { | 1717 | { |
1666 | struct cardstate *cs = urb->context; | 1718 | struct cardstate *cs = urb->context; |
1667 | struct bas_cardstate *ucs = cs->hw.bas; | 1719 | struct bas_cardstate *ucs = cs->hw.bas; |
1720 | int status = urb->status; | ||
1668 | unsigned long flags; | 1721 | unsigned long flags; |
1669 | 1722 | ||
1670 | update_basstate(ucs, 0, BS_ATWRPEND); | 1723 | update_basstate(ucs, 0, BS_ATWRPEND); |
1724 | wake_up(&ucs->waitqueue); | ||
1671 | 1725 | ||
1672 | /* check status */ | 1726 | /* check status */ |
1673 | switch (urb->status) { | 1727 | switch (status) { |
1674 | case 0: /* normal completion */ | 1728 | case 0: /* normal completion */ |
1675 | break; | 1729 | break; |
1676 | case -ENOENT: /* cancelled */ | 1730 | case -ENOENT: /* cancelled */ |
@@ -1680,26 +1734,33 @@ static void write_command_callback(struct urb *urb) | |||
1680 | case -ESHUTDOWN: /* device shut down */ | 1734 | case -ESHUTDOWN: /* device shut down */ |
1681 | /* ignore silently */ | 1735 | /* ignore silently */ |
1682 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 1736 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
1683 | __func__, get_usb_statmsg(urb->status)); | 1737 | __func__, get_usb_statmsg(status)); |
1684 | return; | 1738 | return; |
1685 | default: /* any failure */ | 1739 | default: /* any failure */ |
1686 | if (++ucs->retry_cmd_out > BAS_RETRY) { | 1740 | if (++ucs->retry_cmd_out > BAS_RETRY) { |
1687 | dev_warn(cs->dev, | 1741 | dev_warn(cs->dev, |
1688 | "command write: %s, " | 1742 | "command write: %s, " |
1689 | "giving up after %d retries\n", | 1743 | "giving up after %d retries\n", |
1690 | get_usb_statmsg(urb->status), | 1744 | get_usb_statmsg(status), |
1691 | ucs->retry_cmd_out); | 1745 | ucs->retry_cmd_out); |
1692 | break; | 1746 | break; |
1693 | } | 1747 | } |
1748 | if (ucs->basstate & BS_SUSPEND) { | ||
1749 | dev_warn(cs->dev, | ||
1750 | "command write: %s, " | ||
1751 | "won't retry - suspend requested\n", | ||
1752 | get_usb_statmsg(status)); | ||
1753 | break; | ||
1754 | } | ||
1694 | if (cs->cmdbuf == NULL) { | 1755 | if (cs->cmdbuf == NULL) { |
1695 | dev_warn(cs->dev, | 1756 | dev_warn(cs->dev, |
1696 | "command write: %s, " | 1757 | "command write: %s, " |
1697 | "cannot retry - cmdbuf gone\n", | 1758 | "cannot retry - cmdbuf gone\n", |
1698 | get_usb_statmsg(urb->status)); | 1759 | get_usb_statmsg(status)); |
1699 | break; | 1760 | break; |
1700 | } | 1761 | } |
1701 | dev_notice(cs->dev, "command write: %s, retry %d\n", | 1762 | dev_notice(cs->dev, "command write: %s, retry %d\n", |
1702 | get_usb_statmsg(urb->status), ucs->retry_cmd_out); | 1763 | get_usb_statmsg(status), ucs->retry_cmd_out); |
1703 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) | 1764 | if (atwrite_submit(cs, cs->cmdbuf->buf, cs->cmdbuf->len) >= 0) |
1704 | /* resubmitted - bypass regular exit block */ | 1765 | /* resubmitted - bypass regular exit block */ |
1705 | return; | 1766 | return; |
@@ -1799,8 +1860,14 @@ static int start_cbsend(struct cardstate *cs) | |||
1799 | int rc; | 1860 | int rc; |
1800 | int retval = 0; | 1861 | int retval = 0; |
1801 | 1862 | ||
1863 | /* check if suspend requested */ | ||
1864 | if (ucs->basstate & BS_SUSPEND) { | ||
1865 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "suspending"); | ||
1866 | return -EHOSTUNREACH; | ||
1867 | } | ||
1868 | |||
1802 | /* check if AT channel is open */ | 1869 | /* check if AT channel is open */ |
1803 | if (!(atomic_read(&ucs->basstate) & BS_ATOPEN)) { | 1870 | if (!(ucs->basstate & BS_ATOPEN)) { |
1804 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); | 1871 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); |
1805 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); | 1872 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); |
1806 | if (rc < 0) { | 1873 | if (rc < 0) { |
@@ -1816,8 +1883,7 @@ static int start_cbsend(struct cardstate *cs) | |||
1816 | /* try to send first command in queue */ | 1883 | /* try to send first command in queue */ |
1817 | spin_lock_irqsave(&cs->cmdlock, flags); | 1884 | spin_lock_irqsave(&cs->cmdlock, flags); |
1818 | 1885 | ||
1819 | while ((cb = cs->cmdbuf) != NULL && | 1886 | while ((cb = cs->cmdbuf) != NULL && (ucs->basstate & BS_ATREADY)) { |
1820 | atomic_read(&ucs->basstate) & BS_ATREADY) { | ||
1821 | ucs->retry_cmd_out = 0; | 1887 | ucs->retry_cmd_out = 0; |
1822 | rc = atwrite_submit(cs, cb->buf, cb->len); | 1888 | rc = atwrite_submit(cs, cb->buf, cb->len); |
1823 | if (unlikely(rc)) { | 1889 | if (unlikely(rc)) { |
@@ -1855,7 +1921,7 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1855 | unsigned long flags; | 1921 | unsigned long flags; |
1856 | int rc; | 1922 | int rc; |
1857 | 1923 | ||
1858 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 1924 | gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? |
1859 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 1925 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
1860 | "CMD Transmit", len, buf); | 1926 | "CMD Transmit", len, buf); |
1861 | 1927 | ||
@@ -1970,7 +2036,7 @@ static int gigaset_freebcshw(struct bc_state *bcs) | |||
1970 | return 0; | 2036 | return 0; |
1971 | 2037 | ||
1972 | /* kill URBs and tasklets before freeing - better safe than sorry */ | 2038 | /* kill URBs and tasklets before freeing - better safe than sorry */ |
1973 | atomic_set(&ubc->running, 0); | 2039 | ubc->running = 0; |
1974 | gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); | 2040 | gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); |
1975 | for (i = 0; i < BAS_OUTURBS; ++i) { | 2041 | for (i = 0; i < BAS_OUTURBS; ++i) { |
1976 | usb_kill_urb(ubc->isoouturbs[i].urb); | 2042 | usb_kill_urb(ubc->isoouturbs[i].urb); |
@@ -2005,7 +2071,7 @@ static int gigaset_initbcshw(struct bc_state *bcs) | |||
2005 | return 0; | 2071 | return 0; |
2006 | } | 2072 | } |
2007 | 2073 | ||
2008 | atomic_set(&ubc->running, 0); | 2074 | ubc->running = 0; |
2009 | atomic_set(&ubc->corrbytes, 0); | 2075 | atomic_set(&ubc->corrbytes, 0); |
2010 | spin_lock_init(&ubc->isooutlock); | 2076 | spin_lock_init(&ubc->isooutlock); |
2011 | for (i = 0; i < BAS_OUTURBS; ++i) { | 2077 | for (i = 0; i < BAS_OUTURBS; ++i) { |
@@ -2050,7 +2116,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
2050 | { | 2116 | { |
2051 | struct bas_bc_state *ubc = bcs->hw.bas; | 2117 | struct bas_bc_state *ubc = bcs->hw.bas; |
2052 | 2118 | ||
2053 | atomic_set(&bcs->hw.bas->running, 0); | 2119 | bcs->hw.bas->running = 0; |
2054 | atomic_set(&bcs->hw.bas->corrbytes, 0); | 2120 | atomic_set(&bcs->hw.bas->corrbytes, 0); |
2055 | bcs->hw.bas->numsub = 0; | 2121 | bcs->hw.bas->numsub = 0; |
2056 | spin_lock_init(&ubc->isooutlock); | 2122 | spin_lock_init(&ubc->isooutlock); |
@@ -2081,10 +2147,11 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
2081 | spin_lock_init(&ucs->lock); | 2147 | spin_lock_init(&ucs->lock); |
2082 | ucs->pending = 0; | 2148 | ucs->pending = 0; |
2083 | 2149 | ||
2084 | atomic_set(&ucs->basstate, 0); | 2150 | ucs->basstate = 0; |
2085 | init_timer(&ucs->timer_ctrl); | 2151 | init_timer(&ucs->timer_ctrl); |
2086 | init_timer(&ucs->timer_atrdy); | 2152 | init_timer(&ucs->timer_atrdy); |
2087 | init_timer(&ucs->timer_cmd_in); | 2153 | init_timer(&ucs->timer_cmd_in); |
2154 | init_waitqueue_head(&ucs->waitqueue); | ||
2088 | 2155 | ||
2089 | return 1; | 2156 | return 1; |
2090 | } | 2157 | } |
@@ -2102,7 +2169,7 @@ static void freeurbs(struct cardstate *cs) | |||
2102 | int i, j; | 2169 | int i, j; |
2103 | 2170 | ||
2104 | gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__); | 2171 | gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__); |
2105 | for (j = 0; j < 2; ++j) { | 2172 | for (j = 0; j < BAS_CHANNELS; ++j) { |
2106 | ubc = cs->bcs[j].hw.bas; | 2173 | ubc = cs->bcs[j].hw.bas; |
2107 | for (i = 0; i < BAS_OUTURBS; ++i) { | 2174 | for (i = 0; i < BAS_OUTURBS; ++i) { |
2108 | usb_kill_urb(ubc->isoouturbs[i].urb); | 2175 | usb_kill_urb(ubc->isoouturbs[i].urb); |
@@ -2179,11 +2246,11 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2179 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2246 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2180 | le16_to_cpu(udev->descriptor.idProduct)); | 2247 | le16_to_cpu(udev->descriptor.idProduct)); |
2181 | 2248 | ||
2182 | cs = gigaset_getunassignedcs(driver); | 2249 | /* allocate memory for our device state and intialize it */ |
2183 | if (!cs) { | 2250 | cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode, |
2184 | dev_err(&udev->dev, "no free cardstate\n"); | 2251 | GIGASET_MODULENAME); |
2252 | if (!cs) | ||
2185 | return -ENODEV; | 2253 | return -ENODEV; |
2186 | } | ||
2187 | ucs = cs->hw.bas; | 2254 | ucs = cs->hw.bas; |
2188 | 2255 | ||
2189 | /* save off device structure ptrs for later use */ | 2256 | /* save off device structure ptrs for later use */ |
@@ -2203,7 +2270,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2203 | !(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL))) | 2270 | !(ucs->urb_ctrl = usb_alloc_urb(0, GFP_KERNEL))) |
2204 | goto allocerr; | 2271 | goto allocerr; |
2205 | 2272 | ||
2206 | for (j = 0; j < 2; ++j) { | 2273 | for (j = 0; j < BAS_CHANNELS; ++j) { |
2207 | ubc = cs->bcs[j].hw.bas; | 2274 | ubc = cs->bcs[j].hw.bas; |
2208 | for (i = 0; i < BAS_OUTURBS; ++i) | 2275 | for (i = 0; i < BAS_OUTURBS; ++i) |
2209 | if (!(ubc->isoouturbs[i].urb = | 2276 | if (!(ubc->isoouturbs[i].urb = |
@@ -2237,7 +2304,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2237 | 2304 | ||
2238 | /* tell common part that the device is ready */ | 2305 | /* tell common part that the device is ready */ |
2239 | if (startmode == SM_LOCKED) | 2306 | if (startmode == SM_LOCKED) |
2240 | atomic_set(&cs->mstate, MS_LOCKED); | 2307 | cs->mstate = MS_LOCKED; |
2241 | 2308 | ||
2242 | /* save address of controller structure */ | 2309 | /* save address of controller structure */ |
2243 | usb_set_intfdata(interface, cs); | 2310 | usb_set_intfdata(interface, cs); |
@@ -2252,7 +2319,7 @@ allocerr: | |||
2252 | error: | 2319 | error: |
2253 | freeurbs(cs); | 2320 | freeurbs(cs); |
2254 | usb_set_intfdata(interface, NULL); | 2321 | usb_set_intfdata(interface, NULL); |
2255 | gigaset_unassign(cs); | 2322 | gigaset_freecs(cs); |
2256 | return -ENODEV; | 2323 | return -ENODEV; |
2257 | } | 2324 | } |
2258 | 2325 | ||
@@ -2272,11 +2339,10 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2272 | dev_info(cs->dev, "disconnecting Gigaset base\n"); | 2339 | dev_info(cs->dev, "disconnecting Gigaset base\n"); |
2273 | 2340 | ||
2274 | /* mark base as not ready, all channels disconnected */ | 2341 | /* mark base as not ready, all channels disconnected */ |
2275 | atomic_set(&ucs->basstate, 0); | 2342 | ucs->basstate = 0; |
2276 | 2343 | ||
2277 | /* tell LL all channels are down */ | 2344 | /* tell LL all channels are down */ |
2278 | //FIXME shouldn't gigaset_stop() do this? | 2345 | for (j = 0; j < BAS_CHANNELS; ++j) |
2279 | for (j = 0; j < 2; ++j) | ||
2280 | gigaset_bchannel_down(cs->bcs + j); | 2346 | gigaset_bchannel_down(cs->bcs + j); |
2281 | 2347 | ||
2282 | /* stop driver (common part) */ | 2348 | /* stop driver (common part) */ |
@@ -2295,9 +2361,113 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2295 | ucs->interface = NULL; | 2361 | ucs->interface = NULL; |
2296 | ucs->udev = NULL; | 2362 | ucs->udev = NULL; |
2297 | cs->dev = NULL; | 2363 | cs->dev = NULL; |
2298 | gigaset_unassign(cs); | 2364 | gigaset_freecs(cs); |
2299 | } | 2365 | } |
2300 | 2366 | ||
2367 | /* gigaset_suspend | ||
2368 | * This function is called before the USB connection is suspended. | ||
2369 | */ | ||
2370 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) | ||
2371 | { | ||
2372 | struct cardstate *cs = usb_get_intfdata(intf); | ||
2373 | struct bas_cardstate *ucs = cs->hw.bas; | ||
2374 | int rc; | ||
2375 | |||
2376 | /* set suspend flag; this stops AT command/response traffic */ | ||
2377 | if (update_basstate(ucs, BS_SUSPEND, 0) & BS_SUSPEND) { | ||
2378 | gig_dbg(DEBUG_SUSPEND, "already suspended"); | ||
2379 | return 0; | ||
2380 | } | ||
2381 | |||
2382 | /* wait a bit for blocking conditions to go away */ | ||
2383 | rc = wait_event_timeout(ucs->waitqueue, | ||
2384 | !(ucs->basstate & | ||
2385 | (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)), | ||
2386 | BAS_TIMEOUT*HZ/10); | ||
2387 | gig_dbg(DEBUG_SUSPEND, "wait_event_timeout() -> %d", rc); | ||
2388 | |||
2389 | /* check for conditions preventing suspend */ | ||
2390 | if (ucs->basstate & (BS_B1OPEN|BS_B2OPEN|BS_ATRDPEND|BS_ATWRPEND)) { | ||
2391 | dev_warn(cs->dev, "cannot suspend:\n"); | ||
2392 | if (ucs->basstate & BS_B1OPEN) | ||
2393 | dev_warn(cs->dev, " B channel 1 open\n"); | ||
2394 | if (ucs->basstate & BS_B2OPEN) | ||
2395 | dev_warn(cs->dev, " B channel 2 open\n"); | ||
2396 | if (ucs->basstate & BS_ATRDPEND) | ||
2397 | dev_warn(cs->dev, " receiving AT reply\n"); | ||
2398 | if (ucs->basstate & BS_ATWRPEND) | ||
2399 | dev_warn(cs->dev, " sending AT command\n"); | ||
2400 | update_basstate(ucs, 0, BS_SUSPEND); | ||
2401 | return -EBUSY; | ||
2402 | } | ||
2403 | |||
2404 | /* close AT channel if open */ | ||
2405 | if (ucs->basstate & BS_ATOPEN) { | ||
2406 | gig_dbg(DEBUG_SUSPEND, "closing AT channel"); | ||
2407 | rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, 0); | ||
2408 | if (rc) { | ||
2409 | update_basstate(ucs, 0, BS_SUSPEND); | ||
2410 | return rc; | ||
2411 | } | ||
2412 | wait_event_timeout(ucs->waitqueue, !ucs->pending, | ||
2413 | BAS_TIMEOUT*HZ/10); | ||
2414 | /* in case of timeout, proceed anyway */ | ||
2415 | } | ||
2416 | |||
2417 | /* kill all URBs and timers that might still be pending */ | ||
2418 | usb_kill_urb(ucs->urb_ctrl); | ||
2419 | usb_kill_urb(ucs->urb_int_in); | ||
2420 | del_timer_sync(&ucs->timer_ctrl); | ||
2421 | |||
2422 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); | ||
2423 | return 0; | ||
2424 | } | ||
2425 | |||
2426 | /* gigaset_resume | ||
2427 | * This function is called after the USB connection has been resumed. | ||
2428 | */ | ||
2429 | static int gigaset_resume(struct usb_interface *intf) | ||
2430 | { | ||
2431 | struct cardstate *cs = usb_get_intfdata(intf); | ||
2432 | struct bas_cardstate *ucs = cs->hw.bas; | ||
2433 | int rc; | ||
2434 | |||
2435 | /* resubmit interrupt URB for spontaneous messages from base */ | ||
2436 | rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL); | ||
2437 | if (rc) { | ||
2438 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", | ||
2439 | get_usb_rcmsg(rc)); | ||
2440 | return rc; | ||
2441 | } | ||
2442 | |||
2443 | /* clear suspend flag to reallow activity */ | ||
2444 | update_basstate(ucs, 0, BS_SUSPEND); | ||
2445 | |||
2446 | gig_dbg(DEBUG_SUSPEND, "resume complete"); | ||
2447 | return 0; | ||
2448 | } | ||
2449 | |||
2450 | /* gigaset_pre_reset | ||
2451 | * This function is called before the USB connection is reset. | ||
2452 | */ | ||
2453 | static int gigaset_pre_reset(struct usb_interface *intf) | ||
2454 | { | ||
2455 | /* handle just like suspend */ | ||
2456 | return gigaset_suspend(intf, PMSG_ON); | ||
2457 | } | ||
2458 | |||
2459 | /* gigaset_post_reset | ||
2460 | * This function is called after the USB connection has been reset. | ||
2461 | */ | ||
2462 | static int gigaset_post_reset(struct usb_interface *intf) | ||
2463 | { | ||
2464 | /* FIXME: send HD_DEVICE_INIT_ACK? */ | ||
2465 | |||
2466 | /* resume operations */ | ||
2467 | return gigaset_resume(intf); | ||
2468 | } | ||
2469 | |||
2470 | |||
2301 | static const struct gigaset_ops gigops = { | 2471 | static const struct gigaset_ops gigops = { |
2302 | gigaset_write_cmd, | 2472 | gigaset_write_cmd, |
2303 | gigaset_write_room, | 2473 | gigaset_write_room, |
@@ -2330,12 +2500,6 @@ static int __init bas_gigaset_init(void) | |||
2330 | &gigops, THIS_MODULE)) == NULL) | 2500 | &gigops, THIS_MODULE)) == NULL) |
2331 | goto error; | 2501 | goto error; |
2332 | 2502 | ||
2333 | /* allocate memory for our device state and intialize it */ | ||
2334 | cardstate = gigaset_initcs(driver, 2, 0, 0, cidmode, | ||
2335 | GIGASET_MODULENAME); | ||
2336 | if (!cardstate) | ||
2337 | goto error; | ||
2338 | |||
2339 | /* register this driver with the USB subsystem */ | 2503 | /* register this driver with the USB subsystem */ |
2340 | result = usb_register(&gigaset_usb_driver); | 2504 | result = usb_register(&gigaset_usb_driver); |
2341 | if (result < 0) { | 2505 | if (result < 0) { |
@@ -2347,9 +2511,7 @@ static int __init bas_gigaset_init(void) | |||
2347 | info(DRIVER_DESC); | 2511 | info(DRIVER_DESC); |
2348 | return 0; | 2512 | return 0; |
2349 | 2513 | ||
2350 | error: if (cardstate) | 2514 | error: |
2351 | gigaset_freecs(cardstate); | ||
2352 | cardstate = NULL; | ||
2353 | if (driver) | 2515 | if (driver) |
2354 | gigaset_freedriver(driver); | 2516 | gigaset_freedriver(driver); |
2355 | driver = NULL; | 2517 | driver = NULL; |
@@ -2361,43 +2523,50 @@ error: if (cardstate) | |||
2361 | */ | 2523 | */ |
2362 | static void __exit bas_gigaset_exit(void) | 2524 | static void __exit bas_gigaset_exit(void) |
2363 | { | 2525 | { |
2364 | struct bas_cardstate *ucs = cardstate->hw.bas; | 2526 | struct bas_cardstate *ucs; |
2527 | int i; | ||
2365 | 2528 | ||
2366 | gigaset_blockdriver(driver); /* => probe will fail | 2529 | gigaset_blockdriver(driver); /* => probe will fail |
2367 | * => no gigaset_start any more | 2530 | * => no gigaset_start any more |
2368 | */ | 2531 | */ |
2369 | 2532 | ||
2370 | gigaset_shutdown(cardstate); | 2533 | /* stop all connected devices */ |
2371 | /* from now on, no isdn callback should be possible */ | 2534 | for (i = 0; i < driver->minors; i++) { |
2372 | 2535 | if (gigaset_shutdown(driver->cs + i) < 0) | |
2373 | /* close all still open channels */ | 2536 | continue; /* no device */ |
2374 | if (atomic_read(&ucs->basstate) & BS_B1OPEN) { | 2537 | /* from now on, no isdn callback should be possible */ |
2375 | gig_dbg(DEBUG_INIT, "closing B1 channel"); | 2538 | |
2376 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), | 2539 | /* close all still open channels */ |
2377 | HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0, | 2540 | ucs = driver->cs[i].hw.bas; |
2378 | NULL, 0, BAS_TIMEOUT); | 2541 | if (ucs->basstate & BS_B1OPEN) { |
2379 | } | 2542 | gig_dbg(DEBUG_INIT, "closing B1 channel"); |
2380 | if (atomic_read(&ucs->basstate) & BS_B2OPEN) { | 2543 | usb_control_msg(ucs->udev, |
2381 | gig_dbg(DEBUG_INIT, "closing B2 channel"); | 2544 | usb_sndctrlpipe(ucs->udev, 0), |
2382 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), | 2545 | HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, |
2383 | HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0, | 2546 | 0, 0, NULL, 0, BAS_TIMEOUT); |
2384 | NULL, 0, BAS_TIMEOUT); | 2547 | } |
2385 | } | 2548 | if (ucs->basstate & BS_B2OPEN) { |
2386 | if (atomic_read(&ucs->basstate) & BS_ATOPEN) { | 2549 | gig_dbg(DEBUG_INIT, "closing B2 channel"); |
2387 | gig_dbg(DEBUG_INIT, "closing AT channel"); | 2550 | usb_control_msg(ucs->udev, |
2388 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), | 2551 | usb_sndctrlpipe(ucs->udev, 0), |
2389 | HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0, | 2552 | HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, |
2390 | NULL, 0, BAS_TIMEOUT); | 2553 | 0, 0, NULL, 0, BAS_TIMEOUT); |
2554 | } | ||
2555 | if (ucs->basstate & BS_ATOPEN) { | ||
2556 | gig_dbg(DEBUG_INIT, "closing AT channel"); | ||
2557 | usb_control_msg(ucs->udev, | ||
2558 | usb_sndctrlpipe(ucs->udev, 0), | ||
2559 | HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, | ||
2560 | 0, 0, NULL, 0, BAS_TIMEOUT); | ||
2561 | } | ||
2562 | ucs->basstate = 0; | ||
2391 | } | 2563 | } |
2392 | atomic_set(&ucs->basstate, 0); | ||
2393 | 2564 | ||
2394 | /* deregister this driver with the USB subsystem */ | 2565 | /* deregister this driver with the USB subsystem */ |
2395 | usb_deregister(&gigaset_usb_driver); | 2566 | usb_deregister(&gigaset_usb_driver); |
2396 | /* this will call the disconnect-callback */ | 2567 | /* this will call the disconnect-callback */ |
2397 | /* from now on, no disconnect/probe callback should be running */ | 2568 | /* from now on, no disconnect/probe callback should be running */ |
2398 | 2569 | ||
2399 | gigaset_freecs(cardstate); | ||
2400 | cardstate = NULL; | ||
2401 | gigaset_freedriver(driver); | 2570 | gigaset_freedriver(driver); |
2402 | driver = NULL; | 2571 | driver = NULL; |
2403 | } | 2572 | } |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index acd417197d03..aacedec4986f 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -31,7 +31,6 @@ MODULE_PARM_DESC(debug, "debug level"); | |||
31 | /* driver state flags */ | 31 | /* driver state flags */ |
32 | #define VALID_MINOR 0x01 | 32 | #define VALID_MINOR 0x01 |
33 | #define VALID_ID 0x02 | 33 | #define VALID_ID 0x02 |
34 | #define ASSIGNED 0x04 | ||
35 | 34 | ||
36 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | 35 | void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, |
37 | size_t len, const unsigned char *buf) | 36 | size_t len, const unsigned char *buf) |
@@ -178,7 +177,7 @@ int gigaset_get_channel(struct bc_state *bcs) | |||
178 | unsigned long flags; | 177 | unsigned long flags; |
179 | 178 | ||
180 | spin_lock_irqsave(&bcs->cs->lock, flags); | 179 | spin_lock_irqsave(&bcs->cs->lock, flags); |
181 | if (bcs->use_count) { | 180 | if (bcs->use_count || !try_module_get(bcs->cs->driver->owner)) { |
182 | gig_dbg(DEBUG_ANY, "could not allocate channel %d", | 181 | gig_dbg(DEBUG_ANY, "could not allocate channel %d", |
183 | bcs->channel); | 182 | bcs->channel); |
184 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 183 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
@@ -203,6 +202,7 @@ void gigaset_free_channel(struct bc_state *bcs) | |||
203 | } | 202 | } |
204 | --bcs->use_count; | 203 | --bcs->use_count; |
205 | bcs->busy = 0; | 204 | bcs->busy = 0; |
205 | module_put(bcs->cs->driver->owner); | ||
206 | gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); | 206 | gig_dbg(DEBUG_ANY, "freed channel %d", bcs->channel); |
207 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 207 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
208 | } | 208 | } |
@@ -356,31 +356,28 @@ static struct cardstate *alloc_cs(struct gigaset_driver *drv) | |||
356 | { | 356 | { |
357 | unsigned long flags; | 357 | unsigned long flags; |
358 | unsigned i; | 358 | unsigned i; |
359 | struct cardstate *cs; | ||
359 | struct cardstate *ret = NULL; | 360 | struct cardstate *ret = NULL; |
360 | 361 | ||
361 | spin_lock_irqsave(&drv->lock, flags); | 362 | spin_lock_irqsave(&drv->lock, flags); |
363 | if (drv->blocked) | ||
364 | goto exit; | ||
362 | for (i = 0; i < drv->minors; ++i) { | 365 | for (i = 0; i < drv->minors; ++i) { |
363 | if (!(drv->flags[i] & VALID_MINOR)) { | 366 | cs = drv->cs + i; |
364 | if (try_module_get(drv->owner)) { | 367 | if (!(cs->flags & VALID_MINOR)) { |
365 | drv->flags[i] = VALID_MINOR; | 368 | cs->flags = VALID_MINOR; |
366 | ret = drv->cs + i; | 369 | ret = cs; |
367 | } | ||
368 | break; | 370 | break; |
369 | } | 371 | } |
370 | } | 372 | } |
373 | exit: | ||
371 | spin_unlock_irqrestore(&drv->lock, flags); | 374 | spin_unlock_irqrestore(&drv->lock, flags); |
372 | return ret; | 375 | return ret; |
373 | } | 376 | } |
374 | 377 | ||
375 | static void free_cs(struct cardstate *cs) | 378 | static void free_cs(struct cardstate *cs) |
376 | { | 379 | { |
377 | unsigned long flags; | 380 | cs->flags = 0; |
378 | struct gigaset_driver *drv = cs->driver; | ||
379 | spin_lock_irqsave(&drv->lock, flags); | ||
380 | if (drv->flags[cs->minor_index] & VALID_MINOR) | ||
381 | module_put(drv->owner); | ||
382 | drv->flags[cs->minor_index] = 0; | ||
383 | spin_unlock_irqrestore(&drv->lock, flags); | ||
384 | } | 381 | } |
385 | 382 | ||
386 | static void make_valid(struct cardstate *cs, unsigned mask) | 383 | static void make_valid(struct cardstate *cs, unsigned mask) |
@@ -388,7 +385,7 @@ static void make_valid(struct cardstate *cs, unsigned mask) | |||
388 | unsigned long flags; | 385 | unsigned long flags; |
389 | struct gigaset_driver *drv = cs->driver; | 386 | struct gigaset_driver *drv = cs->driver; |
390 | spin_lock_irqsave(&drv->lock, flags); | 387 | spin_lock_irqsave(&drv->lock, flags); |
391 | drv->flags[cs->minor_index] |= mask; | 388 | cs->flags |= mask; |
392 | spin_unlock_irqrestore(&drv->lock, flags); | 389 | spin_unlock_irqrestore(&drv->lock, flags); |
393 | } | 390 | } |
394 | 391 | ||
@@ -397,7 +394,7 @@ static void make_invalid(struct cardstate *cs, unsigned mask) | |||
397 | unsigned long flags; | 394 | unsigned long flags; |
398 | struct gigaset_driver *drv = cs->driver; | 395 | struct gigaset_driver *drv = cs->driver; |
399 | spin_lock_irqsave(&drv->lock, flags); | 396 | spin_lock_irqsave(&drv->lock, flags); |
400 | drv->flags[cs->minor_index] &= ~mask; | 397 | cs->flags &= ~mask; |
401 | spin_unlock_irqrestore(&drv->lock, flags); | 398 | spin_unlock_irqrestore(&drv->lock, flags); |
402 | } | 399 | } |
403 | 400 | ||
@@ -501,11 +498,11 @@ static void gigaset_inbuf_init(struct inbuf_t *inbuf, struct bc_state *bcs, | |||
501 | struct cardstate *cs, int inputstate) | 498 | struct cardstate *cs, int inputstate) |
502 | /* inbuf->read must be allocated before! */ | 499 | /* inbuf->read must be allocated before! */ |
503 | { | 500 | { |
504 | atomic_set(&inbuf->head, 0); | 501 | inbuf->head = 0; |
505 | atomic_set(&inbuf->tail, 0); | 502 | inbuf->tail = 0; |
506 | inbuf->cs = cs; | 503 | inbuf->cs = cs; |
507 | inbuf->bcs = bcs; /*base driver: NULL*/ | 504 | inbuf->bcs = bcs; /*base driver: NULL*/ |
508 | inbuf->rcvbuf = NULL; //FIXME | 505 | inbuf->rcvbuf = NULL; |
509 | inbuf->inputstate = inputstate; | 506 | inbuf->inputstate = inputstate; |
510 | } | 507 | } |
511 | 508 | ||
@@ -521,8 +518,8 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | |||
521 | return 0; | 518 | return 0; |
522 | 519 | ||
523 | bytesleft = numbytes; | 520 | bytesleft = numbytes; |
524 | tail = atomic_read(&inbuf->tail); | 521 | tail = inbuf->tail; |
525 | head = atomic_read(&inbuf->head); | 522 | head = inbuf->head; |
526 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 523 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
527 | 524 | ||
528 | while (bytesleft) { | 525 | while (bytesleft) { |
@@ -546,7 +543,7 @@ int gigaset_fill_inbuf(struct inbuf_t *inbuf, const unsigned char *src, | |||
546 | src += n; | 543 | src += n; |
547 | } | 544 | } |
548 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); | 545 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); |
549 | atomic_set(&inbuf->tail, tail); | 546 | inbuf->tail = tail; |
550 | return numbytes != bytesleft; | 547 | return numbytes != bytesleft; |
551 | } | 548 | } |
552 | EXPORT_SYMBOL_GPL(gigaset_fill_inbuf); | 549 | EXPORT_SYMBOL_GPL(gigaset_fill_inbuf); |
@@ -668,7 +665,7 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
668 | 665 | ||
669 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, | 666 | tasklet_init(&cs->event_tasklet, &gigaset_handle_event, |
670 | (unsigned long) cs); | 667 | (unsigned long) cs); |
671 | atomic_set(&cs->commands_pending, 0); | 668 | cs->commands_pending = 0; |
672 | cs->cur_at_seq = 0; | 669 | cs->cur_at_seq = 0; |
673 | cs->gotfwver = -1; | 670 | cs->gotfwver = -1; |
674 | cs->open_count = 0; | 671 | cs->open_count = 0; |
@@ -688,8 +685,8 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, | |||
688 | init_waitqueue_head(&cs->waitqueue); | 685 | init_waitqueue_head(&cs->waitqueue); |
689 | cs->waiting = 0; | 686 | cs->waiting = 0; |
690 | 687 | ||
691 | atomic_set(&cs->mode, M_UNKNOWN); | 688 | cs->mode = M_UNKNOWN; |
692 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 689 | cs->mstate = MS_UNINITIALIZED; |
693 | 690 | ||
694 | for (i = 0; i < channels; ++i) { | 691 | for (i = 0; i < channels; ++i) { |
695 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); | 692 | gig_dbg(DEBUG_INIT, "setting up bcs[%d].read", i); |
@@ -806,8 +803,8 @@ static void cleanup_cs(struct cardstate *cs) | |||
806 | 803 | ||
807 | spin_lock_irqsave(&cs->lock, flags); | 804 | spin_lock_irqsave(&cs->lock, flags); |
808 | 805 | ||
809 | atomic_set(&cs->mode, M_UNKNOWN); | 806 | cs->mode = M_UNKNOWN; |
810 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 807 | cs->mstate = MS_UNINITIALIZED; |
811 | 808 | ||
812 | clear_at_state(&cs->at_state); | 809 | clear_at_state(&cs->at_state); |
813 | dealloc_at_states(cs); | 810 | dealloc_at_states(cs); |
@@ -817,8 +814,8 @@ static void cleanup_cs(struct cardstate *cs) | |||
817 | kfree(cs->inbuf->rcvbuf); | 814 | kfree(cs->inbuf->rcvbuf); |
818 | cs->inbuf->rcvbuf = NULL; | 815 | cs->inbuf->rcvbuf = NULL; |
819 | cs->inbuf->inputstate = INS_command; | 816 | cs->inbuf->inputstate = INS_command; |
820 | atomic_set(&cs->inbuf->head, 0); | 817 | cs->inbuf->head = 0; |
821 | atomic_set(&cs->inbuf->tail, 0); | 818 | cs->inbuf->tail = 0; |
822 | 819 | ||
823 | cb = cs->cmdbuf; | 820 | cb = cs->cmdbuf; |
824 | while (cb) { | 821 | while (cb) { |
@@ -832,7 +829,7 @@ static void cleanup_cs(struct cardstate *cs) | |||
832 | cs->gotfwver = -1; | 829 | cs->gotfwver = -1; |
833 | cs->dle = 0; | 830 | cs->dle = 0; |
834 | cs->cur_at_seq = 0; | 831 | cs->cur_at_seq = 0; |
835 | atomic_set(&cs->commands_pending, 0); | 832 | cs->commands_pending = 0; |
836 | cs->cbytes = 0; | 833 | cs->cbytes = 0; |
837 | 834 | ||
838 | spin_unlock_irqrestore(&cs->lock, flags); | 835 | spin_unlock_irqrestore(&cs->lock, flags); |
@@ -862,7 +859,7 @@ int gigaset_start(struct cardstate *cs) | |||
862 | cs->connected = 1; | 859 | cs->connected = 1; |
863 | spin_unlock_irqrestore(&cs->lock, flags); | 860 | spin_unlock_irqrestore(&cs->lock, flags); |
864 | 861 | ||
865 | if (atomic_read(&cs->mstate) != MS_LOCKED) { | 862 | if (cs->mstate != MS_LOCKED) { |
866 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 863 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
867 | cs->ops->baud_rate(cs, B115200); | 864 | cs->ops->baud_rate(cs, B115200); |
868 | cs->ops->set_line_ctrl(cs, CS8); | 865 | cs->ops->set_line_ctrl(cs, CS8); |
@@ -893,10 +890,17 @@ error: | |||
893 | } | 890 | } |
894 | EXPORT_SYMBOL_GPL(gigaset_start); | 891 | EXPORT_SYMBOL_GPL(gigaset_start); |
895 | 892 | ||
896 | void gigaset_shutdown(struct cardstate *cs) | 893 | /* gigaset_shutdown |
894 | * check if a device is associated to the cardstate structure and stop it | ||
895 | * return value: 0 if ok, -1 if no device was associated | ||
896 | */ | ||
897 | int gigaset_shutdown(struct cardstate *cs) | ||
897 | { | 898 | { |
898 | mutex_lock(&cs->mutex); | 899 | mutex_lock(&cs->mutex); |
899 | 900 | ||
901 | if (!(cs->flags & VALID_MINOR)) | ||
902 | return -1; | ||
903 | |||
900 | cs->waiting = 1; | 904 | cs->waiting = 1; |
901 | 905 | ||
902 | if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { | 906 | if (!gigaset_add_event(cs, &cs->at_state, EV_SHUTDOWN, NULL, 0, NULL)) { |
@@ -913,6 +917,7 @@ void gigaset_shutdown(struct cardstate *cs) | |||
913 | 917 | ||
914 | exit: | 918 | exit: |
915 | mutex_unlock(&cs->mutex); | 919 | mutex_unlock(&cs->mutex); |
920 | return 0; | ||
916 | } | 921 | } |
917 | EXPORT_SYMBOL_GPL(gigaset_shutdown); | 922 | EXPORT_SYMBOL_GPL(gigaset_shutdown); |
918 | 923 | ||
@@ -954,13 +959,11 @@ struct cardstate *gigaset_get_cs_by_id(int id) | |||
954 | list_for_each_entry(drv, &drivers, list) { | 959 | list_for_each_entry(drv, &drivers, list) { |
955 | spin_lock(&drv->lock); | 960 | spin_lock(&drv->lock); |
956 | for (i = 0; i < drv->minors; ++i) { | 961 | for (i = 0; i < drv->minors; ++i) { |
957 | if (drv->flags[i] & VALID_ID) { | 962 | cs = drv->cs + i; |
958 | cs = drv->cs + i; | 963 | if ((cs->flags & VALID_ID) && cs->myid == id) { |
959 | if (cs->myid == id) | 964 | ret = cs; |
960 | ret = cs; | ||
961 | } | ||
962 | if (ret) | ||
963 | break; | 965 | break; |
966 | } | ||
964 | } | 967 | } |
965 | spin_unlock(&drv->lock); | 968 | spin_unlock(&drv->lock); |
966 | if (ret) | 969 | if (ret) |
@@ -983,10 +986,9 @@ void gigaset_debugdrivers(void) | |||
983 | spin_lock(&drv->lock); | 986 | spin_lock(&drv->lock); |
984 | for (i = 0; i < drv->minors; ++i) { | 987 | for (i = 0; i < drv->minors; ++i) { |
985 | gig_dbg(DEBUG_DRIVER, " index %u", i); | 988 | gig_dbg(DEBUG_DRIVER, " index %u", i); |
986 | gig_dbg(DEBUG_DRIVER, " flags 0x%02x", | ||
987 | drv->flags[i]); | ||
988 | cs = drv->cs + i; | 989 | cs = drv->cs + i; |
989 | gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); | 990 | gig_dbg(DEBUG_DRIVER, " cardstate %p", cs); |
991 | gig_dbg(DEBUG_DRIVER, " flags 0x%02x", cs->flags); | ||
990 | gig_dbg(DEBUG_DRIVER, " minor_index %u", | 992 | gig_dbg(DEBUG_DRIVER, " minor_index %u", |
991 | cs->minor_index); | 993 | cs->minor_index); |
992 | gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); | 994 | gig_dbg(DEBUG_DRIVER, " driver %p", cs->driver); |
@@ -1010,7 +1012,7 @@ static struct cardstate *gigaset_get_cs_by_minor(unsigned minor) | |||
1010 | continue; | 1012 | continue; |
1011 | index = minor - drv->minor; | 1013 | index = minor - drv->minor; |
1012 | spin_lock(&drv->lock); | 1014 | spin_lock(&drv->lock); |
1013 | if (drv->flags[index] & VALID_MINOR) | 1015 | if (drv->cs[index].flags & VALID_MINOR) |
1014 | ret = drv->cs + index; | 1016 | ret = drv->cs + index; |
1015 | spin_unlock(&drv->lock); | 1017 | spin_unlock(&drv->lock); |
1016 | if (ret) | 1018 | if (ret) |
@@ -1038,7 +1040,6 @@ void gigaset_freedriver(struct gigaset_driver *drv) | |||
1038 | gigaset_if_freedriver(drv); | 1040 | gigaset_if_freedriver(drv); |
1039 | 1041 | ||
1040 | kfree(drv->cs); | 1042 | kfree(drv->cs); |
1041 | kfree(drv->flags); | ||
1042 | kfree(drv); | 1043 | kfree(drv); |
1043 | } | 1044 | } |
1044 | EXPORT_SYMBOL_GPL(gigaset_freedriver); | 1045 | EXPORT_SYMBOL_GPL(gigaset_freedriver); |
@@ -1080,12 +1081,8 @@ struct gigaset_driver *gigaset_initdriver(unsigned minor, unsigned minors, | |||
1080 | if (!drv->cs) | 1081 | if (!drv->cs) |
1081 | goto error; | 1082 | goto error; |
1082 | 1083 | ||
1083 | drv->flags = kmalloc(minors * sizeof *drv->flags, GFP_KERNEL); | ||
1084 | if (!drv->flags) | ||
1085 | goto error; | ||
1086 | |||
1087 | for (i = 0; i < minors; ++i) { | 1084 | for (i = 0; i < minors; ++i) { |
1088 | drv->flags[i] = 0; | 1085 | drv->cs[i].flags = 0; |
1089 | drv->cs[i].driver = drv; | 1086 | drv->cs[i].driver = drv; |
1090 | drv->cs[i].ops = drv->ops; | 1087 | drv->cs[i].ops = drv->ops; |
1091 | drv->cs[i].minor_index = i; | 1088 | drv->cs[i].minor_index = i; |
@@ -1106,53 +1103,9 @@ error: | |||
1106 | } | 1103 | } |
1107 | EXPORT_SYMBOL_GPL(gigaset_initdriver); | 1104 | EXPORT_SYMBOL_GPL(gigaset_initdriver); |
1108 | 1105 | ||
1109 | /* For drivers without fixed assignment device<->cardstate (usb) */ | ||
1110 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv) | ||
1111 | { | ||
1112 | unsigned long flags; | ||
1113 | struct cardstate *cs = NULL; | ||
1114 | unsigned i; | ||
1115 | |||
1116 | spin_lock_irqsave(&drv->lock, flags); | ||
1117 | if (drv->blocked) | ||
1118 | goto exit; | ||
1119 | for (i = 0; i < drv->minors; ++i) { | ||
1120 | if ((drv->flags[i] & VALID_MINOR) && | ||
1121 | !(drv->flags[i] & ASSIGNED)) { | ||
1122 | drv->flags[i] |= ASSIGNED; | ||
1123 | cs = drv->cs + i; | ||
1124 | break; | ||
1125 | } | ||
1126 | } | ||
1127 | exit: | ||
1128 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1129 | return cs; | ||
1130 | } | ||
1131 | EXPORT_SYMBOL_GPL(gigaset_getunassignedcs); | ||
1132 | |||
1133 | void gigaset_unassign(struct cardstate *cs) | ||
1134 | { | ||
1135 | unsigned long flags; | ||
1136 | unsigned *minor_flags; | ||
1137 | struct gigaset_driver *drv; | ||
1138 | |||
1139 | if (!cs) | ||
1140 | return; | ||
1141 | drv = cs->driver; | ||
1142 | spin_lock_irqsave(&drv->lock, flags); | ||
1143 | minor_flags = drv->flags + cs->minor_index; | ||
1144 | if (*minor_flags & VALID_MINOR) | ||
1145 | *minor_flags &= ~ASSIGNED; | ||
1146 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1147 | } | ||
1148 | EXPORT_SYMBOL_GPL(gigaset_unassign); | ||
1149 | |||
1150 | void gigaset_blockdriver(struct gigaset_driver *drv) | 1106 | void gigaset_blockdriver(struct gigaset_driver *drv) |
1151 | { | 1107 | { |
1152 | unsigned long flags; | ||
1153 | spin_lock_irqsave(&drv->lock, flags); | ||
1154 | drv->blocked = 1; | 1108 | drv->blocked = 1; |
1155 | spin_unlock_irqrestore(&drv->lock, flags); | ||
1156 | } | 1109 | } |
1157 | EXPORT_SYMBOL_GPL(gigaset_blockdriver); | 1110 | EXPORT_SYMBOL_GPL(gigaset_blockdriver); |
1158 | 1111 | ||
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index cec1ef342fcc..5cbf64d850ee 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -735,7 +735,7 @@ static void disconnect(struct at_state_t **at_state_p) | |||
735 | /* revert to selected idle mode */ | 735 | /* revert to selected idle mode */ |
736 | if (!cs->cidmode) { | 736 | if (!cs->cidmode) { |
737 | cs->at_state.pending_commands |= PC_UMMODE; | 737 | cs->at_state.pending_commands |= PC_UMMODE; |
738 | atomic_set(&cs->commands_pending, 1); //FIXME | 738 | cs->commands_pending = 1; |
739 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 739 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
740 | } | 740 | } |
741 | spin_unlock_irqrestore(&cs->lock, flags); | 741 | spin_unlock_irqrestore(&cs->lock, flags); |
@@ -793,15 +793,15 @@ static void init_failed(struct cardstate *cs, int mode) | |||
793 | struct at_state_t *at_state; | 793 | struct at_state_t *at_state; |
794 | 794 | ||
795 | cs->at_state.pending_commands &= ~PC_INIT; | 795 | cs->at_state.pending_commands &= ~PC_INIT; |
796 | atomic_set(&cs->mode, mode); | 796 | cs->mode = mode; |
797 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 797 | cs->mstate = MS_UNINITIALIZED; |
798 | gigaset_free_channels(cs); | 798 | gigaset_free_channels(cs); |
799 | for (i = 0; i < cs->channels; ++i) { | 799 | for (i = 0; i < cs->channels; ++i) { |
800 | at_state = &cs->bcs[i].at_state; | 800 | at_state = &cs->bcs[i].at_state; |
801 | if (at_state->pending_commands & PC_CID) { | 801 | if (at_state->pending_commands & PC_CID) { |
802 | at_state->pending_commands &= ~PC_CID; | 802 | at_state->pending_commands &= ~PC_CID; |
803 | at_state->pending_commands |= PC_NOCID; | 803 | at_state->pending_commands |= PC_NOCID; |
804 | atomic_set(&cs->commands_pending, 1); | 804 | cs->commands_pending = 1; |
805 | } | 805 | } |
806 | } | 806 | } |
807 | } | 807 | } |
@@ -812,11 +812,11 @@ static void schedule_init(struct cardstate *cs, int state) | |||
812 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); | 812 | gig_dbg(DEBUG_CMD, "not scheduling PC_INIT again"); |
813 | return; | 813 | return; |
814 | } | 814 | } |
815 | atomic_set(&cs->mstate, state); | 815 | cs->mstate = state; |
816 | atomic_set(&cs->mode, M_UNKNOWN); | 816 | cs->mode = M_UNKNOWN; |
817 | gigaset_block_channels(cs); | 817 | gigaset_block_channels(cs); |
818 | cs->at_state.pending_commands |= PC_INIT; | 818 | cs->at_state.pending_commands |= PC_INIT; |
819 | atomic_set(&cs->commands_pending, 1); | 819 | cs->commands_pending = 1; |
820 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); | 820 | gig_dbg(DEBUG_CMD, "Scheduling PC_INIT"); |
821 | } | 821 | } |
822 | 822 | ||
@@ -953,13 +953,13 @@ static void start_dial(struct at_state_t *at_state, void *data, unsigned seq_ind | |||
953 | 953 | ||
954 | at_state->pending_commands |= PC_CID; | 954 | at_state->pending_commands |= PC_CID; |
955 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); | 955 | gig_dbg(DEBUG_CMD, "Scheduling PC_CID"); |
956 | atomic_set(&cs->commands_pending, 1); | 956 | cs->commands_pending = 1; |
957 | return; | 957 | return; |
958 | 958 | ||
959 | error: | 959 | error: |
960 | at_state->pending_commands |= PC_NOCID; | 960 | at_state->pending_commands |= PC_NOCID; |
961 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); | 961 | gig_dbg(DEBUG_CMD, "Scheduling PC_NOCID"); |
962 | atomic_set(&cs->commands_pending, 1); | 962 | cs->commands_pending = 1; |
963 | return; | 963 | return; |
964 | } | 964 | } |
965 | 965 | ||
@@ -973,12 +973,12 @@ static void start_accept(struct at_state_t *at_state) | |||
973 | if (retval == 0) { | 973 | if (retval == 0) { |
974 | at_state->pending_commands |= PC_ACCEPT; | 974 | at_state->pending_commands |= PC_ACCEPT; |
975 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); | 975 | gig_dbg(DEBUG_CMD, "Scheduling PC_ACCEPT"); |
976 | atomic_set(&cs->commands_pending, 1); | 976 | cs->commands_pending = 1; |
977 | } else { | 977 | } else { |
978 | //FIXME | 978 | /* error reset */ |
979 | at_state->pending_commands |= PC_HUP; | 979 | at_state->pending_commands |= PC_HUP; |
980 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 980 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
981 | atomic_set(&cs->commands_pending, 1); | 981 | cs->commands_pending = 1; |
982 | } | 982 | } |
983 | } | 983 | } |
984 | 984 | ||
@@ -986,7 +986,7 @@ static void do_start(struct cardstate *cs) | |||
986 | { | 986 | { |
987 | gigaset_free_channels(cs); | 987 | gigaset_free_channels(cs); |
988 | 988 | ||
989 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 989 | if (cs->mstate != MS_LOCKED) |
990 | schedule_init(cs, MS_INIT); | 990 | schedule_init(cs, MS_INIT); |
991 | 991 | ||
992 | cs->isdn_up = 1; | 992 | cs->isdn_up = 1; |
@@ -1000,9 +1000,9 @@ static void do_start(struct cardstate *cs) | |||
1000 | 1000 | ||
1001 | static void finish_shutdown(struct cardstate *cs) | 1001 | static void finish_shutdown(struct cardstate *cs) |
1002 | { | 1002 | { |
1003 | if (atomic_read(&cs->mstate) != MS_LOCKED) { | 1003 | if (cs->mstate != MS_LOCKED) { |
1004 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1004 | cs->mstate = MS_UNINITIALIZED; |
1005 | atomic_set(&cs->mode, M_UNKNOWN); | 1005 | cs->mode = M_UNKNOWN; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | /* Tell the LL that the device is not available .. */ | 1008 | /* Tell the LL that the device is not available .. */ |
@@ -1022,10 +1022,10 @@ static void do_shutdown(struct cardstate *cs) | |||
1022 | { | 1022 | { |
1023 | gigaset_block_channels(cs); | 1023 | gigaset_block_channels(cs); |
1024 | 1024 | ||
1025 | if (atomic_read(&cs->mstate) == MS_READY) { | 1025 | if (cs->mstate == MS_READY) { |
1026 | atomic_set(&cs->mstate, MS_SHUTDOWN); | 1026 | cs->mstate = MS_SHUTDOWN; |
1027 | cs->at_state.pending_commands |= PC_SHUTDOWN; | 1027 | cs->at_state.pending_commands |= PC_SHUTDOWN; |
1028 | atomic_set(&cs->commands_pending, 1); | 1028 | cs->commands_pending = 1; |
1029 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); | 1029 | gig_dbg(DEBUG_CMD, "Scheduling PC_SHUTDOWN"); |
1030 | } else | 1030 | } else |
1031 | finish_shutdown(cs); | 1031 | finish_shutdown(cs); |
@@ -1120,7 +1120,7 @@ static void handle_icall(struct cardstate *cs, struct bc_state *bcs, | |||
1120 | * In fact it doesn't. | 1120 | * In fact it doesn't. |
1121 | */ | 1121 | */ |
1122 | at_state->pending_commands |= PC_HUP; | 1122 | at_state->pending_commands |= PC_HUP; |
1123 | atomic_set(&cs->commands_pending, 1); | 1123 | cs->commands_pending = 1; |
1124 | break; | 1124 | break; |
1125 | } | 1125 | } |
1126 | } | 1126 | } |
@@ -1130,7 +1130,7 @@ static int do_lock(struct cardstate *cs) | |||
1130 | int mode; | 1130 | int mode; |
1131 | int i; | 1131 | int i; |
1132 | 1132 | ||
1133 | switch (atomic_read(&cs->mstate)) { | 1133 | switch (cs->mstate) { |
1134 | case MS_UNINITIALIZED: | 1134 | case MS_UNINITIALIZED: |
1135 | case MS_READY: | 1135 | case MS_READY: |
1136 | if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) || | 1136 | if (cs->cur_at_seq || !list_empty(&cs->temp_at_states) || |
@@ -1152,20 +1152,20 @@ static int do_lock(struct cardstate *cs) | |||
1152 | return -EBUSY; | 1152 | return -EBUSY; |
1153 | } | 1153 | } |
1154 | 1154 | ||
1155 | mode = atomic_read(&cs->mode); | 1155 | mode = cs->mode; |
1156 | atomic_set(&cs->mstate, MS_LOCKED); | 1156 | cs->mstate = MS_LOCKED; |
1157 | atomic_set(&cs->mode, M_UNKNOWN); | 1157 | cs->mode = M_UNKNOWN; |
1158 | 1158 | ||
1159 | return mode; | 1159 | return mode; |
1160 | } | 1160 | } |
1161 | 1161 | ||
1162 | static int do_unlock(struct cardstate *cs) | 1162 | static int do_unlock(struct cardstate *cs) |
1163 | { | 1163 | { |
1164 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 1164 | if (cs->mstate != MS_LOCKED) |
1165 | return -EINVAL; | 1165 | return -EINVAL; |
1166 | 1166 | ||
1167 | atomic_set(&cs->mstate, MS_UNINITIALIZED); | 1167 | cs->mstate = MS_UNINITIALIZED; |
1168 | atomic_set(&cs->mode, M_UNKNOWN); | 1168 | cs->mode = M_UNKNOWN; |
1169 | gigaset_free_channels(cs); | 1169 | gigaset_free_channels(cs); |
1170 | if (cs->connected) | 1170 | if (cs->connected) |
1171 | schedule_init(cs, MS_INIT); | 1171 | schedule_init(cs, MS_INIT); |
@@ -1198,17 +1198,17 @@ static void do_action(int action, struct cardstate *cs, | |||
1198 | case ACT_INIT: | 1198 | case ACT_INIT: |
1199 | cs->at_state.pending_commands &= ~PC_INIT; | 1199 | cs->at_state.pending_commands &= ~PC_INIT; |
1200 | cs->cur_at_seq = SEQ_NONE; | 1200 | cs->cur_at_seq = SEQ_NONE; |
1201 | atomic_set(&cs->mode, M_UNIMODEM); | 1201 | cs->mode = M_UNIMODEM; |
1202 | spin_lock_irqsave(&cs->lock, flags); | 1202 | spin_lock_irqsave(&cs->lock, flags); |
1203 | if (!cs->cidmode) { | 1203 | if (!cs->cidmode) { |
1204 | spin_unlock_irqrestore(&cs->lock, flags); | 1204 | spin_unlock_irqrestore(&cs->lock, flags); |
1205 | gigaset_free_channels(cs); | 1205 | gigaset_free_channels(cs); |
1206 | atomic_set(&cs->mstate, MS_READY); | 1206 | cs->mstate = MS_READY; |
1207 | break; | 1207 | break; |
1208 | } | 1208 | } |
1209 | spin_unlock_irqrestore(&cs->lock, flags); | 1209 | spin_unlock_irqrestore(&cs->lock, flags); |
1210 | cs->at_state.pending_commands |= PC_CIDMODE; | 1210 | cs->at_state.pending_commands |= PC_CIDMODE; |
1211 | atomic_set(&cs->commands_pending, 1); | 1211 | cs->commands_pending = 1; |
1212 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1212 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1213 | break; | 1213 | break; |
1214 | case ACT_FAILINIT: | 1214 | case ACT_FAILINIT: |
@@ -1234,22 +1234,20 @@ static void do_action(int action, struct cardstate *cs, | |||
1234 | | INS_command; | 1234 | | INS_command; |
1235 | break; | 1235 | break; |
1236 | case ACT_CMODESET: | 1236 | case ACT_CMODESET: |
1237 | if (atomic_read(&cs->mstate) == MS_INIT || | 1237 | if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) { |
1238 | atomic_read(&cs->mstate) == MS_RECOVER) { | ||
1239 | gigaset_free_channels(cs); | 1238 | gigaset_free_channels(cs); |
1240 | atomic_set(&cs->mstate, MS_READY); | 1239 | cs->mstate = MS_READY; |
1241 | } | 1240 | } |
1242 | atomic_set(&cs->mode, M_CID); | 1241 | cs->mode = M_CID; |
1243 | cs->cur_at_seq = SEQ_NONE; | 1242 | cs->cur_at_seq = SEQ_NONE; |
1244 | break; | 1243 | break; |
1245 | case ACT_UMODESET: | 1244 | case ACT_UMODESET: |
1246 | atomic_set(&cs->mode, M_UNIMODEM); | 1245 | cs->mode = M_UNIMODEM; |
1247 | cs->cur_at_seq = SEQ_NONE; | 1246 | cs->cur_at_seq = SEQ_NONE; |
1248 | break; | 1247 | break; |
1249 | case ACT_FAILCMODE: | 1248 | case ACT_FAILCMODE: |
1250 | cs->cur_at_seq = SEQ_NONE; | 1249 | cs->cur_at_seq = SEQ_NONE; |
1251 | if (atomic_read(&cs->mstate) == MS_INIT || | 1250 | if (cs->mstate == MS_INIT || cs->mstate == MS_RECOVER) { |
1252 | atomic_read(&cs->mstate) == MS_RECOVER) { | ||
1253 | init_failed(cs, M_UNKNOWN); | 1251 | init_failed(cs, M_UNKNOWN); |
1254 | break; | 1252 | break; |
1255 | } | 1253 | } |
@@ -1307,7 +1305,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1307 | case ACT_CONNECT: | 1305 | case ACT_CONNECT: |
1308 | if (cs->onechannel) { | 1306 | if (cs->onechannel) { |
1309 | at_state->pending_commands |= PC_DLE1; | 1307 | at_state->pending_commands |= PC_DLE1; |
1310 | atomic_set(&cs->commands_pending, 1); | 1308 | cs->commands_pending = 1; |
1311 | break; | 1309 | break; |
1312 | } | 1310 | } |
1313 | bcs->chstate |= CHS_D_UP; | 1311 | bcs->chstate |= CHS_D_UP; |
@@ -1333,7 +1331,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1333 | * DLE only used for M10x with one B channel. | 1331 | * DLE only used for M10x with one B channel. |
1334 | */ | 1332 | */ |
1335 | at_state->pending_commands |= PC_DLE0; | 1333 | at_state->pending_commands |= PC_DLE0; |
1336 | atomic_set(&cs->commands_pending, 1); | 1334 | cs->commands_pending = 1; |
1337 | } else | 1335 | } else |
1338 | disconnect(p_at_state); | 1336 | disconnect(p_at_state); |
1339 | break; | 1337 | break; |
@@ -1369,7 +1367,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1369 | "Could not enter DLE mode. Trying to hang up.\n"); | 1367 | "Could not enter DLE mode. Trying to hang up.\n"); |
1370 | channel = cs->curchannel; | 1368 | channel = cs->curchannel; |
1371 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; | 1369 | cs->bcs[channel].at_state.pending_commands |= PC_HUP; |
1372 | atomic_set(&cs->commands_pending, 1); | 1370 | cs->commands_pending = 1; |
1373 | break; | 1371 | break; |
1374 | 1372 | ||
1375 | case ACT_CID: /* got cid; start dialing */ | 1373 | case ACT_CID: /* got cid; start dialing */ |
@@ -1379,7 +1377,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1379 | cs->bcs[channel].at_state.cid = ev->parameter; | 1377 | cs->bcs[channel].at_state.cid = ev->parameter; |
1380 | cs->bcs[channel].at_state.pending_commands |= | 1378 | cs->bcs[channel].at_state.pending_commands |= |
1381 | PC_DIAL; | 1379 | PC_DIAL; |
1382 | atomic_set(&cs->commands_pending, 1); | 1380 | cs->commands_pending = 1; |
1383 | break; | 1381 | break; |
1384 | } | 1382 | } |
1385 | /* fall through */ | 1383 | /* fall through */ |
@@ -1411,14 +1409,14 @@ static void do_action(int action, struct cardstate *cs, | |||
1411 | case ACT_ABORTDIAL: /* error/timeout during dial preparation */ | 1409 | case ACT_ABORTDIAL: /* error/timeout during dial preparation */ |
1412 | cs->cur_at_seq = SEQ_NONE; | 1410 | cs->cur_at_seq = SEQ_NONE; |
1413 | at_state->pending_commands |= PC_HUP; | 1411 | at_state->pending_commands |= PC_HUP; |
1414 | atomic_set(&cs->commands_pending, 1); | 1412 | cs->commands_pending = 1; |
1415 | break; | 1413 | break; |
1416 | 1414 | ||
1417 | case ACT_REMOTEREJECT: /* DISCONNECT_IND after dialling */ | 1415 | case ACT_REMOTEREJECT: /* DISCONNECT_IND after dialling */ |
1418 | case ACT_CONNTIMEOUT: /* timeout waiting for ZSAU=ACTIVE */ | 1416 | case ACT_CONNTIMEOUT: /* timeout waiting for ZSAU=ACTIVE */ |
1419 | case ACT_REMOTEHUP: /* DISCONNECT_IND with established connection */ | 1417 | case ACT_REMOTEHUP: /* DISCONNECT_IND with established connection */ |
1420 | at_state->pending_commands |= PC_HUP; | 1418 | at_state->pending_commands |= PC_HUP; |
1421 | atomic_set(&cs->commands_pending, 1); | 1419 | cs->commands_pending = 1; |
1422 | break; | 1420 | break; |
1423 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... | 1421 | case ACT_GETSTRING: /* warning: RING, ZDLE, ... |
1424 | are not handled properly anymore */ | 1422 | are not handled properly anymore */ |
@@ -1515,7 +1513,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1515 | break; | 1513 | break; |
1516 | case ACT_HUP: | 1514 | case ACT_HUP: |
1517 | at_state->pending_commands |= PC_HUP; | 1515 | at_state->pending_commands |= PC_HUP; |
1518 | atomic_set(&cs->commands_pending, 1); | 1516 | cs->commands_pending = 1; |
1519 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); | 1517 | gig_dbg(DEBUG_CMD, "Scheduling PC_HUP"); |
1520 | break; | 1518 | break; |
1521 | 1519 | ||
@@ -1558,7 +1556,7 @@ static void do_action(int action, struct cardstate *cs, | |||
1558 | cs->at_state.pending_commands |= PC_UMMODE; | 1556 | cs->at_state.pending_commands |= PC_UMMODE; |
1559 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); | 1557 | gig_dbg(DEBUG_CMD, "Scheduling PC_UMMODE"); |
1560 | } | 1558 | } |
1561 | atomic_set(&cs->commands_pending, 1); | 1559 | cs->commands_pending = 1; |
1562 | } | 1560 | } |
1563 | spin_unlock_irqrestore(&cs->lock, flags); | 1561 | spin_unlock_irqrestore(&cs->lock, flags); |
1564 | cs->waiting = 0; | 1562 | cs->waiting = 0; |
@@ -1741,7 +1739,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1741 | int sequence; | 1739 | int sequence; |
1742 | unsigned long flags; | 1740 | unsigned long flags; |
1743 | 1741 | ||
1744 | atomic_set(&cs->commands_pending, 0); | 1742 | cs->commands_pending = 0; |
1745 | 1743 | ||
1746 | if (cs->cur_at_seq) { | 1744 | if (cs->cur_at_seq) { |
1747 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); | 1745 | gig_dbg(DEBUG_CMD, "not searching scheduled commands: busy"); |
@@ -1779,7 +1777,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1779 | ~(PC_DLE1 | PC_ACCEPT | PC_DIAL); | 1777 | ~(PC_DLE1 | PC_ACCEPT | PC_DIAL); |
1780 | if (at_state->cid > 0) | 1778 | if (at_state->cid > 0) |
1781 | at_state->pending_commands |= PC_HUP; | 1779 | at_state->pending_commands |= PC_HUP; |
1782 | if (atomic_read(&cs->mstate) == MS_RECOVER) { | 1780 | if (cs->mstate == MS_RECOVER) { |
1783 | if (at_state->pending_commands & PC_CID) { | 1781 | if (at_state->pending_commands & PC_CID) { |
1784 | at_state->pending_commands |= PC_NOCID; | 1782 | at_state->pending_commands |= PC_NOCID; |
1785 | at_state->pending_commands &= ~PC_CID; | 1783 | at_state->pending_commands &= ~PC_CID; |
@@ -1793,7 +1791,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1793 | if (cs->at_state.pending_commands == PC_UMMODE | 1791 | if (cs->at_state.pending_commands == PC_UMMODE |
1794 | && !cs->cidmode | 1792 | && !cs->cidmode |
1795 | && list_empty(&cs->temp_at_states) | 1793 | && list_empty(&cs->temp_at_states) |
1796 | && atomic_read(&cs->mode) == M_CID) { | 1794 | && cs->mode == M_CID) { |
1797 | sequence = SEQ_UMMODE; | 1795 | sequence = SEQ_UMMODE; |
1798 | at_state = &cs->at_state; | 1796 | at_state = &cs->at_state; |
1799 | for (i = 0; i < cs->channels; ++i) { | 1797 | for (i = 0; i < cs->channels; ++i) { |
@@ -1860,7 +1858,7 @@ static void process_command_flags(struct cardstate *cs) | |||
1860 | } | 1858 | } |
1861 | if (cs->at_state.pending_commands & PC_CIDMODE) { | 1859 | if (cs->at_state.pending_commands & PC_CIDMODE) { |
1862 | cs->at_state.pending_commands &= ~PC_CIDMODE; | 1860 | cs->at_state.pending_commands &= ~PC_CIDMODE; |
1863 | if (atomic_read(&cs->mode) == M_UNIMODEM) { | 1861 | if (cs->mode == M_UNIMODEM) { |
1864 | cs->retry_count = 1; | 1862 | cs->retry_count = 1; |
1865 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); | 1863 | schedule_sequence(cs, &cs->at_state, SEQ_CIDMODE); |
1866 | return; | 1864 | return; |
@@ -1886,11 +1884,11 @@ static void process_command_flags(struct cardstate *cs) | |||
1886 | return; | 1884 | return; |
1887 | } | 1885 | } |
1888 | if (bcs->at_state.pending_commands & PC_CID) { | 1886 | if (bcs->at_state.pending_commands & PC_CID) { |
1889 | switch (atomic_read(&cs->mode)) { | 1887 | switch (cs->mode) { |
1890 | case M_UNIMODEM: | 1888 | case M_UNIMODEM: |
1891 | cs->at_state.pending_commands |= PC_CIDMODE; | 1889 | cs->at_state.pending_commands |= PC_CIDMODE; |
1892 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); | 1890 | gig_dbg(DEBUG_CMD, "Scheduling PC_CIDMODE"); |
1893 | atomic_set(&cs->commands_pending, 1); | 1891 | cs->commands_pending = 1; |
1894 | return; | 1892 | return; |
1895 | #ifdef GIG_MAYINITONDIAL | 1893 | #ifdef GIG_MAYINITONDIAL |
1896 | case M_UNKNOWN: | 1894 | case M_UNKNOWN: |
@@ -1926,7 +1924,7 @@ static void process_events(struct cardstate *cs) | |||
1926 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { | 1924 | for (i = 0; i < 2 * MAX_EVENTS; ++i) { |
1927 | tail = cs->ev_tail; | 1925 | tail = cs->ev_tail; |
1928 | if (tail == head) { | 1926 | if (tail == head) { |
1929 | if (!check_flags && !atomic_read(&cs->commands_pending)) | 1927 | if (!check_flags && !cs->commands_pending) |
1930 | break; | 1928 | break; |
1931 | check_flags = 0; | 1929 | check_flags = 0; |
1932 | spin_unlock_irqrestore(&cs->ev_lock, flags); | 1930 | spin_unlock_irqrestore(&cs->ev_lock, flags); |
@@ -1934,7 +1932,7 @@ static void process_events(struct cardstate *cs) | |||
1934 | spin_lock_irqsave(&cs->ev_lock, flags); | 1932 | spin_lock_irqsave(&cs->ev_lock, flags); |
1935 | tail = cs->ev_tail; | 1933 | tail = cs->ev_tail; |
1936 | if (tail == head) { | 1934 | if (tail == head) { |
1937 | if (!atomic_read(&cs->commands_pending)) | 1935 | if (!cs->commands_pending) |
1938 | break; | 1936 | break; |
1939 | continue; | 1937 | continue; |
1940 | } | 1938 | } |
@@ -1971,7 +1969,7 @@ void gigaset_handle_event(unsigned long data) | |||
1971 | struct cardstate *cs = (struct cardstate *) data; | 1969 | struct cardstate *cs = (struct cardstate *) data; |
1972 | 1970 | ||
1973 | /* handle incoming data on control/common channel */ | 1971 | /* handle incoming data on control/common channel */ |
1974 | if (atomic_read(&cs->inbuf->head) != atomic_read(&cs->inbuf->tail)) { | 1972 | if (cs->inbuf->head != cs->inbuf->tail) { |
1975 | gig_dbg(DEBUG_INTR, "processing new data"); | 1973 | gig_dbg(DEBUG_INTR, "processing new data"); |
1976 | cs->ops->handle_input(cs->inbuf); | 1974 | cs->ops->handle_input(cs->inbuf); |
1977 | } | 1975 | } |
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 02bdaf22d7ea..f365993161fc 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -70,22 +70,13 @@ | |||
70 | 70 | ||
71 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ | 71 | extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ |
72 | 72 | ||
73 | /* any combination of these can be given with the 'debug=' parameter to insmod, | 73 | /* debug flags, combine by adding/bitwise OR */ |
74 | * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and | ||
75 | * DEBUG_INTR. | ||
76 | */ | ||
77 | enum debuglevel { | 74 | enum debuglevel { |
78 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ | 75 | DEBUG_INTR = 0x00008, /* interrupt processing */ |
79 | DEBUG_OPEN = 0x0004, /* open/close serial port */ | ||
80 | DEBUG_INTR = 0x0008, /* interrupt processing */ | ||
81 | DEBUG_INTR_DUMP = 0x0010, /* Activating hexdump debug output on | ||
82 | interrupt requests, not available as | ||
83 | run-time option */ | ||
84 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ | 76 | DEBUG_CMD = 0x00020, /* sent/received LL commands */ |
85 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ | 77 | DEBUG_STREAM = 0x00040, /* application data stream I/O events */ |
86 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ | 78 | DEBUG_STREAM_DUMP = 0x00080, /* application data stream content */ |
87 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ | 79 | DEBUG_LLDATA = 0x00100, /* sent/received LL data */ |
88 | DEBUG_INTR_0 = 0x00200, /* serial port interrupt processing */ | ||
89 | DEBUG_DRIVER = 0x00400, /* driver structure */ | 80 | DEBUG_DRIVER = 0x00400, /* driver structure */ |
90 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ | 81 | DEBUG_HDLC = 0x00800, /* M10x HDLC processing */ |
91 | DEBUG_WRITE = 0x01000, /* M105 data write */ | 82 | DEBUG_WRITE = 0x01000, /* M105 data write */ |
@@ -93,7 +84,7 @@ enum debuglevel { | |||
93 | DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ | 84 | DEBUG_MCMD = 0x04000, /* COMMANDS THAT ARE SENT VERY OFTEN */ |
94 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data | 85 | DEBUG_INIT = 0x08000, /* (de)allocation+initialization of data |
95 | structures */ | 86 | structures */ |
96 | DEBUG_LOCK = 0x10000, /* semaphore operations */ | 87 | DEBUG_SUSPEND = 0x10000, /* suspend/resume processing */ |
97 | DEBUG_OUTPUT = 0x20000, /* output to device */ | 88 | DEBUG_OUTPUT = 0x20000, /* output to device */ |
98 | DEBUG_ISO = 0x40000, /* isochronous transfers */ | 89 | DEBUG_ISO = 0x40000, /* isochronous transfers */ |
99 | DEBUG_IF = 0x80000, /* character device operations */ | 90 | DEBUG_IF = 0x80000, /* character device operations */ |
@@ -191,6 +182,9 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, | |||
191 | #define HD_OPEN_ATCHANNEL (0x28) // 3070 | 182 | #define HD_OPEN_ATCHANNEL (0x28) // 3070 |
192 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 | 183 | #define HD_CLOSE_ATCHANNEL (0x29) // 3070 |
193 | 184 | ||
185 | /* number of B channels supported by base driver */ | ||
186 | #define BAS_CHANNELS 2 | ||
187 | |||
194 | /* USB frames for isochronous transfer */ | 188 | /* USB frames for isochronous transfer */ |
195 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ | 189 | #define BAS_FRAMETIME 1 /* number of milliseconds between frames */ |
196 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ | 190 | #define BAS_NUMFRAMES 8 /* number of frames per URB */ |
@@ -313,7 +307,7 @@ struct inbuf_t { | |||
313 | struct bc_state *bcs; | 307 | struct bc_state *bcs; |
314 | struct cardstate *cs; | 308 | struct cardstate *cs; |
315 | int inputstate; | 309 | int inputstate; |
316 | atomic_t head, tail; | 310 | int head, tail; |
317 | unsigned char data[RBUFSIZE]; | 311 | unsigned char data[RBUFSIZE]; |
318 | }; | 312 | }; |
319 | 313 | ||
@@ -335,9 +329,9 @@ struct inbuf_t { | |||
335 | * are also filled with that value | 329 | * are also filled with that value |
336 | */ | 330 | */ |
337 | struct isowbuf_t { | 331 | struct isowbuf_t { |
338 | atomic_t read; | 332 | int read; |
339 | atomic_t nextread; | 333 | int nextread; |
340 | atomic_t write; | 334 | int write; |
341 | atomic_t writesem; | 335 | atomic_t writesem; |
342 | int wbits; | 336 | int wbits; |
343 | unsigned char data[BAS_OUTBUFSIZE + BAS_OUTBUFPAD]; | 337 | unsigned char data[BAS_OUTBUFSIZE + BAS_OUTBUFPAD]; |
@@ -350,11 +344,13 @@ struct isowbuf_t { | |||
350 | * - urb: pointer to the URB itself | 344 | * - urb: pointer to the URB itself |
351 | * - bcs: pointer to the B Channel control structure | 345 | * - bcs: pointer to the B Channel control structure |
352 | * - limit: end of write buffer area covered by this URB | 346 | * - limit: end of write buffer area covered by this URB |
347 | * - status: URB completion status | ||
353 | */ | 348 | */ |
354 | struct isow_urbctx_t { | 349 | struct isow_urbctx_t { |
355 | struct urb *urb; | 350 | struct urb *urb; |
356 | struct bc_state *bcs; | 351 | struct bc_state *bcs; |
357 | int limit; | 352 | int limit; |
353 | int status; | ||
358 | }; | 354 | }; |
359 | 355 | ||
360 | /* AT state structure | 356 | /* AT state structure |
@@ -439,14 +435,15 @@ struct cardstate { | |||
439 | unsigned minor_index; | 435 | unsigned minor_index; |
440 | struct device *dev; | 436 | struct device *dev; |
441 | struct device *tty_dev; | 437 | struct device *tty_dev; |
438 | unsigned flags; | ||
442 | 439 | ||
443 | const struct gigaset_ops *ops; | 440 | const struct gigaset_ops *ops; |
444 | 441 | ||
445 | /* Stuff to handle communication */ | 442 | /* Stuff to handle communication */ |
446 | wait_queue_head_t waitqueue; | 443 | wait_queue_head_t waitqueue; |
447 | int waiting; | 444 | int waiting; |
448 | atomic_t mode; /* see M_XXXX */ | 445 | int mode; /* see M_XXXX */ |
449 | atomic_t mstate; /* Modem state: see MS_XXXX */ | 446 | int mstate; /* Modem state: see MS_XXXX */ |
450 | /* only changed by the event layer */ | 447 | /* only changed by the event layer */ |
451 | int cmd_result; | 448 | int cmd_result; |
452 | 449 | ||
@@ -503,7 +500,7 @@ struct cardstate { | |||
503 | processed */ | 500 | processed */ |
504 | int curchannel; /* channel those commands are meant | 501 | int curchannel; /* channel those commands are meant |
505 | for */ | 502 | for */ |
506 | atomic_t commands_pending; /* flag(s) in xxx.commands_pending have | 503 | int commands_pending; /* flag(s) in xxx.commands_pending have |
507 | been set */ | 504 | been set */ |
508 | struct tasklet_struct event_tasklet; | 505 | struct tasklet_struct event_tasklet; |
509 | /* tasklet for serializing AT commands. | 506 | /* tasklet for serializing AT commands. |
@@ -543,7 +540,6 @@ struct gigaset_driver { | |||
543 | unsigned minor; | 540 | unsigned minor; |
544 | unsigned minors; | 541 | unsigned minors; |
545 | struct cardstate *cs; | 542 | struct cardstate *cs; |
546 | unsigned *flags; | ||
547 | int blocked; | 543 | int blocked; |
548 | 544 | ||
549 | const struct gigaset_ops *ops; | 545 | const struct gigaset_ops *ops; |
@@ -559,7 +555,7 @@ struct cmdbuf_t { | |||
559 | 555 | ||
560 | struct bas_bc_state { | 556 | struct bas_bc_state { |
561 | /* isochronous output state */ | 557 | /* isochronous output state */ |
562 | atomic_t running; | 558 | int running; |
563 | atomic_t corrbytes; | 559 | atomic_t corrbytes; |
564 | spinlock_t isooutlock; | 560 | spinlock_t isooutlock; |
565 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; | 561 | struct isow_urbctx_t isoouturbs[BAS_OUTURBS]; |
@@ -574,6 +570,7 @@ struct bas_bc_state { | |||
574 | struct urb *isoinurbs[BAS_INURBS]; | 570 | struct urb *isoinurbs[BAS_INURBS]; |
575 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; | 571 | unsigned char isoinbuf[BAS_INBUFSIZE * BAS_INURBS]; |
576 | struct urb *isoindone; /* completed isoc read URB */ | 572 | struct urb *isoindone; /* completed isoc read URB */ |
573 | int isoinstatus; /* status of completed URB */ | ||
577 | int loststatus; /* status of dropped URB */ | 574 | int loststatus; /* status of dropped URB */ |
578 | unsigned isoinlost; /* number of bytes lost */ | 575 | unsigned isoinlost; /* number of bytes lost */ |
579 | /* state of bit unstuffing algorithm | 576 | /* state of bit unstuffing algorithm |
@@ -770,10 +767,6 @@ void gigaset_freedriver(struct gigaset_driver *drv); | |||
770 | void gigaset_debugdrivers(void); | 767 | void gigaset_debugdrivers(void); |
771 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); | 768 | struct cardstate *gigaset_get_cs_by_tty(struct tty_struct *tty); |
772 | struct cardstate *gigaset_get_cs_by_id(int id); | 769 | struct cardstate *gigaset_get_cs_by_id(int id); |
773 | |||
774 | /* For drivers without fixed assignment device<->cardstate (usb) */ | ||
775 | struct cardstate *gigaset_getunassignedcs(struct gigaset_driver *drv); | ||
776 | void gigaset_unassign(struct cardstate *cs); | ||
777 | void gigaset_blockdriver(struct gigaset_driver *drv); | 770 | void gigaset_blockdriver(struct gigaset_driver *drv); |
778 | 771 | ||
779 | /* Allocate and initialize card state. Calls hardware dependent | 772 | /* Allocate and initialize card state. Calls hardware dependent |
@@ -792,7 +785,7 @@ int gigaset_start(struct cardstate *cs); | |||
792 | void gigaset_stop(struct cardstate *cs); | 785 | void gigaset_stop(struct cardstate *cs); |
793 | 786 | ||
794 | /* Tell common.c that the driver is being unloaded. */ | 787 | /* Tell common.c that the driver is being unloaded. */ |
795 | void gigaset_shutdown(struct cardstate *cs); | 788 | int gigaset_shutdown(struct cardstate *cs); |
796 | 789 | ||
797 | /* Tell common.c that an skb has been sent. */ | 790 | /* Tell common.c that an skb has been sent. */ |
798 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); | 791 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb); |
diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index eb50f3dab5f7..af195b07c191 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c | |||
@@ -28,12 +28,11 @@ static int if_lock(struct cardstate *cs, int *arg) | |||
28 | return -EINVAL; | 28 | return -EINVAL; |
29 | 29 | ||
30 | if (cmd < 0) { | 30 | if (cmd < 0) { |
31 | *arg = atomic_read(&cs->mstate) == MS_LOCKED; //FIXME remove? | 31 | *arg = cs->mstate == MS_LOCKED; |
32 | return 0; | 32 | return 0; |
33 | } | 33 | } |
34 | 34 | ||
35 | if (!cmd && atomic_read(&cs->mstate) == MS_LOCKED | 35 | if (!cmd && cs->mstate == MS_LOCKED && cs->connected) { |
36 | && cs->connected) { | ||
37 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); | 36 | cs->ops->set_modem_ctrl(cs, 0, TIOCM_DTR|TIOCM_RTS); |
38 | cs->ops->baud_rate(cs, B115200); | 37 | cs->ops->baud_rate(cs, B115200); |
39 | cs->ops->set_line_ctrl(cs, CS8); | 38 | cs->ops->set_line_ctrl(cs, CS8); |
@@ -104,7 +103,7 @@ static int if_config(struct cardstate *cs, int *arg) | |||
104 | if (*arg != 1) | 103 | if (*arg != 1) |
105 | return -EINVAL; | 104 | return -EINVAL; |
106 | 105 | ||
107 | if (atomic_read(&cs->mstate) != MS_LOCKED) | 106 | if (cs->mstate != MS_LOCKED) |
108 | return -EBUSY; | 107 | return -EBUSY; |
109 | 108 | ||
110 | if (!cs->connected) { | 109 | if (!cs->connected) { |
@@ -162,7 +161,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) | |||
162 | tty->driver_data = NULL; | 161 | tty->driver_data = NULL; |
163 | 162 | ||
164 | cs = gigaset_get_cs_by_tty(tty); | 163 | cs = gigaset_get_cs_by_tty(tty); |
165 | if (!cs) | 164 | if (!cs || !try_module_get(cs->driver->owner)) |
166 | return -ENODEV; | 165 | return -ENODEV; |
167 | 166 | ||
168 | if (mutex_lock_interruptible(&cs->mutex)) | 167 | if (mutex_lock_interruptible(&cs->mutex)) |
@@ -208,6 +207,8 @@ static void if_close(struct tty_struct *tty, struct file *filp) | |||
208 | } | 207 | } |
209 | 208 | ||
210 | mutex_unlock(&cs->mutex); | 209 | mutex_unlock(&cs->mutex); |
210 | |||
211 | module_put(cs->driver->owner); | ||
211 | } | 212 | } |
212 | 213 | ||
213 | static int if_ioctl(struct tty_struct *tty, struct file *file, | 214 | static int if_ioctl(struct tty_struct *tty, struct file *file, |
@@ -364,7 +365,7 @@ static int if_write(struct tty_struct *tty, const unsigned char *buf, int count) | |||
364 | 365 | ||
365 | if (!cs->open_count) | 366 | if (!cs->open_count) |
366 | warn("%s: device not opened", __func__); | 367 | warn("%s: device not opened", __func__); |
367 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 368 | else if (cs->mstate != MS_LOCKED) { |
368 | warn("can't write to unlocked device"); | 369 | warn("can't write to unlocked device"); |
369 | retval = -EBUSY; | 370 | retval = -EBUSY; |
370 | } else if (!cs->connected) { | 371 | } else if (!cs->connected) { |
@@ -398,9 +399,9 @@ static int if_write_room(struct tty_struct *tty) | |||
398 | 399 | ||
399 | if (!cs->open_count) | 400 | if (!cs->open_count) |
400 | warn("%s: device not opened", __func__); | 401 | warn("%s: device not opened", __func__); |
401 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 402 | else if (cs->mstate != MS_LOCKED) { |
402 | warn("can't write to unlocked device"); | 403 | warn("can't write to unlocked device"); |
403 | retval = -EBUSY; //FIXME | 404 | retval = -EBUSY; |
404 | } else if (!cs->connected) { | 405 | } else if (!cs->connected) { |
405 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); | 406 | gig_dbg(DEBUG_ANY, "can't write to unplugged device"); |
406 | retval = -EBUSY; //FIXME | 407 | retval = -EBUSY; //FIXME |
@@ -430,7 +431,7 @@ static int if_chars_in_buffer(struct tty_struct *tty) | |||
430 | 431 | ||
431 | if (!cs->open_count) | 432 | if (!cs->open_count) |
432 | warn("%s: device not opened", __func__); | 433 | warn("%s: device not opened", __func__); |
433 | else if (atomic_read(&cs->mstate) != MS_LOCKED) { | 434 | else if (cs->mstate != MS_LOCKED) { |
434 | warn("can't write to unlocked device"); | 435 | warn("can't write to unlocked device"); |
435 | retval = -EBUSY; | 436 | retval = -EBUSY; |
436 | } else if (!cs->connected) { | 437 | } else if (!cs->connected) { |
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index e0505f238807..e30a7773f93c 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -23,9 +23,9 @@ | |||
23 | */ | 23 | */ |
24 | void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle) | 24 | void gigaset_isowbuf_init(struct isowbuf_t *iwb, unsigned char idle) |
25 | { | 25 | { |
26 | atomic_set(&iwb->read, 0); | 26 | iwb->read = 0; |
27 | atomic_set(&iwb->nextread, 0); | 27 | iwb->nextread = 0; |
28 | atomic_set(&iwb->write, 0); | 28 | iwb->write = 0; |
29 | atomic_set(&iwb->writesem, 1); | 29 | atomic_set(&iwb->writesem, 1); |
30 | iwb->wbits = 0; | 30 | iwb->wbits = 0; |
31 | iwb->idle = idle; | 31 | iwb->idle = idle; |
@@ -39,8 +39,8 @@ static inline int isowbuf_freebytes(struct isowbuf_t *iwb) | |||
39 | { | 39 | { |
40 | int read, write, freebytes; | 40 | int read, write, freebytes; |
41 | 41 | ||
42 | read = atomic_read(&iwb->read); | 42 | read = iwb->read; |
43 | write = atomic_read(&iwb->write); | 43 | write = iwb->write; |
44 | if ((freebytes = read - write) > 0) { | 44 | if ((freebytes = read - write) > 0) { |
45 | /* no wraparound: need padding space within regular area */ | 45 | /* no wraparound: need padding space within regular area */ |
46 | return freebytes - BAS_OUTBUFPAD; | 46 | return freebytes - BAS_OUTBUFPAD; |
@@ -62,7 +62,7 @@ static inline int isowbuf_poscmp(struct isowbuf_t *iwb, int a, int b) | |||
62 | int read; | 62 | int read; |
63 | if (a == b) | 63 | if (a == b) |
64 | return 0; | 64 | return 0; |
65 | read = atomic_read(&iwb->read); | 65 | read = iwb->read; |
66 | if (a < b) { | 66 | if (a < b) { |
67 | if (a < read && read <= b) | 67 | if (a < read && read <= b) |
68 | return +1; | 68 | return +1; |
@@ -91,18 +91,18 @@ static inline int isowbuf_startwrite(struct isowbuf_t *iwb) | |||
91 | #ifdef CONFIG_GIGASET_DEBUG | 91 | #ifdef CONFIG_GIGASET_DEBUG |
92 | gig_dbg(DEBUG_ISO, | 92 | gig_dbg(DEBUG_ISO, |
93 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", | 93 | "%s: acquired iso write semaphore, data[write]=%02x, nbits=%d", |
94 | __func__, iwb->data[atomic_read(&iwb->write)], iwb->wbits); | 94 | __func__, iwb->data[iwb->write], iwb->wbits); |
95 | #endif | 95 | #endif |
96 | return 1; | 96 | return 1; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* finish writing | 99 | /* finish writing |
100 | * release the write semaphore and update the maximum buffer fill level | 100 | * release the write semaphore |
101 | * returns the current write position | 101 | * returns the current write position |
102 | */ | 102 | */ |
103 | static inline int isowbuf_donewrite(struct isowbuf_t *iwb) | 103 | static inline int isowbuf_donewrite(struct isowbuf_t *iwb) |
104 | { | 104 | { |
105 | int write = atomic_read(&iwb->write); | 105 | int write = iwb->write; |
106 | atomic_inc(&iwb->writesem); | 106 | atomic_inc(&iwb->writesem); |
107 | return write; | 107 | return write; |
108 | } | 108 | } |
@@ -116,7 +116,7 @@ static inline int isowbuf_donewrite(struct isowbuf_t *iwb) | |||
116 | */ | 116 | */ |
117 | static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits) | 117 | static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits) |
118 | { | 118 | { |
119 | int write = atomic_read(&iwb->write); | 119 | int write = iwb->write; |
120 | data <<= iwb->wbits; | 120 | data <<= iwb->wbits; |
121 | data |= iwb->data[write]; | 121 | data |= iwb->data[write]; |
122 | nbits += iwb->wbits; | 122 | nbits += iwb->wbits; |
@@ -128,7 +128,7 @@ static inline void isowbuf_putbits(struct isowbuf_t *iwb, u32 data, int nbits) | |||
128 | } | 128 | } |
129 | iwb->wbits = nbits; | 129 | iwb->wbits = nbits; |
130 | iwb->data[write] = data & 0xff; | 130 | iwb->data[write] = data & 0xff; |
131 | atomic_set(&iwb->write, write); | 131 | iwb->write = write; |
132 | } | 132 | } |
133 | 133 | ||
134 | /* put final flag on HDLC bitstream | 134 | /* put final flag on HDLC bitstream |
@@ -142,7 +142,7 @@ static inline void isowbuf_putflag(struct isowbuf_t *iwb) | |||
142 | /* add two flags, thus reliably covering one byte */ | 142 | /* add two flags, thus reliably covering one byte */ |
143 | isowbuf_putbits(iwb, 0x7e7e, 8); | 143 | isowbuf_putbits(iwb, 0x7e7e, 8); |
144 | /* recover the idle flag byte */ | 144 | /* recover the idle flag byte */ |
145 | write = atomic_read(&iwb->write); | 145 | write = iwb->write; |
146 | iwb->idle = iwb->data[write]; | 146 | iwb->idle = iwb->data[write]; |
147 | gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); | 147 | gig_dbg(DEBUG_ISO, "idle fill byte %02x", iwb->idle); |
148 | /* mask extraneous bits in buffer */ | 148 | /* mask extraneous bits in buffer */ |
@@ -160,8 +160,8 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
160 | int read, write, limit, src, dst; | 160 | int read, write, limit, src, dst; |
161 | unsigned char pbyte; | 161 | unsigned char pbyte; |
162 | 162 | ||
163 | read = atomic_read(&iwb->nextread); | 163 | read = iwb->nextread; |
164 | write = atomic_read(&iwb->write); | 164 | write = iwb->write; |
165 | if (likely(read == write)) { | 165 | if (likely(read == write)) { |
166 | /* return idle frame */ | 166 | /* return idle frame */ |
167 | return read < BAS_OUTBUFPAD ? | 167 | return read < BAS_OUTBUFPAD ? |
@@ -176,7 +176,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
176 | err("invalid size %d", size); | 176 | err("invalid size %d", size); |
177 | return -EINVAL; | 177 | return -EINVAL; |
178 | } | 178 | } |
179 | src = atomic_read(&iwb->read); | 179 | src = iwb->read; |
180 | if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD || | 180 | if (unlikely(limit > BAS_OUTBUFSIZE + BAS_OUTBUFPAD || |
181 | (read < src && limit >= src))) { | 181 | (read < src && limit >= src))) { |
182 | err("isoc write buffer frame reservation violated"); | 182 | err("isoc write buffer frame reservation violated"); |
@@ -191,7 +191,8 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
191 | if (!isowbuf_startwrite(iwb)) | 191 | if (!isowbuf_startwrite(iwb)) |
192 | return -EBUSY; | 192 | return -EBUSY; |
193 | /* write position could have changed */ | 193 | /* write position could have changed */ |
194 | if (limit >= (write = atomic_read(&iwb->write))) { | 194 | write = iwb->write; |
195 | if (limit >= write) { | ||
195 | pbyte = iwb->data[write]; /* save | 196 | pbyte = iwb->data[write]; /* save |
196 | partial byte */ | 197 | partial byte */ |
197 | limit = write + BAS_OUTBUFPAD; | 198 | limit = write + BAS_OUTBUFPAD; |
@@ -213,7 +214,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
213 | __func__, pbyte, limit); | 214 | __func__, pbyte, limit); |
214 | iwb->data[limit] = pbyte; /* restore | 215 | iwb->data[limit] = pbyte; /* restore |
215 | partial byte */ | 216 | partial byte */ |
216 | atomic_set(&iwb->write, limit); | 217 | iwb->write = limit; |
217 | } | 218 | } |
218 | isowbuf_donewrite(iwb); | 219 | isowbuf_donewrite(iwb); |
219 | } | 220 | } |
@@ -233,7 +234,7 @@ int gigaset_isowbuf_getbytes(struct isowbuf_t *iwb, int size) | |||
233 | limit = src; | 234 | limit = src; |
234 | } | 235 | } |
235 | } | 236 | } |
236 | atomic_set(&iwb->nextread, limit); | 237 | iwb->nextread = limit; |
237 | return read; | 238 | return read; |
238 | } | 239 | } |
239 | 240 | ||
@@ -477,7 +478,7 @@ static inline int trans_buildframe(struct isowbuf_t *iwb, | |||
477 | unsigned char c; | 478 | unsigned char c; |
478 | 479 | ||
479 | if (unlikely(count <= 0)) | 480 | if (unlikely(count <= 0)) |
480 | return atomic_read(&iwb->write); /* better ideas? */ | 481 | return iwb->write; |
481 | 482 | ||
482 | if (isowbuf_freebytes(iwb) < count || | 483 | if (isowbuf_freebytes(iwb) < count || |
483 | !isowbuf_startwrite(iwb)) { | 484 | !isowbuf_startwrite(iwb)) { |
@@ -486,13 +487,13 @@ static inline int trans_buildframe(struct isowbuf_t *iwb, | |||
486 | } | 487 | } |
487 | 488 | ||
488 | gig_dbg(DEBUG_STREAM, "put %d bytes", count); | 489 | gig_dbg(DEBUG_STREAM, "put %d bytes", count); |
489 | write = atomic_read(&iwb->write); | 490 | write = iwb->write; |
490 | do { | 491 | do { |
491 | c = bitrev8(*in++); | 492 | c = bitrev8(*in++); |
492 | iwb->data[write++] = c; | 493 | iwb->data[write++] = c; |
493 | write %= BAS_OUTBUFSIZE; | 494 | write %= BAS_OUTBUFSIZE; |
494 | } while (--count > 0); | 495 | } while (--count > 0); |
495 | atomic_set(&iwb->write, write); | 496 | iwb->write = write; |
496 | iwb->idle = c; | 497 | iwb->idle = c; |
497 | 498 | ||
498 | return isowbuf_donewrite(iwb); | 499 | return isowbuf_donewrite(iwb); |
@@ -947,8 +948,8 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
947 | unsigned tail, head, numbytes; | 948 | unsigned tail, head, numbytes; |
948 | unsigned char *src; | 949 | unsigned char *src; |
949 | 950 | ||
950 | head = atomic_read(&inbuf->head); | 951 | head = inbuf->head; |
951 | while (head != (tail = atomic_read(&inbuf->tail))) { | 952 | while (head != (tail = inbuf->tail)) { |
952 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); | 953 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u", head, tail); |
953 | if (head > tail) | 954 | if (head > tail) |
954 | tail = RBUFSIZE; | 955 | tail = RBUFSIZE; |
@@ -956,7 +957,7 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
956 | numbytes = tail - head; | 957 | numbytes = tail - head; |
957 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); | 958 | gig_dbg(DEBUG_INTR, "processing %u bytes", numbytes); |
958 | 959 | ||
959 | if (atomic_read(&cs->mstate) == MS_LOCKED) { | 960 | if (cs->mstate == MS_LOCKED) { |
960 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", | 961 | gigaset_dbg_buffer(DEBUG_LOCKCMD, "received response", |
961 | numbytes, src); | 962 | numbytes, src); |
962 | gigaset_if_receive(inbuf->cs, src, numbytes); | 963 | gigaset_if_receive(inbuf->cs, src, numbytes); |
@@ -970,7 +971,7 @@ void gigaset_isoc_input(struct inbuf_t *inbuf) | |||
970 | if (head == RBUFSIZE) | 971 | if (head == RBUFSIZE) |
971 | head = 0; | 972 | head = 0; |
972 | gig_dbg(DEBUG_INTR, "setting head to %u", head); | 973 | gig_dbg(DEBUG_INTR, "setting head to %u", head); |
973 | atomic_set(&inbuf->head, head); | 974 | inbuf->head = head; |
974 | } | 975 | } |
975 | } | 976 | } |
976 | 977 | ||
diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index ea44302e6e7e..fceeb1d57682 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/platform_device.h> | 17 | #include <linux/platform_device.h> |
18 | #include <linux/tty.h> | 18 | #include <linux/tty.h> |
19 | #include <linux/poll.h> | 19 | #include <linux/poll.h> |
20 | #include <linux/completion.h> | ||
20 | 21 | ||
21 | /* Version Information */ | 22 | /* Version Information */ |
22 | #define DRIVER_AUTHOR "Tilman Schmidt" | 23 | #define DRIVER_AUTHOR "Tilman Schmidt" |
@@ -48,7 +49,7 @@ struct ser_cardstate { | |||
48 | struct platform_device dev; | 49 | struct platform_device dev; |
49 | struct tty_struct *tty; | 50 | struct tty_struct *tty; |
50 | atomic_t refcnt; | 51 | atomic_t refcnt; |
51 | struct mutex dead_mutex; | 52 | struct completion dead_cmp; |
52 | }; | 53 | }; |
53 | 54 | ||
54 | static struct platform_driver device_driver = { | 55 | static struct platform_driver device_driver = { |
@@ -240,7 +241,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | |||
240 | struct cmdbuf_t *cb; | 241 | struct cmdbuf_t *cb; |
241 | unsigned long flags; | 242 | unsigned long flags; |
242 | 243 | ||
243 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 244 | gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? |
244 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 245 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
245 | "CMD Transmit", len, buf); | 246 | "CMD Transmit", len, buf); |
246 | 247 | ||
@@ -498,7 +499,7 @@ static struct cardstate *cs_get(struct tty_struct *tty) | |||
498 | static void cs_put(struct cardstate *cs) | 499 | static void cs_put(struct cardstate *cs) |
499 | { | 500 | { |
500 | if (atomic_dec_and_test(&cs->hw.ser->refcnt)) | 501 | if (atomic_dec_and_test(&cs->hw.ser->refcnt)) |
501 | mutex_unlock(&cs->hw.ser->dead_mutex); | 502 | complete(&cs->hw.ser->dead_cmp); |
502 | } | 503 | } |
503 | 504 | ||
504 | /* | 505 | /* |
@@ -527,8 +528,8 @@ gigaset_tty_open(struct tty_struct *tty) | |||
527 | 528 | ||
528 | cs->dev = &cs->hw.ser->dev.dev; | 529 | cs->dev = &cs->hw.ser->dev.dev; |
529 | cs->hw.ser->tty = tty; | 530 | cs->hw.ser->tty = tty; |
530 | mutex_init(&cs->hw.ser->dead_mutex); | ||
531 | atomic_set(&cs->hw.ser->refcnt, 1); | 531 | atomic_set(&cs->hw.ser->refcnt, 1); |
532 | init_completion(&cs->hw.ser->dead_cmp); | ||
532 | 533 | ||
533 | tty->disc_data = cs; | 534 | tty->disc_data = cs; |
534 | 535 | ||
@@ -536,14 +537,13 @@ gigaset_tty_open(struct tty_struct *tty) | |||
536 | * startup system and notify the LL that we are ready to run | 537 | * startup system and notify the LL that we are ready to run |
537 | */ | 538 | */ |
538 | if (startmode == SM_LOCKED) | 539 | if (startmode == SM_LOCKED) |
539 | atomic_set(&cs->mstate, MS_LOCKED); | 540 | cs->mstate = MS_LOCKED; |
540 | if (!gigaset_start(cs)) { | 541 | if (!gigaset_start(cs)) { |
541 | tasklet_kill(&cs->write_tasklet); | 542 | tasklet_kill(&cs->write_tasklet); |
542 | goto error; | 543 | goto error; |
543 | } | 544 | } |
544 | 545 | ||
545 | gig_dbg(DEBUG_INIT, "Startup of HLL done"); | 546 | gig_dbg(DEBUG_INIT, "Startup of HLL done"); |
546 | mutex_lock(&cs->hw.ser->dead_mutex); | ||
547 | return 0; | 547 | return 0; |
548 | 548 | ||
549 | error: | 549 | error: |
@@ -577,7 +577,7 @@ gigaset_tty_close(struct tty_struct *tty) | |||
577 | else { | 577 | else { |
578 | /* wait for running methods to finish */ | 578 | /* wait for running methods to finish */ |
579 | if (!atomic_dec_and_test(&cs->hw.ser->refcnt)) | 579 | if (!atomic_dec_and_test(&cs->hw.ser->refcnt)) |
580 | mutex_lock(&cs->hw.ser->dead_mutex); | 580 | wait_for_completion(&cs->hw.ser->dead_cmp); |
581 | } | 581 | } |
582 | 582 | ||
583 | /* stop operations */ | 583 | /* stop operations */ |
@@ -714,8 +714,8 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
714 | return; | 714 | return; |
715 | } | 715 | } |
716 | 716 | ||
717 | tail = atomic_read(&inbuf->tail); | 717 | tail = inbuf->tail; |
718 | head = atomic_read(&inbuf->head); | 718 | head = inbuf->head; |
719 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u, receive %u bytes", | 719 | gig_dbg(DEBUG_INTR, "buffer state: %u -> %u, receive %u bytes", |
720 | head, tail, count); | 720 | head, tail, count); |
721 | 721 | ||
@@ -742,7 +742,7 @@ gigaset_tty_receive(struct tty_struct *tty, const unsigned char *buf, | |||
742 | } | 742 | } |
743 | 743 | ||
744 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); | 744 | gig_dbg(DEBUG_INTR, "setting tail to %u", tail); |
745 | atomic_set(&inbuf->tail, tail); | 745 | inbuf->tail = tail; |
746 | 746 | ||
747 | /* Everything was received .. Push data into handler */ | 747 | /* Everything was received .. Push data into handler */ |
748 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | 748 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index ca4bee173cfb..77d20ab0cd4d 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c | |||
@@ -104,12 +104,17 @@ MODULE_DEVICE_TABLE(usb, gigaset_table); | |||
104 | * flags per packet. | 104 | * flags per packet. |
105 | */ | 105 | */ |
106 | 106 | ||
107 | /* functions called if a device of this driver is connected/disconnected */ | ||
107 | static int gigaset_probe(struct usb_interface *interface, | 108 | static int gigaset_probe(struct usb_interface *interface, |
108 | const struct usb_device_id *id); | 109 | const struct usb_device_id *id); |
109 | static void gigaset_disconnect(struct usb_interface *interface); | 110 | static void gigaset_disconnect(struct usb_interface *interface); |
110 | 111 | ||
112 | /* functions called before/after suspend */ | ||
113 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message); | ||
114 | static int gigaset_resume(struct usb_interface *intf); | ||
115 | static int gigaset_pre_reset(struct usb_interface *intf); | ||
116 | |||
111 | static struct gigaset_driver *driver = NULL; | 117 | static struct gigaset_driver *driver = NULL; |
112 | static struct cardstate *cardstate = NULL; | ||
113 | 118 | ||
114 | /* usb specific object needed to register this driver with the usb subsystem */ | 119 | /* usb specific object needed to register this driver with the usb subsystem */ |
115 | static struct usb_driver gigaset_usb_driver = { | 120 | static struct usb_driver gigaset_usb_driver = { |
@@ -117,12 +122,17 @@ static struct usb_driver gigaset_usb_driver = { | |||
117 | .probe = gigaset_probe, | 122 | .probe = gigaset_probe, |
118 | .disconnect = gigaset_disconnect, | 123 | .disconnect = gigaset_disconnect, |
119 | .id_table = gigaset_table, | 124 | .id_table = gigaset_table, |
125 | .suspend = gigaset_suspend, | ||
126 | .resume = gigaset_resume, | ||
127 | .reset_resume = gigaset_resume, | ||
128 | .pre_reset = gigaset_pre_reset, | ||
129 | .post_reset = gigaset_resume, | ||
120 | }; | 130 | }; |
121 | 131 | ||
122 | struct usb_cardstate { | 132 | struct usb_cardstate { |
123 | struct usb_device *udev; /* usb device pointer */ | 133 | struct usb_device *udev; /* usb device pointer */ |
124 | struct usb_interface *interface; /* interface for this device */ | 134 | struct usb_interface *interface; /* interface for this device */ |
125 | atomic_t busy; /* bulk output in progress */ | 135 | int busy; /* bulk output in progress */ |
126 | 136 | ||
127 | /* Output buffer */ | 137 | /* Output buffer */ |
128 | unsigned char *bulk_out_buffer; | 138 | unsigned char *bulk_out_buffer; |
@@ -314,7 +324,7 @@ static void gigaset_modem_fill(unsigned long data) | |||
314 | 324 | ||
315 | gig_dbg(DEBUG_OUTPUT, "modem_fill"); | 325 | gig_dbg(DEBUG_OUTPUT, "modem_fill"); |
316 | 326 | ||
317 | if (atomic_read(&cs->hw.usb->busy)) { | 327 | if (cs->hw.usb->busy) { |
318 | gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); | 328 | gig_dbg(DEBUG_OUTPUT, "modem_fill: busy"); |
319 | return; | 329 | return; |
320 | } | 330 | } |
@@ -361,18 +371,13 @@ static void gigaset_read_int_callback(struct urb *urb) | |||
361 | { | 371 | { |
362 | struct inbuf_t *inbuf = urb->context; | 372 | struct inbuf_t *inbuf = urb->context; |
363 | struct cardstate *cs = inbuf->cs; | 373 | struct cardstate *cs = inbuf->cs; |
364 | int resubmit = 0; | 374 | int status = urb->status; |
365 | int r; | 375 | int r; |
366 | unsigned numbytes; | 376 | unsigned numbytes; |
367 | unsigned char *src; | 377 | unsigned char *src; |
368 | unsigned long flags; | 378 | unsigned long flags; |
369 | 379 | ||
370 | if (!urb->status) { | 380 | if (!status) { |
371 | if (!cs->connected) { | ||
372 | err("%s: disconnected", __func__); /* should never happen */ | ||
373 | return; | ||
374 | } | ||
375 | |||
376 | numbytes = urb->actual_length; | 381 | numbytes = urb->actual_length; |
377 | 382 | ||
378 | if (numbytes) { | 383 | if (numbytes) { |
@@ -389,28 +394,26 @@ static void gigaset_read_int_callback(struct urb *urb) | |||
389 | } | 394 | } |
390 | } else | 395 | } else |
391 | gig_dbg(DEBUG_INTR, "Received zero block length"); | 396 | gig_dbg(DEBUG_INTR, "Received zero block length"); |
392 | resubmit = 1; | ||
393 | } else { | 397 | } else { |
394 | /* The urb might have been killed. */ | 398 | /* The urb might have been killed. */ |
395 | gig_dbg(DEBUG_ANY, "%s - nonzero read bulk status received: %d", | 399 | gig_dbg(DEBUG_ANY, "%s - nonzero status received: %d", |
396 | __func__, urb->status); | 400 | __func__, status); |
397 | if (urb->status != -ENOENT) { /* not killed */ | 401 | if (status == -ENOENT || status == -ESHUTDOWN) |
398 | if (!cs->connected) { | 402 | /* killed or endpoint shutdown: don't resubmit */ |
399 | err("%s: disconnected", __func__); /* should never happen */ | 403 | return; |
400 | return; | ||
401 | } | ||
402 | resubmit = 1; | ||
403 | } | ||
404 | } | 404 | } |
405 | 405 | ||
406 | if (resubmit) { | 406 | /* resubmit URB */ |
407 | spin_lock_irqsave(&cs->lock, flags); | 407 | spin_lock_irqsave(&cs->lock, flags); |
408 | r = cs->connected ? usb_submit_urb(urb, GFP_ATOMIC) : -ENODEV; | 408 | if (!cs->connected) { |
409 | spin_unlock_irqrestore(&cs->lock, flags); | 409 | spin_unlock_irqrestore(&cs->lock, flags); |
410 | if (r) | 410 | err("%s: disconnected", __func__); |
411 | dev_err(cs->dev, "error %d when resubmitting urb.\n", | 411 | return; |
412 | -r); | ||
413 | } | 412 | } |
413 | r = usb_submit_urb(urb, GFP_ATOMIC); | ||
414 | spin_unlock_irqrestore(&cs->lock, flags); | ||
415 | if (r) | ||
416 | dev_err(cs->dev, "error %d resubmitting URB\n", -r); | ||
414 | } | 417 | } |
415 | 418 | ||
416 | 419 | ||
@@ -418,19 +421,28 @@ static void gigaset_read_int_callback(struct urb *urb) | |||
418 | static void gigaset_write_bulk_callback(struct urb *urb) | 421 | static void gigaset_write_bulk_callback(struct urb *urb) |
419 | { | 422 | { |
420 | struct cardstate *cs = urb->context; | 423 | struct cardstate *cs = urb->context; |
424 | int status = urb->status; | ||
421 | unsigned long flags; | 425 | unsigned long flags; |
422 | 426 | ||
423 | if (urb->status) | 427 | switch (status) { |
428 | case 0: /* normal completion */ | ||
429 | break; | ||
430 | case -ENOENT: /* killed */ | ||
431 | gig_dbg(DEBUG_ANY, "%s: killed", __func__); | ||
432 | cs->hw.usb->busy = 0; | ||
433 | return; | ||
434 | default: | ||
424 | dev_err(cs->dev, "bulk transfer failed (status %d)\n", | 435 | dev_err(cs->dev, "bulk transfer failed (status %d)\n", |
425 | -urb->status); | 436 | -status); |
426 | /* That's all we can do. Communication problems | 437 | /* That's all we can do. Communication problems |
427 | are handled by timeouts or network protocols. */ | 438 | are handled by timeouts or network protocols. */ |
439 | } | ||
428 | 440 | ||
429 | spin_lock_irqsave(&cs->lock, flags); | 441 | spin_lock_irqsave(&cs->lock, flags); |
430 | if (!cs->connected) { | 442 | if (!cs->connected) { |
431 | err("%s: not connected", __func__); | 443 | err("%s: not connected", __func__); |
432 | } else { | 444 | } else { |
433 | atomic_set(&cs->hw.usb->busy, 0); | 445 | cs->hw.usb->busy = 0; |
434 | tasklet_schedule(&cs->write_tasklet); | 446 | tasklet_schedule(&cs->write_tasklet); |
435 | } | 447 | } |
436 | spin_unlock_irqrestore(&cs->lock, flags); | 448 | spin_unlock_irqrestore(&cs->lock, flags); |
@@ -478,14 +490,14 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) | |||
478 | 490 | ||
479 | cb->offset += count; | 491 | cb->offset += count; |
480 | cb->len -= count; | 492 | cb->len -= count; |
481 | atomic_set(&ucs->busy, 1); | 493 | ucs->busy = 1; |
482 | 494 | ||
483 | spin_lock_irqsave(&cs->lock, flags); | 495 | spin_lock_irqsave(&cs->lock, flags); |
484 | status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; | 496 | status = cs->connected ? usb_submit_urb(ucs->bulk_out_urb, GFP_ATOMIC) : -ENODEV; |
485 | spin_unlock_irqrestore(&cs->lock, flags); | 497 | spin_unlock_irqrestore(&cs->lock, flags); |
486 | 498 | ||
487 | if (status) { | 499 | if (status) { |
488 | atomic_set(&ucs->busy, 0); | 500 | ucs->busy = 0; |
489 | err("could not submit urb (error %d)\n", | 501 | err("could not submit urb (error %d)\n", |
490 | -status); | 502 | -status); |
491 | cb->len = 0; /* skip urb => remove cb+wakeup | 503 | cb->len = 0; /* skip urb => remove cb+wakeup |
@@ -504,7 +516,7 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf, | |||
504 | struct cmdbuf_t *cb; | 516 | struct cmdbuf_t *cb; |
505 | unsigned long flags; | 517 | unsigned long flags; |
506 | 518 | ||
507 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 519 | gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? |
508 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 520 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
509 | "CMD Transmit", len, buf); | 521 | "CMD Transmit", len, buf); |
510 | 522 | ||
@@ -641,7 +653,7 @@ static int write_modem(struct cardstate *cs) | |||
641 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); | 653 | count = min(bcs->tx_skb->len, (unsigned) ucs->bulk_out_size); |
642 | skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count); | 654 | skb_copy_from_linear_data(bcs->tx_skb, ucs->bulk_out_buffer, count); |
643 | skb_pull(bcs->tx_skb, count); | 655 | skb_pull(bcs->tx_skb, count); |
644 | atomic_set(&ucs->busy, 1); | 656 | ucs->busy = 1; |
645 | gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); | 657 | gig_dbg(DEBUG_OUTPUT, "write_modem: send %d bytes", count); |
646 | 658 | ||
647 | spin_lock_irqsave(&cs->lock, flags); | 659 | spin_lock_irqsave(&cs->lock, flags); |
@@ -659,7 +671,7 @@ static int write_modem(struct cardstate *cs) | |||
659 | 671 | ||
660 | if (ret) { | 672 | if (ret) { |
661 | err("could not submit urb (error %d)\n", -ret); | 673 | err("could not submit urb (error %d)\n", -ret); |
662 | atomic_set(&ucs->busy, 0); | 674 | ucs->busy = 0; |
663 | } | 675 | } |
664 | 676 | ||
665 | if (!bcs->tx_skb->len) { | 677 | if (!bcs->tx_skb->len) { |
@@ -680,53 +692,44 @@ static int gigaset_probe(struct usb_interface *interface, | |||
680 | { | 692 | { |
681 | int retval; | 693 | int retval; |
682 | struct usb_device *udev = interface_to_usbdev(interface); | 694 | struct usb_device *udev = interface_to_usbdev(interface); |
683 | unsigned int ifnum; | 695 | struct usb_host_interface *hostif = interface->cur_altsetting; |
684 | struct usb_host_interface *hostif; | ||
685 | struct cardstate *cs = NULL; | 696 | struct cardstate *cs = NULL; |
686 | struct usb_cardstate *ucs = NULL; | 697 | struct usb_cardstate *ucs = NULL; |
687 | struct usb_endpoint_descriptor *endpoint; | 698 | struct usb_endpoint_descriptor *endpoint; |
688 | int buffer_size; | 699 | int buffer_size; |
689 | int alt; | ||
690 | 700 | ||
691 | gig_dbg(DEBUG_ANY, | 701 | gig_dbg(DEBUG_ANY, "%s: Check if device matches ...", __func__); |
692 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | ||
693 | __func__, le16_to_cpu(udev->descriptor.idVendor), | ||
694 | le16_to_cpu(udev->descriptor.idProduct)); | ||
695 | |||
696 | retval = -ENODEV; //FIXME | ||
697 | 702 | ||
698 | /* See if the device offered us matches what we can accept */ | 703 | /* See if the device offered us matches what we can accept */ |
699 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || | 704 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_M105_VENDOR_ID) || |
700 | (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) | 705 | (le16_to_cpu(udev->descriptor.idProduct) != USB_M105_PRODUCT_ID)) { |
706 | gig_dbg(DEBUG_ANY, "device ID (0x%x, 0x%x) not for me - skip", | ||
707 | le16_to_cpu(udev->descriptor.idVendor), | ||
708 | le16_to_cpu(udev->descriptor.idProduct)); | ||
701 | return -ENODEV; | 709 | return -ENODEV; |
702 | 710 | } | |
703 | /* this starts to become ascii art... */ | 711 | if (hostif->desc.bInterfaceNumber != 0) { |
704 | hostif = interface->cur_altsetting; | 712 | gig_dbg(DEBUG_ANY, "interface %d not for me - skip", |
705 | alt = hostif->desc.bAlternateSetting; | 713 | hostif->desc.bInterfaceNumber); |
706 | ifnum = hostif->desc.bInterfaceNumber; // FIXME ? | 714 | return -ENODEV; |
707 | 715 | } | |
708 | if (alt != 0 || ifnum != 0) { | 716 | if (hostif->desc.bAlternateSetting != 0) { |
709 | dev_warn(&udev->dev, "ifnum %d, alt %d\n", ifnum, alt); | 717 | dev_notice(&udev->dev, "unsupported altsetting %d - skip", |
718 | hostif->desc.bAlternateSetting); | ||
710 | return -ENODEV; | 719 | return -ENODEV; |
711 | } | 720 | } |
712 | |||
713 | /* Reject application specific intefaces | ||
714 | * | ||
715 | */ | ||
716 | if (hostif->desc.bInterfaceClass != 255) { | 721 | if (hostif->desc.bInterfaceClass != 255) { |
717 | dev_info(&udev->dev, | 722 | dev_notice(&udev->dev, "unsupported interface class %d - skip", |
718 | "%s: Device matched but iface_desc[%d]->bInterfaceClass==%d!\n", | 723 | hostif->desc.bInterfaceClass); |
719 | __func__, ifnum, hostif->desc.bInterfaceClass); | ||
720 | return -ENODEV; | 724 | return -ENODEV; |
721 | } | 725 | } |
722 | 726 | ||
723 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); | 727 | dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); |
724 | 728 | ||
725 | cs = gigaset_getunassignedcs(driver); | 729 | /* allocate memory for our device state and intialize it */ |
726 | if (!cs) { | 730 | cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); |
727 | dev_warn(&udev->dev, "no free cardstate\n"); | 731 | if (!cs) |
728 | return -ENODEV; | 732 | return -ENODEV; |
729 | } | ||
730 | ucs = cs->hw.usb; | 733 | ucs = cs->hw.usb; |
731 | 734 | ||
732 | /* save off device structure ptrs for later use */ | 735 | /* save off device structure ptrs for later use */ |
@@ -759,7 +762,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
759 | 762 | ||
760 | endpoint = &hostif->endpoint[1].desc; | 763 | endpoint = &hostif->endpoint[1].desc; |
761 | 764 | ||
762 | atomic_set(&ucs->busy, 0); | 765 | ucs->busy = 0; |
763 | 766 | ||
764 | ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); | 767 | ucs->read_urb = usb_alloc_urb(0, GFP_KERNEL); |
765 | if (!ucs->read_urb) { | 768 | if (!ucs->read_urb) { |
@@ -792,7 +795,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
792 | 795 | ||
793 | /* tell common part that the device is ready */ | 796 | /* tell common part that the device is ready */ |
794 | if (startmode == SM_LOCKED) | 797 | if (startmode == SM_LOCKED) |
795 | atomic_set(&cs->mstate, MS_LOCKED); | 798 | cs->mstate = MS_LOCKED; |
796 | 799 | ||
797 | if (!gigaset_start(cs)) { | 800 | if (!gigaset_start(cs)) { |
798 | tasklet_kill(&cs->write_tasklet); | 801 | tasklet_kill(&cs->write_tasklet); |
@@ -813,7 +816,7 @@ error: | |||
813 | usb_put_dev(ucs->udev); | 816 | usb_put_dev(ucs->udev); |
814 | ucs->udev = NULL; | 817 | ucs->udev = NULL; |
815 | ucs->interface = NULL; | 818 | ucs->interface = NULL; |
816 | gigaset_unassign(cs); | 819 | gigaset_freecs(cs); |
817 | return retval; | 820 | return retval; |
818 | } | 821 | } |
819 | 822 | ||
@@ -824,6 +827,9 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
824 | 827 | ||
825 | cs = usb_get_intfdata(interface); | 828 | cs = usb_get_intfdata(interface); |
826 | ucs = cs->hw.usb; | 829 | ucs = cs->hw.usb; |
830 | |||
831 | dev_info(cs->dev, "disconnecting Gigaset USB adapter\n"); | ||
832 | |||
827 | usb_kill_urb(ucs->read_urb); | 833 | usb_kill_urb(ucs->read_urb); |
828 | 834 | ||
829 | gigaset_stop(cs); | 835 | gigaset_stop(cs); |
@@ -831,7 +837,7 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
831 | usb_set_intfdata(interface, NULL); | 837 | usb_set_intfdata(interface, NULL); |
832 | tasklet_kill(&cs->write_tasklet); | 838 | tasklet_kill(&cs->write_tasklet); |
833 | 839 | ||
834 | usb_kill_urb(ucs->bulk_out_urb); /* FIXME: only if active? */ | 840 | usb_kill_urb(ucs->bulk_out_urb); |
835 | 841 | ||
836 | kfree(ucs->bulk_out_buffer); | 842 | kfree(ucs->bulk_out_buffer); |
837 | usb_free_urb(ucs->bulk_out_urb); | 843 | usb_free_urb(ucs->bulk_out_urb); |
@@ -844,7 +850,53 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
844 | ucs->interface = NULL; | 850 | ucs->interface = NULL; |
845 | ucs->udev = NULL; | 851 | ucs->udev = NULL; |
846 | cs->dev = NULL; | 852 | cs->dev = NULL; |
847 | gigaset_unassign(cs); | 853 | gigaset_freecs(cs); |
854 | } | ||
855 | |||
856 | /* gigaset_suspend | ||
857 | * This function is called before the USB connection is suspended or reset. | ||
858 | */ | ||
859 | static int gigaset_suspend(struct usb_interface *intf, pm_message_t message) | ||
860 | { | ||
861 | struct cardstate *cs = usb_get_intfdata(intf); | ||
862 | |||
863 | /* stop activity */ | ||
864 | cs->connected = 0; /* prevent rescheduling */ | ||
865 | usb_kill_urb(cs->hw.usb->read_urb); | ||
866 | tasklet_kill(&cs->write_tasklet); | ||
867 | usb_kill_urb(cs->hw.usb->bulk_out_urb); | ||
868 | |||
869 | gig_dbg(DEBUG_SUSPEND, "suspend complete"); | ||
870 | return 0; | ||
871 | } | ||
872 | |||
873 | /* gigaset_resume | ||
874 | * This function is called after the USB connection has been resumed or reset. | ||
875 | */ | ||
876 | static int gigaset_resume(struct usb_interface *intf) | ||
877 | { | ||
878 | struct cardstate *cs = usb_get_intfdata(intf); | ||
879 | int rc; | ||
880 | |||
881 | /* resubmit interrupt URB */ | ||
882 | cs->connected = 1; | ||
883 | rc = usb_submit_urb(cs->hw.usb->read_urb, GFP_KERNEL); | ||
884 | if (rc) { | ||
885 | dev_err(cs->dev, "Could not submit read URB (error %d)\n", -rc); | ||
886 | return rc; | ||
887 | } | ||
888 | |||
889 | gig_dbg(DEBUG_SUSPEND, "resume complete"); | ||
890 | return 0; | ||
891 | } | ||
892 | |||
893 | /* gigaset_pre_reset | ||
894 | * This function is called before the USB connection is reset. | ||
895 | */ | ||
896 | static int gigaset_pre_reset(struct usb_interface *intf) | ||
897 | { | ||
898 | /* same as suspend */ | ||
899 | return gigaset_suspend(intf, PMSG_ON); | ||
848 | } | 900 | } |
849 | 901 | ||
850 | static const struct gigaset_ops ops = { | 902 | static const struct gigaset_ops ops = { |
@@ -880,11 +932,6 @@ static int __init usb_gigaset_init(void) | |||
880 | &ops, THIS_MODULE)) == NULL) | 932 | &ops, THIS_MODULE)) == NULL) |
881 | goto error; | 933 | goto error; |
882 | 934 | ||
883 | /* allocate memory for our device state and intialize it */ | ||
884 | cardstate = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); | ||
885 | if (!cardstate) | ||
886 | goto error; | ||
887 | |||
888 | /* register this driver with the USB subsystem */ | 935 | /* register this driver with the USB subsystem */ |
889 | result = usb_register(&gigaset_usb_driver); | 936 | result = usb_register(&gigaset_usb_driver); |
890 | if (result < 0) { | 937 | if (result < 0) { |
@@ -897,9 +944,7 @@ static int __init usb_gigaset_init(void) | |||
897 | info(DRIVER_DESC); | 944 | info(DRIVER_DESC); |
898 | return 0; | 945 | return 0; |
899 | 946 | ||
900 | error: if (cardstate) | 947 | error: |
901 | gigaset_freecs(cardstate); | ||
902 | cardstate = NULL; | ||
903 | if (driver) | 948 | if (driver) |
904 | gigaset_freedriver(driver); | 949 | gigaset_freedriver(driver); |
905 | driver = NULL; | 950 | driver = NULL; |
@@ -913,11 +958,16 @@ error: if (cardstate) | |||
913 | */ | 958 | */ |
914 | static void __exit usb_gigaset_exit(void) | 959 | static void __exit usb_gigaset_exit(void) |
915 | { | 960 | { |
961 | int i; | ||
962 | |||
916 | gigaset_blockdriver(driver); /* => probe will fail | 963 | gigaset_blockdriver(driver); /* => probe will fail |
917 | * => no gigaset_start any more | 964 | * => no gigaset_start any more |
918 | */ | 965 | */ |
919 | 966 | ||
920 | gigaset_shutdown(cardstate); | 967 | /* stop all connected devices */ |
968 | for (i = 0; i < driver->minors; i++) | ||
969 | gigaset_shutdown(driver->cs + i); | ||
970 | |||
921 | /* from now on, no isdn callback should be possible */ | 971 | /* from now on, no isdn callback should be possible */ |
922 | 972 | ||
923 | /* deregister this driver with the USB subsystem */ | 973 | /* deregister this driver with the USB subsystem */ |
@@ -925,8 +975,6 @@ static void __exit usb_gigaset_exit(void) | |||
925 | /* this will call the disconnect-callback */ | 975 | /* this will call the disconnect-callback */ |
926 | /* from now on, no disconnect/probe callback should be running */ | 976 | /* from now on, no disconnect/probe callback should be running */ |
927 | 977 | ||
928 | gigaset_freecs(cardstate); | ||
929 | cardstate = NULL; | ||
930 | gigaset_freedriver(driver); | 978 | gigaset_freedriver(driver); |
931 | driver = NULL; | 979 | driver = NULL; |
932 | } | 980 | } |
diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 0db9cc661e28..84318ec8d13e 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c | |||
@@ -1188,7 +1188,7 @@ int SuperTraceASSIGN (void* AdapterHandle, byte* data) { | |||
1188 | 1188 | ||
1189 | if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) && | 1189 | if ((features[0] & DIVA_XDI_EXTENDED_FEATURES_VALID) && |
1190 | (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) { | 1190 | (features[0] & DIVA_XDI_EXTENDED_FEATURE_MANAGEMENT_DMA)) { |
1191 | dword rx_dma_magic; | 1191 | dword uninitialized_var(rx_dma_magic); |
1192 | if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) { | 1192 | if ((pC->dma_handle = diva_get_dma_descriptor (pC->request, &rx_dma_magic)) >= 0) { |
1193 | pC->xbuffer[0] = LLI; | 1193 | pC->xbuffer[0] = LLI; |
1194 | pC->xbuffer[1] = 8; | 1194 | pC->xbuffer[1] = 8; |
diff --git a/drivers/isdn/hardware/eicon/diva.c b/drivers/isdn/hardware/eicon/diva.c index ffa2afa77c2f..1403a5458e68 100644 --- a/drivers/isdn/hardware/eicon/diva.c +++ b/drivers/isdn/hardware/eicon/diva.c | |||
@@ -515,12 +515,11 @@ diva_xdi_read(void *adapter, void *os_handle, void __user *dst, | |||
515 | 515 | ||
516 | irqreturn_t diva_os_irq_wrapper(int irq, void *context) | 516 | irqreturn_t diva_os_irq_wrapper(int irq, void *context) |
517 | { | 517 | { |
518 | diva_os_xdi_adapter_t *a = (diva_os_xdi_adapter_t *) context; | 518 | diva_os_xdi_adapter_t *a = context; |
519 | diva_xdi_clear_interrupts_proc_t clear_int_proc; | 519 | diva_xdi_clear_interrupts_proc_t clear_int_proc; |
520 | 520 | ||
521 | if (!a || !a->xdi_adapter.diva_isr_handler) { | 521 | if (!a || !a->xdi_adapter.diva_isr_handler) |
522 | return IRQ_NONE; | 522 | return IRQ_NONE; |
523 | } | ||
524 | 523 | ||
525 | if ((clear_int_proc = a->clear_interrupts_proc)) { | 524 | if ((clear_int_proc = a->clear_interrupts_proc)) { |
526 | (*clear_int_proc) (a); | 525 | (*clear_int_proc) (a); |
diff --git a/drivers/isdn/hardware/eicon/message.c b/drivers/isdn/hardware/eicon/message.c index b9177ca4369a..1ff98e7eb794 100644 --- a/drivers/isdn/hardware/eicon/message.c +++ b/drivers/isdn/hardware/eicon/message.c | |||
@@ -9027,7 +9027,7 @@ static byte AddInfo(byte **add_i, | |||
9027 | /* facility is a nested structure */ | 9027 | /* facility is a nested structure */ |
9028 | /* FTY can be more than once */ | 9028 | /* FTY can be more than once */ |
9029 | 9029 | ||
9030 | if(esc_chi[0] && !(esc_chi[esc_chi[0]])&0x7f ) | 9030 | if (esc_chi[0] && !(esc_chi[esc_chi[0]] & 0x7f)) |
9031 | { | 9031 | { |
9032 | add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */ | 9032 | add_i[0] = (byte *)"\x02\x02\x00"; /* use neither b nor d channel */ |
9033 | } | 9033 | } |
diff --git a/drivers/isdn/hisax/avm_pci.c b/drivers/isdn/hisax/avm_pci.c index 035d158779df..0f1db1f669b2 100644 --- a/drivers/isdn/hisax/avm_pci.c +++ b/drivers/isdn/hisax/avm_pci.c | |||
@@ -263,11 +263,7 @@ hdlc_empty_fifo(struct BCState *bcs, int count) | |||
263 | outl(idx, cs->hw.avm.cfg_reg + 4); | 263 | outl(idx, cs->hw.avm.cfg_reg + 4); |
264 | while (cnt < count) { | 264 | while (cnt < count) { |
265 | #ifdef __powerpc__ | 265 | #ifdef __powerpc__ |
266 | #ifdef CONFIG_APUS | ||
267 | *ptr++ = in_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE)); | ||
268 | #else | ||
269 | *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE)); | 266 | *ptr++ = in_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE)); |
270 | #endif /* CONFIG_APUS */ | ||
271 | #else | 267 | #else |
272 | *ptr++ = inl(cs->hw.avm.isac); | 268 | *ptr++ = inl(cs->hw.avm.isac); |
273 | #endif /* __powerpc__ */ | 269 | #endif /* __powerpc__ */ |
@@ -328,11 +324,7 @@ hdlc_fill_fifo(struct BCState *bcs) | |||
328 | if (cs->subtyp == AVM_FRITZ_PCI) { | 324 | if (cs->subtyp == AVM_FRITZ_PCI) { |
329 | while (cnt<count) { | 325 | while (cnt<count) { |
330 | #ifdef __powerpc__ | 326 | #ifdef __powerpc__ |
331 | #ifdef CONFIG_APUS | ||
332 | out_le32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++); | ||
333 | #else | ||
334 | out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++); | 327 | out_be32((unsigned *)(cs->hw.avm.isac +_IO_BASE), *ptr++); |
335 | #endif /* CONFIG_APUS */ | ||
336 | #else | 328 | #else |
337 | outl(*ptr++, cs->hw.avm.isac); | 329 | outl(*ptr++, cs->hw.avm.isac); |
338 | #endif /* __powerpc__ */ | 330 | #endif /* __powerpc__ */ |
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c index 9cb6e5021adb..133eb18e65cc 100644 --- a/drivers/isdn/i4l/isdn_tty.c +++ b/drivers/isdn/i4l/isdn_tty.c | |||
@@ -1917,7 +1917,6 @@ isdn_tty_modem_init(void) | |||
1917 | info->owner = THIS_MODULE; | 1917 | info->owner = THIS_MODULE; |
1918 | #endif | 1918 | #endif |
1919 | spin_lock_init(&info->readlock); | 1919 | spin_lock_init(&info->readlock); |
1920 | init_MUTEX(&info->write_sem); | ||
1921 | sprintf(info->last_cause, "0000"); | 1920 | sprintf(info->last_cause, "0000"); |
1922 | sprintf(info->last_num, "none"); | 1921 | sprintf(info->last_num, "none"); |
1923 | info->last_dir = 0; | 1922 | info->last_dir = 0; |
diff --git a/drivers/isdn/i4l/isdn_ttyfax.c b/drivers/isdn/i4l/isdn_ttyfax.c index a943d078bacc..f93de4a30355 100644 --- a/drivers/isdn/i4l/isdn_ttyfax.c +++ b/drivers/isdn/i4l/isdn_ttyfax.c | |||
@@ -834,7 +834,7 @@ isdn_tty_cmd_FCLASS2(char **p, modem_info * info) | |||
834 | char *rp = &f->resolution; | 834 | char *rp = &f->resolution; |
835 | 835 | ||
836 | p[0] += 2; | 836 | p[0] += 2; |
837 | if (!info->faxonline & 1) /* not outgoing connection */ | 837 | if (!(info->faxonline & 1)) /* not outgoing connection */ |
838 | PARSE_ERROR1; | 838 | PARSE_ERROR1; |
839 | 839 | ||
840 | for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 4); i++) { | 840 | for (i = 0; (((*p[0] >= '0') && (*p[0] <= '9')) || (*p[0] == ',')) && (i < 4); i++) { |
diff --git a/drivers/isdn/icn/icn.c b/drivers/isdn/icn/icn.c index 82d957bde299..bf7997abc4ac 100644 --- a/drivers/isdn/icn/icn.c +++ b/drivers/isdn/icn/icn.c | |||
@@ -1302,7 +1302,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1302 | } | 1302 | } |
1303 | break; | 1303 | break; |
1304 | case ISDN_CMD_DIAL: | 1304 | case ISDN_CMD_DIAL: |
1305 | if (!card->flags & ICN_FLAGS_RUNNING) | 1305 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1306 | return -ENODEV; | 1306 | return -ENODEV; |
1307 | if (card->leased) | 1307 | if (card->leased) |
1308 | break; | 1308 | break; |
@@ -1328,7 +1328,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1328 | } | 1328 | } |
1329 | break; | 1329 | break; |
1330 | case ISDN_CMD_ACCEPTD: | 1330 | case ISDN_CMD_ACCEPTD: |
1331 | if (!card->flags & ICN_FLAGS_RUNNING) | 1331 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1332 | return -ENODEV; | 1332 | return -ENODEV; |
1333 | if (c->arg < ICN_BCH) { | 1333 | if (c->arg < ICN_BCH) { |
1334 | a = c->arg + 1; | 1334 | a = c->arg + 1; |
@@ -1348,7 +1348,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1348 | } | 1348 | } |
1349 | break; | 1349 | break; |
1350 | case ISDN_CMD_ACCEPTB: | 1350 | case ISDN_CMD_ACCEPTB: |
1351 | if (!card->flags & ICN_FLAGS_RUNNING) | 1351 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1352 | return -ENODEV; | 1352 | return -ENODEV; |
1353 | if (c->arg < ICN_BCH) { | 1353 | if (c->arg < ICN_BCH) { |
1354 | a = c->arg + 1; | 1354 | a = c->arg + 1; |
@@ -1366,7 +1366,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1366 | } | 1366 | } |
1367 | break; | 1367 | break; |
1368 | case ISDN_CMD_HANGUP: | 1368 | case ISDN_CMD_HANGUP: |
1369 | if (!card->flags & ICN_FLAGS_RUNNING) | 1369 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1370 | return -ENODEV; | 1370 | return -ENODEV; |
1371 | if (c->arg < ICN_BCH) { | 1371 | if (c->arg < ICN_BCH) { |
1372 | a = c->arg + 1; | 1372 | a = c->arg + 1; |
@@ -1375,7 +1375,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1375 | } | 1375 | } |
1376 | break; | 1376 | break; |
1377 | case ISDN_CMD_SETEAZ: | 1377 | case ISDN_CMD_SETEAZ: |
1378 | if (!card->flags & ICN_FLAGS_RUNNING) | 1378 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1379 | return -ENODEV; | 1379 | return -ENODEV; |
1380 | if (card->leased) | 1380 | if (card->leased) |
1381 | break; | 1381 | break; |
@@ -1391,7 +1391,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1391 | } | 1391 | } |
1392 | break; | 1392 | break; |
1393 | case ISDN_CMD_CLREAZ: | 1393 | case ISDN_CMD_CLREAZ: |
1394 | if (!card->flags & ICN_FLAGS_RUNNING) | 1394 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1395 | return -ENODEV; | 1395 | return -ENODEV; |
1396 | if (card->leased) | 1396 | if (card->leased) |
1397 | break; | 1397 | break; |
@@ -1405,7 +1405,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1405 | } | 1405 | } |
1406 | break; | 1406 | break; |
1407 | case ISDN_CMD_SETL2: | 1407 | case ISDN_CMD_SETL2: |
1408 | if (!card->flags & ICN_FLAGS_RUNNING) | 1408 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1409 | return -ENODEV; | 1409 | return -ENODEV; |
1410 | if ((c->arg & 255) < ICN_BCH) { | 1410 | if ((c->arg & 255) < ICN_BCH) { |
1411 | a = c->arg; | 1411 | a = c->arg; |
@@ -1424,7 +1424,7 @@ icn_command(isdn_ctrl * c, icn_card * card) | |||
1424 | } | 1424 | } |
1425 | break; | 1425 | break; |
1426 | case ISDN_CMD_SETL3: | 1426 | case ISDN_CMD_SETL3: |
1427 | if (!card->flags & ICN_FLAGS_RUNNING) | 1427 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1428 | return -ENODEV; | 1428 | return -ENODEV; |
1429 | return 0; | 1429 | return 0; |
1430 | default: | 1430 | default: |
@@ -1471,7 +1471,7 @@ if_writecmd(const u_char __user *buf, int len, int id, int channel) | |||
1471 | icn_card *card = icn_findcard(id); | 1471 | icn_card *card = icn_findcard(id); |
1472 | 1472 | ||
1473 | if (card) { | 1473 | if (card) { |
1474 | if (!card->flags & ICN_FLAGS_RUNNING) | 1474 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1475 | return -ENODEV; | 1475 | return -ENODEV; |
1476 | return (icn_writecmd(buf, len, 1, card)); | 1476 | return (icn_writecmd(buf, len, 1, card)); |
1477 | } | 1477 | } |
@@ -1486,7 +1486,7 @@ if_readstatus(u_char __user *buf, int len, int id, int channel) | |||
1486 | icn_card *card = icn_findcard(id); | 1486 | icn_card *card = icn_findcard(id); |
1487 | 1487 | ||
1488 | if (card) { | 1488 | if (card) { |
1489 | if (!card->flags & ICN_FLAGS_RUNNING) | 1489 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1490 | return -ENODEV; | 1490 | return -ENODEV; |
1491 | return (icn_readstatus(buf, len, card)); | 1491 | return (icn_readstatus(buf, len, card)); |
1492 | } | 1492 | } |
@@ -1501,7 +1501,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) | |||
1501 | icn_card *card = icn_findcard(id); | 1501 | icn_card *card = icn_findcard(id); |
1502 | 1502 | ||
1503 | if (card) { | 1503 | if (card) { |
1504 | if (!card->flags & ICN_FLAGS_RUNNING) | 1504 | if (!(card->flags & ICN_FLAGS_RUNNING)) |
1505 | return -ENODEV; | 1505 | return -ENODEV; |
1506 | return (icn_sendbuf(channel, ack, skb, card)); | 1506 | return (icn_sendbuf(channel, ack, skb, card)); |
1507 | } | 1507 | } |
diff --git a/drivers/isdn/isdnloop/isdnloop.c b/drivers/isdn/isdnloop/isdnloop.c index bb92e3cd9334..655ef9a3f4df 100644 --- a/drivers/isdn/isdnloop/isdnloop.c +++ b/drivers/isdn/isdnloop/isdnloop.c | |||
@@ -1184,7 +1184,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1184 | } | 1184 | } |
1185 | break; | 1185 | break; |
1186 | case ISDN_CMD_DIAL: | 1186 | case ISDN_CMD_DIAL: |
1187 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1187 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1188 | return -ENODEV; | 1188 | return -ENODEV; |
1189 | if (card->leased) | 1189 | if (card->leased) |
1190 | break; | 1190 | break; |
@@ -1210,7 +1210,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1210 | } | 1210 | } |
1211 | break; | 1211 | break; |
1212 | case ISDN_CMD_ACCEPTD: | 1212 | case ISDN_CMD_ACCEPTD: |
1213 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1213 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1214 | return -ENODEV; | 1214 | return -ENODEV; |
1215 | if (c->arg < ISDNLOOP_BCH) { | 1215 | if (c->arg < ISDNLOOP_BCH) { |
1216 | a = c->arg + 1; | 1216 | a = c->arg + 1; |
@@ -1238,7 +1238,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1238 | } | 1238 | } |
1239 | break; | 1239 | break; |
1240 | case ISDN_CMD_ACCEPTB: | 1240 | case ISDN_CMD_ACCEPTB: |
1241 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1241 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1242 | return -ENODEV; | 1242 | return -ENODEV; |
1243 | if (c->arg < ISDNLOOP_BCH) { | 1243 | if (c->arg < ISDNLOOP_BCH) { |
1244 | a = c->arg + 1; | 1244 | a = c->arg + 1; |
@@ -1264,7 +1264,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1264 | i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); | 1264 | i = isdnloop_writecmd(cbuf, strlen(cbuf), 0, card); |
1265 | break; | 1265 | break; |
1266 | case ISDN_CMD_HANGUP: | 1266 | case ISDN_CMD_HANGUP: |
1267 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1267 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1268 | return -ENODEV; | 1268 | return -ENODEV; |
1269 | if (c->arg < ISDNLOOP_BCH) { | 1269 | if (c->arg < ISDNLOOP_BCH) { |
1270 | a = c->arg + 1; | 1270 | a = c->arg + 1; |
@@ -1273,7 +1273,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1273 | } | 1273 | } |
1274 | break; | 1274 | break; |
1275 | case ISDN_CMD_SETEAZ: | 1275 | case ISDN_CMD_SETEAZ: |
1276 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1276 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1277 | return -ENODEV; | 1277 | return -ENODEV; |
1278 | if (card->leased) | 1278 | if (card->leased) |
1279 | break; | 1279 | break; |
@@ -1303,7 +1303,7 @@ isdnloop_command(isdn_ctrl * c, isdnloop_card * card) | |||
1303 | } | 1303 | } |
1304 | break; | 1304 | break; |
1305 | case ISDN_CMD_SETL2: | 1305 | case ISDN_CMD_SETL2: |
1306 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1306 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1307 | return -ENODEV; | 1307 | return -ENODEV; |
1308 | if ((c->arg & 255) < ISDNLOOP_BCH) { | 1308 | if ((c->arg & 255) < ISDNLOOP_BCH) { |
1309 | a = c->arg; | 1309 | a = c->arg; |
@@ -1395,7 +1395,7 @@ if_readstatus(u_char __user *buf, int len, int id, int channel) | |||
1395 | isdnloop_card *card = isdnloop_findcard(id); | 1395 | isdnloop_card *card = isdnloop_findcard(id); |
1396 | 1396 | ||
1397 | if (card) { | 1397 | if (card) { |
1398 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1398 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1399 | return -ENODEV; | 1399 | return -ENODEV; |
1400 | return (isdnloop_readstatus(buf, len, card)); | 1400 | return (isdnloop_readstatus(buf, len, card)); |
1401 | } | 1401 | } |
@@ -1410,7 +1410,7 @@ if_sendbuf(int id, int channel, int ack, struct sk_buff *skb) | |||
1410 | isdnloop_card *card = isdnloop_findcard(id); | 1410 | isdnloop_card *card = isdnloop_findcard(id); |
1411 | 1411 | ||
1412 | if (card) { | 1412 | if (card) { |
1413 | if (!card->flags & ISDNLOOP_FLAGS_RUNNING) | 1413 | if (!(card->flags & ISDNLOOP_FLAGS_RUNNING)) |
1414 | return -ENODEV; | 1414 | return -ENODEV; |
1415 | /* ack request stored in skb scratch area */ | 1415 | /* ack request stored in skb scratch area */ |
1416 | *(skb->head) = ack; | 1416 | *(skb->head) = ack; |
diff --git a/drivers/macintosh/mediabay.c b/drivers/macintosh/mediabay.c index de9ebbfbf122..936788272a5f 100644 --- a/drivers/macintosh/mediabay.c +++ b/drivers/macintosh/mediabay.c | |||
@@ -78,12 +78,14 @@ struct media_bay_info { | |||
78 | int cached_gpio; | 78 | int cached_gpio; |
79 | int sleeping; | 79 | int sleeping; |
80 | struct semaphore lock; | 80 | struct semaphore lock; |
81 | #ifdef CONFIG_BLK_DEV_IDE | 81 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
82 | void __iomem *cd_base; | 82 | void __iomem *cd_base; |
83 | int cd_index; | ||
84 | int cd_irq; | 83 | int cd_irq; |
85 | int cd_retry; | 84 | int cd_retry; |
86 | #endif | 85 | #endif |
86 | #if defined(CONFIG_BLK_DEV_IDE_PMAC) || defined(CONFIG_MAC_FLOPPY) | ||
87 | int cd_index; | ||
88 | #endif | ||
87 | }; | 89 | }; |
88 | 90 | ||
89 | #define MAX_BAYS 2 | 91 | #define MAX_BAYS 2 |
@@ -91,7 +93,7 @@ struct media_bay_info { | |||
91 | static struct media_bay_info media_bays[MAX_BAYS]; | 93 | static struct media_bay_info media_bays[MAX_BAYS]; |
92 | int media_bay_count = 0; | 94 | int media_bay_count = 0; |
93 | 95 | ||
94 | #ifdef CONFIG_BLK_DEV_IDE | 96 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
95 | /* check the busy bit in the media-bay ide interface | 97 | /* check the busy bit in the media-bay ide interface |
96 | (assumes the media-bay contains an ide device) */ | 98 | (assumes the media-bay contains an ide device) */ |
97 | #define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0) | 99 | #define MB_IDE_READY(i) ((readb(media_bays[i].cd_base + 0x70) & 0x80) == 0) |
@@ -401,7 +403,7 @@ static void poll_media_bay(struct media_bay_info* bay) | |||
401 | set_mb_power(bay, id != MB_NO); | 403 | set_mb_power(bay, id != MB_NO); |
402 | bay->content_id = id; | 404 | bay->content_id = id; |
403 | if (id == MB_NO) { | 405 | if (id == MB_NO) { |
404 | #ifdef CONFIG_BLK_DEV_IDE | 406 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
405 | bay->cd_retry = 0; | 407 | bay->cd_retry = 0; |
406 | #endif | 408 | #endif |
407 | printk(KERN_INFO "media bay %d is empty\n", bay->index); | 409 | printk(KERN_INFO "media bay %d is empty\n", bay->index); |
@@ -414,9 +416,9 @@ static void poll_media_bay(struct media_bay_info* bay) | |||
414 | } | 416 | } |
415 | } | 417 | } |
416 | 418 | ||
419 | #ifdef CONFIG_MAC_FLOPPY | ||
417 | int check_media_bay(struct device_node *which_bay, int what) | 420 | int check_media_bay(struct device_node *which_bay, int what) |
418 | { | 421 | { |
419 | #ifdef CONFIG_BLK_DEV_IDE | ||
420 | int i; | 422 | int i; |
421 | 423 | ||
422 | for (i=0; i<media_bay_count; i++) | 424 | for (i=0; i<media_bay_count; i++) |
@@ -426,14 +428,14 @@ int check_media_bay(struct device_node *which_bay, int what) | |||
426 | media_bays[i].cd_index = -1; | 428 | media_bays[i].cd_index = -1; |
427 | return -EINVAL; | 429 | return -EINVAL; |
428 | } | 430 | } |
429 | #endif /* CONFIG_BLK_DEV_IDE */ | ||
430 | return -ENODEV; | 431 | return -ENODEV; |
431 | } | 432 | } |
432 | EXPORT_SYMBOL(check_media_bay); | 433 | EXPORT_SYMBOL(check_media_bay); |
434 | #endif /* CONFIG_MAC_FLOPPY */ | ||
433 | 435 | ||
436 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | ||
434 | int check_media_bay_by_base(unsigned long base, int what) | 437 | int check_media_bay_by_base(unsigned long base, int what) |
435 | { | 438 | { |
436 | #ifdef CONFIG_BLK_DEV_IDE | ||
437 | int i; | 439 | int i; |
438 | 440 | ||
439 | for (i=0; i<media_bay_count; i++) | 441 | for (i=0; i<media_bay_count; i++) |
@@ -443,15 +445,13 @@ int check_media_bay_by_base(unsigned long base, int what) | |||
443 | media_bays[i].cd_index = -1; | 445 | media_bays[i].cd_index = -1; |
444 | return -EINVAL; | 446 | return -EINVAL; |
445 | } | 447 | } |
446 | #endif | 448 | |
447 | |||
448 | return -ENODEV; | 449 | return -ENODEV; |
449 | } | 450 | } |
450 | 451 | ||
451 | int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, | 452 | int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, |
452 | int irq, int index) | 453 | int irq, int index) |
453 | { | 454 | { |
454 | #ifdef CONFIG_BLK_DEV_IDE | ||
455 | int i; | 455 | int i; |
456 | 456 | ||
457 | for (i=0; i<media_bay_count; i++) { | 457 | for (i=0; i<media_bay_count; i++) { |
@@ -483,10 +483,10 @@ int media_bay_set_ide_infos(struct device_node* which_bay, unsigned long base, | |||
483 | return -ENODEV; | 483 | return -ENODEV; |
484 | } | 484 | } |
485 | } | 485 | } |
486 | #endif /* CONFIG_BLK_DEV_IDE */ | 486 | |
487 | |||
488 | return -ENODEV; | 487 | return -ENODEV; |
489 | } | 488 | } |
489 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ | ||
490 | 490 | ||
491 | static void media_bay_step(int i) | 491 | static void media_bay_step(int i) |
492 | { | 492 | { |
@@ -521,14 +521,13 @@ static void media_bay_step(int i) | |||
521 | bay->state = mb_resetting; | 521 | bay->state = mb_resetting; |
522 | MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id); | 522 | MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id); |
523 | break; | 523 | break; |
524 | |||
525 | case mb_resetting: | 524 | case mb_resetting: |
526 | if (bay->content_id != MB_CD) { | 525 | if (bay->content_id != MB_CD) { |
527 | MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); | 526 | MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id); |
528 | bay->state = mb_up; | 527 | bay->state = mb_up; |
529 | break; | 528 | break; |
530 | } | 529 | } |
531 | #ifdef CONFIG_BLK_DEV_IDE | 530 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
532 | MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); | 531 | MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id); |
533 | bay->ops->un_reset_ide(bay); | 532 | bay->ops->un_reset_ide(bay); |
534 | bay->timer = msecs_to_jiffies(MB_IDE_WAIT); | 533 | bay->timer = msecs_to_jiffies(MB_IDE_WAIT); |
@@ -536,16 +535,14 @@ static void media_bay_step(int i) | |||
536 | #else | 535 | #else |
537 | printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i); | 536 | printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i); |
538 | set_mb_power(bay, 0); | 537 | set_mb_power(bay, 0); |
539 | #endif /* CONFIG_BLK_DEV_IDE */ | 538 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
540 | break; | 539 | break; |
541 | 540 | #ifdef CONFIG_BLK_DEV_IDE_PMAC | |
542 | #ifdef CONFIG_BLK_DEV_IDE | ||
543 | case mb_ide_resetting: | 541 | case mb_ide_resetting: |
544 | bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT); | 542 | bay->timer = msecs_to_jiffies(MB_IDE_TIMEOUT); |
545 | bay->state = mb_ide_waiting; | 543 | bay->state = mb_ide_waiting; |
546 | MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id); | 544 | MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id); |
547 | break; | 545 | break; |
548 | |||
549 | case mb_ide_waiting: | 546 | case mb_ide_waiting: |
550 | if (bay->cd_base == NULL) { | 547 | if (bay->cd_base == NULL) { |
551 | bay->timer = 0; | 548 | bay->timer = 0; |
@@ -587,11 +584,10 @@ static void media_bay_step(int i) | |||
587 | bay->timer = 0; | 584 | bay->timer = 0; |
588 | } | 585 | } |
589 | break; | 586 | break; |
590 | #endif /* CONFIG_BLK_DEV_IDE */ | 587 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
591 | |||
592 | case mb_powering_down: | 588 | case mb_powering_down: |
593 | bay->state = mb_empty; | 589 | bay->state = mb_empty; |
594 | #ifdef CONFIG_BLK_DEV_IDE | 590 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
595 | if (bay->cd_index >= 0) { | 591 | if (bay->cd_index >= 0) { |
596 | printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, | 592 | printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, |
597 | bay->cd_index); | 593 | bay->cd_index); |
@@ -607,7 +603,7 @@ static void media_bay_step(int i) | |||
607 | bay->content_id = MB_NO; | 603 | bay->content_id = MB_NO; |
608 | } | 604 | } |
609 | } | 605 | } |
610 | #endif /* CONFIG_BLK_DEV_IDE */ | 606 | #endif /* CONFIG_BLK_DEV_IDE_PMAC */ |
611 | MBDBG("mediabay%d: end of power down\n", i); | 607 | MBDBG("mediabay%d: end of power down\n", i); |
612 | break; | 608 | break; |
613 | } | 609 | } |
@@ -739,7 +735,7 @@ static int media_bay_resume(struct macio_dev *mdev) | |||
739 | bay->last_value = bay->content_id; | 735 | bay->last_value = bay->content_id; |
740 | bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); | 736 | bay->value_count = msecs_to_jiffies(MB_STABLE_DELAY); |
741 | bay->timer = msecs_to_jiffies(MB_POWER_DELAY); | 737 | bay->timer = msecs_to_jiffies(MB_POWER_DELAY); |
742 | #ifdef CONFIG_BLK_DEV_IDE | 738 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
743 | bay->cd_retry = 0; | 739 | bay->cd_retry = 0; |
744 | #endif | 740 | #endif |
745 | do { | 741 | do { |
@@ -829,7 +825,7 @@ static int __init media_bay_init(void) | |||
829 | for (i=0; i<MAX_BAYS; i++) { | 825 | for (i=0; i<MAX_BAYS; i++) { |
830 | memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info)); | 826 | memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info)); |
831 | media_bays[i].content_id = -1; | 827 | media_bays[i].content_id = -1; |
832 | #ifdef CONFIG_BLK_DEV_IDE | 828 | #ifdef CONFIG_BLK_DEV_IDE_PMAC |
833 | media_bays[i].cd_index = -1; | 829 | media_bays[i].cd_index = -1; |
834 | #endif | 830 | #endif |
835 | } | 831 | } |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 1b1ef3130e6e..a0585fb6da94 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -237,7 +237,7 @@ static struct page *read_sb_page(mddev_t *mddev, long offset, unsigned long inde | |||
237 | if (!page) | 237 | if (!page) |
238 | return ERR_PTR(-ENOMEM); | 238 | return ERR_PTR(-ENOMEM); |
239 | 239 | ||
240 | ITERATE_RDEV(mddev, rdev, tmp) { | 240 | rdev_for_each(rdev, tmp, mddev) { |
241 | if (! test_bit(In_sync, &rdev->flags) | 241 | if (! test_bit(In_sync, &rdev->flags) |
242 | || test_bit(Faulty, &rdev->flags)) | 242 | || test_bit(Faulty, &rdev->flags)) |
243 | continue; | 243 | continue; |
@@ -261,7 +261,7 @@ static int write_sb_page(struct bitmap *bitmap, struct page *page, int wait) | |||
261 | struct list_head *tmp; | 261 | struct list_head *tmp; |
262 | mddev_t *mddev = bitmap->mddev; | 262 | mddev_t *mddev = bitmap->mddev; |
263 | 263 | ||
264 | ITERATE_RDEV(mddev, rdev, tmp) | 264 | rdev_for_each(rdev, tmp, mddev) |
265 | if (test_bit(In_sync, &rdev->flags) | 265 | if (test_bit(In_sync, &rdev->flags) |
266 | && !test_bit(Faulty, &rdev->flags)) { | 266 | && !test_bit(Faulty, &rdev->flags)) { |
267 | int size = PAGE_SIZE; | 267 | int size = PAGE_SIZE; |
@@ -1348,14 +1348,38 @@ void bitmap_close_sync(struct bitmap *bitmap) | |||
1348 | */ | 1348 | */ |
1349 | sector_t sector = 0; | 1349 | sector_t sector = 0; |
1350 | int blocks; | 1350 | int blocks; |
1351 | if (!bitmap) return; | 1351 | if (!bitmap) |
1352 | return; | ||
1352 | while (sector < bitmap->mddev->resync_max_sectors) { | 1353 | while (sector < bitmap->mddev->resync_max_sectors) { |
1353 | bitmap_end_sync(bitmap, sector, &blocks, 0); | 1354 | bitmap_end_sync(bitmap, sector, &blocks, 0); |
1354 | /* | 1355 | sector += blocks; |
1355 | if (sector < 500) printk("bitmap_close_sync: sec %llu blks %d\n", | 1356 | } |
1356 | (unsigned long long)sector, blocks); | 1357 | } |
1357 | */ sector += blocks; | 1358 | |
1359 | void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector) | ||
1360 | { | ||
1361 | sector_t s = 0; | ||
1362 | int blocks; | ||
1363 | |||
1364 | if (!bitmap) | ||
1365 | return; | ||
1366 | if (sector == 0) { | ||
1367 | bitmap->last_end_sync = jiffies; | ||
1368 | return; | ||
1369 | } | ||
1370 | if (time_before(jiffies, (bitmap->last_end_sync | ||
1371 | + bitmap->daemon_sleep * HZ))) | ||
1372 | return; | ||
1373 | wait_event(bitmap->mddev->recovery_wait, | ||
1374 | atomic_read(&bitmap->mddev->recovery_active) == 0); | ||
1375 | |||
1376 | sector &= ~((1ULL << CHUNK_BLOCK_SHIFT(bitmap)) - 1); | ||
1377 | s = 0; | ||
1378 | while (s < sector && s < bitmap->mddev->resync_max_sectors) { | ||
1379 | bitmap_end_sync(bitmap, s, &blocks, 0); | ||
1380 | s += blocks; | ||
1358 | } | 1381 | } |
1382 | bitmap->last_end_sync = jiffies; | ||
1359 | } | 1383 | } |
1360 | 1384 | ||
1361 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) | 1385 | static void bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed) |
@@ -1565,3 +1589,4 @@ EXPORT_SYMBOL(bitmap_start_sync); | |||
1565 | EXPORT_SYMBOL(bitmap_end_sync); | 1589 | EXPORT_SYMBOL(bitmap_end_sync); |
1566 | EXPORT_SYMBOL(bitmap_unplug); | 1590 | EXPORT_SYMBOL(bitmap_unplug); |
1567 | EXPORT_SYMBOL(bitmap_close_sync); | 1591 | EXPORT_SYMBOL(bitmap_close_sync); |
1592 | EXPORT_SYMBOL(bitmap_cond_end_sync); | ||
diff --git a/drivers/md/faulty.c b/drivers/md/faulty.c index cf2ddce34118..d107ddceefcd 100644 --- a/drivers/md/faulty.c +++ b/drivers/md/faulty.c | |||
@@ -294,7 +294,7 @@ static int run(mddev_t *mddev) | |||
294 | } | 294 | } |
295 | conf->nfaults = 0; | 295 | conf->nfaults = 0; |
296 | 296 | ||
297 | ITERATE_RDEV(mddev, rdev, tmp) | 297 | rdev_for_each(rdev, tmp, mddev) |
298 | conf->rdev = rdev; | 298 | conf->rdev = rdev; |
299 | 299 | ||
300 | mddev->array_size = mddev->size; | 300 | mddev->array_size = mddev->size; |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 3dac1cfb8189..0b8511776b3e 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -122,7 +122,7 @@ static linear_conf_t *linear_conf(mddev_t *mddev, int raid_disks) | |||
122 | cnt = 0; | 122 | cnt = 0; |
123 | conf->array_size = 0; | 123 | conf->array_size = 0; |
124 | 124 | ||
125 | ITERATE_RDEV(mddev,rdev,tmp) { | 125 | rdev_for_each(rdev, tmp, mddev) { |
126 | int j = rdev->raid_disk; | 126 | int j = rdev->raid_disk; |
127 | dev_info_t *disk = conf->disks + j; | 127 | dev_info_t *disk = conf->disks + j; |
128 | 128 | ||
diff --git a/drivers/md/md.c b/drivers/md/md.c index c28a120b4161..5fc326d3970e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -195,7 +195,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock); | |||
195 | * Any code which breaks out of this loop while own | 195 | * Any code which breaks out of this loop while own |
196 | * a reference to the current mddev and must mddev_put it. | 196 | * a reference to the current mddev and must mddev_put it. |
197 | */ | 197 | */ |
198 | #define ITERATE_MDDEV(mddev,tmp) \ | 198 | #define for_each_mddev(mddev,tmp) \ |
199 | \ | 199 | \ |
200 | for (({ spin_lock(&all_mddevs_lock); \ | 200 | for (({ spin_lock(&all_mddevs_lock); \ |
201 | tmp = all_mddevs.next; \ | 201 | tmp = all_mddevs.next; \ |
@@ -275,6 +275,7 @@ static mddev_t * mddev_find(dev_t unit) | |||
275 | spin_lock_init(&new->write_lock); | 275 | spin_lock_init(&new->write_lock); |
276 | init_waitqueue_head(&new->sb_wait); | 276 | init_waitqueue_head(&new->sb_wait); |
277 | new->reshape_position = MaxSector; | 277 | new->reshape_position = MaxSector; |
278 | new->resync_max = MaxSector; | ||
278 | 279 | ||
279 | new->queue = blk_alloc_queue(GFP_KERNEL); | 280 | new->queue = blk_alloc_queue(GFP_KERNEL); |
280 | if (!new->queue) { | 281 | if (!new->queue) { |
@@ -310,7 +311,7 @@ static mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) | |||
310 | mdk_rdev_t * rdev; | 311 | mdk_rdev_t * rdev; |
311 | struct list_head *tmp; | 312 | struct list_head *tmp; |
312 | 313 | ||
313 | ITERATE_RDEV(mddev,rdev,tmp) { | 314 | rdev_for_each(rdev, tmp, mddev) { |
314 | if (rdev->desc_nr == nr) | 315 | if (rdev->desc_nr == nr) |
315 | return rdev; | 316 | return rdev; |
316 | } | 317 | } |
@@ -322,7 +323,7 @@ static mdk_rdev_t * find_rdev(mddev_t * mddev, dev_t dev) | |||
322 | struct list_head *tmp; | 323 | struct list_head *tmp; |
323 | mdk_rdev_t *rdev; | 324 | mdk_rdev_t *rdev; |
324 | 325 | ||
325 | ITERATE_RDEV(mddev,rdev,tmp) { | 326 | rdev_for_each(rdev, tmp, mddev) { |
326 | if (rdev->bdev->bd_dev == dev) | 327 | if (rdev->bdev->bd_dev == dev) |
327 | return rdev; | 328 | return rdev; |
328 | } | 329 | } |
@@ -773,12 +774,16 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
773 | __u64 ev1 = md_event(sb); | 774 | __u64 ev1 = md_event(sb); |
774 | 775 | ||
775 | rdev->raid_disk = -1; | 776 | rdev->raid_disk = -1; |
776 | rdev->flags = 0; | 777 | clear_bit(Faulty, &rdev->flags); |
778 | clear_bit(In_sync, &rdev->flags); | ||
779 | clear_bit(WriteMostly, &rdev->flags); | ||
780 | clear_bit(BarriersNotsupp, &rdev->flags); | ||
781 | |||
777 | if (mddev->raid_disks == 0) { | 782 | if (mddev->raid_disks == 0) { |
778 | mddev->major_version = 0; | 783 | mddev->major_version = 0; |
779 | mddev->minor_version = sb->minor_version; | 784 | mddev->minor_version = sb->minor_version; |
780 | mddev->patch_version = sb->patch_version; | 785 | mddev->patch_version = sb->patch_version; |
781 | mddev->persistent = ! sb->not_persistent; | 786 | mddev->external = 0; |
782 | mddev->chunk_size = sb->chunk_size; | 787 | mddev->chunk_size = sb->chunk_size; |
783 | mddev->ctime = sb->ctime; | 788 | mddev->ctime = sb->ctime; |
784 | mddev->utime = sb->utime; | 789 | mddev->utime = sb->utime; |
@@ -904,7 +909,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
904 | sb->size = mddev->size; | 909 | sb->size = mddev->size; |
905 | sb->raid_disks = mddev->raid_disks; | 910 | sb->raid_disks = mddev->raid_disks; |
906 | sb->md_minor = mddev->md_minor; | 911 | sb->md_minor = mddev->md_minor; |
907 | sb->not_persistent = !mddev->persistent; | 912 | sb->not_persistent = 0; |
908 | sb->utime = mddev->utime; | 913 | sb->utime = mddev->utime; |
909 | sb->state = 0; | 914 | sb->state = 0; |
910 | sb->events_hi = (mddev->events>>32); | 915 | sb->events_hi = (mddev->events>>32); |
@@ -938,7 +943,7 @@ static void super_90_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
938 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); | 943 | sb->state |= (1<<MD_SB_BITMAP_PRESENT); |
939 | 944 | ||
940 | sb->disks[0].state = (1<<MD_DISK_REMOVED); | 945 | sb->disks[0].state = (1<<MD_DISK_REMOVED); |
941 | ITERATE_RDEV(mddev,rdev2,tmp) { | 946 | rdev_for_each(rdev2, tmp, mddev) { |
942 | mdp_disk_t *d; | 947 | mdp_disk_t *d; |
943 | int desc_nr; | 948 | int desc_nr; |
944 | if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags) | 949 | if (rdev2->raid_disk >= 0 && test_bit(In_sync, &rdev2->flags) |
@@ -1153,11 +1158,15 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1153 | __u64 ev1 = le64_to_cpu(sb->events); | 1158 | __u64 ev1 = le64_to_cpu(sb->events); |
1154 | 1159 | ||
1155 | rdev->raid_disk = -1; | 1160 | rdev->raid_disk = -1; |
1156 | rdev->flags = 0; | 1161 | clear_bit(Faulty, &rdev->flags); |
1162 | clear_bit(In_sync, &rdev->flags); | ||
1163 | clear_bit(WriteMostly, &rdev->flags); | ||
1164 | clear_bit(BarriersNotsupp, &rdev->flags); | ||
1165 | |||
1157 | if (mddev->raid_disks == 0) { | 1166 | if (mddev->raid_disks == 0) { |
1158 | mddev->major_version = 1; | 1167 | mddev->major_version = 1; |
1159 | mddev->patch_version = 0; | 1168 | mddev->patch_version = 0; |
1160 | mddev->persistent = 1; | 1169 | mddev->external = 0; |
1161 | mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9; | 1170 | mddev->chunk_size = le32_to_cpu(sb->chunksize) << 9; |
1162 | mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); | 1171 | mddev->ctime = le64_to_cpu(sb->ctime) & ((1ULL << 32)-1); |
1163 | mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); | 1172 | mddev->utime = le64_to_cpu(sb->utime) & ((1ULL << 32)-1); |
@@ -1286,7 +1295,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1286 | } | 1295 | } |
1287 | 1296 | ||
1288 | max_dev = 0; | 1297 | max_dev = 0; |
1289 | ITERATE_RDEV(mddev,rdev2,tmp) | 1298 | rdev_for_each(rdev2, tmp, mddev) |
1290 | if (rdev2->desc_nr+1 > max_dev) | 1299 | if (rdev2->desc_nr+1 > max_dev) |
1291 | max_dev = rdev2->desc_nr+1; | 1300 | max_dev = rdev2->desc_nr+1; |
1292 | 1301 | ||
@@ -1295,7 +1304,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
1295 | for (i=0; i<max_dev;i++) | 1304 | for (i=0; i<max_dev;i++) |
1296 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1305 | sb->dev_roles[i] = cpu_to_le16(0xfffe); |
1297 | 1306 | ||
1298 | ITERATE_RDEV(mddev,rdev2,tmp) { | 1307 | rdev_for_each(rdev2, tmp, mddev) { |
1299 | i = rdev2->desc_nr; | 1308 | i = rdev2->desc_nr; |
1300 | if (test_bit(Faulty, &rdev2->flags)) | 1309 | if (test_bit(Faulty, &rdev2->flags)) |
1301 | sb->dev_roles[i] = cpu_to_le16(0xfffe); | 1310 | sb->dev_roles[i] = cpu_to_le16(0xfffe); |
@@ -1333,8 +1342,8 @@ static int match_mddev_units(mddev_t *mddev1, mddev_t *mddev2) | |||
1333 | struct list_head *tmp, *tmp2; | 1342 | struct list_head *tmp, *tmp2; |
1334 | mdk_rdev_t *rdev, *rdev2; | 1343 | mdk_rdev_t *rdev, *rdev2; |
1335 | 1344 | ||
1336 | ITERATE_RDEV(mddev1,rdev,tmp) | 1345 | rdev_for_each(rdev, tmp, mddev1) |
1337 | ITERATE_RDEV(mddev2, rdev2, tmp2) | 1346 | rdev_for_each(rdev2, tmp2, mddev2) |
1338 | if (rdev->bdev->bd_contains == | 1347 | if (rdev->bdev->bd_contains == |
1339 | rdev2->bdev->bd_contains) | 1348 | rdev2->bdev->bd_contains) |
1340 | return 1; | 1349 | return 1; |
@@ -1401,7 +1410,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1401 | goto fail; | 1410 | goto fail; |
1402 | } | 1411 | } |
1403 | list_add(&rdev->same_set, &mddev->disks); | 1412 | list_add(&rdev->same_set, &mddev->disks); |
1404 | bd_claim_by_disk(rdev->bdev, rdev, mddev->gendisk); | 1413 | bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); |
1405 | return 0; | 1414 | return 0; |
1406 | 1415 | ||
1407 | fail: | 1416 | fail: |
@@ -1410,10 +1419,11 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) | |||
1410 | return err; | 1419 | return err; |
1411 | } | 1420 | } |
1412 | 1421 | ||
1413 | static void delayed_delete(struct work_struct *ws) | 1422 | static void md_delayed_delete(struct work_struct *ws) |
1414 | { | 1423 | { |
1415 | mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work); | 1424 | mdk_rdev_t *rdev = container_of(ws, mdk_rdev_t, del_work); |
1416 | kobject_del(&rdev->kobj); | 1425 | kobject_del(&rdev->kobj); |
1426 | kobject_put(&rdev->kobj); | ||
1417 | } | 1427 | } |
1418 | 1428 | ||
1419 | static void unbind_rdev_from_array(mdk_rdev_t * rdev) | 1429 | static void unbind_rdev_from_array(mdk_rdev_t * rdev) |
@@ -1432,7 +1442,8 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1432 | /* We need to delay this, otherwise we can deadlock when | 1442 | /* We need to delay this, otherwise we can deadlock when |
1433 | * writing to 'remove' to "dev/state" | 1443 | * writing to 'remove' to "dev/state" |
1434 | */ | 1444 | */ |
1435 | INIT_WORK(&rdev->del_work, delayed_delete); | 1445 | INIT_WORK(&rdev->del_work, md_delayed_delete); |
1446 | kobject_get(&rdev->kobj); | ||
1436 | schedule_work(&rdev->del_work); | 1447 | schedule_work(&rdev->del_work); |
1437 | } | 1448 | } |
1438 | 1449 | ||
@@ -1441,7 +1452,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) | |||
1441 | * otherwise reused by a RAID array (or any other kernel | 1452 | * otherwise reused by a RAID array (or any other kernel |
1442 | * subsystem), by bd_claiming the device. | 1453 | * subsystem), by bd_claiming the device. |
1443 | */ | 1454 | */ |
1444 | static int lock_rdev(mdk_rdev_t *rdev, dev_t dev) | 1455 | static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) |
1445 | { | 1456 | { |
1446 | int err = 0; | 1457 | int err = 0; |
1447 | struct block_device *bdev; | 1458 | struct block_device *bdev; |
@@ -1453,13 +1464,15 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev) | |||
1453 | __bdevname(dev, b)); | 1464 | __bdevname(dev, b)); |
1454 | return PTR_ERR(bdev); | 1465 | return PTR_ERR(bdev); |
1455 | } | 1466 | } |
1456 | err = bd_claim(bdev, rdev); | 1467 | err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev); |
1457 | if (err) { | 1468 | if (err) { |
1458 | printk(KERN_ERR "md: could not bd_claim %s.\n", | 1469 | printk(KERN_ERR "md: could not bd_claim %s.\n", |
1459 | bdevname(bdev, b)); | 1470 | bdevname(bdev, b)); |
1460 | blkdev_put(bdev); | 1471 | blkdev_put(bdev); |
1461 | return err; | 1472 | return err; |
1462 | } | 1473 | } |
1474 | if (!shared) | ||
1475 | set_bit(AllReserved, &rdev->flags); | ||
1463 | rdev->bdev = bdev; | 1476 | rdev->bdev = bdev; |
1464 | return err; | 1477 | return err; |
1465 | } | 1478 | } |
@@ -1503,7 +1516,7 @@ static void export_array(mddev_t *mddev) | |||
1503 | struct list_head *tmp; | 1516 | struct list_head *tmp; |
1504 | mdk_rdev_t *rdev; | 1517 | mdk_rdev_t *rdev; |
1505 | 1518 | ||
1506 | ITERATE_RDEV(mddev,rdev,tmp) { | 1519 | rdev_for_each(rdev, tmp, mddev) { |
1507 | if (!rdev->mddev) { | 1520 | if (!rdev->mddev) { |
1508 | MD_BUG(); | 1521 | MD_BUG(); |
1509 | continue; | 1522 | continue; |
@@ -1581,17 +1594,17 @@ static void md_print_devices(void) | |||
1581 | printk("md: **********************************\n"); | 1594 | printk("md: **********************************\n"); |
1582 | printk("md: * <COMPLETE RAID STATE PRINTOUT> *\n"); | 1595 | printk("md: * <COMPLETE RAID STATE PRINTOUT> *\n"); |
1583 | printk("md: **********************************\n"); | 1596 | printk("md: **********************************\n"); |
1584 | ITERATE_MDDEV(mddev,tmp) { | 1597 | for_each_mddev(mddev, tmp) { |
1585 | 1598 | ||
1586 | if (mddev->bitmap) | 1599 | if (mddev->bitmap) |
1587 | bitmap_print_sb(mddev->bitmap); | 1600 | bitmap_print_sb(mddev->bitmap); |
1588 | else | 1601 | else |
1589 | printk("%s: ", mdname(mddev)); | 1602 | printk("%s: ", mdname(mddev)); |
1590 | ITERATE_RDEV(mddev,rdev,tmp2) | 1603 | rdev_for_each(rdev, tmp2, mddev) |
1591 | printk("<%s>", bdevname(rdev->bdev,b)); | 1604 | printk("<%s>", bdevname(rdev->bdev,b)); |
1592 | printk("\n"); | 1605 | printk("\n"); |
1593 | 1606 | ||
1594 | ITERATE_RDEV(mddev,rdev,tmp2) | 1607 | rdev_for_each(rdev, tmp2, mddev) |
1595 | print_rdev(rdev); | 1608 | print_rdev(rdev); |
1596 | } | 1609 | } |
1597 | printk("md: **********************************\n"); | 1610 | printk("md: **********************************\n"); |
@@ -1610,7 +1623,7 @@ static void sync_sbs(mddev_t * mddev, int nospares) | |||
1610 | mdk_rdev_t *rdev; | 1623 | mdk_rdev_t *rdev; |
1611 | struct list_head *tmp; | 1624 | struct list_head *tmp; |
1612 | 1625 | ||
1613 | ITERATE_RDEV(mddev,rdev,tmp) { | 1626 | rdev_for_each(rdev, tmp, mddev) { |
1614 | if (rdev->sb_events == mddev->events || | 1627 | if (rdev->sb_events == mddev->events || |
1615 | (nospares && | 1628 | (nospares && |
1616 | rdev->raid_disk < 0 && | 1629 | rdev->raid_disk < 0 && |
@@ -1696,18 +1709,20 @@ repeat: | |||
1696 | MD_BUG(); | 1709 | MD_BUG(); |
1697 | mddev->events --; | 1710 | mddev->events --; |
1698 | } | 1711 | } |
1699 | sync_sbs(mddev, nospares); | ||
1700 | 1712 | ||
1701 | /* | 1713 | /* |
1702 | * do not write anything to disk if using | 1714 | * do not write anything to disk if using |
1703 | * nonpersistent superblocks | 1715 | * nonpersistent superblocks |
1704 | */ | 1716 | */ |
1705 | if (!mddev->persistent) { | 1717 | if (!mddev->persistent) { |
1706 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | 1718 | if (!mddev->external) |
1719 | clear_bit(MD_CHANGE_PENDING, &mddev->flags); | ||
1720 | |||
1707 | spin_unlock_irq(&mddev->write_lock); | 1721 | spin_unlock_irq(&mddev->write_lock); |
1708 | wake_up(&mddev->sb_wait); | 1722 | wake_up(&mddev->sb_wait); |
1709 | return; | 1723 | return; |
1710 | } | 1724 | } |
1725 | sync_sbs(mddev, nospares); | ||
1711 | spin_unlock_irq(&mddev->write_lock); | 1726 | spin_unlock_irq(&mddev->write_lock); |
1712 | 1727 | ||
1713 | dprintk(KERN_INFO | 1728 | dprintk(KERN_INFO |
@@ -1715,7 +1730,7 @@ repeat: | |||
1715 | mdname(mddev),mddev->in_sync); | 1730 | mdname(mddev),mddev->in_sync); |
1716 | 1731 | ||
1717 | bitmap_update_sb(mddev->bitmap); | 1732 | bitmap_update_sb(mddev->bitmap); |
1718 | ITERATE_RDEV(mddev,rdev,tmp) { | 1733 | rdev_for_each(rdev, tmp, mddev) { |
1719 | char b[BDEVNAME_SIZE]; | 1734 | char b[BDEVNAME_SIZE]; |
1720 | dprintk(KERN_INFO "md: "); | 1735 | dprintk(KERN_INFO "md: "); |
1721 | if (rdev->sb_loaded != 1) | 1736 | if (rdev->sb_loaded != 1) |
@@ -1785,7 +1800,7 @@ static ssize_t | |||
1785 | state_show(mdk_rdev_t *rdev, char *page) | 1800 | state_show(mdk_rdev_t *rdev, char *page) |
1786 | { | 1801 | { |
1787 | char *sep = ""; | 1802 | char *sep = ""; |
1788 | int len=0; | 1803 | size_t len = 0; |
1789 | 1804 | ||
1790 | if (test_bit(Faulty, &rdev->flags)) { | 1805 | if (test_bit(Faulty, &rdev->flags)) { |
1791 | len+= sprintf(page+len, "%sfaulty",sep); | 1806 | len+= sprintf(page+len, "%sfaulty",sep); |
@@ -1887,20 +1902,45 @@ static ssize_t | |||
1887 | slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) | 1902 | slot_store(mdk_rdev_t *rdev, const char *buf, size_t len) |
1888 | { | 1903 | { |
1889 | char *e; | 1904 | char *e; |
1905 | int err; | ||
1906 | char nm[20]; | ||
1890 | int slot = simple_strtoul(buf, &e, 10); | 1907 | int slot = simple_strtoul(buf, &e, 10); |
1891 | if (strncmp(buf, "none", 4)==0) | 1908 | if (strncmp(buf, "none", 4)==0) |
1892 | slot = -1; | 1909 | slot = -1; |
1893 | else if (e==buf || (*e && *e!= '\n')) | 1910 | else if (e==buf || (*e && *e!= '\n')) |
1894 | return -EINVAL; | 1911 | return -EINVAL; |
1895 | if (rdev->mddev->pers) | 1912 | if (rdev->mddev->pers) { |
1896 | /* Cannot set slot in active array (yet) */ | 1913 | /* Setting 'slot' on an active array requires also |
1897 | return -EBUSY; | 1914 | * updating the 'rd%d' link, and communicating |
1898 | if (slot >= rdev->mddev->raid_disks) | 1915 | * with the personality with ->hot_*_disk. |
1899 | return -ENOSPC; | 1916 | * For now we only support removing |
1900 | rdev->raid_disk = slot; | 1917 | * failed/spare devices. This normally happens automatically, |
1901 | /* assume it is working */ | 1918 | * but not when the metadata is externally managed. |
1902 | rdev->flags = 0; | 1919 | */ |
1903 | set_bit(In_sync, &rdev->flags); | 1920 | if (slot != -1) |
1921 | return -EBUSY; | ||
1922 | if (rdev->raid_disk == -1) | ||
1923 | return -EEXIST; | ||
1924 | /* personality does all needed checks */ | ||
1925 | if (rdev->mddev->pers->hot_add_disk == NULL) | ||
1926 | return -EINVAL; | ||
1927 | err = rdev->mddev->pers-> | ||
1928 | hot_remove_disk(rdev->mddev, rdev->raid_disk); | ||
1929 | if (err) | ||
1930 | return err; | ||
1931 | sprintf(nm, "rd%d", rdev->raid_disk); | ||
1932 | sysfs_remove_link(&rdev->mddev->kobj, nm); | ||
1933 | set_bit(MD_RECOVERY_NEEDED, &rdev->mddev->recovery); | ||
1934 | md_wakeup_thread(rdev->mddev->thread); | ||
1935 | } else { | ||
1936 | if (slot >= rdev->mddev->raid_disks) | ||
1937 | return -ENOSPC; | ||
1938 | rdev->raid_disk = slot; | ||
1939 | /* assume it is working */ | ||
1940 | clear_bit(Faulty, &rdev->flags); | ||
1941 | clear_bit(WriteMostly, &rdev->flags); | ||
1942 | set_bit(In_sync, &rdev->flags); | ||
1943 | } | ||
1904 | return len; | 1944 | return len; |
1905 | } | 1945 | } |
1906 | 1946 | ||
@@ -1923,6 +1963,10 @@ offset_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
1923 | return -EINVAL; | 1963 | return -EINVAL; |
1924 | if (rdev->mddev->pers) | 1964 | if (rdev->mddev->pers) |
1925 | return -EBUSY; | 1965 | return -EBUSY; |
1966 | if (rdev->size && rdev->mddev->external) | ||
1967 | /* Must set offset before size, so overlap checks | ||
1968 | * can be sane */ | ||
1969 | return -EBUSY; | ||
1926 | rdev->data_offset = offset; | 1970 | rdev->data_offset = offset; |
1927 | return len; | 1971 | return len; |
1928 | } | 1972 | } |
@@ -1936,16 +1980,69 @@ rdev_size_show(mdk_rdev_t *rdev, char *page) | |||
1936 | return sprintf(page, "%llu\n", (unsigned long long)rdev->size); | 1980 | return sprintf(page, "%llu\n", (unsigned long long)rdev->size); |
1937 | } | 1981 | } |
1938 | 1982 | ||
1983 | static int overlaps(sector_t s1, sector_t l1, sector_t s2, sector_t l2) | ||
1984 | { | ||
1985 | /* check if two start/length pairs overlap */ | ||
1986 | if (s1+l1 <= s2) | ||
1987 | return 0; | ||
1988 | if (s2+l2 <= s1) | ||
1989 | return 0; | ||
1990 | return 1; | ||
1991 | } | ||
1992 | |||
1939 | static ssize_t | 1993 | static ssize_t |
1940 | rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | 1994 | rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) |
1941 | { | 1995 | { |
1942 | char *e; | 1996 | char *e; |
1943 | unsigned long long size = simple_strtoull(buf, &e, 10); | 1997 | unsigned long long size = simple_strtoull(buf, &e, 10); |
1998 | unsigned long long oldsize = rdev->size; | ||
1944 | if (e==buf || (*e && *e != '\n')) | 1999 | if (e==buf || (*e && *e != '\n')) |
1945 | return -EINVAL; | 2000 | return -EINVAL; |
1946 | if (rdev->mddev->pers) | 2001 | if (rdev->mddev->pers) |
1947 | return -EBUSY; | 2002 | return -EBUSY; |
1948 | rdev->size = size; | 2003 | rdev->size = size; |
2004 | if (size > oldsize && rdev->mddev->external) { | ||
2005 | /* need to check that all other rdevs with the same ->bdev | ||
2006 | * do not overlap. We need to unlock the mddev to avoid | ||
2007 | * a deadlock. We have already changed rdev->size, and if | ||
2008 | * we have to change it back, we will have the lock again. | ||
2009 | */ | ||
2010 | mddev_t *mddev; | ||
2011 | int overlap = 0; | ||
2012 | struct list_head *tmp, *tmp2; | ||
2013 | |||
2014 | mddev_unlock(rdev->mddev); | ||
2015 | for_each_mddev(mddev, tmp) { | ||
2016 | mdk_rdev_t *rdev2; | ||
2017 | |||
2018 | mddev_lock(mddev); | ||
2019 | rdev_for_each(rdev2, tmp2, mddev) | ||
2020 | if (test_bit(AllReserved, &rdev2->flags) || | ||
2021 | (rdev->bdev == rdev2->bdev && | ||
2022 | rdev != rdev2 && | ||
2023 | overlaps(rdev->data_offset, rdev->size, | ||
2024 | rdev2->data_offset, rdev2->size))) { | ||
2025 | overlap = 1; | ||
2026 | break; | ||
2027 | } | ||
2028 | mddev_unlock(mddev); | ||
2029 | if (overlap) { | ||
2030 | mddev_put(mddev); | ||
2031 | break; | ||
2032 | } | ||
2033 | } | ||
2034 | mddev_lock(rdev->mddev); | ||
2035 | if (overlap) { | ||
2036 | /* Someone else could have slipped in a size | ||
2037 | * change here, but doing so is just silly. | ||
2038 | * We put oldsize back because we *know* it is | ||
2039 | * safe, and trust userspace not to race with | ||
2040 | * itself | ||
2041 | */ | ||
2042 | rdev->size = oldsize; | ||
2043 | return -EBUSY; | ||
2044 | } | ||
2045 | } | ||
1949 | if (size < rdev->mddev->size || rdev->mddev->size == 0) | 2046 | if (size < rdev->mddev->size || rdev->mddev->size == 0) |
1950 | rdev->mddev->size = size; | 2047 | rdev->mddev->size = size; |
1951 | return len; | 2048 | return len; |
@@ -1980,12 +2077,18 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
1980 | { | 2077 | { |
1981 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); | 2078 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); |
1982 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); | 2079 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); |
2080 | int rv; | ||
1983 | 2081 | ||
1984 | if (!entry->store) | 2082 | if (!entry->store) |
1985 | return -EIO; | 2083 | return -EIO; |
1986 | if (!capable(CAP_SYS_ADMIN)) | 2084 | if (!capable(CAP_SYS_ADMIN)) |
1987 | return -EACCES; | 2085 | return -EACCES; |
1988 | return entry->store(rdev, page, length); | 2086 | rv = mddev_lock(rdev->mddev); |
2087 | if (!rv) { | ||
2088 | rv = entry->store(rdev, page, length); | ||
2089 | mddev_unlock(rdev->mddev); | ||
2090 | } | ||
2091 | return rv; | ||
1989 | } | 2092 | } |
1990 | 2093 | ||
1991 | static void rdev_free(struct kobject *ko) | 2094 | static void rdev_free(struct kobject *ko) |
@@ -2029,7 +2132,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi | |||
2029 | if ((err = alloc_disk_sb(rdev))) | 2132 | if ((err = alloc_disk_sb(rdev))) |
2030 | goto abort_free; | 2133 | goto abort_free; |
2031 | 2134 | ||
2032 | err = lock_rdev(rdev, newdev); | 2135 | err = lock_rdev(rdev, newdev, super_format == -2); |
2033 | if (err) | 2136 | if (err) |
2034 | goto abort_free; | 2137 | goto abort_free; |
2035 | 2138 | ||
@@ -2099,7 +2202,7 @@ static void analyze_sbs(mddev_t * mddev) | |||
2099 | char b[BDEVNAME_SIZE]; | 2202 | char b[BDEVNAME_SIZE]; |
2100 | 2203 | ||
2101 | freshest = NULL; | 2204 | freshest = NULL; |
2102 | ITERATE_RDEV(mddev,rdev,tmp) | 2205 | rdev_for_each(rdev, tmp, mddev) |
2103 | switch (super_types[mddev->major_version]. | 2206 | switch (super_types[mddev->major_version]. |
2104 | load_super(rdev, freshest, mddev->minor_version)) { | 2207 | load_super(rdev, freshest, mddev->minor_version)) { |
2105 | case 1: | 2208 | case 1: |
@@ -2120,7 +2223,7 @@ static void analyze_sbs(mddev_t * mddev) | |||
2120 | validate_super(mddev, freshest); | 2223 | validate_super(mddev, freshest); |
2121 | 2224 | ||
2122 | i = 0; | 2225 | i = 0; |
2123 | ITERATE_RDEV(mddev,rdev,tmp) { | 2226 | rdev_for_each(rdev, tmp, mddev) { |
2124 | if (rdev != freshest) | 2227 | if (rdev != freshest) |
2125 | if (super_types[mddev->major_version]. | 2228 | if (super_types[mddev->major_version]. |
2126 | validate_super(mddev, rdev)) { | 2229 | validate_super(mddev, rdev)) { |
@@ -2215,7 +2318,7 @@ level_show(mddev_t *mddev, char *page) | |||
2215 | static ssize_t | 2318 | static ssize_t |
2216 | level_store(mddev_t *mddev, const char *buf, size_t len) | 2319 | level_store(mddev_t *mddev, const char *buf, size_t len) |
2217 | { | 2320 | { |
2218 | int rv = len; | 2321 | ssize_t rv = len; |
2219 | if (mddev->pers) | 2322 | if (mddev->pers) |
2220 | return -EBUSY; | 2323 | return -EBUSY; |
2221 | if (len == 0) | 2324 | if (len == 0) |
@@ -2425,6 +2528,8 @@ array_state_show(mddev_t *mddev, char *page) | |||
2425 | case 0: | 2528 | case 0: |
2426 | if (mddev->in_sync) | 2529 | if (mddev->in_sync) |
2427 | st = clean; | 2530 | st = clean; |
2531 | else if (test_bit(MD_CHANGE_CLEAN, &mddev->flags)) | ||
2532 | st = write_pending; | ||
2428 | else if (mddev->safemode) | 2533 | else if (mddev->safemode) |
2429 | st = active_idle; | 2534 | st = active_idle; |
2430 | else | 2535 | else |
@@ -2455,11 +2560,9 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2455 | break; | 2560 | break; |
2456 | case clear: | 2561 | case clear: |
2457 | /* stopping an active array */ | 2562 | /* stopping an active array */ |
2458 | if (mddev->pers) { | 2563 | if (atomic_read(&mddev->active) > 1) |
2459 | if (atomic_read(&mddev->active) > 1) | 2564 | return -EBUSY; |
2460 | return -EBUSY; | 2565 | err = do_md_stop(mddev, 0); |
2461 | err = do_md_stop(mddev, 0); | ||
2462 | } | ||
2463 | break; | 2566 | break; |
2464 | case inactive: | 2567 | case inactive: |
2465 | /* stopping an active array */ | 2568 | /* stopping an active array */ |
@@ -2467,7 +2570,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2467 | if (atomic_read(&mddev->active) > 1) | 2570 | if (atomic_read(&mddev->active) > 1) |
2468 | return -EBUSY; | 2571 | return -EBUSY; |
2469 | err = do_md_stop(mddev, 2); | 2572 | err = do_md_stop(mddev, 2); |
2470 | } | 2573 | } else |
2574 | err = 0; /* already inactive */ | ||
2471 | break; | 2575 | break; |
2472 | case suspended: | 2576 | case suspended: |
2473 | break; /* not supported yet */ | 2577 | break; /* not supported yet */ |
@@ -2495,9 +2599,15 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2495 | restart_array(mddev); | 2599 | restart_array(mddev); |
2496 | spin_lock_irq(&mddev->write_lock); | 2600 | spin_lock_irq(&mddev->write_lock); |
2497 | if (atomic_read(&mddev->writes_pending) == 0) { | 2601 | if (atomic_read(&mddev->writes_pending) == 0) { |
2498 | mddev->in_sync = 1; | 2602 | if (mddev->in_sync == 0) { |
2499 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 2603 | mddev->in_sync = 1; |
2500 | } | 2604 | if (mddev->persistent) |
2605 | set_bit(MD_CHANGE_CLEAN, | ||
2606 | &mddev->flags); | ||
2607 | } | ||
2608 | err = 0; | ||
2609 | } else | ||
2610 | err = -EBUSY; | ||
2501 | spin_unlock_irq(&mddev->write_lock); | 2611 | spin_unlock_irq(&mddev->write_lock); |
2502 | } else { | 2612 | } else { |
2503 | mddev->ro = 0; | 2613 | mddev->ro = 0; |
@@ -2508,7 +2618,8 @@ array_state_store(mddev_t *mddev, const char *buf, size_t len) | |||
2508 | case active: | 2618 | case active: |
2509 | if (mddev->pers) { | 2619 | if (mddev->pers) { |
2510 | restart_array(mddev); | 2620 | restart_array(mddev); |
2511 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | 2621 | if (mddev->external) |
2622 | clear_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
2512 | wake_up(&mddev->sb_wait); | 2623 | wake_up(&mddev->sb_wait); |
2513 | err = 0; | 2624 | err = 0; |
2514 | } else { | 2625 | } else { |
@@ -2574,7 +2685,9 @@ new_dev_store(mddev_t *mddev, const char *buf, size_t len) | |||
2574 | if (err < 0) | 2685 | if (err < 0) |
2575 | goto out; | 2686 | goto out; |
2576 | } | 2687 | } |
2577 | } else | 2688 | } else if (mddev->external) |
2689 | rdev = md_import_device(dev, -2, -1); | ||
2690 | else | ||
2578 | rdev = md_import_device(dev, -1, -1); | 2691 | rdev = md_import_device(dev, -1, -1); |
2579 | 2692 | ||
2580 | if (IS_ERR(rdev)) | 2693 | if (IS_ERR(rdev)) |
@@ -2659,7 +2772,9 @@ __ATTR(component_size, S_IRUGO|S_IWUSR, size_show, size_store); | |||
2659 | 2772 | ||
2660 | 2773 | ||
2661 | /* Metdata version. | 2774 | /* Metdata version. |
2662 | * This is either 'none' for arrays with externally managed metadata, | 2775 | * This is one of |
2776 | * 'none' for arrays with no metadata (good luck...) | ||
2777 | * 'external' for arrays with externally managed metadata, | ||
2663 | * or N.M for internally known formats | 2778 | * or N.M for internally known formats |
2664 | */ | 2779 | */ |
2665 | static ssize_t | 2780 | static ssize_t |
@@ -2668,6 +2783,8 @@ metadata_show(mddev_t *mddev, char *page) | |||
2668 | if (mddev->persistent) | 2783 | if (mddev->persistent) |
2669 | return sprintf(page, "%d.%d\n", | 2784 | return sprintf(page, "%d.%d\n", |
2670 | mddev->major_version, mddev->minor_version); | 2785 | mddev->major_version, mddev->minor_version); |
2786 | else if (mddev->external) | ||
2787 | return sprintf(page, "external:%s\n", mddev->metadata_type); | ||
2671 | else | 2788 | else |
2672 | return sprintf(page, "none\n"); | 2789 | return sprintf(page, "none\n"); |
2673 | } | 2790 | } |
@@ -2682,6 +2799,21 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len) | |||
2682 | 2799 | ||
2683 | if (cmd_match(buf, "none")) { | 2800 | if (cmd_match(buf, "none")) { |
2684 | mddev->persistent = 0; | 2801 | mddev->persistent = 0; |
2802 | mddev->external = 0; | ||
2803 | mddev->major_version = 0; | ||
2804 | mddev->minor_version = 90; | ||
2805 | return len; | ||
2806 | } | ||
2807 | if (strncmp(buf, "external:", 9) == 0) { | ||
2808 | size_t namelen = len-9; | ||
2809 | if (namelen >= sizeof(mddev->metadata_type)) | ||
2810 | namelen = sizeof(mddev->metadata_type)-1; | ||
2811 | strncpy(mddev->metadata_type, buf+9, namelen); | ||
2812 | mddev->metadata_type[namelen] = 0; | ||
2813 | if (namelen && mddev->metadata_type[namelen-1] == '\n') | ||
2814 | mddev->metadata_type[--namelen] = 0; | ||
2815 | mddev->persistent = 0; | ||
2816 | mddev->external = 1; | ||
2685 | mddev->major_version = 0; | 2817 | mddev->major_version = 0; |
2686 | mddev->minor_version = 90; | 2818 | mddev->minor_version = 90; |
2687 | return len; | 2819 | return len; |
@@ -2698,6 +2830,7 @@ metadata_store(mddev_t *mddev, const char *buf, size_t len) | |||
2698 | mddev->major_version = major; | 2830 | mddev->major_version = major; |
2699 | mddev->minor_version = minor; | 2831 | mddev->minor_version = minor; |
2700 | mddev->persistent = 1; | 2832 | mddev->persistent = 1; |
2833 | mddev->external = 0; | ||
2701 | return len; | 2834 | return len; |
2702 | } | 2835 | } |
2703 | 2836 | ||
@@ -2865,6 +2998,43 @@ sync_completed_show(mddev_t *mddev, char *page) | |||
2865 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); | 2998 | static struct md_sysfs_entry md_sync_completed = __ATTR_RO(sync_completed); |
2866 | 2999 | ||
2867 | static ssize_t | 3000 | static ssize_t |
3001 | max_sync_show(mddev_t *mddev, char *page) | ||
3002 | { | ||
3003 | if (mddev->resync_max == MaxSector) | ||
3004 | return sprintf(page, "max\n"); | ||
3005 | else | ||
3006 | return sprintf(page, "%llu\n", | ||
3007 | (unsigned long long)mddev->resync_max); | ||
3008 | } | ||
3009 | static ssize_t | ||
3010 | max_sync_store(mddev_t *mddev, const char *buf, size_t len) | ||
3011 | { | ||
3012 | if (strncmp(buf, "max", 3) == 0) | ||
3013 | mddev->resync_max = MaxSector; | ||
3014 | else { | ||
3015 | char *ep; | ||
3016 | unsigned long long max = simple_strtoull(buf, &ep, 10); | ||
3017 | if (ep == buf || (*ep != 0 && *ep != '\n')) | ||
3018 | return -EINVAL; | ||
3019 | if (max < mddev->resync_max && | ||
3020 | test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | ||
3021 | return -EBUSY; | ||
3022 | |||
3023 | /* Must be a multiple of chunk_size */ | ||
3024 | if (mddev->chunk_size) { | ||
3025 | if (max & (sector_t)((mddev->chunk_size>>9)-1)) | ||
3026 | return -EINVAL; | ||
3027 | } | ||
3028 | mddev->resync_max = max; | ||
3029 | } | ||
3030 | wake_up(&mddev->recovery_wait); | ||
3031 | return len; | ||
3032 | } | ||
3033 | |||
3034 | static struct md_sysfs_entry md_max_sync = | ||
3035 | __ATTR(sync_max, S_IRUGO|S_IWUSR, max_sync_show, max_sync_store); | ||
3036 | |||
3037 | static ssize_t | ||
2868 | suspend_lo_show(mddev_t *mddev, char *page) | 3038 | suspend_lo_show(mddev_t *mddev, char *page) |
2869 | { | 3039 | { |
2870 | return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo); | 3040 | return sprintf(page, "%llu\n", (unsigned long long)mddev->suspend_lo); |
@@ -2974,6 +3144,7 @@ static struct attribute *md_redundancy_attrs[] = { | |||
2974 | &md_sync_max.attr, | 3144 | &md_sync_max.attr, |
2975 | &md_sync_speed.attr, | 3145 | &md_sync_speed.attr, |
2976 | &md_sync_completed.attr, | 3146 | &md_sync_completed.attr, |
3147 | &md_max_sync.attr, | ||
2977 | &md_suspend_lo.attr, | 3148 | &md_suspend_lo.attr, |
2978 | &md_suspend_hi.attr, | 3149 | &md_suspend_hi.attr, |
2979 | &md_bitmap.attr, | 3150 | &md_bitmap.attr, |
@@ -3118,8 +3289,11 @@ static int do_md_run(mddev_t * mddev) | |||
3118 | /* | 3289 | /* |
3119 | * Analyze all RAID superblock(s) | 3290 | * Analyze all RAID superblock(s) |
3120 | */ | 3291 | */ |
3121 | if (!mddev->raid_disks) | 3292 | if (!mddev->raid_disks) { |
3293 | if (!mddev->persistent) | ||
3294 | return -EINVAL; | ||
3122 | analyze_sbs(mddev); | 3295 | analyze_sbs(mddev); |
3296 | } | ||
3123 | 3297 | ||
3124 | chunk_size = mddev->chunk_size; | 3298 | chunk_size = mddev->chunk_size; |
3125 | 3299 | ||
@@ -3143,7 +3317,7 @@ static int do_md_run(mddev_t * mddev) | |||
3143 | } | 3317 | } |
3144 | 3318 | ||
3145 | /* devices must have minimum size of one chunk */ | 3319 | /* devices must have minimum size of one chunk */ |
3146 | ITERATE_RDEV(mddev,rdev,tmp) { | 3320 | rdev_for_each(rdev, tmp, mddev) { |
3147 | if (test_bit(Faulty, &rdev->flags)) | 3321 | if (test_bit(Faulty, &rdev->flags)) |
3148 | continue; | 3322 | continue; |
3149 | if (rdev->size < chunk_size / 1024) { | 3323 | if (rdev->size < chunk_size / 1024) { |
@@ -3170,7 +3344,7 @@ static int do_md_run(mddev_t * mddev) | |||
3170 | * the only valid external interface is through the md | 3344 | * the only valid external interface is through the md |
3171 | * device. | 3345 | * device. |
3172 | */ | 3346 | */ |
3173 | ITERATE_RDEV(mddev,rdev,tmp) { | 3347 | rdev_for_each(rdev, tmp, mddev) { |
3174 | if (test_bit(Faulty, &rdev->flags)) | 3348 | if (test_bit(Faulty, &rdev->flags)) |
3175 | continue; | 3349 | continue; |
3176 | sync_blockdev(rdev->bdev); | 3350 | sync_blockdev(rdev->bdev); |
@@ -3236,8 +3410,8 @@ static int do_md_run(mddev_t * mddev) | |||
3236 | mdk_rdev_t *rdev2; | 3410 | mdk_rdev_t *rdev2; |
3237 | struct list_head *tmp2; | 3411 | struct list_head *tmp2; |
3238 | int warned = 0; | 3412 | int warned = 0; |
3239 | ITERATE_RDEV(mddev, rdev, tmp) { | 3413 | rdev_for_each(rdev, tmp, mddev) { |
3240 | ITERATE_RDEV(mddev, rdev2, tmp2) { | 3414 | rdev_for_each(rdev2, tmp2, mddev) { |
3241 | if (rdev < rdev2 && | 3415 | if (rdev < rdev2 && |
3242 | rdev->bdev->bd_contains == | 3416 | rdev->bdev->bd_contains == |
3243 | rdev2->bdev->bd_contains) { | 3417 | rdev2->bdev->bd_contains) { |
@@ -3297,7 +3471,7 @@ static int do_md_run(mddev_t * mddev) | |||
3297 | mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ | 3471 | mddev->safemode_delay = (200 * HZ)/1000 +1; /* 200 msec delay */ |
3298 | mddev->in_sync = 1; | 3472 | mddev->in_sync = 1; |
3299 | 3473 | ||
3300 | ITERATE_RDEV(mddev,rdev,tmp) | 3474 | rdev_for_each(rdev, tmp, mddev) |
3301 | if (rdev->raid_disk >= 0) { | 3475 | if (rdev->raid_disk >= 0) { |
3302 | char nm[20]; | 3476 | char nm[20]; |
3303 | sprintf(nm, "rd%d", rdev->raid_disk); | 3477 | sprintf(nm, "rd%d", rdev->raid_disk); |
@@ -3330,7 +3504,7 @@ static int do_md_run(mddev_t * mddev) | |||
3330 | if (mddev->degraded && !mddev->sync_thread) { | 3504 | if (mddev->degraded && !mddev->sync_thread) { |
3331 | struct list_head *rtmp; | 3505 | struct list_head *rtmp; |
3332 | int spares = 0; | 3506 | int spares = 0; |
3333 | ITERATE_RDEV(mddev,rdev,rtmp) | 3507 | rdev_for_each(rdev, rtmp, mddev) |
3334 | if (rdev->raid_disk >= 0 && | 3508 | if (rdev->raid_disk >= 0 && |
3335 | !test_bit(In_sync, &rdev->flags) && | 3509 | !test_bit(In_sync, &rdev->flags) && |
3336 | !test_bit(Faulty, &rdev->flags)) | 3510 | !test_bit(Faulty, &rdev->flags)) |
@@ -3507,14 +3681,14 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3507 | } | 3681 | } |
3508 | mddev->bitmap_offset = 0; | 3682 | mddev->bitmap_offset = 0; |
3509 | 3683 | ||
3510 | ITERATE_RDEV(mddev,rdev,tmp) | 3684 | rdev_for_each(rdev, tmp, mddev) |
3511 | if (rdev->raid_disk >= 0) { | 3685 | if (rdev->raid_disk >= 0) { |
3512 | char nm[20]; | 3686 | char nm[20]; |
3513 | sprintf(nm, "rd%d", rdev->raid_disk); | 3687 | sprintf(nm, "rd%d", rdev->raid_disk); |
3514 | sysfs_remove_link(&mddev->kobj, nm); | 3688 | sysfs_remove_link(&mddev->kobj, nm); |
3515 | } | 3689 | } |
3516 | 3690 | ||
3517 | /* make sure all delayed_delete calls have finished */ | 3691 | /* make sure all md_delayed_delete calls have finished */ |
3518 | flush_scheduled_work(); | 3692 | flush_scheduled_work(); |
3519 | 3693 | ||
3520 | export_array(mddev); | 3694 | export_array(mddev); |
@@ -3523,7 +3697,10 @@ static int do_md_stop(mddev_t * mddev, int mode) | |||
3523 | mddev->size = 0; | 3697 | mddev->size = 0; |
3524 | mddev->raid_disks = 0; | 3698 | mddev->raid_disks = 0; |
3525 | mddev->recovery_cp = 0; | 3699 | mddev->recovery_cp = 0; |
3700 | mddev->resync_max = MaxSector; | ||
3526 | mddev->reshape_position = MaxSector; | 3701 | mddev->reshape_position = MaxSector; |
3702 | mddev->external = 0; | ||
3703 | mddev->persistent = 0; | ||
3527 | 3704 | ||
3528 | } else if (mddev->pers) | 3705 | } else if (mddev->pers) |
3529 | printk(KERN_INFO "md: %s switched to read-only mode.\n", | 3706 | printk(KERN_INFO "md: %s switched to read-only mode.\n", |
@@ -3546,7 +3723,7 @@ static void autorun_array(mddev_t *mddev) | |||
3546 | 3723 | ||
3547 | printk(KERN_INFO "md: running: "); | 3724 | printk(KERN_INFO "md: running: "); |
3548 | 3725 | ||
3549 | ITERATE_RDEV(mddev,rdev,tmp) { | 3726 | rdev_for_each(rdev, tmp, mddev) { |
3550 | char b[BDEVNAME_SIZE]; | 3727 | char b[BDEVNAME_SIZE]; |
3551 | printk("<%s>", bdevname(rdev->bdev,b)); | 3728 | printk("<%s>", bdevname(rdev->bdev,b)); |
3552 | } | 3729 | } |
@@ -3589,7 +3766,7 @@ static void autorun_devices(int part) | |||
3589 | printk(KERN_INFO "md: considering %s ...\n", | 3766 | printk(KERN_INFO "md: considering %s ...\n", |
3590 | bdevname(rdev0->bdev,b)); | 3767 | bdevname(rdev0->bdev,b)); |
3591 | INIT_LIST_HEAD(&candidates); | 3768 | INIT_LIST_HEAD(&candidates); |
3592 | ITERATE_RDEV_PENDING(rdev,tmp) | 3769 | rdev_for_each_list(rdev, tmp, pending_raid_disks) |
3593 | if (super_90_load(rdev, rdev0, 0) >= 0) { | 3770 | if (super_90_load(rdev, rdev0, 0) >= 0) { |
3594 | printk(KERN_INFO "md: adding %s ...\n", | 3771 | printk(KERN_INFO "md: adding %s ...\n", |
3595 | bdevname(rdev->bdev,b)); | 3772 | bdevname(rdev->bdev,b)); |
@@ -3632,7 +3809,8 @@ static void autorun_devices(int part) | |||
3632 | mddev_unlock(mddev); | 3809 | mddev_unlock(mddev); |
3633 | } else { | 3810 | } else { |
3634 | printk(KERN_INFO "md: created %s\n", mdname(mddev)); | 3811 | printk(KERN_INFO "md: created %s\n", mdname(mddev)); |
3635 | ITERATE_RDEV_GENERIC(candidates,rdev,tmp) { | 3812 | mddev->persistent = 1; |
3813 | rdev_for_each_list(rdev, tmp, candidates) { | ||
3636 | list_del_init(&rdev->same_set); | 3814 | list_del_init(&rdev->same_set); |
3637 | if (bind_rdev_to_array(rdev, mddev)) | 3815 | if (bind_rdev_to_array(rdev, mddev)) |
3638 | export_rdev(rdev); | 3816 | export_rdev(rdev); |
@@ -3643,7 +3821,7 @@ static void autorun_devices(int part) | |||
3643 | /* on success, candidates will be empty, on error | 3821 | /* on success, candidates will be empty, on error |
3644 | * it won't... | 3822 | * it won't... |
3645 | */ | 3823 | */ |
3646 | ITERATE_RDEV_GENERIC(candidates,rdev,tmp) | 3824 | rdev_for_each_list(rdev, tmp, candidates) |
3647 | export_rdev(rdev); | 3825 | export_rdev(rdev); |
3648 | mddev_put(mddev); | 3826 | mddev_put(mddev); |
3649 | } | 3827 | } |
@@ -3673,7 +3851,7 @@ static int get_array_info(mddev_t * mddev, void __user * arg) | |||
3673 | struct list_head *tmp; | 3851 | struct list_head *tmp; |
3674 | 3852 | ||
3675 | nr=working=active=failed=spare=0; | 3853 | nr=working=active=failed=spare=0; |
3676 | ITERATE_RDEV(mddev,rdev,tmp) { | 3854 | rdev_for_each(rdev, tmp, mddev) { |
3677 | nr++; | 3855 | nr++; |
3678 | if (test_bit(Faulty, &rdev->flags)) | 3856 | if (test_bit(Faulty, &rdev->flags)) |
3679 | failed++; | 3857 | failed++; |
@@ -3919,8 +4097,6 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
3919 | else | 4097 | else |
3920 | rdev->raid_disk = -1; | 4098 | rdev->raid_disk = -1; |
3921 | 4099 | ||
3922 | rdev->flags = 0; | ||
3923 | |||
3924 | if (rdev->raid_disk < mddev->raid_disks) | 4100 | if (rdev->raid_disk < mddev->raid_disks) |
3925 | if (info->state & (1<<MD_DISK_SYNC)) | 4101 | if (info->state & (1<<MD_DISK_SYNC)) |
3926 | set_bit(In_sync, &rdev->flags); | 4102 | set_bit(In_sync, &rdev->flags); |
@@ -4165,13 +4341,15 @@ static int set_array_info(mddev_t * mddev, mdu_array_info_t *info) | |||
4165 | else | 4341 | else |
4166 | mddev->recovery_cp = 0; | 4342 | mddev->recovery_cp = 0; |
4167 | mddev->persistent = ! info->not_persistent; | 4343 | mddev->persistent = ! info->not_persistent; |
4344 | mddev->external = 0; | ||
4168 | 4345 | ||
4169 | mddev->layout = info->layout; | 4346 | mddev->layout = info->layout; |
4170 | mddev->chunk_size = info->chunk_size; | 4347 | mddev->chunk_size = info->chunk_size; |
4171 | 4348 | ||
4172 | mddev->max_disks = MD_SB_DISKS; | 4349 | mddev->max_disks = MD_SB_DISKS; |
4173 | 4350 | ||
4174 | mddev->flags = 0; | 4351 | if (mddev->persistent) |
4352 | mddev->flags = 0; | ||
4175 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | 4353 | set_bit(MD_CHANGE_DEVS, &mddev->flags); |
4176 | 4354 | ||
4177 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; | 4355 | mddev->default_bitmap_offset = MD_SB_BYTES >> 9; |
@@ -4213,7 +4391,7 @@ static int update_size(mddev_t *mddev, unsigned long size) | |||
4213 | */ | 4391 | */ |
4214 | if (mddev->sync_thread) | 4392 | if (mddev->sync_thread) |
4215 | return -EBUSY; | 4393 | return -EBUSY; |
4216 | ITERATE_RDEV(mddev,rdev,tmp) { | 4394 | rdev_for_each(rdev, tmp, mddev) { |
4217 | sector_t avail; | 4395 | sector_t avail; |
4218 | avail = rdev->size * 2; | 4396 | avail = rdev->size * 2; |
4219 | 4397 | ||
@@ -4471,9 +4649,10 @@ static int md_ioctl(struct inode *inode, struct file *file, | |||
4471 | */ | 4649 | */ |
4472 | /* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY, | 4650 | /* if we are not initialised yet, only ADD_NEW_DISK, STOP_ARRAY, |
4473 | * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */ | 4651 | * RUN_ARRAY, and GET_ and SET_BITMAP_FILE are allowed */ |
4474 | if (!mddev->raid_disks && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY | 4652 | if ((!mddev->raid_disks && !mddev->external) |
4475 | && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE | 4653 | && cmd != ADD_NEW_DISK && cmd != STOP_ARRAY |
4476 | && cmd != GET_BITMAP_FILE) { | 4654 | && cmd != RUN_ARRAY && cmd != SET_BITMAP_FILE |
4655 | && cmd != GET_BITMAP_FILE) { | ||
4477 | err = -ENODEV; | 4656 | err = -ENODEV; |
4478 | goto abort_unlock; | 4657 | goto abort_unlock; |
4479 | } | 4658 | } |
@@ -4757,7 +4936,7 @@ static void status_unused(struct seq_file *seq) | |||
4757 | 4936 | ||
4758 | seq_printf(seq, "unused devices: "); | 4937 | seq_printf(seq, "unused devices: "); |
4759 | 4938 | ||
4760 | ITERATE_RDEV_PENDING(rdev,tmp) { | 4939 | rdev_for_each_list(rdev, tmp, pending_raid_disks) { |
4761 | char b[BDEVNAME_SIZE]; | 4940 | char b[BDEVNAME_SIZE]; |
4762 | i++; | 4941 | i++; |
4763 | seq_printf(seq, "%s ", | 4942 | seq_printf(seq, "%s ", |
@@ -4953,7 +5132,7 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
4953 | } | 5132 | } |
4954 | 5133 | ||
4955 | size = 0; | 5134 | size = 0; |
4956 | ITERATE_RDEV(mddev,rdev,tmp2) { | 5135 | rdev_for_each(rdev, tmp2, mddev) { |
4957 | char b[BDEVNAME_SIZE]; | 5136 | char b[BDEVNAME_SIZE]; |
4958 | seq_printf(seq, " %s[%d]", | 5137 | seq_printf(seq, " %s[%d]", |
4959 | bdevname(rdev->bdev,b), rdev->desc_nr); | 5138 | bdevname(rdev->bdev,b), rdev->desc_nr); |
@@ -4982,7 +5161,10 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
4982 | mddev->major_version, | 5161 | mddev->major_version, |
4983 | mddev->minor_version); | 5162 | mddev->minor_version); |
4984 | } | 5163 | } |
4985 | } else | 5164 | } else if (mddev->external) |
5165 | seq_printf(seq, " super external:%s", | ||
5166 | mddev->metadata_type); | ||
5167 | else | ||
4986 | seq_printf(seq, " super non-persistent"); | 5168 | seq_printf(seq, " super non-persistent"); |
4987 | 5169 | ||
4988 | if (mddev->pers) { | 5170 | if (mddev->pers) { |
@@ -5106,7 +5288,7 @@ static int is_mddev_idle(mddev_t *mddev) | |||
5106 | long curr_events; | 5288 | long curr_events; |
5107 | 5289 | ||
5108 | idle = 1; | 5290 | idle = 1; |
5109 | ITERATE_RDEV(mddev,rdev,tmp) { | 5291 | rdev_for_each(rdev, tmp, mddev) { |
5110 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; | 5292 | struct gendisk *disk = rdev->bdev->bd_contains->bd_disk; |
5111 | curr_events = disk_stat_read(disk, sectors[0]) + | 5293 | curr_events = disk_stat_read(disk, sectors[0]) + |
5112 | disk_stat_read(disk, sectors[1]) - | 5294 | disk_stat_read(disk, sectors[1]) - |
@@ -5283,7 +5465,7 @@ void md_do_sync(mddev_t *mddev) | |||
5283 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | 5465 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); |
5284 | goto skip; | 5466 | goto skip; |
5285 | } | 5467 | } |
5286 | ITERATE_MDDEV(mddev2,tmp) { | 5468 | for_each_mddev(mddev2, tmp) { |
5287 | if (mddev2 == mddev) | 5469 | if (mddev2 == mddev) |
5288 | continue; | 5470 | continue; |
5289 | if (mddev2->curr_resync && | 5471 | if (mddev2->curr_resync && |
@@ -5333,7 +5515,7 @@ void md_do_sync(mddev_t *mddev) | |||
5333 | /* recovery follows the physical size of devices */ | 5515 | /* recovery follows the physical size of devices */ |
5334 | max_sectors = mddev->size << 1; | 5516 | max_sectors = mddev->size << 1; |
5335 | j = MaxSector; | 5517 | j = MaxSector; |
5336 | ITERATE_RDEV(mddev,rdev,rtmp) | 5518 | rdev_for_each(rdev, rtmp, mddev) |
5337 | if (rdev->raid_disk >= 0 && | 5519 | if (rdev->raid_disk >= 0 && |
5338 | !test_bit(Faulty, &rdev->flags) && | 5520 | !test_bit(Faulty, &rdev->flags) && |
5339 | !test_bit(In_sync, &rdev->flags) && | 5521 | !test_bit(In_sync, &rdev->flags) && |
@@ -5381,8 +5563,16 @@ void md_do_sync(mddev_t *mddev) | |||
5381 | sector_t sectors; | 5563 | sector_t sectors; |
5382 | 5564 | ||
5383 | skipped = 0; | 5565 | skipped = 0; |
5566 | if (j >= mddev->resync_max) { | ||
5567 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
5568 | wait_event(mddev->recovery_wait, | ||
5569 | mddev->resync_max > j | ||
5570 | || kthread_should_stop()); | ||
5571 | } | ||
5572 | if (kthread_should_stop()) | ||
5573 | goto interrupted; | ||
5384 | sectors = mddev->pers->sync_request(mddev, j, &skipped, | 5574 | sectors = mddev->pers->sync_request(mddev, j, &skipped, |
5385 | currspeed < speed_min(mddev)); | 5575 | currspeed < speed_min(mddev)); |
5386 | if (sectors == 0) { | 5576 | if (sectors == 0) { |
5387 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); | 5577 | set_bit(MD_RECOVERY_ERR, &mddev->recovery); |
5388 | goto out; | 5578 | goto out; |
@@ -5424,15 +5614,9 @@ void md_do_sync(mddev_t *mddev) | |||
5424 | } | 5614 | } |
5425 | 5615 | ||
5426 | 5616 | ||
5427 | if (kthread_should_stop()) { | 5617 | if (kthread_should_stop()) |
5428 | /* | 5618 | goto interrupted; |
5429 | * got a signal, exit. | 5619 | |
5430 | */ | ||
5431 | printk(KERN_INFO | ||
5432 | "md: md_do_sync() got signal ... exiting\n"); | ||
5433 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | ||
5434 | goto out; | ||
5435 | } | ||
5436 | 5620 | ||
5437 | /* | 5621 | /* |
5438 | * this loop exits only if either when we are slower than | 5622 | * this loop exits only if either when we are slower than |
@@ -5484,7 +5668,7 @@ void md_do_sync(mddev_t *mddev) | |||
5484 | } else { | 5668 | } else { |
5485 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) | 5669 | if (!test_bit(MD_RECOVERY_INTR, &mddev->recovery)) |
5486 | mddev->curr_resync = MaxSector; | 5670 | mddev->curr_resync = MaxSector; |
5487 | ITERATE_RDEV(mddev,rdev,rtmp) | 5671 | rdev_for_each(rdev, rtmp, mddev) |
5488 | if (rdev->raid_disk >= 0 && | 5672 | if (rdev->raid_disk >= 0 && |
5489 | !test_bit(Faulty, &rdev->flags) && | 5673 | !test_bit(Faulty, &rdev->flags) && |
5490 | !test_bit(In_sync, &rdev->flags) && | 5674 | !test_bit(In_sync, &rdev->flags) && |
@@ -5496,9 +5680,22 @@ void md_do_sync(mddev_t *mddev) | |||
5496 | 5680 | ||
5497 | skip: | 5681 | skip: |
5498 | mddev->curr_resync = 0; | 5682 | mddev->curr_resync = 0; |
5683 | mddev->resync_max = MaxSector; | ||
5684 | sysfs_notify(&mddev->kobj, NULL, "sync_completed"); | ||
5499 | wake_up(&resync_wait); | 5685 | wake_up(&resync_wait); |
5500 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); | 5686 | set_bit(MD_RECOVERY_DONE, &mddev->recovery); |
5501 | md_wakeup_thread(mddev->thread); | 5687 | md_wakeup_thread(mddev->thread); |
5688 | return; | ||
5689 | |||
5690 | interrupted: | ||
5691 | /* | ||
5692 | * got a signal, exit. | ||
5693 | */ | ||
5694 | printk(KERN_INFO | ||
5695 | "md: md_do_sync() got signal ... exiting\n"); | ||
5696 | set_bit(MD_RECOVERY_INTR, &mddev->recovery); | ||
5697 | goto out; | ||
5698 | |||
5502 | } | 5699 | } |
5503 | EXPORT_SYMBOL_GPL(md_do_sync); | 5700 | EXPORT_SYMBOL_GPL(md_do_sync); |
5504 | 5701 | ||
@@ -5509,8 +5706,9 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5509 | struct list_head *rtmp; | 5706 | struct list_head *rtmp; |
5510 | int spares = 0; | 5707 | int spares = 0; |
5511 | 5708 | ||
5512 | ITERATE_RDEV(mddev,rdev,rtmp) | 5709 | rdev_for_each(rdev, rtmp, mddev) |
5513 | if (rdev->raid_disk >= 0 && | 5710 | if (rdev->raid_disk >= 0 && |
5711 | !mddev->external && | ||
5514 | (test_bit(Faulty, &rdev->flags) || | 5712 | (test_bit(Faulty, &rdev->flags) || |
5515 | ! test_bit(In_sync, &rdev->flags)) && | 5713 | ! test_bit(In_sync, &rdev->flags)) && |
5516 | atomic_read(&rdev->nr_pending)==0) { | 5714 | atomic_read(&rdev->nr_pending)==0) { |
@@ -5524,7 +5722,7 @@ static int remove_and_add_spares(mddev_t *mddev) | |||
5524 | } | 5722 | } |
5525 | 5723 | ||
5526 | if (mddev->degraded) { | 5724 | if (mddev->degraded) { |
5527 | ITERATE_RDEV(mddev,rdev,rtmp) | 5725 | rdev_for_each(rdev, rtmp, mddev) |
5528 | if (rdev->raid_disk < 0 | 5726 | if (rdev->raid_disk < 0 |
5529 | && !test_bit(Faulty, &rdev->flags)) { | 5727 | && !test_bit(Faulty, &rdev->flags)) { |
5530 | rdev->recovery_offset = 0; | 5728 | rdev->recovery_offset = 0; |
@@ -5589,7 +5787,7 @@ void md_check_recovery(mddev_t *mddev) | |||
5589 | } | 5787 | } |
5590 | 5788 | ||
5591 | if ( ! ( | 5789 | if ( ! ( |
5592 | mddev->flags || | 5790 | (mddev->flags && !mddev->external) || |
5593 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || | 5791 | test_bit(MD_RECOVERY_NEEDED, &mddev->recovery) || |
5594 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || | 5792 | test_bit(MD_RECOVERY_DONE, &mddev->recovery) || |
5595 | (mddev->safemode == 1) || | 5793 | (mddev->safemode == 1) || |
@@ -5605,7 +5803,8 @@ void md_check_recovery(mddev_t *mddev) | |||
5605 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && | 5803 | if (mddev->safemode && !atomic_read(&mddev->writes_pending) && |
5606 | !mddev->in_sync && mddev->recovery_cp == MaxSector) { | 5804 | !mddev->in_sync && mddev->recovery_cp == MaxSector) { |
5607 | mddev->in_sync = 1; | 5805 | mddev->in_sync = 1; |
5608 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | 5806 | if (mddev->persistent) |
5807 | set_bit(MD_CHANGE_CLEAN, &mddev->flags); | ||
5609 | } | 5808 | } |
5610 | if (mddev->safemode == 1) | 5809 | if (mddev->safemode == 1) |
5611 | mddev->safemode = 0; | 5810 | mddev->safemode = 0; |
@@ -5637,7 +5836,7 @@ void md_check_recovery(mddev_t *mddev) | |||
5637 | * information must be scrapped | 5836 | * information must be scrapped |
5638 | */ | 5837 | */ |
5639 | if (!mddev->degraded) | 5838 | if (!mddev->degraded) |
5640 | ITERATE_RDEV(mddev,rdev,rtmp) | 5839 | rdev_for_each(rdev, rtmp, mddev) |
5641 | rdev->saved_raid_disk = -1; | 5840 | rdev->saved_raid_disk = -1; |
5642 | 5841 | ||
5643 | mddev->recovery = 0; | 5842 | mddev->recovery = 0; |
@@ -5714,7 +5913,7 @@ static int md_notify_reboot(struct notifier_block *this, | |||
5714 | 5913 | ||
5715 | printk(KERN_INFO "md: stopping all md devices.\n"); | 5914 | printk(KERN_INFO "md: stopping all md devices.\n"); |
5716 | 5915 | ||
5717 | ITERATE_MDDEV(mddev,tmp) | 5916 | for_each_mddev(mddev, tmp) |
5718 | if (mddev_trylock(mddev)) { | 5917 | if (mddev_trylock(mddev)) { |
5719 | do_md_stop (mddev, 1); | 5918 | do_md_stop (mddev, 1); |
5720 | mddev_unlock(mddev); | 5919 | mddev_unlock(mddev); |
@@ -5848,7 +6047,7 @@ static __exit void md_exit(void) | |||
5848 | unregister_reboot_notifier(&md_notifier); | 6047 | unregister_reboot_notifier(&md_notifier); |
5849 | unregister_sysctl_table(raid_table_header); | 6048 | unregister_sysctl_table(raid_table_header); |
5850 | remove_proc_entry("mdstat", NULL); | 6049 | remove_proc_entry("mdstat", NULL); |
5851 | ITERATE_MDDEV(mddev,tmp) { | 6050 | for_each_mddev(mddev, tmp) { |
5852 | struct gendisk *disk = mddev->gendisk; | 6051 | struct gendisk *disk = mddev->gendisk; |
5853 | if (!disk) | 6052 | if (!disk) |
5854 | continue; | 6053 | continue; |
diff --git a/drivers/md/mktables.c b/drivers/md/mktables.c index adef299908cf..b61d5767aae7 100644 --- a/drivers/md/mktables.c +++ b/drivers/md/mktables.c | |||
@@ -1,13 +1,10 @@ | |||
1 | #ident "$Id: mktables.c,v 1.2 2002/12/12 22:41:27 hpa Exp $" | 1 | /* -*- linux-c -*- ------------------------------------------------------- * |
2 | /* ----------------------------------------------------------------------- * | ||
3 | * | 2 | * |
4 | * Copyright 2002 H. Peter Anvin - All Rights Reserved | 3 | * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved |
5 | * | 4 | * |
6 | * This program is free software; you can redistribute it and/or modify | 5 | * This file is part of the Linux kernel, and is made available under |
7 | * it under the terms of the GNU General Public License as published by | 6 | * the terms of the GNU General Public License version 2 or (at your |
8 | * the Free Software Foundation, Inc., 53 Temple Place Ste 330, | 7 | * option) any later version; incorporated herein by reference. |
9 | * Bostom MA 02111-1307, USA; either version 2 of the License, or | ||
10 | * (at your option) any later version; incorporated herein by reference. | ||
11 | * | 8 | * |
12 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
13 | 10 | ||
@@ -26,100 +23,98 @@ | |||
26 | 23 | ||
27 | static uint8_t gfmul(uint8_t a, uint8_t b) | 24 | static uint8_t gfmul(uint8_t a, uint8_t b) |
28 | { | 25 | { |
29 | uint8_t v = 0; | 26 | uint8_t v = 0; |
30 | 27 | ||
31 | while ( b ) { | 28 | while (b) { |
32 | if ( b & 1 ) v ^= a; | 29 | if (b & 1) |
33 | a = (a << 1) ^ (a & 0x80 ? 0x1d : 0); | 30 | v ^= a; |
34 | b >>= 1; | 31 | a = (a << 1) ^ (a & 0x80 ? 0x1d : 0); |
35 | } | 32 | b >>= 1; |
36 | return v; | 33 | } |
34 | |||
35 | return v; | ||
37 | } | 36 | } |
38 | 37 | ||
39 | static uint8_t gfpow(uint8_t a, int b) | 38 | static uint8_t gfpow(uint8_t a, int b) |
40 | { | 39 | { |
41 | uint8_t v = 1; | 40 | uint8_t v = 1; |
42 | 41 | ||
43 | b %= 255; | 42 | b %= 255; |
44 | if ( b < 0 ) | 43 | if (b < 0) |
45 | b += 255; | 44 | b += 255; |
46 | 45 | ||
47 | while ( b ) { | 46 | while (b) { |
48 | if ( b & 1 ) v = gfmul(v,a); | 47 | if (b & 1) |
49 | a = gfmul(a,a); | 48 | v = gfmul(v, a); |
50 | b >>= 1; | 49 | a = gfmul(a, a); |
51 | } | 50 | b >>= 1; |
52 | return v; | 51 | } |
52 | |||
53 | return v; | ||
53 | } | 54 | } |
54 | 55 | ||
55 | int main(int argc, char *argv[]) | 56 | int main(int argc, char *argv[]) |
56 | { | 57 | { |
57 | int i, j, k; | 58 | int i, j, k; |
58 | uint8_t v; | 59 | uint8_t v; |
59 | uint8_t exptbl[256], invtbl[256]; | 60 | uint8_t exptbl[256], invtbl[256]; |
60 | 61 | ||
61 | printf("#include \"raid6.h\"\n"); | 62 | printf("#include \"raid6.h\"\n"); |
62 | 63 | ||
63 | /* Compute multiplication table */ | 64 | /* Compute multiplication table */ |
64 | printf("\nconst u8 __attribute__((aligned(256)))\n" | 65 | printf("\nconst u8 __attribute__((aligned(256)))\n" |
65 | "raid6_gfmul[256][256] =\n" | 66 | "raid6_gfmul[256][256] =\n" |
66 | "{\n"); | 67 | "{\n"); |
67 | for ( i = 0 ; i < 256 ; i++ ) { | 68 | for (i = 0; i < 256; i++) { |
68 | printf("\t{\n"); | 69 | printf("\t{\n"); |
69 | for ( j = 0 ; j < 256 ; j += 8 ) { | 70 | for (j = 0; j < 256; j += 8) { |
70 | printf("\t\t"); | 71 | printf("\t\t"); |
71 | for ( k = 0 ; k < 8 ; k++ ) { | 72 | for (k = 0; k < 8; k++) |
72 | printf("0x%02x, ", gfmul(i,j+k)); | 73 | printf("0x%02x,%c", gfmul(i, j + k), |
73 | } | 74 | (k == 7) ? '\n' : ' '); |
74 | printf("\n"); | 75 | } |
75 | } | 76 | printf("\t},\n"); |
76 | printf("\t},\n"); | 77 | } |
77 | } | 78 | printf("};\n"); |
78 | printf("};\n"); | 79 | |
79 | 80 | /* Compute power-of-2 table (exponent) */ | |
80 | /* Compute power-of-2 table (exponent) */ | 81 | v = 1; |
81 | v = 1; | 82 | printf("\nconst u8 __attribute__((aligned(256)))\n" |
82 | printf("\nconst u8 __attribute__((aligned(256)))\n" | 83 | "raid6_gfexp[256] =\n" "{\n"); |
83 | "raid6_gfexp[256] =\n" | 84 | for (i = 0; i < 256; i += 8) { |
84 | "{\n"); | 85 | printf("\t"); |
85 | for ( i = 0 ; i < 256 ; i += 8 ) { | 86 | for (j = 0; j < 8; j++) { |
86 | printf("\t"); | 87 | exptbl[i + j] = v; |
87 | for ( j = 0 ; j < 8 ; j++ ) { | 88 | printf("0x%02x,%c", v, (j == 7) ? '\n' : ' '); |
88 | exptbl[i+j] = v; | 89 | v = gfmul(v, 2); |
89 | printf("0x%02x, ", v); | 90 | if (v == 1) |
90 | v = gfmul(v,2); | 91 | v = 0; /* For entry 255, not a real entry */ |
91 | if ( v == 1 ) v = 0; /* For entry 255, not a real entry */ | 92 | } |
92 | } | 93 | } |
93 | printf("\n"); | 94 | printf("};\n"); |
94 | } | 95 | |
95 | printf("};\n"); | 96 | /* Compute inverse table x^-1 == x^254 */ |
96 | 97 | printf("\nconst u8 __attribute__((aligned(256)))\n" | |
97 | /* Compute inverse table x^-1 == x^254 */ | 98 | "raid6_gfinv[256] =\n" "{\n"); |
98 | printf("\nconst u8 __attribute__((aligned(256)))\n" | 99 | for (i = 0; i < 256; i += 8) { |
99 | "raid6_gfinv[256] =\n" | 100 | printf("\t"); |
100 | "{\n"); | 101 | for (j = 0; j < 8; j++) { |
101 | for ( i = 0 ; i < 256 ; i += 8 ) { | 102 | invtbl[i + j] = v = gfpow(i + j, 254); |
102 | printf("\t"); | 103 | printf("0x%02x,%c", v, (j == 7) ? '\n' : ' '); |
103 | for ( j = 0 ; j < 8 ; j++ ) { | 104 | } |
104 | invtbl[i+j] = v = gfpow(i+j,254); | 105 | } |
105 | printf("0x%02x, ", v); | 106 | printf("};\n"); |
106 | } | 107 | |
107 | printf("\n"); | 108 | /* Compute inv(2^x + 1) (exponent-xor-inverse) table */ |
108 | } | 109 | printf("\nconst u8 __attribute__((aligned(256)))\n" |
109 | printf("};\n"); | 110 | "raid6_gfexi[256] =\n" "{\n"); |
110 | 111 | for (i = 0; i < 256; i += 8) { | |
111 | /* Compute inv(2^x + 1) (exponent-xor-inverse) table */ | 112 | printf("\t"); |
112 | printf("\nconst u8 __attribute__((aligned(256)))\n" | 113 | for (j = 0; j < 8; j++) |
113 | "raid6_gfexi[256] =\n" | 114 | printf("0x%02x,%c", invtbl[exptbl[i + j] ^ 1], |
114 | "{\n"); | 115 | (j == 7) ? '\n' : ' '); |
115 | for ( i = 0 ; i < 256 ; i += 8 ) { | 116 | } |
116 | printf("\t"); | 117 | printf("};\n"); |
117 | for ( j = 0 ; j < 8 ; j++ ) { | 118 | |
118 | printf("0x%02x, ", invtbl[exptbl[i+j]^1]); | 119 | return 0; |
119 | } | ||
120 | printf("\n"); | ||
121 | } | ||
122 | printf("};\n\n"); | ||
123 | |||
124 | return 0; | ||
125 | } | 120 | } |
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index eb631ebed686..3f299d835a2b 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -436,7 +436,7 @@ static int multipath_run (mddev_t *mddev) | |||
436 | } | 436 | } |
437 | 437 | ||
438 | conf->working_disks = 0; | 438 | conf->working_disks = 0; |
439 | ITERATE_RDEV(mddev,rdev,tmp) { | 439 | rdev_for_each(rdev, tmp, mddev) { |
440 | disk_idx = rdev->raid_disk; | 440 | disk_idx = rdev->raid_disk; |
441 | if (disk_idx < 0 || | 441 | if (disk_idx < 0 || |
442 | disk_idx >= mddev->raid_disks) | 442 | disk_idx >= mddev->raid_disks) |
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c index f8e591708d1f..818b48284096 100644 --- a/drivers/md/raid0.c +++ b/drivers/md/raid0.c | |||
@@ -72,11 +72,11 @@ static int create_strip_zones (mddev_t *mddev) | |||
72 | */ | 72 | */ |
73 | conf->nr_strip_zones = 0; | 73 | conf->nr_strip_zones = 0; |
74 | 74 | ||
75 | ITERATE_RDEV(mddev,rdev1,tmp1) { | 75 | rdev_for_each(rdev1, tmp1, mddev) { |
76 | printk("raid0: looking at %s\n", | 76 | printk("raid0: looking at %s\n", |
77 | bdevname(rdev1->bdev,b)); | 77 | bdevname(rdev1->bdev,b)); |
78 | c = 0; | 78 | c = 0; |
79 | ITERATE_RDEV(mddev,rdev2,tmp2) { | 79 | rdev_for_each(rdev2, tmp2, mddev) { |
80 | printk("raid0: comparing %s(%llu)", | 80 | printk("raid0: comparing %s(%llu)", |
81 | bdevname(rdev1->bdev,b), | 81 | bdevname(rdev1->bdev,b), |
82 | (unsigned long long)rdev1->size); | 82 | (unsigned long long)rdev1->size); |
@@ -124,7 +124,7 @@ static int create_strip_zones (mddev_t *mddev) | |||
124 | cnt = 0; | 124 | cnt = 0; |
125 | smallest = NULL; | 125 | smallest = NULL; |
126 | zone->dev = conf->devlist; | 126 | zone->dev = conf->devlist; |
127 | ITERATE_RDEV(mddev, rdev1, tmp1) { | 127 | rdev_for_each(rdev1, tmp1, mddev) { |
128 | int j = rdev1->raid_disk; | 128 | int j = rdev1->raid_disk; |
129 | 129 | ||
130 | if (j < 0 || j >= mddev->raid_disks) { | 130 | if (j < 0 || j >= mddev->raid_disks) { |
@@ -293,7 +293,7 @@ static int raid0_run (mddev_t *mddev) | |||
293 | 293 | ||
294 | /* calculate array device size */ | 294 | /* calculate array device size */ |
295 | mddev->array_size = 0; | 295 | mddev->array_size = 0; |
296 | ITERATE_RDEV(mddev,rdev,tmp) | 296 | rdev_for_each(rdev, tmp, mddev) |
297 | mddev->array_size += rdev->size; | 297 | mddev->array_size += rdev->size; |
298 | 298 | ||
299 | printk("raid0 : md_size is %llu blocks.\n", | 299 | printk("raid0 : md_size is %llu blocks.\n", |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 4a69c416e045..5c7fef091cec 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1684,6 +1684,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1684 | if (!go_faster && conf->nr_waiting) | 1684 | if (!go_faster && conf->nr_waiting) |
1685 | msleep_interruptible(1000); | 1685 | msleep_interruptible(1000); |
1686 | 1686 | ||
1687 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
1687 | raise_barrier(conf); | 1688 | raise_barrier(conf); |
1688 | 1689 | ||
1689 | conf->next_resync = sector_nr; | 1690 | conf->next_resync = sector_nr; |
@@ -1766,6 +1767,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1766 | return rv; | 1767 | return rv; |
1767 | } | 1768 | } |
1768 | 1769 | ||
1770 | if (max_sector > mddev->resync_max) | ||
1771 | max_sector = mddev->resync_max; /* Don't do IO beyond here */ | ||
1769 | nr_sectors = 0; | 1772 | nr_sectors = 0; |
1770 | sync_blocks = 0; | 1773 | sync_blocks = 0; |
1771 | do { | 1774 | do { |
@@ -1884,7 +1887,7 @@ static int run(mddev_t *mddev) | |||
1884 | if (!conf->r1bio_pool) | 1887 | if (!conf->r1bio_pool) |
1885 | goto out_no_mem; | 1888 | goto out_no_mem; |
1886 | 1889 | ||
1887 | ITERATE_RDEV(mddev, rdev, tmp) { | 1890 | rdev_for_each(rdev, tmp, mddev) { |
1888 | disk_idx = rdev->raid_disk; | 1891 | disk_idx = rdev->raid_disk; |
1889 | if (disk_idx >= mddev->raid_disks | 1892 | if (disk_idx >= mddev->raid_disks |
1890 | || disk_idx < 0) | 1893 | || disk_idx < 0) |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 5cdcc9386200..017f58113c33 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1657,6 +1657,9 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1657 | return (max_sector - sector_nr) + sectors_skipped; | 1657 | return (max_sector - sector_nr) + sectors_skipped; |
1658 | } | 1658 | } |
1659 | 1659 | ||
1660 | if (max_sector > mddev->resync_max) | ||
1661 | max_sector = mddev->resync_max; /* Don't do IO beyond here */ | ||
1662 | |||
1660 | /* make sure whole request will fit in a chunk - if chunks | 1663 | /* make sure whole request will fit in a chunk - if chunks |
1661 | * are meaningful | 1664 | * are meaningful |
1662 | */ | 1665 | */ |
@@ -1670,6 +1673,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i | |||
1670 | if (!go_faster && conf->nr_waiting) | 1673 | if (!go_faster && conf->nr_waiting) |
1671 | msleep_interruptible(1000); | 1674 | msleep_interruptible(1000); |
1672 | 1675 | ||
1676 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
1677 | |||
1673 | /* Again, very different code for resync and recovery. | 1678 | /* Again, very different code for resync and recovery. |
1674 | * Both must result in an r10bio with a list of bios that | 1679 | * Both must result in an r10bio with a list of bios that |
1675 | * have bi_end_io, bi_sector, bi_bdev set, | 1680 | * have bi_end_io, bi_sector, bi_bdev set, |
@@ -2021,7 +2026,7 @@ static int run(mddev_t *mddev) | |||
2021 | goto out_free_conf; | 2026 | goto out_free_conf; |
2022 | } | 2027 | } |
2023 | 2028 | ||
2024 | ITERATE_RDEV(mddev, rdev, tmp) { | 2029 | rdev_for_each(rdev, tmp, mddev) { |
2025 | disk_idx = rdev->raid_disk; | 2030 | disk_idx = rdev->raid_disk; |
2026 | if (disk_idx >= mddev->raid_disks | 2031 | if (disk_idx >= mddev->raid_disks |
2027 | || disk_idx < 0) | 2032 | || disk_idx < 0) |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e8c8157b02fc..2d6f1a51359c 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -3159,7 +3159,8 @@ static void raid5_activate_delayed(raid5_conf_t *conf) | |||
3159 | atomic_inc(&conf->preread_active_stripes); | 3159 | atomic_inc(&conf->preread_active_stripes); |
3160 | list_add_tail(&sh->lru, &conf->handle_list); | 3160 | list_add_tail(&sh->lru, &conf->handle_list); |
3161 | } | 3161 | } |
3162 | } | 3162 | } else |
3163 | blk_plug_device(conf->mddev->queue); | ||
3163 | } | 3164 | } |
3164 | 3165 | ||
3165 | static void activate_bit_delay(raid5_conf_t *conf) | 3166 | static void activate_bit_delay(raid5_conf_t *conf) |
@@ -3549,7 +3550,8 @@ static int make_request(struct request_queue *q, struct bio * bi) | |||
3549 | goto retry; | 3550 | goto retry; |
3550 | } | 3551 | } |
3551 | finish_wait(&conf->wait_for_overlap, &w); | 3552 | finish_wait(&conf->wait_for_overlap, &w); |
3552 | handle_stripe(sh, NULL); | 3553 | set_bit(STRIPE_HANDLE, &sh->state); |
3554 | clear_bit(STRIPE_DELAYED, &sh->state); | ||
3553 | release_stripe(sh); | 3555 | release_stripe(sh); |
3554 | } else { | 3556 | } else { |
3555 | /* cannot get stripe for read-ahead, just give-up */ | 3557 | /* cannot get stripe for read-ahead, just give-up */ |
@@ -3698,6 +3700,25 @@ static sector_t reshape_request(mddev_t *mddev, sector_t sector_nr, int *skipped | |||
3698 | release_stripe(sh); | 3700 | release_stripe(sh); |
3699 | first_sector += STRIPE_SECTORS; | 3701 | first_sector += STRIPE_SECTORS; |
3700 | } | 3702 | } |
3703 | /* If this takes us to the resync_max point where we have to pause, | ||
3704 | * then we need to write out the superblock. | ||
3705 | */ | ||
3706 | sector_nr += conf->chunk_size>>9; | ||
3707 | if (sector_nr >= mddev->resync_max) { | ||
3708 | /* Cannot proceed until we've updated the superblock... */ | ||
3709 | wait_event(conf->wait_for_overlap, | ||
3710 | atomic_read(&conf->reshape_stripes) == 0); | ||
3711 | mddev->reshape_position = conf->expand_progress; | ||
3712 | set_bit(MD_CHANGE_DEVS, &mddev->flags); | ||
3713 | md_wakeup_thread(mddev->thread); | ||
3714 | wait_event(mddev->sb_wait, | ||
3715 | !test_bit(MD_CHANGE_DEVS, &mddev->flags) | ||
3716 | || kthread_should_stop()); | ||
3717 | spin_lock_irq(&conf->device_lock); | ||
3718 | conf->expand_lo = mddev->reshape_position; | ||
3719 | spin_unlock_irq(&conf->device_lock); | ||
3720 | wake_up(&conf->wait_for_overlap); | ||
3721 | } | ||
3701 | return conf->chunk_size>>9; | 3722 | return conf->chunk_size>>9; |
3702 | } | 3723 | } |
3703 | 3724 | ||
@@ -3734,6 +3755,12 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
3734 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) | 3755 | if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) |
3735 | return reshape_request(mddev, sector_nr, skipped); | 3756 | return reshape_request(mddev, sector_nr, skipped); |
3736 | 3757 | ||
3758 | /* No need to check resync_max as we never do more than one | ||
3759 | * stripe, and as resync_max will always be on a chunk boundary, | ||
3760 | * if the check in md_do_sync didn't fire, there is no chance | ||
3761 | * of overstepping resync_max here | ||
3762 | */ | ||
3763 | |||
3737 | /* if there is too many failed drives and we are trying | 3764 | /* if there is too many failed drives and we are trying |
3738 | * to resync, then assert that we are finished, because there is | 3765 | * to resync, then assert that we are finished, because there is |
3739 | * nothing we can do. | 3766 | * nothing we can do. |
@@ -3753,6 +3780,9 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski | |||
3753 | return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ | 3780 | return sync_blocks * STRIPE_SECTORS; /* keep things rounded to whole stripes */ |
3754 | } | 3781 | } |
3755 | 3782 | ||
3783 | |||
3784 | bitmap_cond_end_sync(mddev->bitmap, sector_nr); | ||
3785 | |||
3756 | pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); | 3786 | pd_idx = stripe_to_pdidx(sector_nr, conf, raid_disks); |
3757 | sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1); | 3787 | sh = get_active_stripe(conf, sector_nr, raid_disks, pd_idx, 1); |
3758 | if (sh == NULL) { | 3788 | if (sh == NULL) { |
@@ -3864,7 +3894,7 @@ static int retry_aligned_read(raid5_conf_t *conf, struct bio *raid_bio) | |||
3864 | * During the scan, completed stripes are saved for us by the interrupt | 3894 | * During the scan, completed stripes are saved for us by the interrupt |
3865 | * handler, so that they will not have to wait for our next wakeup. | 3895 | * handler, so that they will not have to wait for our next wakeup. |
3866 | */ | 3896 | */ |
3867 | static void raid5d (mddev_t *mddev) | 3897 | static void raid5d(mddev_t *mddev) |
3868 | { | 3898 | { |
3869 | struct stripe_head *sh; | 3899 | struct stripe_head *sh; |
3870 | raid5_conf_t *conf = mddev_to_conf(mddev); | 3900 | raid5_conf_t *conf = mddev_to_conf(mddev); |
@@ -3889,12 +3919,6 @@ static void raid5d (mddev_t *mddev) | |||
3889 | activate_bit_delay(conf); | 3919 | activate_bit_delay(conf); |
3890 | } | 3920 | } |
3891 | 3921 | ||
3892 | if (list_empty(&conf->handle_list) && | ||
3893 | atomic_read(&conf->preread_active_stripes) < IO_THRESHOLD && | ||
3894 | !blk_queue_plugged(mddev->queue) && | ||
3895 | !list_empty(&conf->delayed_list)) | ||
3896 | raid5_activate_delayed(conf); | ||
3897 | |||
3898 | while ((bio = remove_bio_from_retry(conf))) { | 3922 | while ((bio = remove_bio_from_retry(conf))) { |
3899 | int ok; | 3923 | int ok; |
3900 | spin_unlock_irq(&conf->device_lock); | 3924 | spin_unlock_irq(&conf->device_lock); |
@@ -4108,7 +4132,7 @@ static int run(mddev_t *mddev) | |||
4108 | 4132 | ||
4109 | pr_debug("raid5: run(%s) called.\n", mdname(mddev)); | 4133 | pr_debug("raid5: run(%s) called.\n", mdname(mddev)); |
4110 | 4134 | ||
4111 | ITERATE_RDEV(mddev,rdev,tmp) { | 4135 | rdev_for_each(rdev, tmp, mddev) { |
4112 | raid_disk = rdev->raid_disk; | 4136 | raid_disk = rdev->raid_disk; |
4113 | if (raid_disk >= conf->raid_disks | 4137 | if (raid_disk >= conf->raid_disks |
4114 | || raid_disk < 0) | 4138 | || raid_disk < 0) |
@@ -4521,7 +4545,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
4521 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) | 4545 | if (test_bit(MD_RECOVERY_RUNNING, &mddev->recovery)) |
4522 | return -EBUSY; | 4546 | return -EBUSY; |
4523 | 4547 | ||
4524 | ITERATE_RDEV(mddev, rdev, rtmp) | 4548 | rdev_for_each(rdev, rtmp, mddev) |
4525 | if (rdev->raid_disk < 0 && | 4549 | if (rdev->raid_disk < 0 && |
4526 | !test_bit(Faulty, &rdev->flags)) | 4550 | !test_bit(Faulty, &rdev->flags)) |
4527 | spares++; | 4551 | spares++; |
@@ -4543,7 +4567,7 @@ static int raid5_start_reshape(mddev_t *mddev) | |||
4543 | /* Add some new drives, as many as will fit. | 4567 | /* Add some new drives, as many as will fit. |
4544 | * We know there are enough to make the newly sized array work. | 4568 | * We know there are enough to make the newly sized array work. |
4545 | */ | 4569 | */ |
4546 | ITERATE_RDEV(mddev, rdev, rtmp) | 4570 | rdev_for_each(rdev, rtmp, mddev) |
4547 | if (rdev->raid_disk < 0 && | 4571 | if (rdev->raid_disk < 0 && |
4548 | !test_bit(Faulty, &rdev->flags)) { | 4572 | !test_bit(Faulty, &rdev->flags)) { |
4549 | if (raid5_add_disk(mddev, rdev)) { | 4573 | if (raid5_add_disk(mddev, rdev)) { |
diff --git a/drivers/md/raid6test/test.c b/drivers/md/raid6test/test.c index 0d5cd57accd7..559cc41b2585 100644 --- a/drivers/md/raid6test/test.c +++ b/drivers/md/raid6test/test.c | |||
@@ -1,12 +1,10 @@ | |||
1 | /* -*- linux-c -*- ------------------------------------------------------- * | 1 | /* -*- linux-c -*- ------------------------------------------------------- * |
2 | * | 2 | * |
3 | * Copyright 2002 H. Peter Anvin - All Rights Reserved | 3 | * Copyright 2002-2007 H. Peter Anvin - All Rights Reserved |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This file is part of the Linux kernel, and is made available under |
6 | * it under the terms of the GNU General Public License as published by | 6 | * the terms of the GNU General Public License version 2 or (at your |
7 | * the Free Software Foundation, Inc., 53 Temple Place Ste 330, | 7 | * option) any later version; incorporated herein by reference. |
8 | * Bostom MA 02111-1307, USA; either version 2 of the License, or | ||
9 | * (at your option) any later version; incorporated herein by reference. | ||
10 | * | 8 | * |
11 | * ----------------------------------------------------------------------- */ | 9 | * ----------------------------------------------------------------------- */ |
12 | 10 | ||
@@ -30,67 +28,87 @@ char *dataptrs[NDISKS]; | |||
30 | char data[NDISKS][PAGE_SIZE]; | 28 | char data[NDISKS][PAGE_SIZE]; |
31 | char recovi[PAGE_SIZE], recovj[PAGE_SIZE]; | 29 | char recovi[PAGE_SIZE], recovj[PAGE_SIZE]; |
32 | 30 | ||
33 | void makedata(void) | 31 | static void makedata(void) |
34 | { | 32 | { |
35 | int i, j; | 33 | int i, j; |
36 | 34 | ||
37 | for ( i = 0 ; i < NDISKS ; i++ ) { | 35 | for (i = 0; i < NDISKS; i++) { |
38 | for ( j = 0 ; j < PAGE_SIZE ; j++ ) { | 36 | for (j = 0; j < PAGE_SIZE; j++) |
39 | data[i][j] = rand(); | 37 | data[i][j] = rand(); |
40 | } | 38 | |
41 | dataptrs[i] = data[i]; | 39 | dataptrs[i] = data[i]; |
42 | } | 40 | } |
43 | } | 41 | } |
44 | 42 | ||
43 | static char disk_type(int d) | ||
44 | { | ||
45 | switch (d) { | ||
46 | case NDISKS-2: | ||
47 | return 'P'; | ||
48 | case NDISKS-1: | ||
49 | return 'Q'; | ||
50 | default: | ||
51 | return 'D'; | ||
52 | } | ||
53 | } | ||
54 | |||
55 | static int test_disks(int i, int j) | ||
56 | { | ||
57 | int erra, errb; | ||
58 | |||
59 | memset(recovi, 0xf0, PAGE_SIZE); | ||
60 | memset(recovj, 0xba, PAGE_SIZE); | ||
61 | |||
62 | dataptrs[i] = recovi; | ||
63 | dataptrs[j] = recovj; | ||
64 | |||
65 | raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs); | ||
66 | |||
67 | erra = memcmp(data[i], recovi, PAGE_SIZE); | ||
68 | errb = memcmp(data[j], recovj, PAGE_SIZE); | ||
69 | |||
70 | if (i < NDISKS-2 && j == NDISKS-1) { | ||
71 | /* We don't implement the DQ failure scenario, since it's | ||
72 | equivalent to a RAID-5 failure (XOR, then recompute Q) */ | ||
73 | erra = errb = 0; | ||
74 | } else { | ||
75 | printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n", | ||
76 | raid6_call.name, | ||
77 | i, disk_type(i), | ||
78 | j, disk_type(j), | ||
79 | (!erra && !errb) ? "OK" : | ||
80 | !erra ? "ERRB" : | ||
81 | !errb ? "ERRA" : "ERRAB"); | ||
82 | } | ||
83 | |||
84 | dataptrs[i] = data[i]; | ||
85 | dataptrs[j] = data[j]; | ||
86 | |||
87 | return erra || errb; | ||
88 | } | ||
89 | |||
45 | int main(int argc, char *argv[]) | 90 | int main(int argc, char *argv[]) |
46 | { | 91 | { |
47 | const struct raid6_calls * const * algo; | 92 | const struct raid6_calls *const *algo; |
48 | int i, j; | 93 | int i, j; |
49 | int erra, errb; | 94 | int err = 0; |
50 | 95 | ||
51 | makedata(); | 96 | makedata(); |
52 | 97 | ||
53 | for ( algo = raid6_algos ; *algo ; algo++ ) { | 98 | for (algo = raid6_algos; *algo; algo++) { |
54 | if ( !(*algo)->valid || (*algo)->valid() ) { | 99 | if (!(*algo)->valid || (*algo)->valid()) { |
55 | raid6_call = **algo; | 100 | raid6_call = **algo; |
56 | 101 | ||
57 | /* Nuke syndromes */ | 102 | /* Nuke syndromes */ |
58 | memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE); | 103 | memset(data[NDISKS-2], 0xee, 2*PAGE_SIZE); |
59 | 104 | ||
60 | /* Generate assumed good syndrome */ | 105 | /* Generate assumed good syndrome */ |
61 | raid6_call.gen_syndrome(NDISKS, PAGE_SIZE, (void **)&dataptrs); | 106 | raid6_call.gen_syndrome(NDISKS, PAGE_SIZE, |
62 | 107 | (void **)&dataptrs); | |
63 | for ( i = 0 ; i < NDISKS-1 ; i++ ) { | 108 | |
64 | for ( j = i+1 ; j < NDISKS ; j++ ) { | 109 | for (i = 0; i < NDISKS-1; i++) |
65 | memset(recovi, 0xf0, PAGE_SIZE); | 110 | for (j = i+1; j < NDISKS; j++) |
66 | memset(recovj, 0xba, PAGE_SIZE); | 111 | err += test_disks(i, j); |
67 | |||
68 | dataptrs[i] = recovi; | ||
69 | dataptrs[j] = recovj; | ||
70 | |||
71 | raid6_dual_recov(NDISKS, PAGE_SIZE, i, j, (void **)&dataptrs); | ||
72 | |||
73 | erra = memcmp(data[i], recovi, PAGE_SIZE); | ||
74 | errb = memcmp(data[j], recovj, PAGE_SIZE); | ||
75 | |||
76 | if ( i < NDISKS-2 && j == NDISKS-1 ) { | ||
77 | /* We don't implement the DQ failure scenario, since it's | ||
78 | equivalent to a RAID-5 failure (XOR, then recompute Q) */ | ||
79 | } else { | ||
80 | printf("algo=%-8s faila=%3d(%c) failb=%3d(%c) %s\n", | ||
81 | raid6_call.name, | ||
82 | i, (i==NDISKS-2)?'P':'D', | ||
83 | j, (j==NDISKS-1)?'Q':(j==NDISKS-2)?'P':'D', | ||
84 | (!erra && !errb) ? "OK" : | ||
85 | !erra ? "ERRB" : | ||
86 | !errb ? "ERRA" : | ||
87 | "ERRAB"); | ||
88 | } | ||
89 | |||
90 | dataptrs[i] = data[i]; | ||
91 | dataptrs[j] = data[j]; | ||
92 | } | ||
93 | } | ||
94 | } | 112 | } |
95 | printf("\n"); | 113 | printf("\n"); |
96 | } | 114 | } |
@@ -99,5 +117,8 @@ int main(int argc, char *argv[]) | |||
99 | /* Pick the best algorithm test */ | 117 | /* Pick the best algorithm test */ |
100 | raid6_select_algo(); | 118 | raid6_select_algo(); |
101 | 119 | ||
102 | return 0; | 120 | if (err) |
121 | printf("\n*** ERRORS FOUND ***\n"); | ||
122 | |||
123 | return err; | ||
103 | } | 124 | } |
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 28ddd146c1c5..850b8c6f4577 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile | |||
@@ -22,7 +22,6 @@ obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o | |||
22 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o | 22 | obj-$(CONFIG_VIDEO_TVAUDIO) += tvaudio.o |
23 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o | 23 | obj-$(CONFIG_VIDEO_TDA7432) += tda7432.o |
24 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o | 24 | obj-$(CONFIG_VIDEO_TDA9875) += tda9875.o |
25 | obj-$(CONFIG_SOUND_TVMIXER) += tvmixer.o | ||
26 | 25 | ||
27 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o | 26 | obj-$(CONFIG_VIDEO_SAA6588) += saa6588.o |
28 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o | 27 | obj-$(CONFIG_VIDEO_SAA5246A) += saa5246a.o |
diff --git a/drivers/media/video/tvmixer.c b/drivers/media/video/tvmixer.c deleted file mode 100644 index 9fa5b702e073..000000000000 --- a/drivers/media/video/tvmixer.c +++ /dev/null | |||
@@ -1,336 +0,0 @@ | |||
1 | /* | ||
2 | */ | ||
3 | |||
4 | #include <linux/module.h> | ||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/string.h> | ||
7 | #include <linux/timer.h> | ||
8 | #include <linux/delay.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/slab.h> | ||
11 | #include <linux/i2c.h> | ||
12 | #include <linux/videodev.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kdev_t.h> | ||
15 | #include <linux/sound.h> | ||
16 | #include <linux/soundcard.h> | ||
17 | |||
18 | #include <asm/semaphore.h> | ||
19 | #include <asm/uaccess.h> | ||
20 | |||
21 | |||
22 | #define DEV_MAX 4 | ||
23 | |||
24 | static int devnr = -1; | ||
25 | module_param(devnr, int, 0644); | ||
26 | |||
27 | MODULE_AUTHOR("Gerd Knorr"); | ||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | /* ----------------------------------------------------------------------- */ | ||
31 | |||
32 | struct TVMIXER { | ||
33 | struct i2c_client *dev; | ||
34 | int minor; | ||
35 | int count; | ||
36 | }; | ||
37 | |||
38 | static struct TVMIXER devices[DEV_MAX]; | ||
39 | |||
40 | static int tvmixer_adapters(struct i2c_adapter *adap); | ||
41 | static int tvmixer_clients(struct i2c_client *client); | ||
42 | |||
43 | /* ----------------------------------------------------------------------- */ | ||
44 | |||
45 | static int mix_to_v4l(int i) | ||
46 | { | ||
47 | int r; | ||
48 | |||
49 | r = ((i & 0xff) * 65536 + 50) / 100; | ||
50 | if (r > 65535) r = 65535; | ||
51 | if (r < 0) r = 0; | ||
52 | return r; | ||
53 | } | ||
54 | |||
55 | static int v4l_to_mix(int i) | ||
56 | { | ||
57 | int r; | ||
58 | |||
59 | r = (i * 100 + 32768) / 65536; | ||
60 | if (r > 100) r = 100; | ||
61 | if (r < 0) r = 0; | ||
62 | return r | (r << 8); | ||
63 | } | ||
64 | |||
65 | static int v4l_to_mix2(int l, int r) | ||
66 | { | ||
67 | r = (r * 100 + 32768) / 65536; | ||
68 | if (r > 100) r = 100; | ||
69 | if (r < 0) r = 0; | ||
70 | l = (l * 100 + 32768) / 65536; | ||
71 | if (l > 100) l = 100; | ||
72 | if (l < 0) l = 0; | ||
73 | return (r << 8) | l; | ||
74 | } | ||
75 | |||
76 | static int tvmixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
77 | { | ||
78 | struct video_audio va; | ||
79 | int left,right,ret,val = 0; | ||
80 | struct TVMIXER *mix = file->private_data; | ||
81 | struct i2c_client *client = mix->dev; | ||
82 | void __user *argp = (void __user *)arg; | ||
83 | int __user *p = argp; | ||
84 | |||
85 | if (NULL == client) | ||
86 | return -ENODEV; | ||
87 | |||
88 | if (cmd == SOUND_MIXER_INFO) { | ||
89 | mixer_info info; | ||
90 | strlcpy(info.id, "tv card", sizeof(info.id)); | ||
91 | strlcpy(info.name, client->name, sizeof(info.name)); | ||
92 | info.modify_counter = 42 /* FIXME */; | ||
93 | if (copy_to_user(argp, &info, sizeof(info))) | ||
94 | return -EFAULT; | ||
95 | return 0; | ||
96 | } | ||
97 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
98 | _old_mixer_info info; | ||
99 | strlcpy(info.id, "tv card", sizeof(info.id)); | ||
100 | strlcpy(info.name, client->name, sizeof(info.name)); | ||
101 | if (copy_to_user(argp, &info, sizeof(info))) | ||
102 | return -EFAULT; | ||
103 | return 0; | ||
104 | } | ||
105 | if (cmd == OSS_GETVERSION) | ||
106 | return put_user(SOUND_VERSION, p); | ||
107 | |||
108 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) | ||
109 | if (get_user(val, p)) | ||
110 | return -EFAULT; | ||
111 | |||
112 | /* read state */ | ||
113 | memset(&va,0,sizeof(va)); | ||
114 | client->driver->command(client,VIDIOCGAUDIO,&va); | ||
115 | |||
116 | switch (cmd) { | ||
117 | case MIXER_READ(SOUND_MIXER_RECMASK): | ||
118 | case MIXER_READ(SOUND_MIXER_CAPS): | ||
119 | case MIXER_READ(SOUND_MIXER_RECSRC): | ||
120 | case MIXER_WRITE(SOUND_MIXER_RECSRC): | ||
121 | ret = 0; | ||
122 | break; | ||
123 | |||
124 | case MIXER_READ(SOUND_MIXER_STEREODEVS): | ||
125 | ret = SOUND_MASK_VOLUME; | ||
126 | break; | ||
127 | case MIXER_READ(SOUND_MIXER_DEVMASK): | ||
128 | ret = SOUND_MASK_VOLUME; | ||
129 | if (va.flags & VIDEO_AUDIO_BASS) | ||
130 | ret |= SOUND_MASK_BASS; | ||
131 | if (va.flags & VIDEO_AUDIO_TREBLE) | ||
132 | ret |= SOUND_MASK_TREBLE; | ||
133 | break; | ||
134 | |||
135 | case MIXER_WRITE(SOUND_MIXER_VOLUME): | ||
136 | left = mix_to_v4l(val); | ||
137 | right = mix_to_v4l(val >> 8); | ||
138 | va.volume = max(left,right); | ||
139 | va.balance = (32768*min(left,right)) / (va.volume ? va.volume : 1); | ||
140 | va.balance = (left<right) ? (65535-va.balance) : va.balance; | ||
141 | if (va.volume) | ||
142 | va.flags &= ~VIDEO_AUDIO_MUTE; | ||
143 | client->driver->command(client,VIDIOCSAUDIO,&va); | ||
144 | client->driver->command(client,VIDIOCGAUDIO,&va); | ||
145 | /* fall throuth */ | ||
146 | case MIXER_READ(SOUND_MIXER_VOLUME): | ||
147 | left = (min(65536 - va.balance,32768) * | ||
148 | va.volume) / 32768; | ||
149 | right = (min(va.balance,(u16)32768) * | ||
150 | va.volume) / 32768; | ||
151 | ret = v4l_to_mix2(left,right); | ||
152 | break; | ||
153 | |||
154 | case MIXER_WRITE(SOUND_MIXER_BASS): | ||
155 | va.bass = mix_to_v4l(val); | ||
156 | client->driver->command(client,VIDIOCSAUDIO,&va); | ||
157 | client->driver->command(client,VIDIOCGAUDIO,&va); | ||
158 | /* fall throuth */ | ||
159 | case MIXER_READ(SOUND_MIXER_BASS): | ||
160 | ret = v4l_to_mix(va.bass); | ||
161 | break; | ||
162 | |||
163 | case MIXER_WRITE(SOUND_MIXER_TREBLE): | ||
164 | va.treble = mix_to_v4l(val); | ||
165 | client->driver->command(client,VIDIOCSAUDIO,&va); | ||
166 | client->driver->command(client,VIDIOCGAUDIO,&va); | ||
167 | /* fall throuth */ | ||
168 | case MIXER_READ(SOUND_MIXER_TREBLE): | ||
169 | ret = v4l_to_mix(va.treble); | ||
170 | break; | ||
171 | |||
172 | default: | ||
173 | return -EINVAL; | ||
174 | } | ||
175 | if (put_user(ret, p)) | ||
176 | return -EFAULT; | ||
177 | return 0; | ||
178 | } | ||
179 | |||
180 | static int tvmixer_open(struct inode *inode, struct file *file) | ||
181 | { | ||
182 | int i, minor = iminor(inode); | ||
183 | struct TVMIXER *mix = NULL; | ||
184 | struct i2c_client *client = NULL; | ||
185 | |||
186 | for (i = 0; i < DEV_MAX; i++) { | ||
187 | if (devices[i].minor == minor) { | ||
188 | mix = devices+i; | ||
189 | client = mix->dev; | ||
190 | break; | ||
191 | } | ||
192 | } | ||
193 | |||
194 | if (NULL == client) | ||
195 | return -ENODEV; | ||
196 | |||
197 | /* lock bttv in memory while the mixer is in use */ | ||
198 | file->private_data = mix; | ||
199 | if (client->adapter->owner) | ||
200 | try_module_get(client->adapter->owner); | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static int tvmixer_release(struct inode *inode, struct file *file) | ||
205 | { | ||
206 | struct TVMIXER *mix = file->private_data; | ||
207 | struct i2c_client *client; | ||
208 | |||
209 | client = mix->dev; | ||
210 | if (NULL == client) { | ||
211 | return -ENODEV; | ||
212 | } | ||
213 | |||
214 | module_put(client->adapter->owner); | ||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static struct i2c_driver driver = { | ||
219 | .driver = { | ||
220 | .name = "tvmixer", | ||
221 | }, | ||
222 | .id = I2C_DRIVERID_TVMIXER, | ||
223 | .detach_adapter = tvmixer_adapters, | ||
224 | .attach_adapter = tvmixer_adapters, | ||
225 | .detach_client = tvmixer_clients, | ||
226 | }; | ||
227 | |||
228 | static const struct file_operations tvmixer_fops = { | ||
229 | .owner = THIS_MODULE, | ||
230 | .llseek = no_llseek, | ||
231 | .ioctl = tvmixer_ioctl, | ||
232 | .open = tvmixer_open, | ||
233 | .release = tvmixer_release, | ||
234 | }; | ||
235 | |||
236 | /* ----------------------------------------------------------------------- */ | ||
237 | |||
238 | static int tvmixer_adapters(struct i2c_adapter *adap) | ||
239 | { | ||
240 | struct i2c_client *client; | ||
241 | |||
242 | list_for_each_entry(client, &adap->clients, list) | ||
243 | tvmixer_clients(client); | ||
244 | return 0; | ||
245 | } | ||
246 | |||
247 | static int tvmixer_clients(struct i2c_client *client) | ||
248 | { | ||
249 | struct video_audio va; | ||
250 | int i,minor; | ||
251 | |||
252 | if (!(client->adapter->class & I2C_CLASS_TV_ANALOG)) | ||
253 | return -1; | ||
254 | |||
255 | /* unregister ?? */ | ||
256 | for (i = 0; i < DEV_MAX; i++) { | ||
257 | if (devices[i].dev == client) { | ||
258 | /* unregister */ | ||
259 | unregister_sound_mixer(devices[i].minor); | ||
260 | devices[i].dev = NULL; | ||
261 | devices[i].minor = -1; | ||
262 | printk("tvmixer: %s unregistered (#1)\n", | ||
263 | client->name); | ||
264 | return 0; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /* look for a free slot */ | ||
269 | for (i = 0; i < DEV_MAX; i++) | ||
270 | if (NULL == devices[i].dev) | ||
271 | break; | ||
272 | if (i == DEV_MAX) { | ||
273 | printk(KERN_WARNING "tvmixer: DEV_MAX too small\n"); | ||
274 | return -1; | ||
275 | } | ||
276 | |||
277 | /* audio chip with mixer ??? */ | ||
278 | if (NULL == client->driver->command) | ||
279 | return -1; | ||
280 | memset(&va,0,sizeof(va)); | ||
281 | if (0 != client->driver->command(client,VIDIOCGAUDIO,&va)) | ||
282 | return -1; | ||
283 | if (0 == (va.flags & VIDEO_AUDIO_VOLUME)) | ||
284 | return -1; | ||
285 | |||
286 | /* everything is fine, register */ | ||
287 | if ((minor = register_sound_mixer(&tvmixer_fops,devnr)) < 0) { | ||
288 | printk(KERN_ERR "tvmixer: cannot allocate mixer device\n"); | ||
289 | return -1; | ||
290 | } | ||
291 | |||
292 | devices[i].minor = minor; | ||
293 | devices[i].count = 0; | ||
294 | devices[i].dev = client; | ||
295 | printk("tvmixer: %s (%s) registered with minor %d\n", | ||
296 | client->name,client->adapter->name,minor); | ||
297 | |||
298 | return 0; | ||
299 | } | ||
300 | |||
301 | /* ----------------------------------------------------------------------- */ | ||
302 | |||
303 | static int __init tvmixer_init_module(void) | ||
304 | { | ||
305 | int i; | ||
306 | |||
307 | for (i = 0; i < DEV_MAX; i++) | ||
308 | devices[i].minor = -1; | ||
309 | |||
310 | return i2c_add_driver(&driver); | ||
311 | } | ||
312 | |||
313 | static void __exit tvmixer_cleanup_module(void) | ||
314 | { | ||
315 | int i; | ||
316 | |||
317 | i2c_del_driver(&driver); | ||
318 | for (i = 0; i < DEV_MAX; i++) { | ||
319 | if (devices[i].minor != -1) { | ||
320 | unregister_sound_mixer(devices[i].minor); | ||
321 | printk("tvmixer: %s unregistered (#2)\n", | ||
322 | devices[i].dev->name); | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
327 | module_init(tvmixer_init_module); | ||
328 | module_exit(tvmixer_cleanup_module); | ||
329 | |||
330 | /* | ||
331 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
332 | * --------------------------------------------------------------------------- | ||
333 | * Local variables: | ||
334 | * c-basic-offset: 8 | ||
335 | * End: | ||
336 | */ | ||
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index 7dce318df1bd..0846c33296bc 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c | |||
@@ -33,7 +33,6 @@ | |||
33 | * Sam Lin - GPS support | 33 | * Sam Lin - GPS support |
34 | */ | 34 | */ |
35 | 35 | ||
36 | #include <linux/autoconf.h> | ||
37 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
diff --git a/drivers/misc/fujitsu-laptop.c b/drivers/misc/fujitsu-laptop.c index c8d62c268b11..1cfd7f3f1294 100644 --- a/drivers/misc/fujitsu-laptop.c +++ b/drivers/misc/fujitsu-laptop.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <linux/dmi.h> | 50 | #include <linux/dmi.h> |
51 | #include <linux/backlight.h> | 51 | #include <linux/backlight.h> |
52 | #include <linux/platform_device.h> | 52 | #include <linux/platform_device.h> |
53 | #include <linux/autoconf.h> | ||
54 | 53 | ||
55 | #define FUJITSU_DRIVER_VERSION "0.3" | 54 | #define FUJITSU_DRIVER_VERSION "0.3" |
56 | 55 | ||
diff --git a/drivers/misc/lkdtm.c b/drivers/misc/lkdtm.c index 552b7957a92a..c884730c5eaf 100644 --- a/drivers/misc/lkdtm.c +++ b/drivers/misc/lkdtm.c | |||
@@ -129,27 +129,28 @@ module_param(cpoint_count, int, 0644); | |||
129 | MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ | 129 | MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\ |
130 | "crash point is to be hit to trigger action"); | 130 | "crash point is to be hit to trigger action"); |
131 | 131 | ||
132 | unsigned int jp_do_irq(unsigned int irq) | 132 | static unsigned int jp_do_irq(unsigned int irq) |
133 | { | 133 | { |
134 | lkdtm_handler(); | 134 | lkdtm_handler(); |
135 | jprobe_return(); | 135 | jprobe_return(); |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | irqreturn_t jp_handle_irq_event(unsigned int irq, struct irqaction *action) | 139 | static irqreturn_t jp_handle_irq_event(unsigned int irq, |
140 | struct irqaction *action) | ||
140 | { | 141 | { |
141 | lkdtm_handler(); | 142 | lkdtm_handler(); |
142 | jprobe_return(); | 143 | jprobe_return(); |
143 | return 0; | 144 | return 0; |
144 | } | 145 | } |
145 | 146 | ||
146 | void jp_tasklet_action(struct softirq_action *a) | 147 | static void jp_tasklet_action(struct softirq_action *a) |
147 | { | 148 | { |
148 | lkdtm_handler(); | 149 | lkdtm_handler(); |
149 | jprobe_return(); | 150 | jprobe_return(); |
150 | } | 151 | } |
151 | 152 | ||
152 | void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | 153 | static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) |
153 | { | 154 | { |
154 | lkdtm_handler(); | 155 | lkdtm_handler(); |
155 | jprobe_return(); | 156 | jprobe_return(); |
@@ -157,23 +158,24 @@ void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | |||
157 | 158 | ||
158 | struct scan_control; | 159 | struct scan_control; |
159 | 160 | ||
160 | unsigned long jp_shrink_inactive_list(unsigned long max_scan, | 161 | static unsigned long jp_shrink_inactive_list(unsigned long max_scan, |
161 | struct zone *zone, struct scan_control *sc) | 162 | struct zone *zone, |
163 | struct scan_control *sc) | ||
162 | { | 164 | { |
163 | lkdtm_handler(); | 165 | lkdtm_handler(); |
164 | jprobe_return(); | 166 | jprobe_return(); |
165 | return 0; | 167 | return 0; |
166 | } | 168 | } |
167 | 169 | ||
168 | int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim, | 170 | static int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim, |
169 | const enum hrtimer_mode mode) | 171 | const enum hrtimer_mode mode) |
170 | { | 172 | { |
171 | lkdtm_handler(); | 173 | lkdtm_handler(); |
172 | jprobe_return(); | 174 | jprobe_return(); |
173 | return 0; | 175 | return 0; |
174 | } | 176 | } |
175 | 177 | ||
176 | int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd) | 178 | static int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd) |
177 | { | 179 | { |
178 | lkdtm_handler(); | 180 | lkdtm_handler(); |
179 | jprobe_return(); | 181 | jprobe_return(); |
@@ -270,7 +272,7 @@ void lkdtm_handler(void) | |||
270 | } | 272 | } |
271 | } | 273 | } |
272 | 274 | ||
273 | int lkdtm_module_init(void) | 275 | static int __init lkdtm_module_init(void) |
274 | { | 276 | { |
275 | int ret; | 277 | int ret; |
276 | 278 | ||
@@ -331,7 +333,7 @@ int lkdtm_module_init(void) | |||
331 | return 0; | 333 | return 0; |
332 | } | 334 | } |
333 | 335 | ||
334 | void lkdtm_module_exit(void) | 336 | static void __exit lkdtm_module_exit(void) |
335 | { | 337 | { |
336 | unregister_jprobe(&lkdtm); | 338 | unregister_jprobe(&lkdtm); |
337 | printk(KERN_INFO "lkdtm : Crash point unregistered\n"); | 339 | printk(KERN_INFO "lkdtm : Crash point unregistered\n"); |
diff --git a/drivers/misc/msi-laptop.c b/drivers/misc/msi-laptop.c index 83679c762925..de898c6938f3 100644 --- a/drivers/misc/msi-laptop.c +++ b/drivers/misc/msi-laptop.c | |||
@@ -58,7 +58,6 @@ | |||
58 | #include <linux/dmi.h> | 58 | #include <linux/dmi.h> |
59 | #include <linux/backlight.h> | 59 | #include <linux/backlight.h> |
60 | #include <linux/platform_device.h> | 60 | #include <linux/platform_device.h> |
61 | #include <linux/autoconf.h> | ||
62 | 61 | ||
63 | #define MSI_DRIVER_VERSION "0.5" | 62 | #define MSI_DRIVER_VERSION "0.5" |
64 | 63 | ||
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c index cd221fd0fb94..7fa61e907e1c 100644 --- a/drivers/misc/phantom.c +++ b/drivers/misc/phantom.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <asm/atomic.h> | 25 | #include <asm/atomic.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | #define PHANTOM_VERSION "n0.9.7" | 28 | #define PHANTOM_VERSION "n0.9.8" |
29 | 29 | ||
30 | #define PHANTOM_MAX_MINORS 8 | 30 | #define PHANTOM_MAX_MINORS 8 |
31 | 31 | ||
@@ -456,8 +456,9 @@ static int phantom_resume(struct pci_dev *pdev) | |||
456 | #endif | 456 | #endif |
457 | 457 | ||
458 | static struct pci_device_id phantom_pci_tbl[] __devinitdata = { | 458 | static struct pci_device_id phantom_pci_tbl[] __devinitdata = { |
459 | { PCI_DEVICE(PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050), | 459 | { .vendor = PCI_VENDOR_ID_PLX, .device = PCI_DEVICE_ID_PLX_9050, |
460 | .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 }, | 460 | .subvendor = PCI_VENDOR_ID_PLX, .subdevice = PCI_DEVICE_ID_PLX_9050, |
461 | .class = PCI_CLASS_BRIDGE_OTHER << 8, .class_mask = 0xffff00 }, | ||
461 | { 0, } | 462 | { 0, } |
462 | }; | 463 | }; |
463 | MODULE_DEVICE_TABLE(pci, phantom_pci_tbl); | 464 | MODULE_DEVICE_TABLE(pci, phantom_pci_tbl); |
diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index be4b9948c762..eeaaa9dce6ef 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * block2mtd.c - create an mtd from a block device | 4 | * block2mtd.c - create an mtd from a block device |
5 | * | 5 | * |
6 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> | 6 | * Copyright (C) 2001,2002 Simon Evans <spse@secret.org.uk> |
7 | * Copyright (C) 2004-2006 Jörn Engel <joern@wh.fh-wedel.de> | 7 | * Copyright (C) 2004-2006 Joern Engel <joern@wh.fh-wedel.de> |
8 | * | 8 | * |
9 | * Licence: GPL | 9 | * Licence: GPL |
10 | */ | 10 | */ |
@@ -485,5 +485,5 @@ module_init(block2mtd_init); | |||
485 | module_exit(block2mtd_exit); | 485 | module_exit(block2mtd_exit); |
486 | 486 | ||
487 | MODULE_LICENSE("GPL"); | 487 | MODULE_LICENSE("GPL"); |
488 | MODULE_AUTHOR("Simon Evans <spse@secret.org.uk> and others"); | 488 | MODULE_AUTHOR("Joern Engel <joern@lazybastard.org>"); |
489 | MODULE_DESCRIPTION("Emulate an MTD using a block device"); | 489 | MODULE_DESCRIPTION("Emulate an MTD using a block device"); |
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 56cc1ca7ffd5..180298b92a7a 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $ | 2 | * $Id: phram.c,v 1.16 2005/11/07 11:14:25 gleixner Exp $ |
3 | * | 3 | * |
4 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> | 4 | * Copyright (c) ???? Jochen Schäuble <psionic@psionic.de> |
5 | * Copyright (c) 2003-2004 Jörn Engel <joern@wh.fh-wedel.de> | 5 | * Copyright (c) 2003-2004 Joern Engel <joern@wh.fh-wedel.de> |
6 | * | 6 | * |
7 | * Usage: | 7 | * Usage: |
8 | * | 8 | * |
@@ -299,5 +299,5 @@ module_init(init_phram); | |||
299 | module_exit(cleanup_phram); | 299 | module_exit(cleanup_phram); |
300 | 300 | ||
301 | MODULE_LICENSE("GPL"); | 301 | MODULE_LICENSE("GPL"); |
302 | MODULE_AUTHOR("Jörn Engel <joern@wh.fh-wedel.de>"); | 302 | MODULE_AUTHOR("Joern Engel <joern@wh.fh-wedel.de>"); |
303 | MODULE_DESCRIPTION("MTD driver for physical RAM"); | 303 | MODULE_DESCRIPTION("MTD driver for physical RAM"); |
diff --git a/drivers/mtd/maps/mtx-1_flash.c b/drivers/mtd/maps/mtx-1_flash.c index d884f2be28f6..2a8fde9b92f0 100644 --- a/drivers/mtd/maps/mtx-1_flash.c +++ b/drivers/mtd/maps/mtx-1_flash.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $ | 4 | * $Id: mtx-1_flash.c,v 1.2 2005/11/07 11:14:27 gleixner Exp $ |
5 | * | 5 | * |
6 | * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz> | 6 | * (C) 2005 Bruno Randolf <bruno.randolf@4g-systems.biz> |
7 | * (C) 2005 Jörn Engel <joern@wohnheim.fh-wedel.de> | 7 | * (C) 2005 Joern Engel <joern@wohnheim.fh-wedel.de> |
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index e9743d3efaf6..238628d3a854 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -1540,6 +1540,38 @@ static void __devinit detect_and_report_smsc (void) | |||
1540 | smsc_check(0x3f0,0x44); | 1540 | smsc_check(0x3f0,0x44); |
1541 | smsc_check(0x370,0x44); | 1541 | smsc_check(0x370,0x44); |
1542 | } | 1542 | } |
1543 | |||
1544 | static void __devinit detect_and_report_it87(void) | ||
1545 | { | ||
1546 | u16 dev; | ||
1547 | u8 r; | ||
1548 | if (verbose_probing) | ||
1549 | printk(KERN_DEBUG "IT8705 Super-IO detection, now testing port 2E ...\n"); | ||
1550 | if (!request_region(0x2e, 1, __FUNCTION__)) | ||
1551 | return; | ||
1552 | outb(0x87, 0x2e); | ||
1553 | outb(0x01, 0x2e); | ||
1554 | outb(0x55, 0x2e); | ||
1555 | outb(0x55, 0x2e); | ||
1556 | outb(0x20, 0x2e); | ||
1557 | dev = inb(0x2f) << 8; | ||
1558 | outb(0x21, 0x2e); | ||
1559 | dev |= inb(0x2f); | ||
1560 | if (dev == 0x8712 || dev == 0x8705 || dev == 0x8715 || | ||
1561 | dev == 0x8716 || dev == 0x8718 || dev == 0x8726) { | ||
1562 | printk(KERN_INFO "IT%04X SuperIO detected.\n", dev); | ||
1563 | outb(0x07, 0x2E); /* Parallel Port */ | ||
1564 | outb(0x03, 0x2F); | ||
1565 | outb(0xF0, 0x2E); /* BOOT 0x80 off */ | ||
1566 | r = inb(0x2f); | ||
1567 | outb(0xF0, 0x2E); | ||
1568 | outb(r | 8, 0x2F); | ||
1569 | outb(0x02, 0x2E); /* Lock */ | ||
1570 | outb(0x02, 0x2F); | ||
1571 | |||
1572 | release_region(0x2e, 1); | ||
1573 | } | ||
1574 | } | ||
1543 | #endif /* CONFIG_PARPORT_PC_SUPERIO */ | 1575 | #endif /* CONFIG_PARPORT_PC_SUPERIO */ |
1544 | 1576 | ||
1545 | static int get_superio_dma (struct parport *p) | 1577 | static int get_superio_dma (struct parport *p) |
@@ -2767,6 +2799,7 @@ enum parport_pc_pci_cards { | |||
2767 | netmos_9755, | 2799 | netmos_9755, |
2768 | netmos_9805, | 2800 | netmos_9805, |
2769 | netmos_9815, | 2801 | netmos_9815, |
2802 | quatech_sppxp100, | ||
2770 | }; | 2803 | }; |
2771 | 2804 | ||
2772 | 2805 | ||
@@ -2843,6 +2876,7 @@ static struct parport_pc_pci { | |||
2843 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */ | 2876 | /* netmos_9755 */ { 2, { { 0, 1 }, { 2, 3 },} }, /* untested */ |
2844 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ | 2877 | /* netmos_9805 */ { 1, { { 0, -1 }, } }, /* untested */ |
2845 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ | 2878 | /* netmos_9815 */ { 2, { { 0, -1 }, { 2, -1 }, } }, /* untested */ |
2879 | /* quatech_sppxp100 */ { 1, { { 0, 1 }, } }, | ||
2846 | }; | 2880 | }; |
2847 | 2881 | ||
2848 | static const struct pci_device_id parport_pc_pci_tbl[] = { | 2882 | static const struct pci_device_id parport_pc_pci_tbl[] = { |
@@ -2926,6 +2960,9 @@ static const struct pci_device_id parport_pc_pci_tbl[] = { | |||
2926 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, | 2960 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9805 }, |
2927 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, | 2961 | { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9815, |
2928 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, | 2962 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9815 }, |
2963 | /* Quatech SPPXP-100 Parallel port PCI ExpressCard */ | ||
2964 | { PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SPPXP_100, | ||
2965 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, quatech_sppxp100 }, | ||
2929 | { 0, } /* terminate list */ | 2966 | { 0, } /* terminate list */ |
2930 | }; | 2967 | }; |
2931 | MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); | 2968 | MODULE_DEVICE_TABLE(pci,parport_pc_pci_tbl); |
@@ -3159,24 +3196,25 @@ static void __init parport_pc_find_ports (int autoirq, int autodma) | |||
3159 | int count = 0, err; | 3196 | int count = 0, err; |
3160 | 3197 | ||
3161 | #ifdef CONFIG_PARPORT_PC_SUPERIO | 3198 | #ifdef CONFIG_PARPORT_PC_SUPERIO |
3162 | detect_and_report_winbond (); | 3199 | detect_and_report_it87(); |
3163 | detect_and_report_smsc (); | 3200 | detect_and_report_winbond(); |
3201 | detect_and_report_smsc(); | ||
3164 | #endif | 3202 | #endif |
3165 | 3203 | ||
3166 | /* Onboard SuperIO chipsets that show themselves on the PCI bus. */ | 3204 | /* Onboard SuperIO chipsets that show themselves on the PCI bus. */ |
3167 | count += parport_pc_init_superio (autoirq, autodma); | 3205 | count += parport_pc_init_superio(autoirq, autodma); |
3168 | 3206 | ||
3169 | /* PnP ports, skip detection if SuperIO already found them */ | 3207 | /* PnP ports, skip detection if SuperIO already found them */ |
3170 | if (!count) { | 3208 | if (!count) { |
3171 | err = pnp_register_driver (&parport_pc_pnp_driver); | 3209 | err = pnp_register_driver(&parport_pc_pnp_driver); |
3172 | if (!err) | 3210 | if (!err) |
3173 | pnp_registered_parport = 1; | 3211 | pnp_registered_parport = 1; |
3174 | } | 3212 | } |
3175 | 3213 | ||
3176 | /* ISA ports and whatever (see asm/parport.h). */ | 3214 | /* ISA ports and whatever (see asm/parport.h). */ |
3177 | parport_pc_find_nonpci_ports (autoirq, autodma); | 3215 | parport_pc_find_nonpci_ports(autoirq, autodma); |
3178 | 3216 | ||
3179 | err = pci_register_driver (&parport_pc_pci_driver); | 3217 | err = pci_register_driver(&parport_pc_pci_driver); |
3180 | if (!err) | 3218 | if (!err) |
3181 | pci_registered_parport = 1; | 3219 | pci_registered_parport = 1; |
3182 | } | 3220 | } |
diff --git a/drivers/parport/parport_serial.c b/drivers/parport/parport_serial.c index bd6ad8b38168..e2e95b36a603 100644 --- a/drivers/parport/parport_serial.c +++ b/drivers/parport/parport_serial.c | |||
@@ -77,7 +77,7 @@ static struct parport_pc_pci cards[] __devinitdata = { | |||
77 | /* titan_110l */ { 1, { { 3, -1 }, } }, | 77 | /* titan_110l */ { 1, { { 3, -1 }, } }, |
78 | /* titan_210l */ { 1, { { 3, -1 }, } }, | 78 | /* titan_210l */ { 1, { { 3, -1 }, } }, |
79 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, | 79 | /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, |
80 | /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, | 80 | /* netmos_9855 */ { 1, { { 2, -1 }, }, netmos_parallel_init }, |
81 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, | 81 | /* avlab_1s1p */ { 1, { { 1, 2}, } }, |
82 | /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, | 82 | /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, |
83 | /* avlab_2s1p */ { 1, { { 2, 3}, } }, | 83 | /* avlab_2s1p */ { 1, { { 2, 3}, } }, |
@@ -185,7 +185,7 @@ static struct pciserial_board pci_parport_serial_boards[] __devinitdata = { | |||
185 | .uart_offset = 8, | 185 | .uart_offset = 8, |
186 | }, | 186 | }, |
187 | [netmos_9855] = { | 187 | [netmos_9855] = { |
188 | .flags = FL_BASE2 | FL_BASE_BARS, | 188 | .flags = FL_BASE4 | FL_BASE_BARS, |
189 | .num_ports = 1, | 189 | .num_ports = 1, |
190 | .base_baud = 115200, | 190 | .base_baud = 115200, |
191 | .uart_offset = 8, | 191 | .uart_offset = 8, |
diff --git a/drivers/pci/dmar.c b/drivers/pci/dmar.c index 91b2dc956be5..8ed26480371f 100644 --- a/drivers/pci/dmar.c +++ b/drivers/pci/dmar.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/dmar.h> | 27 | #include <linux/dmar.h> |
28 | #include "iova.h" | 28 | #include "iova.h" |
29 | #include "intel-iommu.h" | ||
29 | 30 | ||
30 | #undef PREFIX | 31 | #undef PREFIX |
31 | #define PREFIX "DMAR:" | 32 | #define PREFIX "DMAR:" |
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c index 4e01df99681a..31fa6c92aa5e 100644 --- a/drivers/pci/intel-iommu.c +++ b/drivers/pci/intel-iommu.c | |||
@@ -1088,7 +1088,7 @@ static void dmar_init_reserved_ranges(void) | |||
1088 | int i; | 1088 | int i; |
1089 | u64 addr, size; | 1089 | u64 addr, size; |
1090 | 1090 | ||
1091 | init_iova_domain(&reserved_iova_list); | 1091 | init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN); |
1092 | 1092 | ||
1093 | /* IOAPIC ranges shouldn't be accessed by DMA */ | 1093 | /* IOAPIC ranges shouldn't be accessed by DMA */ |
1094 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), | 1094 | iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START), |
@@ -1142,7 +1142,7 @@ static int domain_init(struct dmar_domain *domain, int guest_width) | |||
1142 | int adjust_width, agaw; | 1142 | int adjust_width, agaw; |
1143 | unsigned long sagaw; | 1143 | unsigned long sagaw; |
1144 | 1144 | ||
1145 | init_iova_domain(&domain->iovad); | 1145 | init_iova_domain(&domain->iovad, DMA_32BIT_PFN); |
1146 | spin_lock_init(&domain->mapping_lock); | 1146 | spin_lock_init(&domain->mapping_lock); |
1147 | 1147 | ||
1148 | domain_reserve_special_ranges(domain); | 1148 | domain_reserve_special_ranges(domain); |
diff --git a/drivers/pci/intel-iommu.h b/drivers/pci/intel-iommu.h index 459ad1f9dc54..0e4862675ad2 100644 --- a/drivers/pci/intel-iommu.h +++ b/drivers/pci/intel-iommu.h | |||
@@ -23,10 +23,24 @@ | |||
23 | 23 | ||
24 | #include <linux/types.h> | 24 | #include <linux/types.h> |
25 | #include <linux/msi.h> | 25 | #include <linux/msi.h> |
26 | #include <linux/sysdev.h> | ||
26 | #include "iova.h" | 27 | #include "iova.h" |
27 | #include <linux/io.h> | 28 | #include <linux/io.h> |
28 | 29 | ||
29 | /* | 30 | /* |
31 | * We need a fixed PAGE_SIZE of 4K irrespective of | ||
32 | * arch PAGE_SIZE for IOMMU page tables. | ||
33 | */ | ||
34 | #define PAGE_SHIFT_4K (12) | ||
35 | #define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) | ||
36 | #define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) | ||
37 | #define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) | ||
38 | |||
39 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K) | ||
40 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) | ||
41 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) | ||
42 | |||
43 | /* | ||
30 | * Intel IOMMU register specification per version 1.0 public spec. | 44 | * Intel IOMMU register specification per version 1.0 public spec. |
31 | */ | 45 | */ |
32 | 46 | ||
diff --git a/drivers/pci/iova.c b/drivers/pci/iova.c index a84571c29360..8de7ab6c6d0c 100644 --- a/drivers/pci/iova.c +++ b/drivers/pci/iova.c | |||
@@ -9,19 +9,19 @@ | |||
9 | #include "iova.h" | 9 | #include "iova.h" |
10 | 10 | ||
11 | void | 11 | void |
12 | init_iova_domain(struct iova_domain *iovad) | 12 | init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit) |
13 | { | 13 | { |
14 | spin_lock_init(&iovad->iova_alloc_lock); | 14 | spin_lock_init(&iovad->iova_alloc_lock); |
15 | spin_lock_init(&iovad->iova_rbtree_lock); | 15 | spin_lock_init(&iovad->iova_rbtree_lock); |
16 | iovad->rbroot = RB_ROOT; | 16 | iovad->rbroot = RB_ROOT; |
17 | iovad->cached32_node = NULL; | 17 | iovad->cached32_node = NULL; |
18 | 18 | iovad->dma_32bit_pfn = pfn_32bit; | |
19 | } | 19 | } |
20 | 20 | ||
21 | static struct rb_node * | 21 | static struct rb_node * |
22 | __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn) | 22 | __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn) |
23 | { | 23 | { |
24 | if ((*limit_pfn != DMA_32BIT_PFN) || | 24 | if ((*limit_pfn != iovad->dma_32bit_pfn) || |
25 | (iovad->cached32_node == NULL)) | 25 | (iovad->cached32_node == NULL)) |
26 | return rb_last(&iovad->rbroot); | 26 | return rb_last(&iovad->rbroot); |
27 | else { | 27 | else { |
@@ -37,7 +37,7 @@ static void | |||
37 | __cached_rbnode_insert_update(struct iova_domain *iovad, | 37 | __cached_rbnode_insert_update(struct iova_domain *iovad, |
38 | unsigned long limit_pfn, struct iova *new) | 38 | unsigned long limit_pfn, struct iova *new) |
39 | { | 39 | { |
40 | if (limit_pfn != DMA_32BIT_PFN) | 40 | if (limit_pfn != iovad->dma_32bit_pfn) |
41 | return; | 41 | return; |
42 | iovad->cached32_node = &new->node; | 42 | iovad->cached32_node = &new->node; |
43 | } | 43 | } |
diff --git a/drivers/pci/iova.h b/drivers/pci/iova.h index ae3028d5a941..d521b5b7319c 100644 --- a/drivers/pci/iova.h +++ b/drivers/pci/iova.h | |||
@@ -15,22 +15,9 @@ | |||
15 | #include <linux/rbtree.h> | 15 | #include <linux/rbtree.h> |
16 | #include <linux/dma-mapping.h> | 16 | #include <linux/dma-mapping.h> |
17 | 17 | ||
18 | /* | ||
19 | * We need a fixed PAGE_SIZE of 4K irrespective of | ||
20 | * arch PAGE_SIZE for IOMMU page tables. | ||
21 | */ | ||
22 | #define PAGE_SHIFT_4K (12) | ||
23 | #define PAGE_SIZE_4K (1UL << PAGE_SHIFT_4K) | ||
24 | #define PAGE_MASK_4K (((u64)-1) << PAGE_SHIFT_4K) | ||
25 | #define PAGE_ALIGN_4K(addr) (((addr) + PAGE_SIZE_4K - 1) & PAGE_MASK_4K) | ||
26 | |||
27 | /* IO virtual address start page frame number */ | 18 | /* IO virtual address start page frame number */ |
28 | #define IOVA_START_PFN (1) | 19 | #define IOVA_START_PFN (1) |
29 | 20 | ||
30 | #define IOVA_PFN(addr) ((addr) >> PAGE_SHIFT_4K) | ||
31 | #define DMA_32BIT_PFN IOVA_PFN(DMA_32BIT_MASK) | ||
32 | #define DMA_64BIT_PFN IOVA_PFN(DMA_64BIT_MASK) | ||
33 | |||
34 | /* iova structure */ | 21 | /* iova structure */ |
35 | struct iova { | 22 | struct iova { |
36 | struct rb_node node; | 23 | struct rb_node node; |
@@ -44,6 +31,7 @@ struct iova_domain { | |||
44 | spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ | 31 | spinlock_t iova_rbtree_lock; /* Lock to protect update of rbtree */ |
45 | struct rb_root rbroot; /* iova domain rbtree root */ | 32 | struct rb_root rbroot; /* iova domain rbtree root */ |
46 | struct rb_node *cached32_node; /* Save last alloced node */ | 33 | struct rb_node *cached32_node; /* Save last alloced node */ |
34 | unsigned long dma_32bit_pfn; | ||
47 | }; | 35 | }; |
48 | 36 | ||
49 | struct iova *alloc_iova_mem(void); | 37 | struct iova *alloc_iova_mem(void); |
@@ -56,7 +44,7 @@ struct iova *alloc_iova(struct iova_domain *iovad, unsigned long size, | |||
56 | struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, | 44 | struct iova *reserve_iova(struct iova_domain *iovad, unsigned long pfn_lo, |
57 | unsigned long pfn_hi); | 45 | unsigned long pfn_hi); |
58 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); | 46 | void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to); |
59 | void init_iova_domain(struct iova_domain *iovad); | 47 | void init_iova_domain(struct iova_domain *iovad, unsigned long pfn_32bit); |
60 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); | 48 | struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn); |
61 | void put_iova_domain(struct iova_domain *iovad); | 49 | void put_iova_domain(struct iova_domain *iovad); |
62 | 50 | ||
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index a262762c5b88..12a1645a2e43 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c | |||
@@ -161,8 +161,7 @@ static int pnp_bus_suspend(struct device *dev, pm_message_t state) | |||
161 | return error; | 161 | return error; |
162 | } | 162 | } |
163 | 163 | ||
164 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE) && | 164 | if (pnp_can_disable(pnp_dev)) { |
165 | pnp_can_disable(pnp_dev)) { | ||
166 | error = pnp_stop_dev(pnp_dev); | 165 | error = pnp_stop_dev(pnp_dev); |
167 | if (error) | 166 | if (error) |
168 | return error; | 167 | return error; |
@@ -185,14 +184,17 @@ static int pnp_bus_resume(struct device *dev) | |||
185 | if (pnp_dev->protocol && pnp_dev->protocol->resume) | 184 | if (pnp_dev->protocol && pnp_dev->protocol->resume) |
186 | pnp_dev->protocol->resume(pnp_dev); | 185 | pnp_dev->protocol->resume(pnp_dev); |
187 | 186 | ||
188 | if (!(pnp_drv->flags & PNP_DRIVER_RES_DO_NOT_CHANGE)) { | 187 | if (pnp_can_write(pnp_dev)) { |
189 | error = pnp_start_dev(pnp_dev); | 188 | error = pnp_start_dev(pnp_dev); |
190 | if (error) | 189 | if (error) |
191 | return error; | 190 | return error; |
192 | } | 191 | } |
193 | 192 | ||
194 | if (pnp_drv->resume) | 193 | if (pnp_drv->resume) { |
195 | return pnp_drv->resume(pnp_dev); | 194 | error = pnp_drv->resume(pnp_dev); |
195 | if (error) | ||
196 | return error; | ||
197 | } | ||
196 | 198 | ||
197 | return 0; | 199 | return 0; |
198 | } | 200 | } |
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index 31548044fdde..982658477a58 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c | |||
@@ -10,9 +10,12 @@ | |||
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/types.h> | 12 | #include <linux/types.h> |
13 | #include <linux/pnp.h> | ||
13 | #include <linux/stat.h> | 14 | #include <linux/stat.h> |
14 | #include <linux/ctype.h> | 15 | #include <linux/ctype.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/mutex.h> | ||
18 | |||
16 | #include <asm/uaccess.h> | 19 | #include <asm/uaccess.h> |
17 | 20 | ||
18 | #include "base.h" | 21 | #include "base.h" |
@@ -315,8 +318,6 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, | |||
315 | return ret; | 318 | return ret; |
316 | } | 319 | } |
317 | 320 | ||
318 | extern struct semaphore pnp_res_mutex; | ||
319 | |||
320 | static ssize_t | 321 | static ssize_t |
321 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | 322 | pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, |
322 | const char *ubuf, size_t count) | 323 | const char *ubuf, size_t count) |
@@ -361,10 +362,10 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
361 | goto done; | 362 | goto done; |
362 | } | 363 | } |
363 | if (!strnicmp(buf, "get", 3)) { | 364 | if (!strnicmp(buf, "get", 3)) { |
364 | down(&pnp_res_mutex); | 365 | mutex_lock(&pnp_res_mutex); |
365 | if (pnp_can_read(dev)) | 366 | if (pnp_can_read(dev)) |
366 | dev->protocol->get(dev, &dev->res); | 367 | dev->protocol->get(dev, &dev->res); |
367 | up(&pnp_res_mutex); | 368 | mutex_unlock(&pnp_res_mutex); |
368 | goto done; | 369 | goto done; |
369 | } | 370 | } |
370 | if (!strnicmp(buf, "set", 3)) { | 371 | if (!strnicmp(buf, "set", 3)) { |
@@ -373,7 +374,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
373 | goto done; | 374 | goto done; |
374 | buf += 3; | 375 | buf += 3; |
375 | pnp_init_resource_table(&dev->res); | 376 | pnp_init_resource_table(&dev->res); |
376 | down(&pnp_res_mutex); | 377 | mutex_lock(&pnp_res_mutex); |
377 | while (1) { | 378 | while (1) { |
378 | while (isspace(*buf)) | 379 | while (isspace(*buf)) |
379 | ++buf; | 380 | ++buf; |
@@ -455,7 +456,7 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, | |||
455 | } | 456 | } |
456 | break; | 457 | break; |
457 | } | 458 | } |
458 | up(&pnp_res_mutex); | 459 | mutex_unlock(&pnp_res_mutex); |
459 | goto done; | 460 | goto done; |
460 | } | 461 | } |
461 | 462 | ||
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c6b3d4e63ccc..c28caf272c11 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -12,9 +12,10 @@ | |||
12 | #include <linux/pnp.h> | 12 | #include <linux/pnp.h> |
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/bitmap.h> | 14 | #include <linux/bitmap.h> |
15 | #include <linux/mutex.h> | ||
15 | #include "base.h" | 16 | #include "base.h" |
16 | 17 | ||
17 | DECLARE_MUTEX(pnp_res_mutex); | 18 | DEFINE_MUTEX(pnp_res_mutex); |
18 | 19 | ||
19 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) | 20 | static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) |
20 | { | 21 | { |
@@ -297,7 +298,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
297 | if (!pnp_can_configure(dev)) | 298 | if (!pnp_can_configure(dev)) |
298 | return -ENODEV; | 299 | return -ENODEV; |
299 | 300 | ||
300 | down(&pnp_res_mutex); | 301 | mutex_lock(&pnp_res_mutex); |
301 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ | 302 | pnp_clean_resource_table(&dev->res); /* start with a fresh slate */ |
302 | if (dev->independent) { | 303 | if (dev->independent) { |
303 | port = dev->independent->port; | 304 | port = dev->independent->port; |
@@ -366,12 +367,12 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) | |||
366 | } else if (dev->dependent) | 367 | } else if (dev->dependent) |
367 | goto fail; | 368 | goto fail; |
368 | 369 | ||
369 | up(&pnp_res_mutex); | 370 | mutex_unlock(&pnp_res_mutex); |
370 | return 1; | 371 | return 1; |
371 | 372 | ||
372 | fail: | 373 | fail: |
373 | pnp_clean_resource_table(&dev->res); | 374 | pnp_clean_resource_table(&dev->res); |
374 | up(&pnp_res_mutex); | 375 | mutex_unlock(&pnp_res_mutex); |
375 | return 0; | 376 | return 0; |
376 | } | 377 | } |
377 | 378 | ||
@@ -396,7 +397,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
396 | return -ENOMEM; | 397 | return -ENOMEM; |
397 | *bak = dev->res; | 398 | *bak = dev->res; |
398 | 399 | ||
399 | down(&pnp_res_mutex); | 400 | mutex_lock(&pnp_res_mutex); |
400 | dev->res = *res; | 401 | dev->res = *res; |
401 | if (!(mode & PNP_CONFIG_FORCE)) { | 402 | if (!(mode & PNP_CONFIG_FORCE)) { |
402 | for (i = 0; i < PNP_MAX_PORT; i++) { | 403 | for (i = 0; i < PNP_MAX_PORT; i++) { |
@@ -416,14 +417,14 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, | |||
416 | goto fail; | 417 | goto fail; |
417 | } | 418 | } |
418 | } | 419 | } |
419 | up(&pnp_res_mutex); | 420 | mutex_unlock(&pnp_res_mutex); |
420 | 421 | ||
421 | kfree(bak); | 422 | kfree(bak); |
422 | return 0; | 423 | return 0; |
423 | 424 | ||
424 | fail: | 425 | fail: |
425 | dev->res = *bak; | 426 | dev->res = *bak; |
426 | up(&pnp_res_mutex); | 427 | mutex_unlock(&pnp_res_mutex); |
427 | kfree(bak); | 428 | kfree(bak); |
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | } | 430 | } |
@@ -513,7 +514,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
513 | int error; | 514 | int error; |
514 | 515 | ||
515 | if (dev->active) | 516 | if (dev->active) |
516 | return 0; /* the device is already active */ | 517 | return 0; |
517 | 518 | ||
518 | /* ensure resources are allocated */ | 519 | /* ensure resources are allocated */ |
519 | if (pnp_auto_config_dev(dev)) | 520 | if (pnp_auto_config_dev(dev)) |
@@ -524,7 +525,7 @@ int pnp_activate_dev(struct pnp_dev *dev) | |||
524 | return error; | 525 | return error; |
525 | 526 | ||
526 | dev->active = 1; | 527 | dev->active = 1; |
527 | return 1; | 528 | return 0; |
528 | } | 529 | } |
529 | 530 | ||
530 | /** | 531 | /** |
@@ -538,7 +539,7 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
538 | int error; | 539 | int error; |
539 | 540 | ||
540 | if (!dev->active) | 541 | if (!dev->active) |
541 | return 0; /* the device is already disabled */ | 542 | return 0; |
542 | 543 | ||
543 | error = pnp_stop_dev(dev); | 544 | error = pnp_stop_dev(dev); |
544 | if (error) | 545 | if (error) |
@@ -547,11 +548,11 @@ int pnp_disable_dev(struct pnp_dev *dev) | |||
547 | dev->active = 0; | 548 | dev->active = 0; |
548 | 549 | ||
549 | /* release the resources so that other devices can use them */ | 550 | /* release the resources so that other devices can use them */ |
550 | down(&pnp_res_mutex); | 551 | mutex_lock(&pnp_res_mutex); |
551 | pnp_clean_resource_table(&dev->res); | 552 | pnp_clean_resource_table(&dev->res); |
552 | up(&pnp_res_mutex); | 553 | mutex_unlock(&pnp_res_mutex); |
553 | 554 | ||
554 | return 1; | 555 | return 0; |
555 | } | 556 | } |
556 | 557 | ||
557 | /** | 558 | /** |
diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 6b9840cce0f4..6aa231ef642d 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c | |||
@@ -391,8 +391,8 @@ acpi_status pnpacpi_parse_allocated_resource(acpi_handle handle, | |||
391 | pnpacpi_allocated_resource, res); | 391 | pnpacpi_allocated_resource, res); |
392 | } | 392 | } |
393 | 393 | ||
394 | static void pnpacpi_parse_dma_option(struct pnp_option *option, | 394 | static __init void pnpacpi_parse_dma_option(struct pnp_option *option, |
395 | struct acpi_resource_dma *p) | 395 | struct acpi_resource_dma *p) |
396 | { | 396 | { |
397 | int i; | 397 | int i; |
398 | struct pnp_dma *dma; | 398 | struct pnp_dma *dma; |
@@ -411,8 +411,8 @@ static void pnpacpi_parse_dma_option(struct pnp_option *option, | |||
411 | pnp_register_dma_resource(option, dma); | 411 | pnp_register_dma_resource(option, dma); |
412 | } | 412 | } |
413 | 413 | ||
414 | static void pnpacpi_parse_irq_option(struct pnp_option *option, | 414 | static __init void pnpacpi_parse_irq_option(struct pnp_option *option, |
415 | struct acpi_resource_irq *p) | 415 | struct acpi_resource_irq *p) |
416 | { | 416 | { |
417 | int i; | 417 | int i; |
418 | struct pnp_irq *irq; | 418 | struct pnp_irq *irq; |
@@ -431,8 +431,8 @@ static void pnpacpi_parse_irq_option(struct pnp_option *option, | |||
431 | pnp_register_irq_resource(option, irq); | 431 | pnp_register_irq_resource(option, irq); |
432 | } | 432 | } |
433 | 433 | ||
434 | static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | 434 | static __init void pnpacpi_parse_ext_irq_option(struct pnp_option *option, |
435 | struct acpi_resource_extended_irq *p) | 435 | struct acpi_resource_extended_irq *p) |
436 | { | 436 | { |
437 | int i; | 437 | int i; |
438 | struct pnp_irq *irq; | 438 | struct pnp_irq *irq; |
@@ -451,8 +451,8 @@ static void pnpacpi_parse_ext_irq_option(struct pnp_option *option, | |||
451 | pnp_register_irq_resource(option, irq); | 451 | pnp_register_irq_resource(option, irq); |
452 | } | 452 | } |
453 | 453 | ||
454 | static void pnpacpi_parse_port_option(struct pnp_option *option, | 454 | static __init void pnpacpi_parse_port_option(struct pnp_option *option, |
455 | struct acpi_resource_io *io) | 455 | struct acpi_resource_io *io) |
456 | { | 456 | { |
457 | struct pnp_port *port; | 457 | struct pnp_port *port; |
458 | 458 | ||
@@ -470,8 +470,8 @@ static void pnpacpi_parse_port_option(struct pnp_option *option, | |||
470 | pnp_register_port_resource(option, port); | 470 | pnp_register_port_resource(option, port); |
471 | } | 471 | } |
472 | 472 | ||
473 | static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | 473 | static __init void pnpacpi_parse_fixed_port_option(struct pnp_option *option, |
474 | struct acpi_resource_fixed_io *io) | 474 | struct acpi_resource_fixed_io *io) |
475 | { | 475 | { |
476 | struct pnp_port *port; | 476 | struct pnp_port *port; |
477 | 477 | ||
@@ -487,8 +487,8 @@ static void pnpacpi_parse_fixed_port_option(struct pnp_option *option, | |||
487 | pnp_register_port_resource(option, port); | 487 | pnp_register_port_resource(option, port); |
488 | } | 488 | } |
489 | 489 | ||
490 | static void pnpacpi_parse_mem24_option(struct pnp_option *option, | 490 | static __init void pnpacpi_parse_mem24_option(struct pnp_option *option, |
491 | struct acpi_resource_memory24 *p) | 491 | struct acpi_resource_memory24 *p) |
492 | { | 492 | { |
493 | struct pnp_mem *mem; | 493 | struct pnp_mem *mem; |
494 | 494 | ||
@@ -508,8 +508,8 @@ static void pnpacpi_parse_mem24_option(struct pnp_option *option, | |||
508 | pnp_register_mem_resource(option, mem); | 508 | pnp_register_mem_resource(option, mem); |
509 | } | 509 | } |
510 | 510 | ||
511 | static void pnpacpi_parse_mem32_option(struct pnp_option *option, | 511 | static __init void pnpacpi_parse_mem32_option(struct pnp_option *option, |
512 | struct acpi_resource_memory32 *p) | 512 | struct acpi_resource_memory32 *p) |
513 | { | 513 | { |
514 | struct pnp_mem *mem; | 514 | struct pnp_mem *mem; |
515 | 515 | ||
@@ -529,8 +529,8 @@ static void pnpacpi_parse_mem32_option(struct pnp_option *option, | |||
529 | pnp_register_mem_resource(option, mem); | 529 | pnp_register_mem_resource(option, mem); |
530 | } | 530 | } |
531 | 531 | ||
532 | static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | 532 | static __init void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, |
533 | struct acpi_resource_fixed_memory32 *p) | 533 | struct acpi_resource_fixed_memory32 *p) |
534 | { | 534 | { |
535 | struct pnp_mem *mem; | 535 | struct pnp_mem *mem; |
536 | 536 | ||
@@ -549,8 +549,8 @@ static void pnpacpi_parse_fixed_mem32_option(struct pnp_option *option, | |||
549 | pnp_register_mem_resource(option, mem); | 549 | pnp_register_mem_resource(option, mem); |
550 | } | 550 | } |
551 | 551 | ||
552 | static void pnpacpi_parse_address_option(struct pnp_option *option, | 552 | static __init void pnpacpi_parse_address_option(struct pnp_option *option, |
553 | struct acpi_resource *r) | 553 | struct acpi_resource *r) |
554 | { | 554 | { |
555 | struct acpi_resource_address64 addr, *p = &addr; | 555 | struct acpi_resource_address64 addr, *p = &addr; |
556 | acpi_status status; | 556 | acpi_status status; |
@@ -596,8 +596,8 @@ struct acpipnp_parse_option_s { | |||
596 | struct pnp_dev *dev; | 596 | struct pnp_dev *dev; |
597 | }; | 597 | }; |
598 | 598 | ||
599 | static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | 599 | static __init acpi_status pnpacpi_option_resource(struct acpi_resource *res, |
600 | void *data) | 600 | void *data) |
601 | { | 601 | { |
602 | int priority = 0; | 602 | int priority = 0; |
603 | struct acpipnp_parse_option_s *parse_data = data; | 603 | struct acpipnp_parse_option_s *parse_data = data; |
@@ -696,8 +696,8 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, | |||
696 | return AE_OK; | 696 | return AE_OK; |
697 | } | 697 | } |
698 | 698 | ||
699 | acpi_status pnpacpi_parse_resource_option_data(acpi_handle handle, | 699 | acpi_status __init pnpacpi_parse_resource_option_data(acpi_handle handle, |
700 | struct pnp_dev * dev) | 700 | struct pnp_dev *dev) |
701 | { | 701 | { |
702 | acpi_status status; | 702 | acpi_status status; |
703 | struct acpipnp_parse_option_s parse_data; | 703 | struct acpipnp_parse_option_s parse_data; |
diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index e33e03f71084..f7e67197a568 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c | |||
@@ -315,7 +315,7 @@ struct pnp_protocol pnpbios_protocol = { | |||
315 | .disable = pnpbios_disable_resources, | 315 | .disable = pnpbios_disable_resources, |
316 | }; | 316 | }; |
317 | 317 | ||
318 | static int insert_device(struct pnp_bios_node *node) | 318 | static int __init insert_device(struct pnp_bios_node *node) |
319 | { | 319 | { |
320 | struct list_head *pos; | 320 | struct list_head *pos; |
321 | struct pnp_dev *dev; | 321 | struct pnp_dev *dev; |
diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 3fabf11b0027..caade3531416 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c | |||
@@ -262,8 +262,8 @@ len_err: | |||
262 | * Resource Configuration Options | 262 | * Resource Configuration Options |
263 | */ | 263 | */ |
264 | 264 | ||
265 | static void pnpbios_parse_mem_option(unsigned char *p, int size, | 265 | static __init void pnpbios_parse_mem_option(unsigned char *p, int size, |
266 | struct pnp_option *option) | 266 | struct pnp_option *option) |
267 | { | 267 | { |
268 | struct pnp_mem *mem; | 268 | struct pnp_mem *mem; |
269 | 269 | ||
@@ -278,8 +278,8 @@ static void pnpbios_parse_mem_option(unsigned char *p, int size, | |||
278 | pnp_register_mem_resource(option, mem); | 278 | pnp_register_mem_resource(option, mem); |
279 | } | 279 | } |
280 | 280 | ||
281 | static void pnpbios_parse_mem32_option(unsigned char *p, int size, | 281 | static __init void pnpbios_parse_mem32_option(unsigned char *p, int size, |
282 | struct pnp_option *option) | 282 | struct pnp_option *option) |
283 | { | 283 | { |
284 | struct pnp_mem *mem; | 284 | struct pnp_mem *mem; |
285 | 285 | ||
@@ -294,8 +294,8 @@ static void pnpbios_parse_mem32_option(unsigned char *p, int size, | |||
294 | pnp_register_mem_resource(option, mem); | 294 | pnp_register_mem_resource(option, mem); |
295 | } | 295 | } |
296 | 296 | ||
297 | static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | 297 | static __init void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, |
298 | struct pnp_option *option) | 298 | struct pnp_option *option) |
299 | { | 299 | { |
300 | struct pnp_mem *mem; | 300 | struct pnp_mem *mem; |
301 | 301 | ||
@@ -309,7 +309,7 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, | |||
309 | pnp_register_mem_resource(option, mem); | 309 | pnp_register_mem_resource(option, mem); |
310 | } | 310 | } |
311 | 311 | ||
312 | static void pnpbios_parse_irq_option(unsigned char *p, int size, | 312 | static __init void pnpbios_parse_irq_option(unsigned char *p, int size, |
313 | struct pnp_option *option) | 313 | struct pnp_option *option) |
314 | { | 314 | { |
315 | struct pnp_irq *irq; | 315 | struct pnp_irq *irq; |
@@ -327,7 +327,7 @@ static void pnpbios_parse_irq_option(unsigned char *p, int size, | |||
327 | pnp_register_irq_resource(option, irq); | 327 | pnp_register_irq_resource(option, irq); |
328 | } | 328 | } |
329 | 329 | ||
330 | static void pnpbios_parse_dma_option(unsigned char *p, int size, | 330 | static __init void pnpbios_parse_dma_option(unsigned char *p, int size, |
331 | struct pnp_option *option) | 331 | struct pnp_option *option) |
332 | { | 332 | { |
333 | struct pnp_dma *dma; | 333 | struct pnp_dma *dma; |
@@ -340,8 +340,8 @@ static void pnpbios_parse_dma_option(unsigned char *p, int size, | |||
340 | pnp_register_dma_resource(option, dma); | 340 | pnp_register_dma_resource(option, dma); |
341 | } | 341 | } |
342 | 342 | ||
343 | static void pnpbios_parse_port_option(unsigned char *p, int size, | 343 | static __init void pnpbios_parse_port_option(unsigned char *p, int size, |
344 | struct pnp_option *option) | 344 | struct pnp_option *option) |
345 | { | 345 | { |
346 | struct pnp_port *port; | 346 | struct pnp_port *port; |
347 | 347 | ||
@@ -356,8 +356,8 @@ static void pnpbios_parse_port_option(unsigned char *p, int size, | |||
356 | pnp_register_port_resource(option, port); | 356 | pnp_register_port_resource(option, port); |
357 | } | 357 | } |
358 | 358 | ||
359 | static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | 359 | static __init void pnpbios_parse_fixed_port_option(unsigned char *p, int size, |
360 | struct pnp_option *option) | 360 | struct pnp_option *option) |
361 | { | 361 | { |
362 | struct pnp_port *port; | 362 | struct pnp_port *port; |
363 | 363 | ||
@@ -371,9 +371,9 @@ static void pnpbios_parse_fixed_port_option(unsigned char *p, int size, | |||
371 | pnp_register_port_resource(option, port); | 371 | pnp_register_port_resource(option, port); |
372 | } | 372 | } |
373 | 373 | ||
374 | static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, | 374 | static __init unsigned char * |
375 | unsigned char *end, | 375 | pnpbios_parse_resource_option_data(unsigned char *p, unsigned char *end, |
376 | struct pnp_dev *dev) | 376 | struct pnp_dev *dev) |
377 | { | 377 | { |
378 | unsigned int len, tag; | 378 | unsigned int len, tag; |
379 | int priority = 0; | 379 | int priority = 0; |
@@ -781,7 +781,8 @@ len_err: | |||
781 | * Core Parsing Functions | 781 | * Core Parsing Functions |
782 | */ | 782 | */ |
783 | 783 | ||
784 | int pnpbios_parse_data_stream(struct pnp_dev *dev, struct pnp_bios_node *node) | 784 | int __init pnpbios_parse_data_stream(struct pnp_dev *dev, |
785 | struct pnp_bios_node *node) | ||
785 | { | 786 | { |
786 | unsigned char *p = (char *)node->data; | 787 | unsigned char *p = (char *)node->data; |
787 | unsigned char *end = (char *)(node->data + node->size); | 788 | unsigned char *end = (char *)(node->data + node->size); |
diff --git a/drivers/pnp/quirks.c b/drivers/pnp/quirks.c index e903b8c2b1fa..4065139753b6 100644 --- a/drivers/pnp/quirks.c +++ b/drivers/pnp/quirks.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <linux/pnp.h> | 18 | #include <linux/pnp.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | #include <linux/dmi.h> | ||
20 | #include <linux/kallsyms.h> | 21 | #include <linux/kallsyms.h> |
21 | #include "base.h" | 22 | #include "base.h" |
22 | 23 | ||
@@ -108,6 +109,46 @@ static void quirk_sb16audio_resources(struct pnp_dev *dev) | |||
108 | "pnp: SB audio device quirk - increasing port range\n"); | 109 | "pnp: SB audio device quirk - increasing port range\n"); |
109 | } | 110 | } |
110 | 111 | ||
112 | static void quirk_supermicro_h8dce_system(struct pnp_dev *dev) | ||
113 | { | ||
114 | int i; | ||
115 | static struct dmi_system_id supermicro_h8dce[] = { | ||
116 | { | ||
117 | .ident = "Supermicro H8DCE", | ||
118 | .matches = { | ||
119 | DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"), | ||
120 | DMI_MATCH(DMI_PRODUCT_NAME, "H8DCE"), | ||
121 | }, | ||
122 | }, | ||
123 | { } | ||
124 | }; | ||
125 | |||
126 | if (!dmi_check_system(supermicro_h8dce)) | ||
127 | return; | ||
128 | |||
129 | /* | ||
130 | * On the Supermicro H8DCE, there's a system device with resources | ||
131 | * that overlap BAR 6 of the built-in SATA PCI adapter. If the PNP | ||
132 | * system device claims them, the sata_nv driver won't be able to. | ||
133 | * More details at: | ||
134 | * https://bugzilla.redhat.com/show_bug.cgi?id=280641 | ||
135 | * https://bugzilla.redhat.com/show_bug.cgi?id=313491 | ||
136 | * http://lkml.org/lkml/2008/1/9/449 | ||
137 | * http://thread.gmane.org/gmane.linux.acpi.devel/27312 | ||
138 | */ | ||
139 | for (i = 0; i < PNP_MAX_MEM; i++) { | ||
140 | if (pnp_mem_valid(dev, i) && pnp_mem_len(dev, i) && | ||
141 | (pnp_mem_start(dev, i) & 0xdfef0000) == 0xdfef0000) { | ||
142 | dev_warn(&dev->dev, "disabling 0x%llx-0x%llx to prevent" | ||
143 | " conflict with sata_nv PCI device\n", | ||
144 | (unsigned long long) pnp_mem_start(dev, i), | ||
145 | (unsigned long long) (pnp_mem_start(dev, i) + | ||
146 | pnp_mem_len(dev, i) - 1)); | ||
147 | pnp_mem_flags(dev, i) = 0; | ||
148 | } | ||
149 | } | ||
150 | } | ||
151 | |||
111 | /* | 152 | /* |
112 | * PnP Quirks | 153 | * PnP Quirks |
113 | * Cards or devices that need some tweaking due to incomplete resource info | 154 | * Cards or devices that need some tweaking due to incomplete resource info |
@@ -128,6 +169,8 @@ static struct pnp_fixup pnp_fixups[] = { | |||
128 | {"CTL0043", quirk_sb16audio_resources}, | 169 | {"CTL0043", quirk_sb16audio_resources}, |
129 | {"CTL0044", quirk_sb16audio_resources}, | 170 | {"CTL0044", quirk_sb16audio_resources}, |
130 | {"CTL0045", quirk_sb16audio_resources}, | 171 | {"CTL0045", quirk_sb16audio_resources}, |
172 | {"PNP0c01", quirk_supermicro_h8dce_system}, | ||
173 | {"PNP0c02", quirk_supermicro_h8dce_system}, | ||
131 | {""} | 174 | {""} |
132 | }; | 175 | }; |
133 | 176 | ||
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c index 87b3493d88e5..6f2f90ebb020 100644 --- a/drivers/ps3/ps3av.c +++ b/drivers/ps3/ps3av.c | |||
@@ -78,23 +78,21 @@ static const struct avset_video_mode { | |||
78 | u32 aspect; | 78 | u32 aspect; |
79 | u32 x; | 79 | u32 x; |
80 | u32 y; | 80 | u32 y; |
81 | u32 interlace; | ||
82 | u32 freq; | ||
83 | } video_mode_table[] = { | 81 | } video_mode_table[] = { |
84 | { 0, }, /* auto */ | 82 | { 0, }, /* auto */ |
85 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480, 1, 60}, | 83 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480I, A_N, 720, 480}, |
86 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480, 0, 60}, | 84 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_480P, A_N, 720, 480}, |
87 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720, 0, 60}, | 85 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_60HZ, A_N, 1280, 720}, |
88 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080, 1, 60}, | 86 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_60HZ, A_W, 1920, 1080}, |
89 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080, 0, 60}, | 87 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_60HZ, A_W, 1920, 1080}, |
90 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576, 1, 50}, | 88 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576I, A_N, 720, 576}, |
91 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576, 0, 50}, | 89 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_576P, A_N, 720, 576}, |
92 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720, 0, 50}, | 90 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_720P_50HZ, A_N, 1280, 720}, |
93 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080, 1, 50}, | 91 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080I_50HZ, A_W, 1920, 1080}, |
94 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080, 0, 50}, | 92 | {YUV444, XRGB, PS3AV_CMD_VIDEO_VID_1080P_50HZ, A_W, 1920, 1080}, |
95 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768, 0, 60}, | 93 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WXGA, A_W, 1280, 768}, |
96 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024, 0, 60}, | 94 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_SXGA, A_N, 1280, 1024}, |
97 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200, 0, 60}, | 95 | { RGB8, XRGB, PS3AV_CMD_VIDEO_VID_WUXGA, A_W, 1920, 1200}, |
98 | }; | 96 | }; |
99 | 97 | ||
100 | /* supported CIDs */ | 98 | /* supported CIDs */ |
@@ -544,7 +542,7 @@ static void ps3av_set_videomode_packet(u32 id) | |||
544 | 542 | ||
545 | static void ps3av_set_videomode_cont(u32 id, u32 old_id) | 543 | static void ps3av_set_videomode_cont(u32 id, u32 old_id) |
546 | { | 544 | { |
547 | static int vesa = 0; | 545 | static int vesa; |
548 | int res; | 546 | int res; |
549 | 547 | ||
550 | /* video signal off */ | 548 | /* video signal off */ |
@@ -554,9 +552,9 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id) | |||
554 | * AV backend needs non-VESA mode setting at least one time | 552 | * AV backend needs non-VESA mode setting at least one time |
555 | * when VESA mode is used. | 553 | * when VESA mode is used. |
556 | */ | 554 | */ |
557 | if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) { | 555 | if (vesa == 0 && (id & PS3AV_MODE_MASK) >= PS3AV_MODE_WXGA) { |
558 | /* vesa mode */ | 556 | /* vesa mode */ |
559 | ps3av_set_videomode_packet(2); /* 480P */ | 557 | ps3av_set_videomode_packet(PS3AV_MODE_480P); |
560 | } | 558 | } |
561 | vesa = 1; | 559 | vesa = 1; |
562 | 560 | ||
@@ -596,20 +594,21 @@ static const struct { | |||
596 | unsigned mask : 19; | 594 | unsigned mask : 19; |
597 | unsigned id : 4; | 595 | unsigned id : 4; |
598 | } ps3av_preferred_modes[] = { | 596 | } ps3av_preferred_modes[] = { |
599 | { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 }, | 597 | { PS3AV_RESBIT_WUXGA << SHIFT_VESA, PS3AV_MODE_WUXGA }, |
600 | { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 }, | 598 | { PS3AV_RESBIT_1920x1080P << SHIFT_60, PS3AV_MODE_1080P60 }, |
601 | { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 }, | 599 | { PS3AV_RESBIT_1920x1080P << SHIFT_50, PS3AV_MODE_1080P50 }, |
602 | { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 }, | 600 | { PS3AV_RESBIT_1920x1080I << SHIFT_60, PS3AV_MODE_1080I60 }, |
603 | { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 }, | 601 | { PS3AV_RESBIT_1920x1080I << SHIFT_50, PS3AV_MODE_1080I50 }, |
604 | { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 }, | 602 | { PS3AV_RESBIT_SXGA << SHIFT_VESA, PS3AV_MODE_SXGA }, |
605 | { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 }, | 603 | { PS3AV_RESBIT_WXGA << SHIFT_VESA, PS3AV_MODE_WXGA }, |
606 | { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 }, | 604 | { PS3AV_RESBIT_1280x720P << SHIFT_60, PS3AV_MODE_720P60 }, |
607 | { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 }, | 605 | { PS3AV_RESBIT_1280x720P << SHIFT_50, PS3AV_MODE_720P50 }, |
608 | { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 }, | 606 | { PS3AV_RESBIT_720x480P << SHIFT_60, PS3AV_MODE_480P }, |
609 | { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 }, | 607 | { PS3AV_RESBIT_720x576P << SHIFT_50, PS3AV_MODE_576P }, |
610 | }; | 608 | }; |
611 | 609 | ||
612 | static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa) | 610 | static enum ps3av_mode_num ps3av_resbit2id(u32 res_50, u32 res_60, |
611 | u32 res_vesa) | ||
613 | { | 612 | { |
614 | unsigned int i; | 613 | unsigned int i; |
615 | u32 res_all; | 614 | u32 res_all; |
@@ -638,9 +637,9 @@ static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa) | |||
638 | return 0; | 637 | return 0; |
639 | } | 638 | } |
640 | 639 | ||
641 | static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) | 640 | static enum ps3av_mode_num ps3av_hdmi_get_id(struct ps3av_info_monitor *info) |
642 | { | 641 | { |
643 | int id; | 642 | enum ps3av_mode_num id; |
644 | 643 | ||
645 | if (safe_mode) | 644 | if (safe_mode) |
646 | return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; | 645 | return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; |
@@ -854,7 +853,7 @@ int ps3av_set_video_mode(u32 id) | |||
854 | 853 | ||
855 | /* auto mode */ | 854 | /* auto mode */ |
856 | option = id & ~PS3AV_MODE_MASK; | 855 | option = id & ~PS3AV_MODE_MASK; |
857 | if ((id & PS3AV_MODE_MASK) == 0) { | 856 | if ((id & PS3AV_MODE_MASK) == PS3AV_MODE_AUTO) { |
858 | id = ps3av_auto_videomode(&ps3av->av_hw_conf); | 857 | id = ps3av_auto_videomode(&ps3av->av_hw_conf); |
859 | if (id < 1) { | 858 | if (id < 1) { |
860 | printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); | 859 | printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); |
@@ -889,36 +888,6 @@ int ps3av_get_mode(void) | |||
889 | 888 | ||
890 | EXPORT_SYMBOL_GPL(ps3av_get_mode); | 889 | EXPORT_SYMBOL_GPL(ps3av_get_mode); |
891 | 890 | ||
892 | int ps3av_get_scanmode(int id) | ||
893 | { | ||
894 | int size; | ||
895 | |||
896 | id = id & PS3AV_MODE_MASK; | ||
897 | size = ARRAY_SIZE(video_mode_table); | ||
898 | if (id > size - 1 || id < 0) { | ||
899 | printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); | ||
900 | return -EINVAL; | ||
901 | } | ||
902 | return video_mode_table[id].interlace; | ||
903 | } | ||
904 | |||
905 | EXPORT_SYMBOL_GPL(ps3av_get_scanmode); | ||
906 | |||
907 | int ps3av_get_refresh_rate(int id) | ||
908 | { | ||
909 | int size; | ||
910 | |||
911 | id = id & PS3AV_MODE_MASK; | ||
912 | size = ARRAY_SIZE(video_mode_table); | ||
913 | if (id > size - 1 || id < 0) { | ||
914 | printk(KERN_ERR "%s: invalid mode %d\n", __func__, id); | ||
915 | return -EINVAL; | ||
916 | } | ||
917 | return video_mode_table[id].freq; | ||
918 | } | ||
919 | |||
920 | EXPORT_SYMBOL_GPL(ps3av_get_refresh_rate); | ||
921 | |||
922 | /* get resolution by video_mode */ | 891 | /* get resolution by video_mode */ |
923 | int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres) | 892 | int ps3av_video_mode2res(u32 id, u32 *xres, u32 *yres) |
924 | { | 893 | { |
@@ -990,7 +959,7 @@ static int ps3av_probe(struct ps3_system_bus_device *dev) | |||
990 | return -ENOMEM; | 959 | return -ENOMEM; |
991 | 960 | ||
992 | mutex_init(&ps3av->mutex); | 961 | mutex_init(&ps3av->mutex); |
993 | ps3av->ps3av_mode = 0; | 962 | ps3av->ps3av_mode = PS3AV_MODE_AUTO; |
994 | ps3av->dev = dev; | 963 | ps3av->dev = dev; |
995 | 964 | ||
996 | INIT_WORK(&ps3av->work, ps3avd); | 965 | INIT_WORK(&ps3av->work, ps3avd); |
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 45e4b9648176..6402d699072b 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig | |||
@@ -20,6 +20,10 @@ menuconfig RTC_CLASS | |||
20 | 20 | ||
21 | if RTC_CLASS | 21 | if RTC_CLASS |
22 | 22 | ||
23 | if GEN_RTC || RTC | ||
24 | comment "Conflicting RTC option has been selected, check GEN_RTC and RTC" | ||
25 | endif | ||
26 | |||
23 | config RTC_HCTOSYS | 27 | config RTC_HCTOSYS |
24 | bool "Set system time from RTC on startup and resume" | 28 | bool "Set system time from RTC on startup and resume" |
25 | depends on RTC_CLASS = y | 29 | depends on RTC_CLASS = y |
@@ -49,7 +53,7 @@ config RTC_HCTOSYS_DEVICE | |||
49 | 53 | ||
50 | If the clock you specify here is not battery backed, it may still | 54 | If the clock you specify here is not battery backed, it may still |
51 | be useful to reinitialize system time when resuming from system | 55 | be useful to reinitialize system time when resuming from system |
52 | sleep states. Do not specify an RTC here unless it stays powered | 56 | sleep states. Do not specify an RTC here unless it stays powered |
53 | during all this system's supported sleep states. | 57 | during all this system's supported sleep states. |
54 | 58 | ||
55 | config RTC_DEBUG | 59 | config RTC_DEBUG |
@@ -142,7 +146,7 @@ config RTC_DRV_DS1307 | |||
142 | will be called rtc-ds1307. | 146 | will be called rtc-ds1307. |
143 | 147 | ||
144 | config RTC_DRV_DS1374 | 148 | config RTC_DRV_DS1374 |
145 | tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock" | 149 | tristate "Dallas/Maxim DS1374" |
146 | depends on RTC_CLASS && I2C | 150 | depends on RTC_CLASS && I2C |
147 | help | 151 | help |
148 | If you say yes here you get support for Dallas Semiconductor | 152 | If you say yes here you get support for Dallas Semiconductor |
@@ -162,7 +166,7 @@ config RTC_DRV_DS1672 | |||
162 | will be called rtc-ds1672. | 166 | will be called rtc-ds1672. |
163 | 167 | ||
164 | config RTC_DRV_MAX6900 | 168 | config RTC_DRV_MAX6900 |
165 | tristate "Maxim 6900" | 169 | tristate "Maxim MAX6900" |
166 | help | 170 | help |
167 | If you say yes here you will get support for the | 171 | If you say yes here you will get support for the |
168 | Maxim MAX6900 I2C RTC chip. | 172 | Maxim MAX6900 I2C RTC chip. |
@@ -180,10 +184,10 @@ config RTC_DRV_RS5C372 | |||
180 | will be called rtc-rs5c372. | 184 | will be called rtc-rs5c372. |
181 | 185 | ||
182 | config RTC_DRV_ISL1208 | 186 | config RTC_DRV_ISL1208 |
183 | tristate "Intersil 1208" | 187 | tristate "Intersil ISL1208" |
184 | help | 188 | help |
185 | If you say yes here you get support for the | 189 | If you say yes here you get support for the |
186 | Intersil 1208 RTC chip. | 190 | Intersil ISL1208 RTC chip. |
187 | 191 | ||
188 | This driver can also be built as a module. If so, the module | 192 | This driver can also be built as a module. If so, the module |
189 | will be called rtc-isl1208. | 193 | will be called rtc-isl1208. |
@@ -220,7 +224,7 @@ config RTC_DRV_PCF8583 | |||
220 | will be called rtc-pcf8583. | 224 | will be called rtc-pcf8583. |
221 | 225 | ||
222 | config RTC_DRV_M41T80 | 226 | config RTC_DRV_M41T80 |
223 | tristate "ST M41T80 series RTC" | 227 | tristate "ST M41T80/81/82/83/84/85/87" |
224 | help | 228 | help |
225 | If you say Y here you will get support for the | 229 | If you say Y here you will get support for the |
226 | ST M41T80 RTC chips series. Currently following chips are | 230 | ST M41T80 RTC chips series. Currently following chips are |
@@ -252,23 +256,32 @@ comment "SPI RTC drivers" | |||
252 | 256 | ||
253 | if SPI_MASTER | 257 | if SPI_MASTER |
254 | 258 | ||
255 | config RTC_DRV_RS5C348 | 259 | config RTC_DRV_MAX6902 |
256 | tristate "Ricoh RS5C348A/B" | 260 | tristate "Maxim MAX6902" |
257 | help | 261 | help |
258 | If you say yes here you get support for the | 262 | If you say yes here you will get support for the |
259 | Ricoh RS5C348A and RS5C348B RTC chips. | 263 | Maxim MAX6902 SPI RTC chip. |
260 | 264 | ||
261 | This driver can also be built as a module. If so, the module | 265 | This driver can also be built as a module. If so, the module |
262 | will be called rtc-rs5c348. | 266 | will be called rtc-max6902. |
263 | 267 | ||
264 | config RTC_DRV_MAX6902 | 268 | config RTC_DRV_R9701 |
265 | tristate "Maxim 6902" | 269 | tristate "Epson RTC-9701JE" |
266 | help | 270 | help |
267 | If you say yes here you will get support for the | 271 | If you say yes here you will get support for the |
268 | Maxim MAX6902 SPI RTC chip. | 272 | Epson RTC-9701JE SPI RTC chip. |
269 | 273 | ||
270 | This driver can also be built as a module. If so, the module | 274 | This driver can also be built as a module. If so, the module |
271 | will be called rtc-max6902. | 275 | will be called rtc-r9701. |
276 | |||
277 | config RTC_DRV_RS5C348 | ||
278 | tristate "Ricoh RS5C348A/B" | ||
279 | help | ||
280 | If you say yes here you get support for the | ||
281 | Ricoh RS5C348A and RS5C348B RTC chips. | ||
282 | |||
283 | This driver can also be built as a module. If so, the module | ||
284 | will be called rtc-rs5c348. | ||
272 | 285 | ||
273 | endif # SPI_MASTER | 286 | endif # SPI_MASTER |
274 | 287 | ||
@@ -302,34 +315,50 @@ config RTC_DRV_DS1216 | |||
302 | help | 315 | help |
303 | If you say yes here you get support for the Dallas DS1216 RTC chips. | 316 | If you say yes here you get support for the Dallas DS1216 RTC chips. |
304 | 317 | ||
305 | config RTC_DRV_DS1553 | 318 | config RTC_DRV_DS1302 |
306 | tristate "Dallas DS1553" | 319 | tristate "Dallas DS1302" |
320 | depends on SH_SECUREEDGE5410 | ||
321 | help | ||
322 | If you say yes here you get support for the Dallas DS1302 RTC chips. | ||
323 | |||
324 | config RTC_DRV_DS1511 | ||
325 | tristate "Dallas DS1511" | ||
326 | depends on RTC_CLASS | ||
307 | help | 327 | help |
308 | If you say yes here you get support for the | 328 | If you say yes here you get support for the |
309 | Dallas DS1553 timekeeping chip. | 329 | Dallas DS1511 timekeeping/watchdog chip. |
310 | 330 | ||
311 | This driver can also be built as a module. If so, the module | 331 | This driver can also be built as a module. If so, the module |
312 | will be called rtc-ds1553. | 332 | will be called rtc-ds1511. |
313 | 333 | ||
314 | config RTC_DRV_STK17TA8 | 334 | config RTC_DRV_DS1553 |
315 | tristate "Simtek STK17TA8" | 335 | tristate "Maxim/Dallas DS1553" |
316 | depends on RTC_CLASS | ||
317 | help | 336 | help |
318 | If you say yes here you get support for the | 337 | If you say yes here you get support for the |
319 | Simtek STK17TA8 timekeeping chip. | 338 | Maxim/Dallas DS1553 timekeeping chip. |
320 | 339 | ||
321 | This driver can also be built as a module. If so, the module | 340 | This driver can also be built as a module. If so, the module |
322 | will be called rtc-stk17ta8. | 341 | will be called rtc-ds1553. |
323 | 342 | ||
324 | config RTC_DRV_DS1742 | 343 | config RTC_DRV_DS1742 |
325 | tristate "Dallas DS1742/1743" | 344 | tristate "Maxim/Dallas DS1742/1743" |
326 | help | 345 | help |
327 | If you say yes here you get support for the | 346 | If you say yes here you get support for the |
328 | Dallas DS1742/1743 timekeeping chip. | 347 | Maxim/Dallas DS1742/1743 timekeeping chip. |
329 | 348 | ||
330 | This driver can also be built as a module. If so, the module | 349 | This driver can also be built as a module. If so, the module |
331 | will be called rtc-ds1742. | 350 | will be called rtc-ds1742. |
332 | 351 | ||
352 | config RTC_DRV_STK17TA8 | ||
353 | tristate "Simtek STK17TA8" | ||
354 | depends on RTC_CLASS | ||
355 | help | ||
356 | If you say yes here you get support for the | ||
357 | Simtek STK17TA8 timekeeping chip. | ||
358 | |||
359 | This driver can also be built as a module. If so, the module | ||
360 | will be called rtc-stk17ta8. | ||
361 | |||
333 | config RTC_DRV_M48T86 | 362 | config RTC_DRV_M48T86 |
334 | tristate "ST M48T86/Dallas DS12887" | 363 | tristate "ST M48T86/Dallas DS12887" |
335 | help | 364 | help |
@@ -440,10 +469,47 @@ config RTC_DRV_AT32AP700X | |||
440 | AT32AP700x family processors. | 469 | AT32AP700x family processors. |
441 | 470 | ||
442 | config RTC_DRV_AT91RM9200 | 471 | config RTC_DRV_AT91RM9200 |
443 | tristate "AT91RM9200" | 472 | tristate "AT91RM9200 or AT91SAM9RL" |
444 | depends on ARCH_AT91RM9200 | 473 | depends on ARCH_AT91RM9200 || ARCH_AT91SAM9RL |
445 | help | 474 | help |
446 | Driver for the Atmel AT91RM9200's internal RTC (Realtime Clock). | 475 | Driver for the internal RTC (Realtime Clock) module found on |
476 | Atmel AT91RM9200's and AT91SAM9RL chips. On SAM9RL chips | ||
477 | this is powered by the backup power supply. | ||
478 | |||
479 | config RTC_DRV_AT91SAM9 | ||
480 | tristate "AT91SAM9x" | ||
481 | depends on ARCH_AT91 && !(ARCH_AT91RM9200 || ARCH_AT91X40) | ||
482 | help | ||
483 | RTC driver for the Atmel AT91SAM9x internal RTT (Real Time Timer). | ||
484 | These timers are powered by the backup power supply (such as a | ||
485 | small coin cell battery), but do not need to be used as RTCs. | ||
486 | |||
487 | (On AT91SAM9rl chips you probably want to use the dedicated RTC | ||
488 | module and leave the RTT available for other uses.) | ||
489 | |||
490 | config RTC_DRV_AT91SAM9_RTT | ||
491 | int | ||
492 | range 0 1 | ||
493 | default 0 | ||
494 | prompt "RTT module Number" if ARCH_AT91SAM9263 | ||
495 | depends on RTC_DRV_AT91SAM9 | ||
496 | help | ||
497 | More than one RTT module is available. You can choose which | ||
498 | one will be used as an RTC. The default of zero is normally | ||
499 | OK to use, though some systems use that for non-RTC purposes. | ||
500 | |||
501 | config RTC_DRV_AT91SAM9_GPBR | ||
502 | int | ||
503 | range 0 3 if !ARCH_AT91SAM9263 | ||
504 | range 0 15 if ARCH_AT91SAM9263 | ||
505 | default 0 | ||
506 | prompt "Backup Register Number" | ||
507 | depends on RTC_DRV_AT91SAM9 | ||
508 | help | ||
509 | The RTC driver needs to use one of the General Purpose Backup | ||
510 | Registers (GPBRs) as well as the RTT. You can choose which one | ||
511 | will be used. The default of zero is normally OK to use, but | ||
512 | on some systems other software needs to use that register. | ||
447 | 513 | ||
448 | config RTC_DRV_BFIN | 514 | config RTC_DRV_BFIN |
449 | tristate "Blackfin On-Chip RTC" | 515 | tristate "Blackfin On-Chip RTC" |
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 465db4dd50b2..ec703f34ab86 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile | |||
@@ -19,11 +19,14 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o | |||
19 | 19 | ||
20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o | 20 | obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o |
21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o | 21 | obj-$(CONFIG_RTC_DRV_AT91RM9200)+= rtc-at91rm9200.o |
22 | obj-$(CONFIG_RTC_DRV_AT91SAM9) += rtc-at91sam9.o | ||
22 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o | 23 | obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o |
23 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o | 24 | obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o |
24 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o | 25 | obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o |
26 | obj-$(CONFIG_RTC_DRV_DS1302) += rtc-ds1302.o | ||
25 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o | 27 | obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o |
26 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o | 28 | obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o |
29 | obj-$(CONFIG_RTC_DRV_DS1511) += rtc-ds1511.o | ||
27 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o | 30 | obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o |
28 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o | 31 | obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o |
29 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o | 32 | obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o |
@@ -38,6 +41,7 @@ obj-$(CONFIG_RTC_DRV_OMAP) += rtc-omap.o | |||
38 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o | 41 | obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o |
39 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o | 42 | obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o |
40 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o | 43 | obj-$(CONFIG_RTC_DRV_PL031) += rtc-pl031.o |
44 | obj-$(CONFIG_RTC_DRV_R9701) += rtc-r9701.o | ||
41 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o | 45 | obj-$(CONFIG_RTC_DRV_RS5C313) += rtc-rs5c313.o |
42 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o | 46 | obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o |
43 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o | 47 | obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o |
diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c new file mode 100644 index 000000000000..bbf10ecf416c --- /dev/null +++ b/drivers/rtc/rtc-at91sam9.c | |||
@@ -0,0 +1,520 @@ | |||
1 | /* | ||
2 | * "RTT as Real Time Clock" driver for AT91SAM9 SoC family | ||
3 | * | ||
4 | * (C) 2007 Michel Benoit | ||
5 | * | ||
6 | * Based on rtc-at91rm9200.c by Rick Bronson | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/module.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/time.h> | ||
18 | #include <linux/rtc.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <linux/ioctl.h> | ||
21 | |||
22 | #include <asm/mach/time.h> | ||
23 | #include <asm/arch/board.h> | ||
24 | #include <asm/arch/at91_rtt.h> | ||
25 | |||
26 | |||
27 | /* | ||
28 | * This driver uses two configurable hardware resources that live in the | ||
29 | * AT91SAM9 backup power domain (intended to be powered at all times) | ||
30 | * to implement the Real Time Clock interfaces | ||
31 | * | ||
32 | * - A "Real-time Timer" (RTT) counts up in seconds from a base time. | ||
33 | * We can't assign the counter value (CRTV) ... but we can reset it. | ||
34 | * | ||
35 | * - One of the "General Purpose Backup Registers" (GPBRs) holds the | ||
36 | * base time, normally an offset from the beginning of the POSIX | ||
37 | * epoch (1970-Jan-1 00:00:00 UTC). Some systems also include the | ||
38 | * local timezone's offset. | ||
39 | * | ||
40 | * The RTC's value is the RTT counter plus that offset. The RTC's alarm | ||
41 | * is likewise a base (ALMV) plus that offset. | ||
42 | * | ||
43 | * Not all RTTs will be used as RTCs; some systems have multiple RTTs to | ||
44 | * choose from, or a "real" RTC module. All systems have multiple GPBR | ||
45 | * registers available, likewise usable for more than "RTC" support. | ||
46 | */ | ||
47 | |||
48 | /* | ||
49 | * We store ALARM_DISABLED in ALMV to record that no alarm is set. | ||
50 | * It's also the reset value for that field. | ||
51 | */ | ||
52 | #define ALARM_DISABLED ((u32)~0) | ||
53 | |||
54 | |||
55 | struct sam9_rtc { | ||
56 | void __iomem *rtt; | ||
57 | struct rtc_device *rtcdev; | ||
58 | u32 imr; | ||
59 | }; | ||
60 | |||
61 | #define rtt_readl(rtc, field) \ | ||
62 | __raw_readl((rtc)->rtt + AT91_RTT_ ## field) | ||
63 | #define rtt_writel(rtc, field, val) \ | ||
64 | __raw_writel((val), (rtc)->rtt + AT91_RTT_ ## field) | ||
65 | |||
66 | #define gpbr_readl(rtc) \ | ||
67 | at91_sys_read(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR) | ||
68 | #define gpbr_writel(rtc, val) \ | ||
69 | at91_sys_write(AT91_GPBR + 4 * CONFIG_RTC_DRV_AT91SAM9_GPBR, (val)) | ||
70 | |||
71 | /* | ||
72 | * Read current time and date in RTC | ||
73 | */ | ||
74 | static int at91_rtc_readtime(struct device *dev, struct rtc_time *tm) | ||
75 | { | ||
76 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
77 | u32 secs, secs2; | ||
78 | u32 offset; | ||
79 | |||
80 | /* read current time offset */ | ||
81 | offset = gpbr_readl(rtc); | ||
82 | if (offset == 0) | ||
83 | return -EILSEQ; | ||
84 | |||
85 | /* reread the counter to help sync the two clock domains */ | ||
86 | secs = rtt_readl(rtc, VR); | ||
87 | secs2 = rtt_readl(rtc, VR); | ||
88 | if (secs != secs2) | ||
89 | secs = rtt_readl(rtc, VR); | ||
90 | |||
91 | rtc_time_to_tm(offset + secs, tm); | ||
92 | |||
93 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readtime", | ||
94 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
95 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
96 | |||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Set current time and date in RTC | ||
102 | */ | ||
103 | static int at91_rtc_settime(struct device *dev, struct rtc_time *tm) | ||
104 | { | ||
105 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
106 | int err; | ||
107 | u32 offset, alarm, mr; | ||
108 | unsigned long secs; | ||
109 | |||
110 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "settime", | ||
111 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
112 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
113 | |||
114 | err = rtc_tm_to_time(tm, &secs); | ||
115 | if (err != 0) | ||
116 | return err; | ||
117 | |||
118 | mr = rtt_readl(rtc, MR); | ||
119 | |||
120 | /* disable interrupts */ | ||
121 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | ||
122 | |||
123 | /* read current time offset */ | ||
124 | offset = gpbr_readl(rtc); | ||
125 | |||
126 | /* store the new base time in a battery backup register */ | ||
127 | secs += 1; | ||
128 | gpbr_writel(rtc, secs); | ||
129 | |||
130 | /* adjust the alarm time for the new base */ | ||
131 | alarm = rtt_readl(rtc, AR); | ||
132 | if (alarm != ALARM_DISABLED) { | ||
133 | if (offset > secs) { | ||
134 | /* time jumped backwards, increase time until alarm */ | ||
135 | alarm += (offset - secs); | ||
136 | } else if ((alarm + offset) > secs) { | ||
137 | /* time jumped forwards, decrease time until alarm */ | ||
138 | alarm -= (secs - offset); | ||
139 | } else { | ||
140 | /* time jumped past the alarm, disable alarm */ | ||
141 | alarm = ALARM_DISABLED; | ||
142 | mr &= ~AT91_RTT_ALMIEN; | ||
143 | } | ||
144 | rtt_writel(rtc, AR, alarm); | ||
145 | } | ||
146 | |||
147 | /* reset the timer, and re-enable interrupts */ | ||
148 | rtt_writel(rtc, MR, mr | AT91_RTT_RTTRST); | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
154 | { | ||
155 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
156 | struct rtc_time *tm = &alrm->time; | ||
157 | u32 alarm = rtt_readl(rtc, AR); | ||
158 | u32 offset; | ||
159 | |||
160 | offset = gpbr_readl(rtc); | ||
161 | if (offset == 0) | ||
162 | return -EILSEQ; | ||
163 | |||
164 | memset(alrm, 0, sizeof(alrm)); | ||
165 | if (alarm != ALARM_DISABLED && offset != 0) { | ||
166 | rtc_time_to_tm(offset + alarm, tm); | ||
167 | |||
168 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "readalarm", | ||
169 | 1900 + tm->tm_year, tm->tm_mon, tm->tm_mday, | ||
170 | tm->tm_hour, tm->tm_min, tm->tm_sec); | ||
171 | |||
172 | if (rtt_readl(rtc, MR) & AT91_RTT_ALMIEN) | ||
173 | alrm->enabled = 1; | ||
174 | } | ||
175 | |||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
180 | { | ||
181 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
182 | struct rtc_time *tm = &alrm->time; | ||
183 | unsigned long secs; | ||
184 | u32 offset; | ||
185 | u32 mr; | ||
186 | int err; | ||
187 | |||
188 | err = rtc_tm_to_time(tm, &secs); | ||
189 | if (err != 0) | ||
190 | return err; | ||
191 | |||
192 | offset = gpbr_readl(rtc); | ||
193 | if (offset == 0) { | ||
194 | /* time is not set */ | ||
195 | return -EILSEQ; | ||
196 | } | ||
197 | mr = rtt_readl(rtc, MR); | ||
198 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); | ||
199 | |||
200 | /* alarm in the past? finish and leave disabled */ | ||
201 | if (secs <= offset) { | ||
202 | rtt_writel(rtc, AR, ALARM_DISABLED); | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /* else set alarm and maybe enable it */ | ||
207 | rtt_writel(rtc, AR, secs - offset); | ||
208 | if (alrm->enabled) | ||
209 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); | ||
210 | |||
211 | dev_dbg(dev, "%s: %4d-%02d-%02d %02d:%02d:%02d\n", "setalarm", | ||
212 | tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_hour, | ||
213 | tm->tm_min, tm->tm_sec); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Handle commands from user-space | ||
220 | */ | ||
221 | static int at91_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
222 | unsigned long arg) | ||
223 | { | ||
224 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
225 | int ret = 0; | ||
226 | u32 mr = rtt_readl(rtc, MR); | ||
227 | |||
228 | dev_dbg(dev, "ioctl: cmd=%08x, arg=%08lx, mr %08x\n", cmd, arg, mr); | ||
229 | |||
230 | switch (cmd) { | ||
231 | case RTC_AIE_OFF: /* alarm off */ | ||
232 | rtt_writel(rtc, MR, mr & ~AT91_RTT_ALMIEN); | ||
233 | break; | ||
234 | case RTC_AIE_ON: /* alarm on */ | ||
235 | rtt_writel(rtc, MR, mr | AT91_RTT_ALMIEN); | ||
236 | break; | ||
237 | case RTC_UIE_OFF: /* update off */ | ||
238 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | ||
239 | break; | ||
240 | case RTC_UIE_ON: /* update on */ | ||
241 | rtt_writel(rtc, MR, mr | AT91_RTT_RTTINCIEN); | ||
242 | break; | ||
243 | default: | ||
244 | ret = -ENOIOCTLCMD; | ||
245 | break; | ||
246 | } | ||
247 | |||
248 | return ret; | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * Provide additional RTC information in /proc/driver/rtc | ||
253 | */ | ||
254 | static int at91_rtc_proc(struct device *dev, struct seq_file *seq) | ||
255 | { | ||
256 | struct sam9_rtc *rtc = dev_get_drvdata(dev); | ||
257 | u32 mr = mr = rtt_readl(rtc, MR); | ||
258 | |||
259 | seq_printf(seq, "update_IRQ\t: %s\n", | ||
260 | (mr & AT91_RTT_RTTINCIEN) ? "yes" : "no"); | ||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | /* | ||
265 | * IRQ handler for the RTC | ||
266 | */ | ||
267 | static irqreturn_t at91_rtc_interrupt(int irq, void *_rtc) | ||
268 | { | ||
269 | struct sam9_rtc *rtc = _rtc; | ||
270 | u32 sr, mr; | ||
271 | unsigned long events = 0; | ||
272 | |||
273 | /* Shared interrupt may be for another device. Note: reading | ||
274 | * SR clears it, so we must only read it in this irq handler! | ||
275 | */ | ||
276 | mr = rtt_readl(rtc, MR) & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
277 | sr = rtt_readl(rtc, SR) & mr; | ||
278 | if (!sr) | ||
279 | return IRQ_NONE; | ||
280 | |||
281 | /* alarm status */ | ||
282 | if (sr & AT91_RTT_ALMS) | ||
283 | events |= (RTC_AF | RTC_IRQF); | ||
284 | |||
285 | /* timer update/increment */ | ||
286 | if (sr & AT91_RTT_RTTINC) | ||
287 | events |= (RTC_UF | RTC_IRQF); | ||
288 | |||
289 | rtc_update_irq(rtc->rtcdev, 1, events); | ||
290 | |||
291 | pr_debug("%s: num=%ld, events=0x%02lx\n", __FUNCTION__, | ||
292 | events >> 8, events & 0x000000FF); | ||
293 | |||
294 | return IRQ_HANDLED; | ||
295 | } | ||
296 | |||
297 | static const struct rtc_class_ops at91_rtc_ops = { | ||
298 | .ioctl = at91_rtc_ioctl, | ||
299 | .read_time = at91_rtc_readtime, | ||
300 | .set_time = at91_rtc_settime, | ||
301 | .read_alarm = at91_rtc_readalarm, | ||
302 | .set_alarm = at91_rtc_setalarm, | ||
303 | .proc = at91_rtc_proc, | ||
304 | }; | ||
305 | |||
306 | /* | ||
307 | * Initialize and install RTC driver | ||
308 | */ | ||
309 | static int __init at91_rtc_probe(struct platform_device *pdev) | ||
310 | { | ||
311 | struct resource *r; | ||
312 | struct sam9_rtc *rtc; | ||
313 | int ret; | ||
314 | u32 mr; | ||
315 | |||
316 | r = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
317 | if (!r) | ||
318 | return -ENODEV; | ||
319 | |||
320 | rtc = kzalloc(sizeof *rtc, GFP_KERNEL); | ||
321 | if (!rtc) | ||
322 | return -ENOMEM; | ||
323 | |||
324 | platform_set_drvdata(pdev, rtc); | ||
325 | rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS); | ||
326 | rtc->rtt += r->start; | ||
327 | |||
328 | mr = rtt_readl(rtc, MR); | ||
329 | |||
330 | /* unless RTT is counting at 1 Hz, re-initialize it */ | ||
331 | if ((mr & AT91_RTT_RTPRES) != AT91_SLOW_CLOCK) { | ||
332 | mr = AT91_RTT_RTTRST | (AT91_SLOW_CLOCK & AT91_RTT_RTPRES); | ||
333 | gpbr_writel(rtc, 0); | ||
334 | } | ||
335 | |||
336 | /* disable all interrupts (same as on shutdown path) */ | ||
337 | mr &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
338 | rtt_writel(rtc, MR, mr); | ||
339 | |||
340 | rtc->rtcdev = rtc_device_register(pdev->name, &pdev->dev, | ||
341 | &at91_rtc_ops, THIS_MODULE); | ||
342 | if (IS_ERR(rtc->rtcdev)) { | ||
343 | ret = PTR_ERR(rtc->rtcdev); | ||
344 | goto fail; | ||
345 | } | ||
346 | |||
347 | /* register irq handler after we know what name we'll use */ | ||
348 | ret = request_irq(AT91_ID_SYS, at91_rtc_interrupt, | ||
349 | IRQF_DISABLED | IRQF_SHARED, | ||
350 | rtc->rtcdev->dev.bus_id, rtc); | ||
351 | if (ret) { | ||
352 | dev_dbg(&pdev->dev, "can't share IRQ %d?\n", AT91_ID_SYS); | ||
353 | rtc_device_unregister(rtc->rtcdev); | ||
354 | goto fail; | ||
355 | } | ||
356 | |||
357 | /* NOTE: sam9260 rev A silicon has a ROM bug which resets the | ||
358 | * RTT on at least some reboots. If you have that chip, you must | ||
359 | * initialize the time from some external source like a GPS, wall | ||
360 | * clock, discrete RTC, etc | ||
361 | */ | ||
362 | |||
363 | if (gpbr_readl(rtc) == 0) | ||
364 | dev_warn(&pdev->dev, "%s: SET TIME!\n", | ||
365 | rtc->rtcdev->dev.bus_id); | ||
366 | |||
367 | return 0; | ||
368 | |||
369 | fail: | ||
370 | platform_set_drvdata(pdev, NULL); | ||
371 | kfree(rtc); | ||
372 | return ret; | ||
373 | } | ||
374 | |||
375 | /* | ||
376 | * Disable and remove the RTC driver | ||
377 | */ | ||
378 | static int __exit at91_rtc_remove(struct platform_device *pdev) | ||
379 | { | ||
380 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
381 | u32 mr = rtt_readl(rtc, MR); | ||
382 | |||
383 | /* disable all interrupts */ | ||
384 | rtt_writel(rtc, MR, mr & ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)); | ||
385 | free_irq(AT91_ID_SYS, rtc); | ||
386 | |||
387 | rtc_device_unregister(rtc->rtcdev); | ||
388 | |||
389 | platform_set_drvdata(pdev, NULL); | ||
390 | kfree(rtc); | ||
391 | return 0; | ||
392 | } | ||
393 | |||
394 | static void at91_rtc_shutdown(struct platform_device *pdev) | ||
395 | { | ||
396 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
397 | u32 mr = rtt_readl(rtc, MR); | ||
398 | |||
399 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
400 | rtt_writel(rtc, MR, mr & ~rtc->imr); | ||
401 | } | ||
402 | |||
403 | #ifdef CONFIG_PM | ||
404 | |||
405 | /* AT91SAM9 RTC Power management control */ | ||
406 | |||
407 | static int at91_rtc_suspend(struct platform_device *pdev, | ||
408 | pm_message_t state) | ||
409 | { | ||
410 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
411 | u32 mr = rtt_readl(rtc, MR); | ||
412 | |||
413 | /* | ||
414 | * This IRQ is shared with DBGU and other hardware which isn't | ||
415 | * necessarily a wakeup event source. | ||
416 | */ | ||
417 | rtc->imr = mr & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN); | ||
418 | if (rtc->imr) { | ||
419 | if (device_may_wakeup(&pdev->dev) && (mr & AT91_RTT_ALMIEN)) { | ||
420 | enable_irq_wake(AT91_ID_SYS); | ||
421 | /* don't let RTTINC cause wakeups */ | ||
422 | if (mr & AT91_RTT_RTTINCIEN) | ||
423 | rtt_writel(rtc, MR, mr & ~AT91_RTT_RTTINCIEN); | ||
424 | } else | ||
425 | rtt_writel(rtc, MR, mr & ~rtc->imr); | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int at91_rtc_resume(struct platform_device *pdev) | ||
432 | { | ||
433 | struct sam9_rtc *rtc = platform_get_drvdata(pdev); | ||
434 | u32 mr; | ||
435 | |||
436 | if (rtc->imr) { | ||
437 | if (device_may_wakeup(&pdev->dev)) | ||
438 | disable_irq_wake(AT91_ID_SYS); | ||
439 | mr = rtt_readl(rtc, MR); | ||
440 | rtt_writel(rtc, MR, mr | rtc->imr); | ||
441 | } | ||
442 | |||
443 | return 0; | ||
444 | } | ||
445 | #else | ||
446 | #define at91_rtc_suspend NULL | ||
447 | #define at91_rtc_resume NULL | ||
448 | #endif | ||
449 | |||
450 | static struct platform_driver at91_rtc_driver = { | ||
451 | .driver.name = "rtc-at91sam9", | ||
452 | .driver.owner = THIS_MODULE, | ||
453 | .remove = __exit_p(at91_rtc_remove), | ||
454 | .shutdown = at91_rtc_shutdown, | ||
455 | .suspend = at91_rtc_suspend, | ||
456 | .resume = at91_rtc_resume, | ||
457 | }; | ||
458 | |||
459 | /* Chips can have more than one RTT module, and they can be used for more | ||
460 | * than just RTCs. So we can't just register as "the" RTT driver. | ||
461 | * | ||
462 | * A normal approach in such cases is to create a library to allocate and | ||
463 | * free the modules. Here we just use bus_find_device() as like such a | ||
464 | * library, binding directly ... no runtime "library" footprint is needed. | ||
465 | */ | ||
466 | static int __init at91_rtc_match(struct device *dev, void *v) | ||
467 | { | ||
468 | struct platform_device *pdev = to_platform_device(dev); | ||
469 | int ret; | ||
470 | |||
471 | /* continue searching if this isn't the RTT we need */ | ||
472 | if (strcmp("at91_rtt", pdev->name) != 0 | ||
473 | || pdev->id != CONFIG_RTC_DRV_AT91SAM9_RTT) | ||
474 | goto fail; | ||
475 | |||
476 | /* else we found it ... but fail unless we can bind to the RTC driver */ | ||
477 | if (dev->driver) { | ||
478 | dev_dbg(dev, "busy, can't use as RTC!\n"); | ||
479 | goto fail; | ||
480 | } | ||
481 | dev->driver = &at91_rtc_driver.driver; | ||
482 | if (device_attach(dev) == 0) { | ||
483 | dev_dbg(dev, "can't attach RTC!\n"); | ||
484 | goto fail; | ||
485 | } | ||
486 | ret = at91_rtc_probe(pdev); | ||
487 | if (ret == 0) | ||
488 | return true; | ||
489 | |||
490 | dev_dbg(dev, "RTC probe err %d!\n", ret); | ||
491 | fail: | ||
492 | return false; | ||
493 | } | ||
494 | |||
495 | static int __init at91_rtc_init(void) | ||
496 | { | ||
497 | int status; | ||
498 | struct device *rtc; | ||
499 | |||
500 | status = platform_driver_register(&at91_rtc_driver); | ||
501 | if (status) | ||
502 | return status; | ||
503 | rtc = bus_find_device(&platform_bus_type, NULL, | ||
504 | NULL, at91_rtc_match); | ||
505 | if (!rtc) | ||
506 | platform_driver_unregister(&at91_rtc_driver); | ||
507 | return rtc ? 0 : -ENODEV; | ||
508 | } | ||
509 | module_init(at91_rtc_init); | ||
510 | |||
511 | static void __exit at91_rtc_exit(void) | ||
512 | { | ||
513 | platform_driver_unregister(&at91_rtc_driver); | ||
514 | } | ||
515 | module_exit(at91_rtc_exit); | ||
516 | |||
517 | |||
518 | MODULE_AUTHOR("Michel Benoit"); | ||
519 | MODULE_DESCRIPTION("RTC driver for Atmel AT91SAM9x"); | ||
520 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 1aa709dda0d6..d90ba860d216 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Blackfin On-Chip Real Time Clock Driver | 2 | * Blackfin On-Chip Real Time Clock Driver |
3 | * Supports BF53[123]/BF53[467]/BF54[2489] | 3 | * Supports BF52[257]/BF53[123]/BF53[467]/BF54[24789] |
4 | * | 4 | * |
5 | * Copyright 2004-2007 Analog Devices Inc. | 5 | * Copyright 2004-2007 Analog Devices Inc. |
6 | * | 6 | * |
@@ -32,26 +32,25 @@ | |||
32 | * writes to clear status registers complete immediately. | 32 | * writes to clear status registers complete immediately. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/kernel.h> | ||
37 | #include <linux/bcd.h> | 35 | #include <linux/bcd.h> |
38 | #include <linux/rtc.h> | 36 | #include <linux/completion.h> |
37 | #include <linux/delay.h> | ||
39 | #include <linux/init.h> | 38 | #include <linux/init.h> |
39 | #include <linux/interrupt.h> | ||
40 | #include <linux/kernel.h> | ||
41 | #include <linux/module.h> | ||
40 | #include <linux/platform_device.h> | 42 | #include <linux/platform_device.h> |
43 | #include <linux/rtc.h> | ||
41 | #include <linux/seq_file.h> | 44 | #include <linux/seq_file.h> |
42 | #include <linux/interrupt.h> | ||
43 | #include <linux/spinlock.h> | ||
44 | #include <linux/delay.h> | ||
45 | 45 | ||
46 | #include <asm/blackfin.h> | 46 | #include <asm/blackfin.h> |
47 | 47 | ||
48 | #define stamp(fmt, args...) pr_debug("%s:%i: " fmt "\n", __FUNCTION__, __LINE__, ## args) | 48 | #define dev_dbg_stamp(dev) dev_dbg(dev, "%s:%i: here i am\n", __func__, __LINE__) |
49 | #define stampit() stamp("here i am") | ||
50 | 49 | ||
51 | struct bfin_rtc { | 50 | struct bfin_rtc { |
52 | struct rtc_device *rtc_dev; | 51 | struct rtc_device *rtc_dev; |
53 | struct rtc_time rtc_alarm; | 52 | struct rtc_time rtc_alarm; |
54 | spinlock_t lock; | 53 | u16 rtc_wrote_regs; |
55 | }; | 54 | }; |
56 | 55 | ||
57 | /* Bit values for the ISTAT / ICTL registers */ | 56 | /* Bit values for the ISTAT / ICTL registers */ |
@@ -72,7 +71,7 @@ struct bfin_rtc { | |||
72 | #define SEC_BITS_OFF 0 | 71 | #define SEC_BITS_OFF 0 |
73 | 72 | ||
74 | /* Some helper functions to convert between the common RTC notion of time | 73 | /* Some helper functions to convert between the common RTC notion of time |
75 | * and the internal Blackfin notion that is stored in 32bits. | 74 | * and the internal Blackfin notion that is encoded in 32bits. |
76 | */ | 75 | */ |
77 | static inline u32 rtc_time_to_bfin(unsigned long now) | 76 | static inline u32 rtc_time_to_bfin(unsigned long now) |
78 | { | 77 | { |
@@ -97,7 +96,10 @@ static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) | |||
97 | rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); | 96 | rtc_time_to_tm(rtc_bfin_to_time(rtc_bfin), tm); |
98 | } | 97 | } |
99 | 98 | ||
100 | /* Wait for the previous write to a RTC register to complete. | 99 | /** |
100 | * bfin_rtc_sync_pending - make sure pending writes have complete | ||
101 | * | ||
102 | * Wait for the previous write to a RTC register to complete. | ||
101 | * Unfortunately, we can't sleep here as that introduces a race condition when | 103 | * Unfortunately, we can't sleep here as that introduces a race condition when |
102 | * turning on interrupt events. Consider this: | 104 | * turning on interrupt events. Consider this: |
103 | * - process sets alarm | 105 | * - process sets alarm |
@@ -112,188 +114,202 @@ static inline void rtc_bfin_to_tm(u32 rtc_bfin, struct rtc_time *tm) | |||
112 | * If anyone can point out the obvious solution here, i'm listening :). This | 114 | * If anyone can point out the obvious solution here, i'm listening :). This |
113 | * shouldn't be an issue on an SMP or preempt system as this function should | 115 | * shouldn't be an issue on an SMP or preempt system as this function should |
114 | * only be called with the rtc lock held. | 116 | * only be called with the rtc lock held. |
117 | * | ||
118 | * Other options: | ||
119 | * - disable PREN so the sync happens at 32.768kHZ ... but this changes the | ||
120 | * inc rate for all RTC registers from 1HZ to 32.768kHZ ... | ||
121 | * - use the write complete IRQ | ||
115 | */ | 122 | */ |
116 | static void rtc_bfin_sync_pending(void) | 123 | /* |
124 | static void bfin_rtc_sync_pending_polled(void) | ||
117 | { | 125 | { |
118 | stampit(); | 126 | while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) |
119 | while (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_COMPLETE)) { | ||
120 | if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) | 127 | if (!(bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING)) |
121 | break; | 128 | break; |
122 | } | ||
123 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); | 129 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); |
124 | } | 130 | } |
131 | */ | ||
132 | static DECLARE_COMPLETION(bfin_write_complete); | ||
133 | static void bfin_rtc_sync_pending(struct device *dev) | ||
134 | { | ||
135 | dev_dbg_stamp(dev); | ||
136 | while (bfin_read_RTC_ISTAT() & RTC_ISTAT_WRITE_PENDING) | ||
137 | wait_for_completion_timeout(&bfin_write_complete, HZ * 5); | ||
138 | dev_dbg_stamp(dev); | ||
139 | } | ||
125 | 140 | ||
126 | static void rtc_bfin_reset(struct bfin_rtc *rtc) | 141 | /** |
142 | * bfin_rtc_reset - set RTC to sane/known state | ||
143 | * | ||
144 | * Initialize the RTC. Enable pre-scaler to scale RTC clock | ||
145 | * to 1Hz and clear interrupt/status registers. | ||
146 | */ | ||
147 | static void bfin_rtc_reset(struct device *dev) | ||
127 | { | 148 | { |
128 | /* Initialize the RTC. Enable pre-scaler to scale RTC clock | 149 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
129 | * to 1Hz and clear interrupt/status registers. */ | 150 | dev_dbg_stamp(dev); |
130 | spin_lock_irq(&rtc->lock); | 151 | bfin_rtc_sync_pending(dev); |
131 | rtc_bfin_sync_pending(); | ||
132 | bfin_write_RTC_PREN(0x1); | 152 | bfin_write_RTC_PREN(0x1); |
133 | bfin_write_RTC_ICTL(0); | 153 | bfin_write_RTC_ICTL(RTC_ISTAT_WRITE_COMPLETE); |
134 | bfin_write_RTC_SWCNT(0); | 154 | bfin_write_RTC_SWCNT(0); |
135 | bfin_write_RTC_ALARM(0); | 155 | bfin_write_RTC_ALARM(0); |
136 | bfin_write_RTC_ISTAT(0xFFFF); | 156 | bfin_write_RTC_ISTAT(0xFFFF); |
137 | spin_unlock_irq(&rtc->lock); | 157 | rtc->rtc_wrote_regs = 0; |
138 | } | 158 | } |
139 | 159 | ||
160 | /** | ||
161 | * bfin_rtc_interrupt - handle interrupt from RTC | ||
162 | * | ||
163 | * Since we handle all RTC events here, we have to make sure the requested | ||
164 | * interrupt is enabled (in RTC_ICTL) as the event status register (RTC_ISTAT) | ||
165 | * always gets updated regardless of the interrupt being enabled. So when one | ||
166 | * even we care about (e.g. stopwatch) goes off, we don't want to turn around | ||
167 | * and say that other events have happened as well (e.g. second). We do not | ||
168 | * have to worry about pending writes to the RTC_ICTL register as interrupts | ||
169 | * only fire if they are enabled in the RTC_ICTL register. | ||
170 | */ | ||
140 | static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) | 171 | static irqreturn_t bfin_rtc_interrupt(int irq, void *dev_id) |
141 | { | 172 | { |
142 | struct platform_device *pdev = to_platform_device(dev_id); | 173 | struct device *dev = dev_id; |
143 | struct bfin_rtc *rtc = platform_get_drvdata(pdev); | 174 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
144 | unsigned long events = 0; | 175 | unsigned long events = 0; |
145 | u16 rtc_istat; | 176 | bool write_complete = false; |
146 | 177 | u16 rtc_istat, rtc_ictl; | |
147 | stampit(); | ||
148 | 178 | ||
149 | spin_lock_irq(&rtc->lock); | 179 | dev_dbg_stamp(dev); |
150 | 180 | ||
151 | rtc_istat = bfin_read_RTC_ISTAT(); | 181 | rtc_istat = bfin_read_RTC_ISTAT(); |
182 | rtc_ictl = bfin_read_RTC_ICTL(); | ||
152 | 183 | ||
153 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { | 184 | if (rtc_istat & RTC_ISTAT_WRITE_COMPLETE) { |
154 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); | 185 | bfin_write_RTC_ISTAT(RTC_ISTAT_WRITE_COMPLETE); |
155 | events |= RTC_AF | RTC_IRQF; | 186 | write_complete = true; |
187 | complete(&bfin_write_complete); | ||
156 | } | 188 | } |
157 | 189 | ||
158 | if (rtc_istat & RTC_ISTAT_STOPWATCH) { | 190 | if (rtc_ictl & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { |
159 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); | 191 | if (rtc_istat & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)) { |
160 | events |= RTC_PF | RTC_IRQF; | 192 | bfin_write_RTC_ISTAT(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY); |
161 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | 193 | events |= RTC_AF | RTC_IRQF; |
194 | } | ||
162 | } | 195 | } |
163 | 196 | ||
164 | if (rtc_istat & RTC_ISTAT_SEC) { | 197 | if (rtc_ictl & RTC_ISTAT_STOPWATCH) { |
165 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | 198 | if (rtc_istat & RTC_ISTAT_STOPWATCH) { |
166 | events |= RTC_UF | RTC_IRQF; | 199 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); |
200 | events |= RTC_PF | RTC_IRQF; | ||
201 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | ||
202 | } | ||
167 | } | 203 | } |
168 | 204 | ||
169 | rtc_update_irq(rtc->rtc_dev, 1, events); | 205 | if (rtc_ictl & RTC_ISTAT_SEC) { |
206 | if (rtc_istat & RTC_ISTAT_SEC) { | ||
207 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | ||
208 | events |= RTC_UF | RTC_IRQF; | ||
209 | } | ||
210 | } | ||
170 | 211 | ||
171 | spin_unlock_irq(&rtc->lock); | 212 | if (events) |
213 | rtc_update_irq(rtc->rtc_dev, 1, events); | ||
172 | 214 | ||
173 | return IRQ_HANDLED; | 215 | if (write_complete || events) |
216 | return IRQ_HANDLED; | ||
217 | else | ||
218 | return IRQ_NONE; | ||
174 | } | 219 | } |
175 | 220 | ||
176 | static int bfin_rtc_open(struct device *dev) | 221 | static int bfin_rtc_open(struct device *dev) |
177 | { | 222 | { |
178 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | ||
179 | int ret; | 223 | int ret; |
180 | 224 | ||
181 | stampit(); | 225 | dev_dbg_stamp(dev); |
182 | 226 | ||
183 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_DISABLED, "rtc-bfin", dev); | 227 | ret = request_irq(IRQ_RTC, bfin_rtc_interrupt, IRQF_SHARED, to_platform_device(dev)->name, dev); |
184 | if (unlikely(ret)) { | 228 | if (!ret) |
185 | dev_err(dev, "request RTC IRQ failed with %d\n", ret); | 229 | bfin_rtc_reset(dev); |
186 | return ret; | ||
187 | } | ||
188 | |||
189 | rtc_bfin_reset(rtc); | ||
190 | 230 | ||
191 | return ret; | 231 | return ret; |
192 | } | 232 | } |
193 | 233 | ||
194 | static void bfin_rtc_release(struct device *dev) | 234 | static void bfin_rtc_release(struct device *dev) |
195 | { | 235 | { |
196 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 236 | dev_dbg_stamp(dev); |
197 | stampit(); | 237 | bfin_rtc_reset(dev); |
198 | rtc_bfin_reset(rtc); | ||
199 | free_irq(IRQ_RTC, dev); | 238 | free_irq(IRQ_RTC, dev); |
200 | } | 239 | } |
201 | 240 | ||
241 | static void bfin_rtc_int_set(struct bfin_rtc *rtc, u16 rtc_int) | ||
242 | { | ||
243 | bfin_write_RTC_ISTAT(rtc_int); | ||
244 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | rtc_int); | ||
245 | } | ||
246 | static void bfin_rtc_int_clear(struct bfin_rtc *rtc, u16 rtc_int) | ||
247 | { | ||
248 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & rtc_int); | ||
249 | } | ||
250 | static void bfin_rtc_int_set_alarm(struct bfin_rtc *rtc) | ||
251 | { | ||
252 | /* Blackfin has different bits for whether the alarm is | ||
253 | * more than 24 hours away. | ||
254 | */ | ||
255 | bfin_rtc_int_set(rtc, (rtc->rtc_alarm.tm_yday == -1 ? RTC_ISTAT_ALARM : RTC_ISTAT_ALARM_DAY)); | ||
256 | } | ||
202 | static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | 257 | static int bfin_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) |
203 | { | 258 | { |
204 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 259 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
260 | int ret = 0; | ||
261 | |||
262 | dev_dbg_stamp(dev); | ||
205 | 263 | ||
206 | stampit(); | 264 | bfin_rtc_sync_pending(dev); |
207 | 265 | ||
208 | switch (cmd) { | 266 | switch (cmd) { |
209 | case RTC_PIE_ON: | 267 | case RTC_PIE_ON: |
210 | stampit(); | 268 | dev_dbg_stamp(dev); |
211 | spin_lock_irq(&rtc->lock); | 269 | bfin_rtc_int_set(rtc, RTC_ISTAT_STOPWATCH); |
212 | rtc_bfin_sync_pending(); | ||
213 | bfin_write_RTC_ISTAT(RTC_ISTAT_STOPWATCH); | ||
214 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); | 270 | bfin_write_RTC_SWCNT(rtc->rtc_dev->irq_freq); |
215 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_STOPWATCH); | 271 | break; |
216 | spin_unlock_irq(&rtc->lock); | ||
217 | return 0; | ||
218 | case RTC_PIE_OFF: | 272 | case RTC_PIE_OFF: |
219 | stampit(); | 273 | dev_dbg_stamp(dev); |
220 | spin_lock_irq(&rtc->lock); | 274 | bfin_rtc_int_clear(rtc, ~RTC_ISTAT_STOPWATCH); |
221 | rtc_bfin_sync_pending(); | 275 | break; |
222 | bfin_write_RTC_SWCNT(0); | ||
223 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_STOPWATCH); | ||
224 | spin_unlock_irq(&rtc->lock); | ||
225 | return 0; | ||
226 | 276 | ||
227 | case RTC_UIE_ON: | 277 | case RTC_UIE_ON: |
228 | stampit(); | 278 | dev_dbg_stamp(dev); |
229 | spin_lock_irq(&rtc->lock); | 279 | bfin_rtc_int_set(rtc, RTC_ISTAT_SEC); |
230 | rtc_bfin_sync_pending(); | 280 | break; |
231 | bfin_write_RTC_ISTAT(RTC_ISTAT_SEC); | ||
232 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | RTC_ISTAT_SEC); | ||
233 | spin_unlock_irq(&rtc->lock); | ||
234 | return 0; | ||
235 | case RTC_UIE_OFF: | 281 | case RTC_UIE_OFF: |
236 | stampit(); | 282 | dev_dbg_stamp(dev); |
237 | spin_lock_irq(&rtc->lock); | 283 | bfin_rtc_int_clear(rtc, ~RTC_ISTAT_SEC); |
238 | rtc_bfin_sync_pending(); | 284 | break; |
239 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~RTC_ISTAT_SEC); | 285 | |
240 | spin_unlock_irq(&rtc->lock); | 286 | case RTC_AIE_ON: |
241 | return 0; | 287 | dev_dbg_stamp(dev); |
242 | 288 | bfin_rtc_int_set_alarm(rtc); | |
243 | case RTC_AIE_ON: { | 289 | break; |
244 | unsigned long rtc_alarm; | ||
245 | u16 which_alarm; | ||
246 | int ret = 0; | ||
247 | |||
248 | stampit(); | ||
249 | |||
250 | spin_lock_irq(&rtc->lock); | ||
251 | |||
252 | rtc_bfin_sync_pending(); | ||
253 | if (rtc->rtc_alarm.tm_yday == -1) { | ||
254 | struct rtc_time now; | ||
255 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), &now); | ||
256 | now.tm_sec = rtc->rtc_alarm.tm_sec; | ||
257 | now.tm_min = rtc->rtc_alarm.tm_min; | ||
258 | now.tm_hour = rtc->rtc_alarm.tm_hour; | ||
259 | ret = rtc_tm_to_time(&now, &rtc_alarm); | ||
260 | which_alarm = RTC_ISTAT_ALARM; | ||
261 | } else { | ||
262 | ret = rtc_tm_to_time(&rtc->rtc_alarm, &rtc_alarm); | ||
263 | which_alarm = RTC_ISTAT_ALARM_DAY; | ||
264 | } | ||
265 | if (ret == 0) { | ||
266 | bfin_write_RTC_ISTAT(which_alarm); | ||
267 | bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); | ||
268 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() | which_alarm); | ||
269 | } | ||
270 | |||
271 | spin_unlock_irq(&rtc->lock); | ||
272 | |||
273 | return ret; | ||
274 | } | ||
275 | case RTC_AIE_OFF: | 290 | case RTC_AIE_OFF: |
276 | stampit(); | 291 | dev_dbg_stamp(dev); |
277 | spin_lock_irq(&rtc->lock); | 292 | bfin_rtc_int_clear(rtc, ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); |
278 | rtc_bfin_sync_pending(); | 293 | break; |
279 | bfin_write_RTC_ICTL(bfin_read_RTC_ICTL() & ~(RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 294 | |
280 | spin_unlock_irq(&rtc->lock); | 295 | default: |
281 | return 0; | 296 | dev_dbg_stamp(dev); |
297 | ret = -ENOIOCTLCMD; | ||
282 | } | 298 | } |
283 | 299 | ||
284 | return -ENOIOCTLCMD; | 300 | return ret; |
285 | } | 301 | } |
286 | 302 | ||
287 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) | 303 | static int bfin_rtc_read_time(struct device *dev, struct rtc_time *tm) |
288 | { | 304 | { |
289 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 305 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
290 | 306 | ||
291 | stampit(); | 307 | dev_dbg_stamp(dev); |
308 | |||
309 | if (rtc->rtc_wrote_regs & 0x1) | ||
310 | bfin_rtc_sync_pending(dev); | ||
292 | 311 | ||
293 | spin_lock_irq(&rtc->lock); | ||
294 | rtc_bfin_sync_pending(); | ||
295 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); | 312 | rtc_bfin_to_tm(bfin_read_RTC_STAT(), tm); |
296 | spin_unlock_irq(&rtc->lock); | ||
297 | 313 | ||
298 | return 0; | 314 | return 0; |
299 | } | 315 | } |
@@ -304,64 +320,79 @@ static int bfin_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
304 | int ret; | 320 | int ret; |
305 | unsigned long now; | 321 | unsigned long now; |
306 | 322 | ||
307 | stampit(); | 323 | dev_dbg_stamp(dev); |
308 | |||
309 | spin_lock_irq(&rtc->lock); | ||
310 | 324 | ||
311 | ret = rtc_tm_to_time(tm, &now); | 325 | ret = rtc_tm_to_time(tm, &now); |
312 | if (ret == 0) { | 326 | if (ret == 0) { |
313 | rtc_bfin_sync_pending(); | 327 | if (rtc->rtc_wrote_regs & 0x1) |
328 | bfin_rtc_sync_pending(dev); | ||
314 | bfin_write_RTC_STAT(rtc_time_to_bfin(now)); | 329 | bfin_write_RTC_STAT(rtc_time_to_bfin(now)); |
330 | rtc->rtc_wrote_regs = 0x1; | ||
315 | } | 331 | } |
316 | 332 | ||
317 | spin_unlock_irq(&rtc->lock); | ||
318 | |||
319 | return ret; | 333 | return ret; |
320 | } | 334 | } |
321 | 335 | ||
322 | static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 336 | static int bfin_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
323 | { | 337 | { |
324 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 338 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
325 | stampit(); | 339 | dev_dbg_stamp(dev); |
326 | memcpy(&alrm->time, &rtc->rtc_alarm, sizeof(struct rtc_time)); | 340 | alrm->time = rtc->rtc_alarm; |
327 | alrm->pending = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | 341 | bfin_rtc_sync_pending(dev); |
342 | alrm->enabled = !!(bfin_read_RTC_ICTL() & (RTC_ISTAT_ALARM | RTC_ISTAT_ALARM_DAY)); | ||
328 | return 0; | 343 | return 0; |
329 | } | 344 | } |
330 | 345 | ||
331 | static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | 346 | static int bfin_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) |
332 | { | 347 | { |
333 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 348 | struct bfin_rtc *rtc = dev_get_drvdata(dev); |
334 | stampit(); | 349 | unsigned long rtc_alarm; |
335 | memcpy(&rtc->rtc_alarm, &alrm->time, sizeof(struct rtc_time)); | 350 | |
351 | dev_dbg_stamp(dev); | ||
352 | |||
353 | if (rtc_tm_to_time(&alrm->time, &rtc_alarm)) | ||
354 | return -EINVAL; | ||
355 | |||
356 | rtc->rtc_alarm = alrm->time; | ||
357 | |||
358 | bfin_rtc_sync_pending(dev); | ||
359 | bfin_write_RTC_ALARM(rtc_time_to_bfin(rtc_alarm)); | ||
360 | if (alrm->enabled) | ||
361 | bfin_rtc_int_set_alarm(rtc); | ||
362 | |||
336 | return 0; | 363 | return 0; |
337 | } | 364 | } |
338 | 365 | ||
339 | static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) | 366 | static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) |
340 | { | 367 | { |
341 | #define yesno(x) (x ? "yes" : "no") | 368 | #define yesno(x) ((x) ? "yes" : "no") |
342 | u16 ictl = bfin_read_RTC_ICTL(); | 369 | u16 ictl = bfin_read_RTC_ICTL(); |
343 | stampit(); | 370 | dev_dbg_stamp(dev); |
344 | seq_printf(seq, "alarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM)); | 371 | seq_printf(seq, |
345 | seq_printf(seq, "wkalarm_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_ALARM_DAY)); | 372 | "alarm_IRQ\t: %s\n" |
346 | seq_printf(seq, "seconds_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_SEC)); | 373 | "wkalarm_IRQ\t: %s\n" |
347 | seq_printf(seq, "periodic_IRQ\t: %s\n", yesno(ictl & RTC_ISTAT_STOPWATCH)); | 374 | "seconds_IRQ\t: %s\n" |
348 | #ifdef DEBUG | 375 | "periodic_IRQ\t: %s\n", |
349 | seq_printf(seq, "RTC_STAT\t: 0x%08X\n", bfin_read_RTC_STAT()); | 376 | yesno(ictl & RTC_ISTAT_ALARM), |
350 | seq_printf(seq, "RTC_ICTL\t: 0x%04X\n", bfin_read_RTC_ICTL()); | 377 | yesno(ictl & RTC_ISTAT_ALARM_DAY), |
351 | seq_printf(seq, "RTC_ISTAT\t: 0x%04X\n", bfin_read_RTC_ISTAT()); | 378 | yesno(ictl & RTC_ISTAT_SEC), |
352 | seq_printf(seq, "RTC_SWCNT\t: 0x%04X\n", bfin_read_RTC_SWCNT()); | 379 | yesno(ictl & RTC_ISTAT_STOPWATCH)); |
353 | seq_printf(seq, "RTC_ALARM\t: 0x%08X\n", bfin_read_RTC_ALARM()); | ||
354 | seq_printf(seq, "RTC_PREN\t: 0x%04X\n", bfin_read_RTC_PREN()); | ||
355 | #endif | ||
356 | return 0; | 380 | return 0; |
381 | #undef yesno | ||
357 | } | 382 | } |
358 | 383 | ||
384 | /** | ||
385 | * bfin_irq_set_freq - make sure hardware supports requested freq | ||
386 | * @dev: pointer to RTC device structure | ||
387 | * @freq: requested frequency rate | ||
388 | * | ||
389 | * The Blackfin RTC can only generate periodic events at 1 per | ||
390 | * second (1 Hz), so reject any attempt at changing it. | ||
391 | */ | ||
359 | static int bfin_irq_set_freq(struct device *dev, int freq) | 392 | static int bfin_irq_set_freq(struct device *dev, int freq) |
360 | { | 393 | { |
361 | struct bfin_rtc *rtc = dev_get_drvdata(dev); | 394 | dev_dbg_stamp(dev); |
362 | stampit(); | 395 | return -ENOTTY; |
363 | rtc->rtc_dev->irq_freq = freq; | ||
364 | return 0; | ||
365 | } | 396 | } |
366 | 397 | ||
367 | static struct rtc_class_ops bfin_rtc_ops = { | 398 | static struct rtc_class_ops bfin_rtc_ops = { |
@@ -381,27 +412,24 @@ static int __devinit bfin_rtc_probe(struct platform_device *pdev) | |||
381 | struct bfin_rtc *rtc; | 412 | struct bfin_rtc *rtc; |
382 | int ret = 0; | 413 | int ret = 0; |
383 | 414 | ||
384 | stampit(); | 415 | dev_dbg_stamp(&pdev->dev); |
385 | 416 | ||
386 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); | 417 | rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); |
387 | if (unlikely(!rtc)) | 418 | if (unlikely(!rtc)) |
388 | return -ENOMEM; | 419 | return -ENOMEM; |
389 | 420 | ||
390 | spin_lock_init(&rtc->lock); | ||
391 | |||
392 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); | 421 | rtc->rtc_dev = rtc_device_register(pdev->name, &pdev->dev, &bfin_rtc_ops, THIS_MODULE); |
393 | if (unlikely(IS_ERR(rtc))) { | 422 | if (unlikely(IS_ERR(rtc))) { |
394 | ret = PTR_ERR(rtc->rtc_dev); | 423 | ret = PTR_ERR(rtc->rtc_dev); |
395 | goto err; | 424 | goto err; |
396 | } | 425 | } |
397 | rtc->rtc_dev->irq_freq = 0; | 426 | rtc->rtc_dev->irq_freq = 1; |
398 | rtc->rtc_dev->max_user_freq = (2 << 16); /* stopwatch is an unsigned 16 bit reg */ | ||
399 | 427 | ||
400 | platform_set_drvdata(pdev, rtc); | 428 | platform_set_drvdata(pdev, rtc); |
401 | 429 | ||
402 | return 0; | 430 | return 0; |
403 | 431 | ||
404 | err: | 432 | err: |
405 | kfree(rtc); | 433 | kfree(rtc); |
406 | return ret; | 434 | return ret; |
407 | } | 435 | } |
@@ -428,7 +456,6 @@ static struct platform_driver bfin_rtc_driver = { | |||
428 | 456 | ||
429 | static int __init bfin_rtc_init(void) | 457 | static int __init bfin_rtc_init(void) |
430 | { | 458 | { |
431 | stampit(); | ||
432 | return platform_driver_register(&bfin_rtc_driver); | 459 | return platform_driver_register(&bfin_rtc_driver); |
433 | } | 460 | } |
434 | 461 | ||
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 29cf1457ca10..e059f94c79eb 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -36,9 +36,24 @@ | |||
36 | #include <linux/platform_device.h> | 36 | #include <linux/platform_device.h> |
37 | #include <linux/mod_devicetable.h> | 37 | #include <linux/mod_devicetable.h> |
38 | 38 | ||
39 | #ifdef CONFIG_HPET_EMULATE_RTC | ||
40 | #include <asm/hpet.h> | ||
41 | #endif | ||
42 | |||
39 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ | 43 | /* this is for "generic access to PC-style RTC" using CMOS_READ/CMOS_WRITE */ |
40 | #include <asm-generic/rtc.h> | 44 | #include <asm-generic/rtc.h> |
41 | 45 | ||
46 | #ifndef CONFIG_HPET_EMULATE_RTC | ||
47 | #define is_hpet_enabled() 0 | ||
48 | #define hpet_set_alarm_time(hrs, min, sec) do { } while (0) | ||
49 | #define hpet_set_periodic_freq(arg) 0 | ||
50 | #define hpet_mask_rtc_irq_bit(arg) do { } while (0) | ||
51 | #define hpet_set_rtc_irq_bit(arg) do { } while (0) | ||
52 | #define hpet_rtc_timer_init() do { } while (0) | ||
53 | #define hpet_register_irq_handler(h) 0 | ||
54 | #define hpet_unregister_irq_handler(h) do { } while (0) | ||
55 | extern irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id); | ||
56 | #endif | ||
42 | 57 | ||
43 | struct cmos_rtc { | 58 | struct cmos_rtc { |
44 | struct rtc_device *rtc; | 59 | struct rtc_device *rtc; |
@@ -199,6 +214,7 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) | |||
199 | sec = t->time.tm_sec; | 214 | sec = t->time.tm_sec; |
200 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; | 215 | sec = (sec < 60) ? BIN2BCD(sec) : 0xff; |
201 | 216 | ||
217 | hpet_set_alarm_time(t->time.tm_hour, t->time.tm_min, t->time.tm_sec); | ||
202 | spin_lock_irq(&rtc_lock); | 218 | spin_lock_irq(&rtc_lock); |
203 | 219 | ||
204 | /* next rtc irq must not be from previous alarm setting */ | 220 | /* next rtc irq must not be from previous alarm setting */ |
@@ -252,7 +268,8 @@ static int cmos_irq_set_freq(struct device *dev, int freq) | |||
252 | f = 16 - f; | 268 | f = 16 - f; |
253 | 269 | ||
254 | spin_lock_irqsave(&rtc_lock, flags); | 270 | spin_lock_irqsave(&rtc_lock, flags); |
255 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | 271 | if (!hpet_set_periodic_freq(freq)) |
272 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); | ||
256 | spin_unlock_irqrestore(&rtc_lock, flags); | 273 | spin_unlock_irqrestore(&rtc_lock, flags); |
257 | 274 | ||
258 | return 0; | 275 | return 0; |
@@ -314,28 +331,37 @@ cmos_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | |||
314 | switch (cmd) { | 331 | switch (cmd) { |
315 | case RTC_AIE_OFF: /* alarm off */ | 332 | case RTC_AIE_OFF: /* alarm off */ |
316 | rtc_control &= ~RTC_AIE; | 333 | rtc_control &= ~RTC_AIE; |
334 | hpet_mask_rtc_irq_bit(RTC_AIE); | ||
317 | break; | 335 | break; |
318 | case RTC_AIE_ON: /* alarm on */ | 336 | case RTC_AIE_ON: /* alarm on */ |
319 | rtc_control |= RTC_AIE; | 337 | rtc_control |= RTC_AIE; |
338 | hpet_set_rtc_irq_bit(RTC_AIE); | ||
320 | break; | 339 | break; |
321 | case RTC_UIE_OFF: /* update off */ | 340 | case RTC_UIE_OFF: /* update off */ |
322 | rtc_control &= ~RTC_UIE; | 341 | rtc_control &= ~RTC_UIE; |
342 | hpet_mask_rtc_irq_bit(RTC_UIE); | ||
323 | break; | 343 | break; |
324 | case RTC_UIE_ON: /* update on */ | 344 | case RTC_UIE_ON: /* update on */ |
325 | rtc_control |= RTC_UIE; | 345 | rtc_control |= RTC_UIE; |
346 | hpet_set_rtc_irq_bit(RTC_UIE); | ||
326 | break; | 347 | break; |
327 | case RTC_PIE_OFF: /* periodic off */ | 348 | case RTC_PIE_OFF: /* periodic off */ |
328 | rtc_control &= ~RTC_PIE; | 349 | rtc_control &= ~RTC_PIE; |
350 | hpet_mask_rtc_irq_bit(RTC_PIE); | ||
329 | break; | 351 | break; |
330 | case RTC_PIE_ON: /* periodic on */ | 352 | case RTC_PIE_ON: /* periodic on */ |
331 | rtc_control |= RTC_PIE; | 353 | rtc_control |= RTC_PIE; |
354 | hpet_set_rtc_irq_bit(RTC_PIE); | ||
332 | break; | 355 | break; |
333 | } | 356 | } |
334 | CMOS_WRITE(rtc_control, RTC_CONTROL); | 357 | if (!is_hpet_enabled()) |
358 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
359 | |||
335 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); | 360 | rtc_intr = CMOS_READ(RTC_INTR_FLAGS); |
336 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | 361 | rtc_intr &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; |
337 | if (is_intr(rtc_intr)) | 362 | if (is_intr(rtc_intr)) |
338 | rtc_update_irq(cmos->rtc, 1, rtc_intr); | 363 | rtc_update_irq(cmos->rtc, 1, rtc_intr); |
364 | |||
339 | spin_unlock_irqrestore(&rtc_lock, flags); | 365 | spin_unlock_irqrestore(&rtc_lock, flags); |
340 | return 0; | 366 | return 0; |
341 | } | 367 | } |
@@ -393,15 +419,111 @@ static const struct rtc_class_ops cmos_rtc_ops = { | |||
393 | 419 | ||
394 | /*----------------------------------------------------------------*/ | 420 | /*----------------------------------------------------------------*/ |
395 | 421 | ||
422 | /* | ||
423 | * All these chips have at least 64 bytes of address space, shared by | ||
424 | * RTC registers and NVRAM. Most of those bytes of NVRAM are used | ||
425 | * by boot firmware. Modern chips have 128 or 256 bytes. | ||
426 | */ | ||
427 | |||
428 | #define NVRAM_OFFSET (RTC_REG_D + 1) | ||
429 | |||
430 | static ssize_t | ||
431 | cmos_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | ||
432 | char *buf, loff_t off, size_t count) | ||
433 | { | ||
434 | int retval; | ||
435 | |||
436 | if (unlikely(off >= attr->size)) | ||
437 | return 0; | ||
438 | if ((off + count) > attr->size) | ||
439 | count = attr->size - off; | ||
440 | |||
441 | spin_lock_irq(&rtc_lock); | ||
442 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) | ||
443 | *buf++ = CMOS_READ(off); | ||
444 | spin_unlock_irq(&rtc_lock); | ||
445 | |||
446 | return retval; | ||
447 | } | ||
448 | |||
449 | static ssize_t | ||
450 | cmos_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | ||
451 | char *buf, loff_t off, size_t count) | ||
452 | { | ||
453 | struct cmos_rtc *cmos; | ||
454 | int retval; | ||
455 | |||
456 | cmos = dev_get_drvdata(container_of(kobj, struct device, kobj)); | ||
457 | if (unlikely(off >= attr->size)) | ||
458 | return -EFBIG; | ||
459 | if ((off + count) > attr->size) | ||
460 | count = attr->size - off; | ||
461 | |||
462 | /* NOTE: on at least PCs and Ataris, the boot firmware uses a | ||
463 | * checksum on part of the NVRAM data. That's currently ignored | ||
464 | * here. If userspace is smart enough to know what fields of | ||
465 | * NVRAM to update, updating checksums is also part of its job. | ||
466 | */ | ||
467 | spin_lock_irq(&rtc_lock); | ||
468 | for (retval = 0, off += NVRAM_OFFSET; count--; retval++, off++) { | ||
469 | /* don't trash RTC registers */ | ||
470 | if (off == cmos->day_alrm | ||
471 | || off == cmos->mon_alrm | ||
472 | || off == cmos->century) | ||
473 | buf++; | ||
474 | else | ||
475 | CMOS_WRITE(*buf++, off); | ||
476 | } | ||
477 | spin_unlock_irq(&rtc_lock); | ||
478 | |||
479 | return retval; | ||
480 | } | ||
481 | |||
482 | static struct bin_attribute nvram = { | ||
483 | .attr = { | ||
484 | .name = "nvram", | ||
485 | .mode = S_IRUGO | S_IWUSR, | ||
486 | .owner = THIS_MODULE, | ||
487 | }, | ||
488 | |||
489 | .read = cmos_nvram_read, | ||
490 | .write = cmos_nvram_write, | ||
491 | /* size gets set up later */ | ||
492 | }; | ||
493 | |||
494 | /*----------------------------------------------------------------*/ | ||
495 | |||
396 | static struct cmos_rtc cmos_rtc; | 496 | static struct cmos_rtc cmos_rtc; |
397 | 497 | ||
398 | static irqreturn_t cmos_interrupt(int irq, void *p) | 498 | static irqreturn_t cmos_interrupt(int irq, void *p) |
399 | { | 499 | { |
400 | u8 irqstat; | 500 | u8 irqstat; |
501 | u8 rtc_control; | ||
401 | 502 | ||
402 | spin_lock(&rtc_lock); | 503 | spin_lock(&rtc_lock); |
403 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | 504 | /* |
404 | irqstat &= (CMOS_READ(RTC_CONTROL) & RTC_IRQMASK) | RTC_IRQF; | 505 | * In this case it is HPET RTC interrupt handler |
506 | * calling us, with the interrupt information | ||
507 | * passed as arg1, instead of irq. | ||
508 | */ | ||
509 | if (is_hpet_enabled()) | ||
510 | irqstat = (unsigned long)irq & 0xF0; | ||
511 | else { | ||
512 | irqstat = CMOS_READ(RTC_INTR_FLAGS); | ||
513 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
514 | irqstat &= (rtc_control & RTC_IRQMASK) | RTC_IRQF; | ||
515 | } | ||
516 | |||
517 | /* All Linux RTC alarms should be treated as if they were oneshot. | ||
518 | * Similar code may be needed in system wakeup paths, in case the | ||
519 | * alarm woke the system. | ||
520 | */ | ||
521 | if (irqstat & RTC_AIE) { | ||
522 | rtc_control = CMOS_READ(RTC_CONTROL); | ||
523 | rtc_control &= ~RTC_AIE; | ||
524 | CMOS_WRITE(rtc_control, RTC_CONTROL); | ||
525 | CMOS_READ(RTC_INTR_FLAGS); | ||
526 | } | ||
405 | spin_unlock(&rtc_lock); | 527 | spin_unlock(&rtc_lock); |
406 | 528 | ||
407 | if (is_intr(irqstat)) { | 529 | if (is_intr(irqstat)) { |
@@ -412,11 +534,9 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
412 | } | 534 | } |
413 | 535 | ||
414 | #ifdef CONFIG_PNP | 536 | #ifdef CONFIG_PNP |
415 | #define is_pnp() 1 | ||
416 | #define INITSECTION | 537 | #define INITSECTION |
417 | 538 | ||
418 | #else | 539 | #else |
419 | #define is_pnp() 0 | ||
420 | #define INITSECTION __init | 540 | #define INITSECTION __init |
421 | #endif | 541 | #endif |
422 | 542 | ||
@@ -426,6 +546,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
426 | struct cmos_rtc_board_info *info = dev->platform_data; | 546 | struct cmos_rtc_board_info *info = dev->platform_data; |
427 | int retval = 0; | 547 | int retval = 0; |
428 | unsigned char rtc_control; | 548 | unsigned char rtc_control; |
549 | unsigned address_space; | ||
429 | 550 | ||
430 | /* there can be only one ... */ | 551 | /* there can be only one ... */ |
431 | if (cmos_rtc.dev) | 552 | if (cmos_rtc.dev) |
@@ -450,15 +571,36 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
450 | cmos_rtc.irq = rtc_irq; | 571 | cmos_rtc.irq = rtc_irq; |
451 | cmos_rtc.iomem = ports; | 572 | cmos_rtc.iomem = ports; |
452 | 573 | ||
574 | /* Heuristic to deduce NVRAM size ... do what the legacy NVRAM | ||
575 | * driver did, but don't reject unknown configs. Old hardware | ||
576 | * won't address 128 bytes, and for now we ignore the way newer | ||
577 | * chips can address 256 bytes (using two more i/o ports). | ||
578 | */ | ||
579 | #if defined(CONFIG_ATARI) | ||
580 | address_space = 64; | ||
581 | #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) | ||
582 | address_space = 128; | ||
583 | #else | ||
584 | #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. | ||
585 | address_space = 128; | ||
586 | #endif | ||
587 | |||
453 | /* For ACPI systems extension info comes from the FADT. On others, | 588 | /* For ACPI systems extension info comes from the FADT. On others, |
454 | * board specific setup provides it as appropriate. Systems where | 589 | * board specific setup provides it as appropriate. Systems where |
455 | * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and | 590 | * the alarm IRQ isn't automatically a wakeup IRQ (like ACPI, and |
456 | * some almost-clones) can provide hooks to make that behave. | 591 | * some almost-clones) can provide hooks to make that behave. |
592 | * | ||
593 | * Note that ACPI doesn't preclude putting these registers into | ||
594 | * "extended" areas of the chip, including some that we won't yet | ||
595 | * expect CMOS_READ and friends to handle. | ||
457 | */ | 596 | */ |
458 | if (info) { | 597 | if (info) { |
459 | cmos_rtc.day_alrm = info->rtc_day_alarm; | 598 | if (info->rtc_day_alarm && info->rtc_day_alarm < 128) |
460 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; | 599 | cmos_rtc.day_alrm = info->rtc_day_alarm; |
461 | cmos_rtc.century = info->rtc_century; | 600 | if (info->rtc_mon_alarm && info->rtc_mon_alarm < 128) |
601 | cmos_rtc.mon_alrm = info->rtc_mon_alarm; | ||
602 | if (info->rtc_century && info->rtc_century < 128) | ||
603 | cmos_rtc.century = info->rtc_century; | ||
462 | 604 | ||
463 | if (info->wake_on && info->wake_off) { | 605 | if (info->wake_on && info->wake_off) { |
464 | cmos_rtc.wake_on = info->wake_on; | 606 | cmos_rtc.wake_on = info->wake_on; |
@@ -485,8 +627,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
485 | * doesn't use 32KHz here ... for portability we might need to | 627 | * doesn't use 32KHz here ... for portability we might need to |
486 | * do something about other clock frequencies. | 628 | * do something about other clock frequencies. |
487 | */ | 629 | */ |
488 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); | ||
489 | cmos_rtc.rtc->irq_freq = 1024; | 630 | cmos_rtc.rtc->irq_freq = 1024; |
631 | if (!hpet_set_periodic_freq(cmos_rtc.rtc->irq_freq)) | ||
632 | CMOS_WRITE(RTC_REF_CLCK_32KHZ | 0x06, RTC_FREQ_SELECT); | ||
490 | 633 | ||
491 | /* disable irqs. | 634 | /* disable irqs. |
492 | * | 635 | * |
@@ -509,19 +652,39 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
509 | goto cleanup1; | 652 | goto cleanup1; |
510 | } | 653 | } |
511 | 654 | ||
512 | if (is_valid_irq(rtc_irq)) | 655 | if (is_valid_irq(rtc_irq)) { |
513 | retval = request_irq(rtc_irq, cmos_interrupt, IRQF_DISABLED, | 656 | irq_handler_t rtc_cmos_int_handler; |
514 | cmos_rtc.rtc->dev.bus_id, | 657 | |
658 | if (is_hpet_enabled()) { | ||
659 | int err; | ||
660 | |||
661 | rtc_cmos_int_handler = hpet_rtc_interrupt; | ||
662 | err = hpet_register_irq_handler(cmos_interrupt); | ||
663 | if (err != 0) { | ||
664 | printk(KERN_WARNING "hpet_register_irq_handler " | ||
665 | " failed in rtc_init()."); | ||
666 | goto cleanup1; | ||
667 | } | ||
668 | } else | ||
669 | rtc_cmos_int_handler = cmos_interrupt; | ||
670 | |||
671 | retval = request_irq(rtc_irq, rtc_cmos_int_handler, | ||
672 | IRQF_DISABLED, cmos_rtc.rtc->dev.bus_id, | ||
515 | cmos_rtc.rtc); | 673 | cmos_rtc.rtc); |
516 | if (retval < 0) { | 674 | if (retval < 0) { |
517 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); | 675 | dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq); |
518 | goto cleanup1; | 676 | goto cleanup1; |
677 | } | ||
519 | } | 678 | } |
679 | hpet_rtc_timer_init(); | ||
520 | 680 | ||
521 | /* REVISIT optionally make 50 or 114 bytes NVRAM available, | 681 | /* export at least the first block of NVRAM */ |
522 | * like rtc-ds1553, rtc-ds1742 ... this will often include | 682 | nvram.size = address_space - NVRAM_OFFSET; |
523 | * registers for century, and day/month alarm. | 683 | retval = sysfs_create_bin_file(&dev->kobj, &nvram); |
524 | */ | 684 | if (retval < 0) { |
685 | dev_dbg(dev, "can't create nvram file? %d\n", retval); | ||
686 | goto cleanup2; | ||
687 | } | ||
525 | 688 | ||
526 | pr_info("%s: alarms up to one %s%s\n", | 689 | pr_info("%s: alarms up to one %s%s\n", |
527 | cmos_rtc.rtc->dev.bus_id, | 690 | cmos_rtc.rtc->dev.bus_id, |
@@ -536,6 +699,9 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) | |||
536 | 699 | ||
537 | return 0; | 700 | return 0; |
538 | 701 | ||
702 | cleanup2: | ||
703 | if (is_valid_irq(rtc_irq)) | ||
704 | free_irq(rtc_irq, cmos_rtc.rtc); | ||
539 | cleanup1: | 705 | cleanup1: |
540 | cmos_rtc.dev = NULL; | 706 | cmos_rtc.dev = NULL; |
541 | rtc_device_unregister(cmos_rtc.rtc); | 707 | rtc_device_unregister(cmos_rtc.rtc); |
@@ -563,8 +729,12 @@ static void __exit cmos_do_remove(struct device *dev) | |||
563 | 729 | ||
564 | cmos_do_shutdown(); | 730 | cmos_do_shutdown(); |
565 | 731 | ||
566 | if (is_valid_irq(cmos->irq)) | 732 | sysfs_remove_bin_file(&dev->kobj, &nvram); |
733 | |||
734 | if (is_valid_irq(cmos->irq)) { | ||
567 | free_irq(cmos->irq, cmos->rtc); | 735 | free_irq(cmos->irq, cmos->rtc); |
736 | hpet_unregister_irq_handler(cmos_interrupt); | ||
737 | } | ||
568 | 738 | ||
569 | rtc_device_unregister(cmos->rtc); | 739 | rtc_device_unregister(cmos->rtc); |
570 | cmos->rtc = NULL; | 740 | cmos->rtc = NULL; |
@@ -659,9 +829,12 @@ static int cmos_resume(struct device *dev) | |||
659 | 829 | ||
660 | /*----------------------------------------------------------------*/ | 830 | /*----------------------------------------------------------------*/ |
661 | 831 | ||
662 | /* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, | 832 | /* On non-x86 systems, a "CMOS" RTC lives most naturally on platform_bus. |
663 | * the device node will always be created as a PNPACPI device. Plus | 833 | * ACPI systems always list these as PNPACPI devices, and pre-ACPI PCs |
664 | * pre-ACPI PCs probably list it in the PNPBIOS tables. | 834 | * probably list them in similar PNPBIOS tables; so PNP is more common. |
835 | * | ||
836 | * We don't use legacy "poke at the hardware" probing. Ancient PCs that | ||
837 | * predate even PNPBIOS should set up platform_bus devices. | ||
665 | */ | 838 | */ |
666 | 839 | ||
667 | #ifdef CONFIG_PNP | 840 | #ifdef CONFIG_PNP |
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 025c60a17a4a..90dfa0df747a 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c | |||
@@ -246,6 +246,15 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file, | |||
246 | /* if the driver does not provide the ioctl interface | 246 | /* if the driver does not provide the ioctl interface |
247 | * or if that particular ioctl was not implemented | 247 | * or if that particular ioctl was not implemented |
248 | * (-ENOIOCTLCMD), we will try to emulate here. | 248 | * (-ENOIOCTLCMD), we will try to emulate here. |
249 | * | ||
250 | * Drivers *SHOULD NOT* provide ioctl implementations | ||
251 | * for these requests. Instead, provide methods to | ||
252 | * support the following code, so that the RTC's main | ||
253 | * features are accessible without using ioctls. | ||
254 | * | ||
255 | * RTC and alarm times will be in UTC, by preference, | ||
256 | * but dual-booting with MS-Windows implies RTCs must | ||
257 | * use the local wall clock time. | ||
249 | */ | 258 | */ |
250 | 259 | ||
251 | switch (cmd) { | 260 | switch (cmd) { |
diff --git a/drivers/rtc/rtc-ds1302.c b/drivers/rtc/rtc-ds1302.c new file mode 100644 index 000000000000..7b002ceeaa7d --- /dev/null +++ b/drivers/rtc/rtc-ds1302.c | |||
@@ -0,0 +1,262 @@ | |||
1 | /* | ||
2 | * Dallas DS1302 RTC Support | ||
3 | * | ||
4 | * Copyright (C) 2002 David McCullough | ||
5 | * Copyright (C) 2003 - 2007 Paul Mundt | ||
6 | * | ||
7 | * This file is subject to the terms and conditions of the GNU General Public | ||
8 | * License version 2. See the file "COPYING" in the main directory of | ||
9 | * this archive for more details. | ||
10 | */ | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/time.h> | ||
16 | #include <linux/rtc.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/io.h> | ||
19 | #include <linux/bcd.h> | ||
20 | #include <asm/rtc.h> | ||
21 | |||
22 | #define DRV_NAME "rtc-ds1302" | ||
23 | #define DRV_VERSION "0.1.0" | ||
24 | |||
25 | #define RTC_CMD_READ 0x81 /* Read command */ | ||
26 | #define RTC_CMD_WRITE 0x80 /* Write command */ | ||
27 | |||
28 | #define RTC_ADDR_RAM0 0x20 /* Address of RAM0 */ | ||
29 | #define RTC_ADDR_TCR 0x08 /* Address of trickle charge register */ | ||
30 | #define RTC_ADDR_YEAR 0x06 /* Address of year register */ | ||
31 | #define RTC_ADDR_DAY 0x05 /* Address of day of week register */ | ||
32 | #define RTC_ADDR_MON 0x04 /* Address of month register */ | ||
33 | #define RTC_ADDR_DATE 0x03 /* Address of day of month register */ | ||
34 | #define RTC_ADDR_HOUR 0x02 /* Address of hour register */ | ||
35 | #define RTC_ADDR_MIN 0x01 /* Address of minute register */ | ||
36 | #define RTC_ADDR_SEC 0x00 /* Address of second register */ | ||
37 | |||
38 | #define RTC_RESET 0x1000 | ||
39 | #define RTC_IODATA 0x0800 | ||
40 | #define RTC_SCLK 0x0400 | ||
41 | |||
42 | #ifdef CONFIG_SH_SECUREEDGE5410 | ||
43 | #include <asm/snapgear.h> | ||
44 | #define set_dp(x) SECUREEDGE_WRITE_IOPORT(x, 0x1c00) | ||
45 | #define get_dp() SECUREEDGE_READ_IOPORT() | ||
46 | #else | ||
47 | #error "Add support for your platform" | ||
48 | #endif | ||
49 | |||
50 | struct ds1302_rtc { | ||
51 | struct rtc_device *rtc_dev; | ||
52 | spinlock_t lock; | ||
53 | }; | ||
54 | |||
55 | static void ds1302_sendbits(unsigned int val) | ||
56 | { | ||
57 | int i; | ||
58 | |||
59 | for (i = 8; (i); i--, val >>= 1) { | ||
60 | set_dp((get_dp() & ~RTC_IODATA) | ((val & 0x1) ? | ||
61 | RTC_IODATA : 0)); | ||
62 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
63 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
64 | } | ||
65 | } | ||
66 | |||
67 | static unsigned int ds1302_recvbits(void) | ||
68 | { | ||
69 | unsigned int val; | ||
70 | int i; | ||
71 | |||
72 | for (i = 0, val = 0; (i < 8); i++) { | ||
73 | val |= (((get_dp() & RTC_IODATA) ? 1 : 0) << i); | ||
74 | set_dp(get_dp() | RTC_SCLK); /* clock high */ | ||
75 | set_dp(get_dp() & ~RTC_SCLK); /* clock low */ | ||
76 | } | ||
77 | |||
78 | return val; | ||
79 | } | ||
80 | |||
81 | static unsigned int ds1302_readbyte(unsigned int addr) | ||
82 | { | ||
83 | unsigned int val; | ||
84 | |||
85 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
86 | |||
87 | set_dp(get_dp() | RTC_RESET); | ||
88 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_READ); | ||
89 | val = ds1302_recvbits(); | ||
90 | set_dp(get_dp() & ~RTC_RESET); | ||
91 | |||
92 | return val; | ||
93 | } | ||
94 | |||
95 | static void ds1302_writebyte(unsigned int addr, unsigned int val) | ||
96 | { | ||
97 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
98 | set_dp(get_dp() | RTC_RESET); | ||
99 | ds1302_sendbits(((addr & 0x3f) << 1) | RTC_CMD_WRITE); | ||
100 | ds1302_sendbits(val); | ||
101 | set_dp(get_dp() & ~RTC_RESET); | ||
102 | } | ||
103 | |||
104 | static int ds1302_rtc_read_time(struct device *dev, struct rtc_time *tm) | ||
105 | { | ||
106 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
107 | |||
108 | spin_lock_irq(&rtc->lock); | ||
109 | |||
110 | tm->tm_sec = BCD2BIN(ds1302_readbyte(RTC_ADDR_SEC)); | ||
111 | tm->tm_min = BCD2BIN(ds1302_readbyte(RTC_ADDR_MIN)); | ||
112 | tm->tm_hour = BCD2BIN(ds1302_readbyte(RTC_ADDR_HOUR)); | ||
113 | tm->tm_wday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DAY)); | ||
114 | tm->tm_mday = BCD2BIN(ds1302_readbyte(RTC_ADDR_DATE)); | ||
115 | tm->tm_mon = BCD2BIN(ds1302_readbyte(RTC_ADDR_MON)) - 1; | ||
116 | tm->tm_year = BCD2BIN(ds1302_readbyte(RTC_ADDR_YEAR)); | ||
117 | |||
118 | if (tm->tm_year < 70) | ||
119 | tm->tm_year += 100; | ||
120 | |||
121 | spin_unlock_irq(&rtc->lock); | ||
122 | |||
123 | dev_dbg(dev, "%s: tm is secs=%d, mins=%d, hours=%d, " | ||
124 | "mday=%d, mon=%d, year=%d, wday=%d\n", | ||
125 | __FUNCTION__, | ||
126 | tm->tm_sec, tm->tm_min, tm->tm_hour, | ||
127 | tm->tm_mday, tm->tm_mon + 1, tm->tm_year, tm->tm_wday); | ||
128 | |||
129 | if (rtc_valid_tm(tm) < 0) | ||
130 | dev_err(dev, "invalid date\n"); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
135 | static int ds1302_rtc_set_time(struct device *dev, struct rtc_time *tm) | ||
136 | { | ||
137 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
138 | |||
139 | spin_lock_irq(&rtc->lock); | ||
140 | |||
141 | /* Stop RTC */ | ||
142 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80); | ||
143 | |||
144 | ds1302_writebyte(RTC_ADDR_SEC, BIN2BCD(tm->tm_sec)); | ||
145 | ds1302_writebyte(RTC_ADDR_MIN, BIN2BCD(tm->tm_min)); | ||
146 | ds1302_writebyte(RTC_ADDR_HOUR, BIN2BCD(tm->tm_hour)); | ||
147 | ds1302_writebyte(RTC_ADDR_DAY, BIN2BCD(tm->tm_wday)); | ||
148 | ds1302_writebyte(RTC_ADDR_DATE, BIN2BCD(tm->tm_mday)); | ||
149 | ds1302_writebyte(RTC_ADDR_MON, BIN2BCD(tm->tm_mon + 1)); | ||
150 | ds1302_writebyte(RTC_ADDR_YEAR, BIN2BCD(tm->tm_year % 100)); | ||
151 | |||
152 | /* Start RTC */ | ||
153 | ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80); | ||
154 | |||
155 | spin_unlock_irq(&rtc->lock); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static int ds1302_rtc_ioctl(struct device *dev, unsigned int cmd, | ||
161 | unsigned long arg) | ||
162 | { | ||
163 | switch (cmd) { | ||
164 | #ifdef RTC_SET_CHARGE | ||
165 | case RTC_SET_CHARGE: | ||
166 | { | ||
167 | struct ds1302_rtc *rtc = dev_get_drvdata(dev); | ||
168 | int tcs_val; | ||
169 | |||
170 | if (copy_from_user(&tcs_val, (int __user *)arg, sizeof(int))) | ||
171 | return -EFAULT; | ||
172 | |||
173 | spin_lock_irq(&rtc->lock); | ||
174 | ds1302_writebyte(RTC_ADDR_TCR, (0xa0 | tcs_val * 0xf)); | ||
175 | spin_unlock_irq(&rtc->lock); | ||
176 | return 0; | ||
177 | } | ||
178 | #endif | ||
179 | } | ||
180 | |||
181 | return -ENOIOCTLCMD; | ||
182 | } | ||
183 | |||
184 | static struct rtc_class_ops ds1302_rtc_ops = { | ||
185 | .read_time = ds1302_rtc_read_time, | ||
186 | .set_time = ds1302_rtc_set_time, | ||
187 | .ioctl = ds1302_rtc_ioctl, | ||
188 | }; | ||
189 | |||
190 | static int __devinit ds1302_rtc_probe(struct platform_device *pdev) | ||
191 | { | ||
192 | struct ds1302_rtc *rtc; | ||
193 | int ret; | ||
194 | |||
195 | /* Reset */ | ||
196 | set_dp(get_dp() & ~(RTC_RESET | RTC_IODATA | RTC_SCLK)); | ||
197 | |||
198 | /* Write a magic value to the DS1302 RAM, and see if it sticks. */ | ||
199 | ds1302_writebyte(RTC_ADDR_RAM0, 0x42); | ||
200 | if (ds1302_readbyte(RTC_ADDR_RAM0) != 0x42) | ||
201 | return -ENODEV; | ||
202 | |||
203 | rtc = kzalloc(sizeof(struct ds1302_rtc), GFP_KERNEL); | ||
204 | if (unlikely(!rtc)) | ||
205 | return -ENOMEM; | ||
206 | |||
207 | spin_lock_init(&rtc->lock); | ||
208 | rtc->rtc_dev = rtc_device_register("ds1302", &pdev->dev, | ||
209 | &ds1302_rtc_ops, THIS_MODULE); | ||
210 | if (IS_ERR(rtc->rtc_dev)) { | ||
211 | ret = PTR_ERR(rtc->rtc_dev); | ||
212 | goto out; | ||
213 | } | ||
214 | |||
215 | platform_set_drvdata(pdev, rtc); | ||
216 | |||
217 | return 0; | ||
218 | out: | ||
219 | kfree(rtc); | ||
220 | return ret; | ||
221 | } | ||
222 | |||
223 | static int __devexit ds1302_rtc_remove(struct platform_device *pdev) | ||
224 | { | ||
225 | struct ds1302_rtc *rtc = platform_get_drvdata(pdev); | ||
226 | |||
227 | if (likely(rtc->rtc_dev)) | ||
228 | rtc_device_unregister(rtc->rtc_dev); | ||
229 | |||
230 | platform_set_drvdata(pdev, NULL); | ||
231 | |||
232 | kfree(rtc); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static struct platform_driver ds1302_platform_driver = { | ||
238 | .driver = { | ||
239 | .name = DRV_NAME, | ||
240 | .owner = THIS_MODULE, | ||
241 | }, | ||
242 | .probe = ds1302_rtc_probe, | ||
243 | .remove = __devexit_p(ds1302_rtc_remove), | ||
244 | }; | ||
245 | |||
246 | static int __init ds1302_rtc_init(void) | ||
247 | { | ||
248 | return platform_driver_register(&ds1302_platform_driver); | ||
249 | } | ||
250 | |||
251 | static void __exit ds1302_rtc_exit(void) | ||
252 | { | ||
253 | platform_driver_unregister(&ds1302_platform_driver); | ||
254 | } | ||
255 | |||
256 | module_init(ds1302_rtc_init); | ||
257 | module_exit(ds1302_rtc_exit); | ||
258 | |||
259 | MODULE_DESCRIPTION("Dallas DS1302 RTC driver"); | ||
260 | MODULE_VERSION(DRV_VERSION); | ||
261 | MODULE_AUTHOR("Paul Mundt, David McCullough"); | ||
262 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/rtc/rtc-ds1307.c b/drivers/rtc/rtc-ds1307.c index bc1c7fe94ad3..f389a28720d2 100644 --- a/drivers/rtc/rtc-ds1307.c +++ b/drivers/rtc/rtc-ds1307.c | |||
@@ -256,7 +256,7 @@ ds1307_nvram_read(struct kobject *kobj, struct bin_attribute *attr, | |||
256 | struct i2c_msg msg[2]; | 256 | struct i2c_msg msg[2]; |
257 | int result; | 257 | int result; |
258 | 258 | ||
259 | client = to_i2c_client(container_of(kobj, struct device, kobj)); | 259 | client = kobj_to_i2c_client(kobj); |
260 | ds1307 = i2c_get_clientdata(client); | 260 | ds1307 = i2c_get_clientdata(client); |
261 | 261 | ||
262 | if (unlikely(off >= NVRAM_SIZE)) | 262 | if (unlikely(off >= NVRAM_SIZE)) |
@@ -294,7 +294,7 @@ ds1307_nvram_write(struct kobject *kobj, struct bin_attribute *attr, | |||
294 | u8 buffer[NVRAM_SIZE + 1]; | 294 | u8 buffer[NVRAM_SIZE + 1]; |
295 | int ret; | 295 | int ret; |
296 | 296 | ||
297 | client = to_i2c_client(container_of(kobj, struct device, kobj)); | 297 | client = kobj_to_i2c_client(kobj); |
298 | 298 | ||
299 | if (unlikely(off >= NVRAM_SIZE)) | 299 | if (unlikely(off >= NVRAM_SIZE)) |
300 | return -EFBIG; | 300 | return -EFBIG; |
@@ -412,11 +412,6 @@ read_rtc: | |||
412 | */ | 412 | */ |
413 | tmp = ds1307->regs[DS1307_REG_SECS]; | 413 | tmp = ds1307->regs[DS1307_REG_SECS]; |
414 | switch (ds1307->type) { | 414 | switch (ds1307->type) { |
415 | case ds_1340: | ||
416 | /* FIXME read register with DS1340_BIT_OSF, use that to | ||
417 | * trigger the "set time" warning (*after* restarting the | ||
418 | * oscillator!) instead of this weaker ds1307/m41t00 test. | ||
419 | */ | ||
420 | case ds_1307: | 415 | case ds_1307: |
421 | case m41t00: | 416 | case m41t00: |
422 | /* clock halted? turn it on, so clock can tick. */ | 417 | /* clock halted? turn it on, so clock can tick. */ |
@@ -440,6 +435,24 @@ read_rtc: | |||
440 | goto read_rtc; | 435 | goto read_rtc; |
441 | } | 436 | } |
442 | break; | 437 | break; |
438 | case ds_1340: | ||
439 | /* clock halted? turn it on, so clock can tick. */ | ||
440 | if (tmp & DS1340_BIT_nEOSC) | ||
441 | i2c_smbus_write_byte_data(client, DS1307_REG_SECS, 0); | ||
442 | |||
443 | tmp = i2c_smbus_read_byte_data(client, DS1340_REG_FLAG); | ||
444 | if (tmp < 0) { | ||
445 | pr_debug("read error %d\n", tmp); | ||
446 | err = -EIO; | ||
447 | goto exit_free; | ||
448 | } | ||
449 | |||
450 | /* oscillator fault? clear flag, and warn */ | ||
451 | if (tmp & DS1340_BIT_OSF) { | ||
452 | i2c_smbus_write_byte_data(client, DS1340_REG_FLAG, 0); | ||
453 | dev_warn(&client->dev, "SET TIME!\n"); | ||
454 | } | ||
455 | break; | ||
443 | case ds_1337: | 456 | case ds_1337: |
444 | case ds_1339: | 457 | case ds_1339: |
445 | break; | 458 | break; |
diff --git a/drivers/rtc/rtc-ds1511.c b/drivers/rtc/rtc-ds1511.c new file mode 100644 index 000000000000..d74b8086fa31 --- /dev/null +++ b/drivers/rtc/rtc-ds1511.c | |||
@@ -0,0 +1,656 @@ | |||
1 | /* | ||
2 | * An rtc driver for the Dallas DS1511 | ||
3 | * | ||
4 | * Copyright (C) 2006 Atsushi Nemoto <anemo@mba.ocn.ne.jp> | ||
5 | * Copyright (C) 2007 Andrew Sharp <andy.sharp@onstor.com> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * Real time clock driver for the Dallas 1511 chip, which also | ||
12 | * contains a watchdog timer. There is a tiny amount of code that | ||
13 | * platform code could use to mess with the watchdog device a little | ||
14 | * bit, but not a full watchdog driver. | ||
15 | */ | ||
16 | |||
17 | #include <linux/bcd.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/interrupt.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/io.h> | ||
25 | |||
26 | #define DRV_VERSION "0.6" | ||
27 | |||
28 | enum ds1511reg { | ||
29 | DS1511_SEC = 0x0, | ||
30 | DS1511_MIN = 0x1, | ||
31 | DS1511_HOUR = 0x2, | ||
32 | DS1511_DOW = 0x3, | ||
33 | DS1511_DOM = 0x4, | ||
34 | DS1511_MONTH = 0x5, | ||
35 | DS1511_YEAR = 0x6, | ||
36 | DS1511_CENTURY = 0x7, | ||
37 | DS1511_AM1_SEC = 0x8, | ||
38 | DS1511_AM2_MIN = 0x9, | ||
39 | DS1511_AM3_HOUR = 0xa, | ||
40 | DS1511_AM4_DATE = 0xb, | ||
41 | DS1511_WD_MSEC = 0xc, | ||
42 | DS1511_WD_SEC = 0xd, | ||
43 | DS1511_CONTROL_A = 0xe, | ||
44 | DS1511_CONTROL_B = 0xf, | ||
45 | DS1511_RAMADDR_LSB = 0x10, | ||
46 | DS1511_RAMDATA = 0x13 | ||
47 | }; | ||
48 | |||
49 | #define DS1511_BLF1 0x80 | ||
50 | #define DS1511_BLF2 0x40 | ||
51 | #define DS1511_PRS 0x20 | ||
52 | #define DS1511_PAB 0x10 | ||
53 | #define DS1511_TDF 0x08 | ||
54 | #define DS1511_KSF 0x04 | ||
55 | #define DS1511_WDF 0x02 | ||
56 | #define DS1511_IRQF 0x01 | ||
57 | #define DS1511_TE 0x80 | ||
58 | #define DS1511_CS 0x40 | ||
59 | #define DS1511_BME 0x20 | ||
60 | #define DS1511_TPE 0x10 | ||
61 | #define DS1511_TIE 0x08 | ||
62 | #define DS1511_KIE 0x04 | ||
63 | #define DS1511_WDE 0x02 | ||
64 | #define DS1511_WDS 0x01 | ||
65 | #define DS1511_RAM_MAX 0xff | ||
66 | |||
67 | #define RTC_CMD DS1511_CONTROL_B | ||
68 | #define RTC_CMD1 DS1511_CONTROL_A | ||
69 | |||
70 | #define RTC_ALARM_SEC DS1511_AM1_SEC | ||
71 | #define RTC_ALARM_MIN DS1511_AM2_MIN | ||
72 | #define RTC_ALARM_HOUR DS1511_AM3_HOUR | ||
73 | #define RTC_ALARM_DATE DS1511_AM4_DATE | ||
74 | |||
75 | #define RTC_SEC DS1511_SEC | ||
76 | #define RTC_MIN DS1511_MIN | ||
77 | #define RTC_HOUR DS1511_HOUR | ||
78 | #define RTC_DOW DS1511_DOW | ||
79 | #define RTC_DOM DS1511_DOM | ||
80 | #define RTC_MON DS1511_MONTH | ||
81 | #define RTC_YEAR DS1511_YEAR | ||
82 | #define RTC_CENTURY DS1511_CENTURY | ||
83 | |||
84 | #define RTC_TIE DS1511_TIE | ||
85 | #define RTC_TE DS1511_TE | ||
86 | |||
87 | struct rtc_plat_data { | ||
88 | struct rtc_device *rtc; | ||
89 | void __iomem *ioaddr; /* virtual base address */ | ||
90 | unsigned long baseaddr; /* physical base address */ | ||
91 | int size; /* amount of memory mapped */ | ||
92 | int irq; | ||
93 | unsigned int irqen; | ||
94 | int alrm_sec; | ||
95 | int alrm_min; | ||
96 | int alrm_hour; | ||
97 | int alrm_mday; | ||
98 | }; | ||
99 | |||
100 | static DEFINE_SPINLOCK(ds1511_lock); | ||
101 | |||
102 | static __iomem char *ds1511_base; | ||
103 | static u32 reg_spacing = 1; | ||
104 | |||
105 | static noinline void | ||
106 | rtc_write(uint8_t val, uint32_t reg) | ||
107 | { | ||
108 | writeb(val, ds1511_base + (reg * reg_spacing)); | ||
109 | } | ||
110 | |||
111 | static inline void | ||
112 | rtc_write_alarm(uint8_t val, enum ds1511reg reg) | ||
113 | { | ||
114 | rtc_write((val | 0x80), reg); | ||
115 | } | ||
116 | |||
117 | static noinline uint8_t | ||
118 | rtc_read(enum ds1511reg reg) | ||
119 | { | ||
120 | return readb(ds1511_base + (reg * reg_spacing)); | ||
121 | } | ||
122 | |||
123 | static inline void | ||
124 | rtc_disable_update(void) | ||
125 | { | ||
126 | rtc_write((rtc_read(RTC_CMD) & ~RTC_TE), RTC_CMD); | ||
127 | } | ||
128 | |||
129 | static void | ||
130 | rtc_enable_update(void) | ||
131 | { | ||
132 | rtc_write((rtc_read(RTC_CMD) | RTC_TE), RTC_CMD); | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * #define DS1511_WDOG_RESET_SUPPORT | ||
137 | * | ||
138 | * Uncomment this if you want to use these routines in | ||
139 | * some platform code. | ||
140 | */ | ||
141 | #ifdef DS1511_WDOG_RESET_SUPPORT | ||
142 | /* | ||
143 | * just enough code to set the watchdog timer so that it | ||
144 | * will reboot the system | ||
145 | */ | ||
146 | void | ||
147 | ds1511_wdog_set(unsigned long deciseconds) | ||
148 | { | ||
149 | /* | ||
150 | * the wdog timer can take 99.99 seconds | ||
151 | */ | ||
152 | deciseconds %= 10000; | ||
153 | /* | ||
154 | * set the wdog values in the wdog registers | ||
155 | */ | ||
156 | rtc_write(BIN2BCD(deciseconds % 100), DS1511_WD_MSEC); | ||
157 | rtc_write(BIN2BCD(deciseconds / 100), DS1511_WD_SEC); | ||
158 | /* | ||
159 | * set wdog enable and wdog 'steering' bit to issue a reset | ||
160 | */ | ||
161 | rtc_write(DS1511_WDE | DS1511_WDS, RTC_CMD); | ||
162 | } | ||
163 | |||
164 | void | ||
165 | ds1511_wdog_disable(void) | ||
166 | { | ||
167 | /* | ||
168 | * clear wdog enable and wdog 'steering' bits | ||
169 | */ | ||
170 | rtc_write(rtc_read(RTC_CMD) & ~(DS1511_WDE | DS1511_WDS), RTC_CMD); | ||
171 | /* | ||
172 | * clear the wdog counter | ||
173 | */ | ||
174 | rtc_write(0, DS1511_WD_MSEC); | ||
175 | rtc_write(0, DS1511_WD_SEC); | ||
176 | } | ||
177 | #endif | ||
178 | |||
179 | /* | ||
180 | * set the rtc chip's idea of the time. | ||
181 | * stupidly, some callers call with year unmolested; | ||
182 | * and some call with year = year - 1900. thanks. | ||
183 | */ | ||
184 | int | ||
185 | ds1511_rtc_set_time(struct device *dev, struct rtc_time *rtc_tm) | ||
186 | { | ||
187 | u8 mon, day, dow, hrs, min, sec, yrs, cen; | ||
188 | unsigned int flags; | ||
189 | |||
190 | /* | ||
191 | * won't have to change this for a while | ||
192 | */ | ||
193 | if (rtc_tm->tm_year < 1900) { | ||
194 | rtc_tm->tm_year += 1900; | ||
195 | } | ||
196 | |||
197 | if (rtc_tm->tm_year < 1970) { | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | yrs = rtc_tm->tm_year % 100; | ||
201 | cen = rtc_tm->tm_year / 100; | ||
202 | mon = rtc_tm->tm_mon + 1; /* tm_mon starts at zero */ | ||
203 | day = rtc_tm->tm_mday; | ||
204 | dow = rtc_tm->tm_wday & 0x7; /* automatic BCD */ | ||
205 | hrs = rtc_tm->tm_hour; | ||
206 | min = rtc_tm->tm_min; | ||
207 | sec = rtc_tm->tm_sec; | ||
208 | |||
209 | if ((mon > 12) || (day == 0)) { | ||
210 | return -EINVAL; | ||
211 | } | ||
212 | |||
213 | if (day > rtc_month_days(rtc_tm->tm_mon, rtc_tm->tm_year)) { | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | if ((hrs >= 24) || (min >= 60) || (sec >= 60)) { | ||
218 | return -EINVAL; | ||
219 | } | ||
220 | |||
221 | /* | ||
222 | * each register is a different number of valid bits | ||
223 | */ | ||
224 | sec = BIN2BCD(sec) & 0x7f; | ||
225 | min = BIN2BCD(min) & 0x7f; | ||
226 | hrs = BIN2BCD(hrs) & 0x3f; | ||
227 | day = BIN2BCD(day) & 0x3f; | ||
228 | mon = BIN2BCD(mon) & 0x1f; | ||
229 | yrs = BIN2BCD(yrs) & 0xff; | ||
230 | cen = BIN2BCD(cen) & 0xff; | ||
231 | |||
232 | spin_lock_irqsave(&ds1511_lock, flags); | ||
233 | rtc_disable_update(); | ||
234 | rtc_write(cen, RTC_CENTURY); | ||
235 | rtc_write(yrs, RTC_YEAR); | ||
236 | rtc_write((rtc_read(RTC_MON) & 0xe0) | mon, RTC_MON); | ||
237 | rtc_write(day, RTC_DOM); | ||
238 | rtc_write(hrs, RTC_HOUR); | ||
239 | rtc_write(min, RTC_MIN); | ||
240 | rtc_write(sec, RTC_SEC); | ||
241 | rtc_write(dow, RTC_DOW); | ||
242 | rtc_enable_update(); | ||
243 | spin_unlock_irqrestore(&ds1511_lock, flags); | ||
244 | |||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | int | ||
249 | ds1511_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) | ||
250 | { | ||
251 | unsigned int century; | ||
252 | unsigned int flags; | ||
253 | |||
254 | spin_lock_irqsave(&ds1511_lock, flags); | ||
255 | rtc_disable_update(); | ||
256 | |||
257 | rtc_tm->tm_sec = rtc_read(RTC_SEC) & 0x7f; | ||
258 | rtc_tm->tm_min = rtc_read(RTC_MIN) & 0x7f; | ||
259 | rtc_tm->tm_hour = rtc_read(RTC_HOUR) & 0x3f; | ||
260 | rtc_tm->tm_mday = rtc_read(RTC_DOM) & 0x3f; | ||
261 | rtc_tm->tm_wday = rtc_read(RTC_DOW) & 0x7; | ||
262 | rtc_tm->tm_mon = rtc_read(RTC_MON) & 0x1f; | ||
263 | rtc_tm->tm_year = rtc_read(RTC_YEAR) & 0x7f; | ||
264 | century = rtc_read(RTC_CENTURY); | ||
265 | |||
266 | rtc_enable_update(); | ||
267 | spin_unlock_irqrestore(&ds1511_lock, flags); | ||
268 | |||
269 | rtc_tm->tm_sec = BCD2BIN(rtc_tm->tm_sec); | ||
270 | rtc_tm->tm_min = BCD2BIN(rtc_tm->tm_min); | ||
271 | rtc_tm->tm_hour = BCD2BIN(rtc_tm->tm_hour); | ||
272 | rtc_tm->tm_mday = BCD2BIN(rtc_tm->tm_mday); | ||
273 | rtc_tm->tm_wday = BCD2BIN(rtc_tm->tm_wday); | ||
274 | rtc_tm->tm_mon = BCD2BIN(rtc_tm->tm_mon); | ||
275 | rtc_tm->tm_year = BCD2BIN(rtc_tm->tm_year); | ||
276 | century = BCD2BIN(century) * 100; | ||
277 | |||
278 | /* | ||
279 | * Account for differences between how the RTC uses the values | ||
280 | * and how they are defined in a struct rtc_time; | ||
281 | */ | ||
282 | century += rtc_tm->tm_year; | ||
283 | rtc_tm->tm_year = century - 1900; | ||
284 | |||
285 | rtc_tm->tm_mon--; | ||
286 | |||
287 | if (rtc_valid_tm(rtc_tm) < 0) { | ||
288 | dev_err(dev, "retrieved date/time is not valid.\n"); | ||
289 | rtc_time_to_tm(0, rtc_tm); | ||
290 | } | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * write the alarm register settings | ||
296 | * | ||
297 | * we only have the use to interrupt every second, otherwise | ||
298 | * known as the update interrupt, or the interrupt if the whole | ||
299 | * date/hours/mins/secs matches. the ds1511 has many more | ||
300 | * permutations, but the kernel doesn't. | ||
301 | */ | ||
302 | static void | ||
303 | ds1511_rtc_update_alarm(struct rtc_plat_data *pdata) | ||
304 | { | ||
305 | unsigned long flags; | ||
306 | |||
307 | spin_lock_irqsave(&pdata->rtc->irq_lock, flags); | ||
308 | rtc_write(pdata->alrm_mday < 0 || (pdata->irqen & RTC_UF) ? | ||
309 | 0x80 : BIN2BCD(pdata->alrm_mday) & 0x3f, | ||
310 | RTC_ALARM_DATE); | ||
311 | rtc_write(pdata->alrm_hour < 0 || (pdata->irqen & RTC_UF) ? | ||
312 | 0x80 : BIN2BCD(pdata->alrm_hour) & 0x3f, | ||
313 | RTC_ALARM_HOUR); | ||
314 | rtc_write(pdata->alrm_min < 0 || (pdata->irqen & RTC_UF) ? | ||
315 | 0x80 : BIN2BCD(pdata->alrm_min) & 0x7f, | ||
316 | RTC_ALARM_MIN); | ||
317 | rtc_write(pdata->alrm_sec < 0 || (pdata->irqen & RTC_UF) ? | ||
318 | 0x80 : BIN2BCD(pdata->alrm_sec) & 0x7f, | ||
319 | RTC_ALARM_SEC); | ||
320 | rtc_write(rtc_read(RTC_CMD) | (pdata->irqen ? RTC_TIE : 0), RTC_CMD); | ||
321 | rtc_read(RTC_CMD1); /* clear interrupts */ | ||
322 | spin_unlock_irqrestore(&pdata->rtc->irq_lock, flags); | ||
323 | } | ||
324 | |||
325 | static int | ||
326 | ds1511_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
327 | { | ||
328 | struct platform_device *pdev = to_platform_device(dev); | ||
329 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
330 | |||
331 | if (pdata->irq < 0) { | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | pdata->alrm_mday = alrm->time.tm_mday; | ||
335 | pdata->alrm_hour = alrm->time.tm_hour; | ||
336 | pdata->alrm_min = alrm->time.tm_min; | ||
337 | pdata->alrm_sec = alrm->time.tm_sec; | ||
338 | if (alrm->enabled) { | ||
339 | pdata->irqen |= RTC_AF; | ||
340 | } | ||
341 | ds1511_rtc_update_alarm(pdata); | ||
342 | return 0; | ||
343 | } | ||
344 | |||
345 | static int | ||
346 | ds1511_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) | ||
347 | { | ||
348 | struct platform_device *pdev = to_platform_device(dev); | ||
349 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
350 | |||
351 | if (pdata->irq < 0) { | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | alrm->time.tm_mday = pdata->alrm_mday < 0 ? 0 : pdata->alrm_mday; | ||
355 | alrm->time.tm_hour = pdata->alrm_hour < 0 ? 0 : pdata->alrm_hour; | ||
356 | alrm->time.tm_min = pdata->alrm_min < 0 ? 0 : pdata->alrm_min; | ||
357 | alrm->time.tm_sec = pdata->alrm_sec < 0 ? 0 : pdata->alrm_sec; | ||
358 | alrm->enabled = (pdata->irqen & RTC_AF) ? 1 : 0; | ||
359 | return 0; | ||
360 | } | ||
361 | |||
362 | static irqreturn_t | ||
363 | ds1511_interrupt(int irq, void *dev_id) | ||
364 | { | ||
365 | struct platform_device *pdev = dev_id; | ||
366 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
367 | unsigned long events = RTC_IRQF; | ||
368 | |||
369 | /* | ||
370 | * read and clear interrupt | ||
371 | */ | ||
372 | if (!(rtc_read(RTC_CMD1) & DS1511_IRQF)) { | ||
373 | return IRQ_NONE; | ||
374 | } | ||
375 | if (rtc_read(RTC_ALARM_SEC) & 0x80) { | ||
376 | events |= RTC_UF; | ||
377 | } else { | ||
378 | events |= RTC_AF; | ||
379 | } | ||
380 | rtc_update_irq(pdata->rtc, 1, events); | ||
381 | return IRQ_HANDLED; | ||
382 | } | ||
383 | |||
384 | static void | ||
385 | ds1511_rtc_release(struct device *dev) | ||
386 | { | ||
387 | struct platform_device *pdev = to_platform_device(dev); | ||
388 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
389 | |||
390 | if (pdata->irq >= 0) { | ||
391 | pdata->irqen = 0; | ||
392 | ds1511_rtc_update_alarm(pdata); | ||
393 | } | ||
394 | } | ||
395 | |||
396 | static int | ||
397 | ds1511_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) | ||
398 | { | ||
399 | struct platform_device *pdev = to_platform_device(dev); | ||
400 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
401 | |||
402 | if (pdata->irq < 0) { | ||
403 | return -ENOIOCTLCMD; /* fall back into rtc-dev's emulation */ | ||
404 | } | ||
405 | switch (cmd) { | ||
406 | case RTC_AIE_OFF: | ||
407 | pdata->irqen &= ~RTC_AF; | ||
408 | ds1511_rtc_update_alarm(pdata); | ||
409 | break; | ||
410 | case RTC_AIE_ON: | ||
411 | pdata->irqen |= RTC_AF; | ||
412 | ds1511_rtc_update_alarm(pdata); | ||
413 | break; | ||
414 | case RTC_UIE_OFF: | ||
415 | pdata->irqen &= ~RTC_UF; | ||
416 | ds1511_rtc_update_alarm(pdata); | ||
417 | break; | ||
418 | case RTC_UIE_ON: | ||
419 | pdata->irqen |= RTC_UF; | ||
420 | ds1511_rtc_update_alarm(pdata); | ||
421 | break; | ||
422 | default: | ||
423 | return -ENOIOCTLCMD; | ||
424 | } | ||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | static const struct rtc_class_ops ds1511_rtc_ops = { | ||
429 | .read_time = ds1511_rtc_read_time, | ||
430 | .set_time = ds1511_rtc_set_time, | ||
431 | .read_alarm = ds1511_rtc_read_alarm, | ||
432 | .set_alarm = ds1511_rtc_set_alarm, | ||
433 | .release = ds1511_rtc_release, | ||
434 | .ioctl = ds1511_rtc_ioctl, | ||
435 | }; | ||
436 | |||
437 | static ssize_t | ||
438 | ds1511_nvram_read(struct kobject *kobj, struct bin_attribute *ba, | ||
439 | char *buf, loff_t pos, size_t size) | ||
440 | { | ||
441 | ssize_t count; | ||
442 | |||
443 | /* | ||
444 | * if count is more than one, turn on "burst" mode | ||
445 | * turn it off when you're done | ||
446 | */ | ||
447 | if (size > 1) { | ||
448 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | ||
449 | } | ||
450 | if (pos > DS1511_RAM_MAX) { | ||
451 | pos = DS1511_RAM_MAX; | ||
452 | } | ||
453 | if (size + pos > DS1511_RAM_MAX + 1) { | ||
454 | size = DS1511_RAM_MAX - pos + 1; | ||
455 | } | ||
456 | rtc_write(pos, DS1511_RAMADDR_LSB); | ||
457 | for (count = 0; size > 0; count++, size--) { | ||
458 | *buf++ = rtc_read(DS1511_RAMDATA); | ||
459 | } | ||
460 | if (count > 1) { | ||
461 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | ||
462 | } | ||
463 | return count; | ||
464 | } | ||
465 | |||
466 | static ssize_t | ||
467 | ds1511_nvram_write(struct kobject *kobj, struct bin_attribute *bin_attr, | ||
468 | char *buf, loff_t pos, size_t size) | ||
469 | { | ||
470 | ssize_t count; | ||
471 | |||
472 | /* | ||
473 | * if count is more than one, turn on "burst" mode | ||
474 | * turn it off when you're done | ||
475 | */ | ||
476 | if (size > 1) { | ||
477 | rtc_write((rtc_read(RTC_CMD) | DS1511_BME), RTC_CMD); | ||
478 | } | ||
479 | if (pos > DS1511_RAM_MAX) { | ||
480 | pos = DS1511_RAM_MAX; | ||
481 | } | ||
482 | if (size + pos > DS1511_RAM_MAX + 1) { | ||
483 | size = DS1511_RAM_MAX - pos + 1; | ||
484 | } | ||
485 | rtc_write(pos, DS1511_RAMADDR_LSB); | ||
486 | for (count = 0; size > 0; count++, size--) { | ||
487 | rtc_write(*buf++, DS1511_RAMDATA); | ||
488 | } | ||
489 | if (count > 1) { | ||
490 | rtc_write((rtc_read(RTC_CMD) & ~DS1511_BME), RTC_CMD); | ||
491 | } | ||
492 | return count; | ||
493 | } | ||
494 | |||
495 | static struct bin_attribute ds1511_nvram_attr = { | ||
496 | .attr = { | ||
497 | .name = "nvram", | ||
498 | .mode = S_IRUGO | S_IWUGO, | ||
499 | .owner = THIS_MODULE, | ||
500 | }, | ||
501 | .size = DS1511_RAM_MAX, | ||
502 | .read = ds1511_nvram_read, | ||
503 | .write = ds1511_nvram_write, | ||
504 | }; | ||
505 | |||
506 | static int __devinit | ||
507 | ds1511_rtc_probe(struct platform_device *pdev) | ||
508 | { | ||
509 | struct rtc_device *rtc; | ||
510 | struct resource *res; | ||
511 | struct rtc_plat_data *pdata = NULL; | ||
512 | int ret = 0; | ||
513 | |||
514 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
515 | if (!res) { | ||
516 | return -ENODEV; | ||
517 | } | ||
518 | pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); | ||
519 | if (!pdata) { | ||
520 | return -ENOMEM; | ||
521 | } | ||
522 | pdata->irq = -1; | ||
523 | pdata->size = res->end - res->start + 1; | ||
524 | if (!request_mem_region(res->start, pdata->size, pdev->name)) { | ||
525 | ret = -EBUSY; | ||
526 | goto out; | ||
527 | } | ||
528 | pdata->baseaddr = res->start; | ||
529 | pdata->size = pdata->size; | ||
530 | ds1511_base = ioremap(pdata->baseaddr, pdata->size); | ||
531 | if (!ds1511_base) { | ||
532 | ret = -ENOMEM; | ||
533 | goto out; | ||
534 | } | ||
535 | pdata->ioaddr = ds1511_base; | ||
536 | pdata->irq = platform_get_irq(pdev, 0); | ||
537 | |||
538 | /* | ||
539 | * turn on the clock and the crystal, etc. | ||
540 | */ | ||
541 | rtc_write(0, RTC_CMD); | ||
542 | rtc_write(0, RTC_CMD1); | ||
543 | /* | ||
544 | * clear the wdog counter | ||
545 | */ | ||
546 | rtc_write(0, DS1511_WD_MSEC); | ||
547 | rtc_write(0, DS1511_WD_SEC); | ||
548 | /* | ||
549 | * start the clock | ||
550 | */ | ||
551 | rtc_enable_update(); | ||
552 | |||
553 | /* | ||
554 | * check for a dying bat-tree | ||
555 | */ | ||
556 | if (rtc_read(RTC_CMD1) & DS1511_BLF1) { | ||
557 | dev_warn(&pdev->dev, "voltage-low detected.\n"); | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * if the platform has an interrupt in mind for this device, | ||
562 | * then by all means, set it | ||
563 | */ | ||
564 | if (pdata->irq >= 0) { | ||
565 | rtc_read(RTC_CMD1); | ||
566 | if (request_irq(pdata->irq, ds1511_interrupt, | ||
567 | IRQF_DISABLED | IRQF_SHARED, pdev->name, pdev) < 0) { | ||
568 | |||
569 | dev_warn(&pdev->dev, "interrupt not available.\n"); | ||
570 | pdata->irq = -1; | ||
571 | } | ||
572 | } | ||
573 | |||
574 | rtc = rtc_device_register(pdev->name, &pdev->dev, &ds1511_rtc_ops, | ||
575 | THIS_MODULE); | ||
576 | if (IS_ERR(rtc)) { | ||
577 | ret = PTR_ERR(rtc); | ||
578 | goto out; | ||
579 | } | ||
580 | pdata->rtc = rtc; | ||
581 | platform_set_drvdata(pdev, pdata); | ||
582 | ret = sysfs_create_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
583 | if (ret) { | ||
584 | goto out; | ||
585 | } | ||
586 | return 0; | ||
587 | out: | ||
588 | if (pdata->rtc) { | ||
589 | rtc_device_unregister(pdata->rtc); | ||
590 | } | ||
591 | if (pdata->irq >= 0) { | ||
592 | free_irq(pdata->irq, pdev); | ||
593 | } | ||
594 | if (ds1511_base) { | ||
595 | iounmap(ds1511_base); | ||
596 | ds1511_base = NULL; | ||
597 | } | ||
598 | if (pdata->baseaddr) { | ||
599 | release_mem_region(pdata->baseaddr, pdata->size); | ||
600 | } | ||
601 | |||
602 | kfree(pdata); | ||
603 | return ret; | ||
604 | } | ||
605 | |||
606 | static int __devexit | ||
607 | ds1511_rtc_remove(struct platform_device *pdev) | ||
608 | { | ||
609 | struct rtc_plat_data *pdata = platform_get_drvdata(pdev); | ||
610 | |||
611 | sysfs_remove_bin_file(&pdev->dev.kobj, &ds1511_nvram_attr); | ||
612 | rtc_device_unregister(pdata->rtc); | ||
613 | pdata->rtc = NULL; | ||
614 | if (pdata->irq >= 0) { | ||
615 | /* | ||
616 | * disable the alarm interrupt | ||
617 | */ | ||
618 | rtc_write(rtc_read(RTC_CMD) & ~RTC_TIE, RTC_CMD); | ||
619 | rtc_read(RTC_CMD1); | ||
620 | free_irq(pdata->irq, pdev); | ||
621 | } | ||
622 | iounmap(pdata->ioaddr); | ||
623 | ds1511_base = NULL; | ||
624 | release_mem_region(pdata->baseaddr, pdata->size); | ||
625 | kfree(pdata); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static struct platform_driver ds1511_rtc_driver = { | ||
630 | .probe = ds1511_rtc_probe, | ||
631 | .remove = __devexit_p(ds1511_rtc_remove), | ||
632 | .driver = { | ||
633 | .name = "ds1511", | ||
634 | .owner = THIS_MODULE, | ||
635 | }, | ||
636 | }; | ||
637 | |||
638 | static int __init | ||
639 | ds1511_rtc_init(void) | ||
640 | { | ||
641 | return platform_driver_register(&ds1511_rtc_driver); | ||
642 | } | ||
643 | |||
644 | static void __exit | ||
645 | ds1511_rtc_exit(void) | ||
646 | { | ||
647 | return platform_driver_unregister(&ds1511_rtc_driver); | ||
648 | } | ||
649 | |||
650 | module_init(ds1511_rtc_init); | ||
651 | module_exit(ds1511_rtc_exit); | ||
652 | |||
653 | MODULE_AUTHOR("Andrew Sharp <andy.sharp@onstor.com>"); | ||
654 | MODULE_DESCRIPTION("Dallas DS1511 RTC driver"); | ||
655 | MODULE_LICENSE("GPL"); | ||
656 | MODULE_VERSION(DRV_VERSION); | ||
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c index c973ba94c422..8b3997007506 100644 --- a/drivers/rtc/rtc-pcf8583.c +++ b/drivers/rtc/rtc-pcf8583.c | |||
@@ -163,27 +163,17 @@ static int pcf8583_read_mem(struct i2c_client *client, struct rtc_mem *mem) | |||
163 | 163 | ||
164 | static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem) | 164 | static int pcf8583_write_mem(struct i2c_client *client, struct rtc_mem *mem) |
165 | { | 165 | { |
166 | unsigned char addr[1]; | 166 | unsigned char buf[9]; |
167 | struct i2c_msg msgs[2] = { | 167 | int ret; |
168 | { | ||
169 | .addr = client->addr, | ||
170 | .flags = 0, | ||
171 | .len = 1, | ||
172 | .buf = addr, | ||
173 | }, { | ||
174 | .addr = client->addr, | ||
175 | .flags = I2C_M_NOSTART, | ||
176 | .len = mem->nr, | ||
177 | .buf = mem->data, | ||
178 | } | ||
179 | }; | ||
180 | 168 | ||
181 | if (mem->loc < 8) | 169 | if (mem->loc < 8 || mem->nr > 8) |
182 | return -EINVAL; | 170 | return -EINVAL; |
183 | 171 | ||
184 | addr[0] = mem->loc; | 172 | buf[0] = mem->loc; |
173 | memcpy(buf + 1, mem->data, mem->nr); | ||
185 | 174 | ||
186 | return i2c_transfer(client->adapter, msgs, 2) == 2 ? 0 : -EIO; | 175 | ret = i2c_master_send(client, buf, mem->nr + 1); |
176 | return ret == mem->nr + 1 ? 0 : -EIO; | ||
187 | } | 177 | } |
188 | 178 | ||
189 | static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) | 179 | static int pcf8583_rtc_read_time(struct device *dev, struct rtc_time *tm) |
diff --git a/drivers/rtc/rtc-r9701.c b/drivers/rtc/rtc-r9701.c new file mode 100644 index 000000000000..a64626a82d0b --- /dev/null +++ b/drivers/rtc/rtc-r9701.c | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * Driver for Epson RTC-9701JE | ||
3 | * | ||
4 | * Copyright (C) 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on rtc-max6902.c | ||
7 | * | ||
8 | * Copyright (C) 2006 8D Technologies inc. | ||
9 | * Copyright (C) 2004 Compulab Ltd. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/module.h> | ||
17 | #include <linux/version.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/device.h> | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/rtc.h> | ||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/bcd.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/bitops.h> | ||
27 | |||
28 | #define RSECCNT 0x00 /* Second Counter */ | ||
29 | #define RMINCNT 0x01 /* Minute Counter */ | ||
30 | #define RHRCNT 0x02 /* Hour Counter */ | ||
31 | #define RWKCNT 0x03 /* Week Counter */ | ||
32 | #define RDAYCNT 0x04 /* Day Counter */ | ||
33 | #define RMONCNT 0x05 /* Month Counter */ | ||
34 | #define RYRCNT 0x06 /* Year Counter */ | ||
35 | #define R100CNT 0x07 /* Y100 Counter */ | ||
36 | #define RMINAR 0x08 /* Minute Alarm */ | ||
37 | #define RHRAR 0x09 /* Hour Alarm */ | ||
38 | #define RWKAR 0x0a /* Week/Day Alarm */ | ||
39 | #define RTIMCNT 0x0c /* Interval Timer */ | ||
40 | #define REXT 0x0d /* Extension Register */ | ||
41 | #define RFLAG 0x0e /* RTC Flag Register */ | ||
42 | #define RCR 0x0f /* RTC Control Register */ | ||
43 | |||
44 | static int write_reg(struct device *dev, int address, unsigned char data) | ||
45 | { | ||
46 | struct spi_device *spi = to_spi_device(dev); | ||
47 | unsigned char buf[2]; | ||
48 | |||
49 | buf[0] = address & 0x7f; | ||
50 | buf[1] = data; | ||
51 | |||
52 | return spi_write(spi, buf, ARRAY_SIZE(buf)); | ||
53 | } | ||
54 | |||
55 | static int read_regs(struct device *dev, unsigned char *regs, int no_regs) | ||
56 | { | ||
57 | struct spi_device *spi = to_spi_device(dev); | ||
58 | u8 txbuf[1], rxbuf[1]; | ||
59 | int k, ret; | ||
60 | |||
61 | ret = 0; | ||
62 | |||
63 | for (k = 0; ret == 0 && k < no_regs; k++) { | ||
64 | txbuf[0] = 0x80 | regs[k]; | ||
65 | ret = spi_write_then_read(spi, txbuf, 1, rxbuf, 1); | ||
66 | regs[k] = rxbuf[0]; | ||
67 | } | ||
68 | |||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | static int r9701_get_datetime(struct device *dev, struct rtc_time *dt) | ||
73 | { | ||
74 | unsigned long time; | ||
75 | int ret; | ||
76 | unsigned char buf[] = { RSECCNT, RMINCNT, RHRCNT, | ||
77 | RDAYCNT, RMONCNT, RYRCNT }; | ||
78 | |||
79 | ret = read_regs(dev, buf, ARRAY_SIZE(buf)); | ||
80 | if (ret) | ||
81 | return ret; | ||
82 | |||
83 | memset(dt, 0, sizeof(*dt)); | ||
84 | |||
85 | dt->tm_sec = BCD2BIN(buf[0]); /* RSECCNT */ | ||
86 | dt->tm_min = BCD2BIN(buf[1]); /* RMINCNT */ | ||
87 | dt->tm_hour = BCD2BIN(buf[2]); /* RHRCNT */ | ||
88 | |||
89 | dt->tm_mday = BCD2BIN(buf[3]); /* RDAYCNT */ | ||
90 | dt->tm_mon = BCD2BIN(buf[4]) - 1; /* RMONCNT */ | ||
91 | dt->tm_year = BCD2BIN(buf[5]) + 100; /* RYRCNT */ | ||
92 | |||
93 | /* the rtc device may contain illegal values on power up | ||
94 | * according to the data sheet. make sure they are valid. | ||
95 | */ | ||
96 | |||
97 | return rtc_valid_tm(dt); | ||
98 | } | ||
99 | |||
100 | static int r9701_set_datetime(struct device *dev, struct rtc_time *dt) | ||
101 | { | ||
102 | int ret, year; | ||
103 | |||
104 | year = dt->tm_year + 1900; | ||
105 | if (year >= 2100 || year < 2000) | ||
106 | return -EINVAL; | ||
107 | |||
108 | ret = write_reg(dev, RHRCNT, BIN2BCD(dt->tm_hour)); | ||
109 | ret = ret ? ret : write_reg(dev, RMINCNT, BIN2BCD(dt->tm_min)); | ||
110 | ret = ret ? ret : write_reg(dev, RSECCNT, BIN2BCD(dt->tm_sec)); | ||
111 | ret = ret ? ret : write_reg(dev, RDAYCNT, BIN2BCD(dt->tm_mday)); | ||
112 | ret = ret ? ret : write_reg(dev, RMONCNT, BIN2BCD(dt->tm_mon + 1)); | ||
113 | ret = ret ? ret : write_reg(dev, RYRCNT, BIN2BCD(dt->tm_year - 100)); | ||
114 | ret = ret ? ret : write_reg(dev, RWKCNT, 1 << dt->tm_wday); | ||
115 | |||
116 | return ret; | ||
117 | } | ||
118 | |||
119 | static const struct rtc_class_ops r9701_rtc_ops = { | ||
120 | .read_time = r9701_get_datetime, | ||
121 | .set_time = r9701_set_datetime, | ||
122 | }; | ||
123 | |||
124 | static int __devinit r9701_probe(struct spi_device *spi) | ||
125 | { | ||
126 | struct rtc_device *rtc; | ||
127 | unsigned char tmp; | ||
128 | int res; | ||
129 | |||
130 | rtc = rtc_device_register("r9701", | ||
131 | &spi->dev, &r9701_rtc_ops, THIS_MODULE); | ||
132 | if (IS_ERR(rtc)) | ||
133 | return PTR_ERR(rtc); | ||
134 | |||
135 | dev_set_drvdata(&spi->dev, rtc); | ||
136 | |||
137 | tmp = R100CNT; | ||
138 | res = read_regs(&spi->dev, &tmp, 1); | ||
139 | if (res || tmp != 0x20) { | ||
140 | rtc_device_unregister(rtc); | ||
141 | return res; | ||
142 | } | ||
143 | |||
144 | return 0; | ||
145 | } | ||
146 | |||
147 | static int __devexit r9701_remove(struct spi_device *spi) | ||
148 | { | ||
149 | struct rtc_device *rtc = dev_get_drvdata(&spi->dev); | ||
150 | |||
151 | rtc_device_unregister(rtc); | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | static struct spi_driver r9701_driver = { | ||
156 | .driver = { | ||
157 | .name = "rtc-r9701", | ||
158 | .owner = THIS_MODULE, | ||
159 | }, | ||
160 | .probe = r9701_probe, | ||
161 | .remove = __devexit_p(r9701_remove), | ||
162 | }; | ||
163 | |||
164 | static __init int r9701_init(void) | ||
165 | { | ||
166 | return spi_register_driver(&r9701_driver); | ||
167 | } | ||
168 | module_init(r9701_init); | ||
169 | |||
170 | static __exit void r9701_exit(void) | ||
171 | { | ||
172 | spi_unregister_driver(&r9701_driver); | ||
173 | } | ||
174 | module_exit(r9701_exit); | ||
175 | |||
176 | MODULE_DESCRIPTION("r9701 spi RTC driver"); | ||
177 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | ||
178 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/rtc/rtc-s3c.c b/drivers/rtc/rtc-s3c.c index e2041b4d0c85..86766f1f2496 100644 --- a/drivers/rtc/rtc-s3c.c +++ b/drivers/rtc/rtc-s3c.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/rtc.h> | 20 | #include <linux/rtc.h> |
21 | #include <linux/bcd.h> | 21 | #include <linux/bcd.h> |
22 | #include <linux/clk.h> | 22 | #include <linux/clk.h> |
23 | #include <linux/log2.h> | ||
23 | 24 | ||
24 | #include <asm/hardware.h> | 25 | #include <asm/hardware.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -309,9 +310,7 @@ static int s3c_rtc_ioctl(struct device *dev, | |||
309 | break; | 310 | break; |
310 | 311 | ||
311 | case RTC_IRQP_SET: | 312 | case RTC_IRQP_SET: |
312 | /* check for power of 2 */ | 313 | if (!is_power_of_2(arg)) { |
313 | |||
314 | if ((arg & (arg-1)) != 0 || arg < 1) { | ||
315 | ret = -EINVAL; | 314 | ret = -EINVAL; |
316 | goto exit; | 315 | goto exit; |
317 | } | 316 | } |
diff --git a/drivers/rtc/rtc-sa1100.c b/drivers/rtc/rtc-sa1100.c index 2eb38520f0c8..ee253cc45de1 100644 --- a/drivers/rtc/rtc-sa1100.c +++ b/drivers/rtc/rtc-sa1100.c | |||
@@ -357,23 +357,15 @@ static int sa1100_rtc_remove(struct platform_device *pdev) | |||
357 | #ifdef CONFIG_PM | 357 | #ifdef CONFIG_PM |
358 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) | 358 | static int sa1100_rtc_suspend(struct platform_device *pdev, pm_message_t state) |
359 | { | 359 | { |
360 | if (pdev->dev.power.power_state.event != state.event) { | 360 | if (device_may_wakeup(&pdev->dev)) |
361 | if (state.event == PM_EVENT_SUSPEND && | 361 | enable_irq_wake(IRQ_RTCAlrm); |
362 | device_may_wakeup(&pdev->dev)) | ||
363 | enable_irq_wake(IRQ_RTCAlrm); | ||
364 | |||
365 | pdev->dev.power.power_state = state; | ||
366 | } | ||
367 | return 0; | 362 | return 0; |
368 | } | 363 | } |
369 | 364 | ||
370 | static int sa1100_rtc_resume(struct platform_device *pdev) | 365 | static int sa1100_rtc_resume(struct platform_device *pdev) |
371 | { | 366 | { |
372 | if (pdev->dev.power.power_state.event != PM_EVENT_ON) { | 367 | if (device_may_wakeup(&pdev->dev)) |
373 | if (device_may_wakeup(&pdev->dev)) | 368 | disable_irq_wake(IRQ_RTCAlrm); |
374 | disable_irq_wake(IRQ_RTCAlrm); | ||
375 | pdev->dev.power.power_state = PMSG_ON; | ||
376 | } | ||
377 | return 0; | 369 | return 0; |
378 | } | 370 | } |
379 | #else | 371 | #else |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 2ae0e8304d3a..4d27ccc4fc06 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -17,6 +17,13 @@ | |||
17 | 17 | ||
18 | /* device attributes */ | 18 | /* device attributes */ |
19 | 19 | ||
20 | /* | ||
21 | * NOTE: RTC times displayed in sysfs use the RTC's timezone. That's | ||
22 | * ideally UTC. However, PCs that also boot to MS-Windows normally use | ||
23 | * the local time and change to match daylight savings time. That affects | ||
24 | * attributes including date, time, since_epoch, and wakealarm. | ||
25 | */ | ||
26 | |||
20 | static ssize_t | 27 | static ssize_t |
21 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, | 28 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, |
22 | char *buf) | 29 | char *buf) |
@@ -113,13 +120,13 @@ rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, | |||
113 | unsigned long alarm; | 120 | unsigned long alarm; |
114 | struct rtc_wkalrm alm; | 121 | struct rtc_wkalrm alm; |
115 | 122 | ||
116 | /* Don't show disabled alarms; but the RTC could leave the | 123 | /* Don't show disabled alarms. For uniformity, RTC alarms are |
117 | * alarm enabled after it's already triggered. Alarms are | 124 | * conceptually one-shot, even though some common RTCs (on PCs) |
118 | * conceptually one-shot, even though some common hardware | 125 | * don't actually work that way. |
119 | * (PCs) doesn't actually work that way. | ||
120 | * | 126 | * |
121 | * REVISIT maybe we should require RTC implementations to | 127 | * NOTE: RTC implementations where the alarm doesn't match an |
122 | * disable the RTC alarm after it triggers, for uniformity. | 128 | * exact YYYY-MM-DD HH:MM[:SS] date *must* disable their RTC |
129 | * alarms after they trigger, to ensure one-shot semantics. | ||
123 | */ | 130 | */ |
124 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); | 131 | retval = rtc_read_alarm(to_rtc_device(dev), &alm); |
125 | if (retval == 0 && alm.enabled) { | 132 | if (retval == 0 && alm.enabled) { |
diff --git a/drivers/s390/sysinfo.c b/drivers/s390/sysinfo.c index 19343f9675c3..291ff6235fe2 100644 --- a/drivers/s390/sysinfo.c +++ b/drivers/s390/sysinfo.c | |||
@@ -422,7 +422,7 @@ void s390_adjust_jiffies(void) | |||
422 | /* | 422 | /* |
423 | * calibrate the delay loop | 423 | * calibrate the delay loop |
424 | */ | 424 | */ |
425 | void __init calibrate_delay(void) | 425 | void __cpuinit calibrate_delay(void) |
426 | { | 426 | { |
427 | s390_adjust_jiffies(); | 427 | s390_adjust_jiffies(); |
428 | /* Print the good old Bogomips line .. */ | 428 | /* Print the good old Bogomips line .. */ |
diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index 23f27c9c9895..5ac3a3e8dfaf 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c | |||
@@ -46,8 +46,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
46 | struct Scsi_Host *instance = cmd->device->host; | 46 | struct Scsi_Host *instance = cmd->device->host; |
47 | 47 | ||
48 | /* don't allow DMA if the physical address is bad */ | 48 | /* don't allow DMA if the physical address is bad */ |
49 | if (addr & A2091_XFER_MASK || | 49 | if (addr & A2091_XFER_MASK) |
50 | (!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual))) | ||
51 | { | 50 | { |
52 | HDATA(instance)->dma_bounce_len = (cmd->SCp.this_residual + 511) | 51 | HDATA(instance)->dma_bounce_len = (cmd->SCp.this_residual + 511) |
53 | & ~0x1ff; | 52 | & ~0x1ff; |
diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index d7255c8bf281..3aeec963940b 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c | |||
@@ -54,8 +54,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
54 | * end of a physical memory chunk, then allocate a bounce | 54 | * end of a physical memory chunk, then allocate a bounce |
55 | * buffer | 55 | * buffer |
56 | */ | 56 | */ |
57 | if (addr & A3000_XFER_MASK || | 57 | if (addr & A3000_XFER_MASK) |
58 | (!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual))) | ||
59 | { | 58 | { |
60 | HDATA(a3000_host)->dma_bounce_len = (cmd->SCp.this_residual + 511) | 59 | HDATA(a3000_host)->dma_bounce_len = (cmd->SCp.this_residual + 511) |
61 | & ~0x1ff; | 60 | & ~0x1ff; |
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 3bfd9296bbfa..93984c9dfe14 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c | |||
@@ -6472,7 +6472,7 @@ do_aic7xxx_isr(int irq, void *dev_id) | |||
6472 | unsigned long cpu_flags; | 6472 | unsigned long cpu_flags; |
6473 | struct aic7xxx_host *p; | 6473 | struct aic7xxx_host *p; |
6474 | 6474 | ||
6475 | p = (struct aic7xxx_host *)dev_id; | 6475 | p = dev_id; |
6476 | if(!p) | 6476 | if(!p) |
6477 | return IRQ_NONE; | 6477 | return IRQ_NONE; |
6478 | spin_lock_irqsave(p->host->host_lock, cpu_flags); | 6478 | spin_lock_irqsave(p->host->host_lock, cpu_flags); |
diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 37741e9b5c3b..91f85226d08f 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c | |||
@@ -54,8 +54,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in) | |||
54 | static int scsi_alloc_out_of_range = 0; | 54 | static int scsi_alloc_out_of_range = 0; |
55 | 55 | ||
56 | /* use bounce buffer if the physical address is bad */ | 56 | /* use bounce buffer if the physical address is bad */ |
57 | if (addr & HDATA(cmd->device->host)->dma_xfer_mask || | 57 | if (addr & HDATA(cmd->device->host)->dma_xfer_mask) |
58 | (!dir_in && mm_end_of_chunk (addr, cmd->SCp.this_residual))) | ||
59 | { | 58 | { |
60 | HDATA(cmd->device->host)->dma_bounce_len = (cmd->SCp.this_residual + 511) | 59 | HDATA(cmd->device->host)->dma_bounce_len = (cmd->SCp.this_residual + 511) |
61 | & ~0x1ff; | 60 | & ~0x1ff; |
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index d63f11e95abf..bd62131b97a1 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -539,9 +539,9 @@ out: | |||
539 | srp_iu_put(iue); | 539 | srp_iu_put(iue); |
540 | } | 540 | } |
541 | 541 | ||
542 | static irqreturn_t ibmvstgt_interrupt(int irq, void *data) | 542 | static irqreturn_t ibmvstgt_interrupt(int dummy, void *data) |
543 | { | 543 | { |
544 | struct srp_target *target = (struct srp_target *) data; | 544 | struct srp_target *target = data; |
545 | struct vio_port *vport = target_to_port(target); | 545 | struct vio_port *vport = target_to_port(target); |
546 | 546 | ||
547 | vio_disable_interrupts(vport->dma_dev); | 547 | vio_disable_interrupts(vport->dma_dev); |
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 6c4f0f081785..68e5c632c5d5 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -287,7 +287,7 @@ static int idescsi_end_request(ide_drive_t *, int, int); | |||
287 | static ide_startstop_t | 287 | static ide_startstop_t |
288 | idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) | 288 | idescsi_atapi_error(ide_drive_t *drive, struct request *rq, u8 stat, u8 err) |
289 | { | 289 | { |
290 | if (HWIF(drive)->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) | 290 | if (ide_read_status(drive) & (BUSY_STAT | DRQ_STAT)) |
291 | /* force an abort */ | 291 | /* force an abort */ |
292 | HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); | 292 | HWIF(drive)->OUTB(WIN_IDLEIMMEDIATE,IDE_COMMAND_REG); |
293 | 293 | ||
@@ -423,7 +423,7 @@ static ide_startstop_t idescsi_pc_intr (ide_drive_t *drive) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | /* Clear the interrupt */ | 425 | /* Clear the interrupt */ |
426 | stat = drive->hwif->INB(IDE_STATUS_REG); | 426 | stat = ide_read_status(drive); |
427 | 427 | ||
428 | if ((stat & DRQ_STAT) == 0) { | 428 | if ((stat & DRQ_STAT) == 0) { |
429 | /* No more interrupts */ | 429 | /* No more interrupts */ |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 4fa7927997ad..6a44fb1dc167 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -877,15 +877,15 @@ config SERIAL_SUNHV | |||
877 | systems. Say Y if you want to be able to use this device. | 877 | systems. Say Y if you want to be able to use this device. |
878 | 878 | ||
879 | config SERIAL_IP22_ZILOG | 879 | config SERIAL_IP22_ZILOG |
880 | tristate "IP22 Zilog8530 serial support" | 880 | tristate "SGI Zilog8530 serial support" |
881 | depends on SGI_IP22 | 881 | depends on SGI_HAS_ZILOG |
882 | select SERIAL_CORE | 882 | select SERIAL_CORE |
883 | help | 883 | help |
884 | This driver supports the Zilog8530 serial ports found on SGI IP22 | 884 | This driver supports the Zilog8530 serial ports found on SGI |
885 | systems. Say Y or M if you want to be able to these serial ports. | 885 | systems. Say Y or M if you want to be able to these serial ports. |
886 | 886 | ||
887 | config SERIAL_IP22_ZILOG_CONSOLE | 887 | config SERIAL_IP22_ZILOG_CONSOLE |
888 | bool "Console on IP22 Zilog8530 serial port" | 888 | bool "Console on SGI Zilog8530 serial port" |
889 | depends on SERIAL_IP22_ZILOG=y | 889 | depends on SERIAL_IP22_ZILOG=y |
890 | select SERIAL_CORE_CONSOLE | 890 | select SERIAL_CORE_CONSOLE |
891 | 891 | ||
@@ -1318,4 +1318,19 @@ config SERIAL_QE | |||
1318 | This driver supports the QE serial ports on Freescale embedded | 1318 | This driver supports the QE serial ports on Freescale embedded |
1319 | PowerPC that contain a QUICC Engine. | 1319 | PowerPC that contain a QUICC Engine. |
1320 | 1320 | ||
1321 | config SERIAL_SC26XX | ||
1322 | tristate "SC2681/SC2692 serial port support" | ||
1323 | depends on SNI_RM | ||
1324 | select SERIAL_CORE | ||
1325 | help | ||
1326 | This is a driver for the onboard serial ports of | ||
1327 | older RM400 machines. | ||
1328 | |||
1329 | config SERIAL_SC26XX_CONSOLE | ||
1330 | bool "Console on SC2681/SC2692 serial port" | ||
1331 | depends on SERIAL_SC26XX | ||
1332 | select SERIAL_CORE_CONSOLE | ||
1333 | help | ||
1334 | Support for Console on SC2681/SC2692 serial ports. | ||
1335 | |||
1321 | endmenu | 1336 | endmenu |
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 2dd41b4cc8db..640cfe44a56d 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile | |||
@@ -55,6 +55,7 @@ obj-$(CONFIG_SERIAL_M32R_SIO) += m32r_sio.o | |||
55 | obj-$(CONFIG_SERIAL_MPSC) += mpsc.o | 55 | obj-$(CONFIG_SERIAL_MPSC) += mpsc.o |
56 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o | 56 | obj-$(CONFIG_SERIAL_SB1250_DUART) += sb1250-duart.o |
57 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o | 57 | obj-$(CONFIG_ETRAX_SERIAL) += crisv10.o |
58 | obj-$(CONFIG_SERIAL_SC26XX) += sc26xx.o | ||
58 | obj-$(CONFIG_SERIAL_JSM) += jsm/ | 59 | obj-$(CONFIG_SERIAL_JSM) += jsm/ |
59 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o | 60 | obj-$(CONFIG_SERIAL_TXX9) += serial_txx9.o |
60 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o | 61 | obj-$(CONFIG_SERIAL_VR41XX) += vr41xx_siu.o |
diff --git a/drivers/serial/cpm_uart/cpm_uart_core.c b/drivers/serial/cpm_uart/cpm_uart_core.c index b5e4478de0e3..236af9d33851 100644 --- a/drivers/serial/cpm_uart/cpm_uart_core.c +++ b/drivers/serial/cpm_uart/cpm_uart_core.c | |||
@@ -380,7 +380,7 @@ static void cpm_uart_int_rx(struct uart_port *port) | |||
380 | static irqreturn_t cpm_uart_int(int irq, void *data) | 380 | static irqreturn_t cpm_uart_int(int irq, void *data) |
381 | { | 381 | { |
382 | u8 events; | 382 | u8 events; |
383 | struct uart_port *port = (struct uart_port *)data; | 383 | struct uart_port *port = data; |
384 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; | 384 | struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; |
385 | smc_t __iomem *smcp = pinfo->smcp; | 385 | smc_t __iomem *smcp = pinfo->smcp; |
386 | scc_t __iomem *sccp = pinfo->sccp; | 386 | scc_t __iomem *sccp = pinfo->sccp; |
diff --git a/drivers/serial/dz.c b/drivers/serial/dz.c index d31721f2744d..bbae5a220219 100644 --- a/drivers/serial/dz.c +++ b/drivers/serial/dz.c | |||
@@ -324,7 +324,7 @@ static inline void check_modem_status(struct dz_port *dport) | |||
324 | */ | 324 | */ |
325 | static irqreturn_t dz_interrupt(int irq, void *dev) | 325 | static irqreturn_t dz_interrupt(int irq, void *dev) |
326 | { | 326 | { |
327 | struct dz_port *dport = (struct dz_port *)dev; | 327 | struct dz_port *dport = dev; |
328 | unsigned short status; | 328 | unsigned short status; |
329 | 329 | ||
330 | /* get the reason why we just got an irq */ | 330 | /* get the reason why we just got an irq */ |
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index dc1967176fe2..56af1f566a4c 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c | |||
@@ -308,7 +308,7 @@ static void imx_start_tx(struct uart_port *port) | |||
308 | 308 | ||
309 | static irqreturn_t imx_rtsint(int irq, void *dev_id) | 309 | static irqreturn_t imx_rtsint(int irq, void *dev_id) |
310 | { | 310 | { |
311 | struct imx_port *sport = (struct imx_port *)dev_id; | 311 | struct imx_port *sport = dev_id; |
312 | unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; | 312 | unsigned int val = readl(sport->port.membase + USR1) & USR1_RTSS; |
313 | unsigned long flags; | 313 | unsigned long flags; |
314 | 314 | ||
@@ -324,7 +324,7 @@ static irqreturn_t imx_rtsint(int irq, void *dev_id) | |||
324 | 324 | ||
325 | static irqreturn_t imx_txint(int irq, void *dev_id) | 325 | static irqreturn_t imx_txint(int irq, void *dev_id) |
326 | { | 326 | { |
327 | struct imx_port *sport = (struct imx_port *)dev_id; | 327 | struct imx_port *sport = dev_id; |
328 | struct circ_buf *xmit = &sport->port.info->xmit; | 328 | struct circ_buf *xmit = &sport->port.info->xmit; |
329 | unsigned long flags; | 329 | unsigned long flags; |
330 | 330 | ||
diff --git a/drivers/serial/sc26xx.c b/drivers/serial/sc26xx.c new file mode 100644 index 000000000000..a350b6d2a181 --- /dev/null +++ b/drivers/serial/sc26xx.c | |||
@@ -0,0 +1,755 @@ | |||
1 | /* | ||
2 | * SC268xx.c: Serial driver for Philiphs SC2681/SC2692 devices. | ||
3 | * | ||
4 | * Copyright (C) 2006,2007 Thomas Bogendörfer (tsbogend@alpha.franken.de) | ||
5 | */ | ||
6 | |||
7 | #include <linux/module.h> | ||
8 | #include <linux/kernel.h> | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/tty.h> | ||
11 | #include <linux/tty_flip.h> | ||
12 | #include <linux/major.h> | ||
13 | #include <linux/circ_buf.h> | ||
14 | #include <linux/serial.h> | ||
15 | #include <linux/sysrq.h> | ||
16 | #include <linux/console.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/delay.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/irq.h> | ||
23 | |||
24 | #if defined(CONFIG_MAGIC_SYSRQ) | ||
25 | #define SUPPORT_SYSRQ | ||
26 | #endif | ||
27 | |||
28 | #include <linux/serial_core.h> | ||
29 | |||
30 | #define SC26XX_MAJOR 204 | ||
31 | #define SC26XX_MINOR_START 205 | ||
32 | #define SC26XX_NR 2 | ||
33 | |||
34 | struct uart_sc26xx_port { | ||
35 | struct uart_port port[2]; | ||
36 | u8 dsr_mask[2]; | ||
37 | u8 cts_mask[2]; | ||
38 | u8 dcd_mask[2]; | ||
39 | u8 ri_mask[2]; | ||
40 | u8 dtr_mask[2]; | ||
41 | u8 rts_mask[2]; | ||
42 | u8 imr; | ||
43 | }; | ||
44 | |||
45 | /* register common to both ports */ | ||
46 | #define RD_ISR 0x14 | ||
47 | #define RD_IPR 0x34 | ||
48 | |||
49 | #define WR_ACR 0x10 | ||
50 | #define WR_IMR 0x14 | ||
51 | #define WR_OPCR 0x34 | ||
52 | #define WR_OPR_SET 0x38 | ||
53 | #define WR_OPR_CLR 0x3C | ||
54 | |||
55 | /* access common register */ | ||
56 | #define READ_SC(p, r) readb((p)->membase + RD_##r) | ||
57 | #define WRITE_SC(p, r, v) writeb((v), (p)->membase + WR_##r) | ||
58 | |||
59 | /* register per port */ | ||
60 | #define RD_PORT_MRx 0x00 | ||
61 | #define RD_PORT_SR 0x04 | ||
62 | #define RD_PORT_RHR 0x0c | ||
63 | |||
64 | #define WR_PORT_MRx 0x00 | ||
65 | #define WR_PORT_CSR 0x04 | ||
66 | #define WR_PORT_CR 0x08 | ||
67 | #define WR_PORT_THR 0x0c | ||
68 | |||
69 | /* SR bits */ | ||
70 | #define SR_BREAK (1 << 7) | ||
71 | #define SR_FRAME (1 << 6) | ||
72 | #define SR_PARITY (1 << 5) | ||
73 | #define SR_OVERRUN (1 << 4) | ||
74 | #define SR_TXRDY (1 << 2) | ||
75 | #define SR_RXRDY (1 << 0) | ||
76 | |||
77 | #define CR_RES_MR (1 << 4) | ||
78 | #define CR_RES_RX (2 << 4) | ||
79 | #define CR_RES_TX (3 << 4) | ||
80 | #define CR_STRT_BRK (6 << 4) | ||
81 | #define CR_STOP_BRK (7 << 4) | ||
82 | #define CR_DIS_TX (1 << 3) | ||
83 | #define CR_ENA_TX (1 << 2) | ||
84 | #define CR_DIS_RX (1 << 1) | ||
85 | #define CR_ENA_RX (1 << 0) | ||
86 | |||
87 | /* ISR bits */ | ||
88 | #define ISR_RXRDYB (1 << 5) | ||
89 | #define ISR_TXRDYB (1 << 4) | ||
90 | #define ISR_RXRDYA (1 << 1) | ||
91 | #define ISR_TXRDYA (1 << 0) | ||
92 | |||
93 | /* IMR bits */ | ||
94 | #define IMR_RXRDY (1 << 1) | ||
95 | #define IMR_TXRDY (1 << 0) | ||
96 | |||
97 | /* access port register */ | ||
98 | static inline u8 read_sc_port(struct uart_port *p, u8 reg) | ||
99 | { | ||
100 | return readb(p->membase + p->line * 0x20 + reg); | ||
101 | } | ||
102 | |||
103 | static inline void write_sc_port(struct uart_port *p, u8 reg, u8 val) | ||
104 | { | ||
105 | writeb(val, p->membase + p->line * 0x20 + reg); | ||
106 | } | ||
107 | |||
108 | #define READ_SC_PORT(p, r) read_sc_port(p, RD_PORT_##r) | ||
109 | #define WRITE_SC_PORT(p, r, v) write_sc_port(p, WR_PORT_##r, v) | ||
110 | |||
111 | static void sc26xx_enable_irq(struct uart_port *port, int mask) | ||
112 | { | ||
113 | struct uart_sc26xx_port *up; | ||
114 | int line = port->line; | ||
115 | |||
116 | port -= line; | ||
117 | up = container_of(port, struct uart_sc26xx_port, port[0]); | ||
118 | |||
119 | up->imr |= mask << (line * 4); | ||
120 | WRITE_SC(port, IMR, up->imr); | ||
121 | } | ||
122 | |||
123 | static void sc26xx_disable_irq(struct uart_port *port, int mask) | ||
124 | { | ||
125 | struct uart_sc26xx_port *up; | ||
126 | int line = port->line; | ||
127 | |||
128 | port -= line; | ||
129 | up = container_of(port, struct uart_sc26xx_port, port[0]); | ||
130 | |||
131 | up->imr &= ~(mask << (line * 4)); | ||
132 | WRITE_SC(port, IMR, up->imr); | ||
133 | } | ||
134 | |||
135 | static struct tty_struct *receive_chars(struct uart_port *port) | ||
136 | { | ||
137 | struct tty_struct *tty = NULL; | ||
138 | int limit = 10000; | ||
139 | unsigned char ch; | ||
140 | char flag; | ||
141 | u8 status; | ||
142 | |||
143 | if (port->info != NULL) /* Unopened serial console */ | ||
144 | tty = port->info->tty; | ||
145 | |||
146 | while (limit-- > 0) { | ||
147 | status = READ_SC_PORT(port, SR); | ||
148 | if (!(status & SR_RXRDY)) | ||
149 | break; | ||
150 | ch = READ_SC_PORT(port, RHR); | ||
151 | |||
152 | flag = TTY_NORMAL; | ||
153 | port->icount.rx++; | ||
154 | |||
155 | if (unlikely(status & (SR_BREAK | SR_FRAME | | ||
156 | SR_PARITY | SR_OVERRUN))) { | ||
157 | if (status & SR_BREAK) { | ||
158 | status &= ~(SR_PARITY | SR_FRAME); | ||
159 | port->icount.brk++; | ||
160 | if (uart_handle_break(port)) | ||
161 | continue; | ||
162 | } else if (status & SR_PARITY) | ||
163 | port->icount.parity++; | ||
164 | else if (status & SR_FRAME) | ||
165 | port->icount.frame++; | ||
166 | if (status & SR_OVERRUN) | ||
167 | port->icount.overrun++; | ||
168 | |||
169 | status &= port->read_status_mask; | ||
170 | if (status & SR_BREAK) | ||
171 | flag = TTY_BREAK; | ||
172 | else if (status & SR_PARITY) | ||
173 | flag = TTY_PARITY; | ||
174 | else if (status & SR_FRAME) | ||
175 | flag = TTY_FRAME; | ||
176 | } | ||
177 | |||
178 | if (uart_handle_sysrq_char(port, ch)) | ||
179 | continue; | ||
180 | |||
181 | if (status & port->ignore_status_mask) | ||
182 | continue; | ||
183 | |||
184 | tty_insert_flip_char(tty, ch, flag); | ||
185 | } | ||
186 | return tty; | ||
187 | } | ||
188 | |||
189 | static void transmit_chars(struct uart_port *port) | ||
190 | { | ||
191 | struct circ_buf *xmit; | ||
192 | |||
193 | if (!port->info) | ||
194 | return; | ||
195 | |||
196 | xmit = &port->info->xmit; | ||
197 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | ||
198 | sc26xx_disable_irq(port, IMR_TXRDY); | ||
199 | return; | ||
200 | } | ||
201 | while (!uart_circ_empty(xmit)) { | ||
202 | if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) | ||
203 | break; | ||
204 | |||
205 | WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]); | ||
206 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
207 | port->icount.tx++; | ||
208 | } | ||
209 | if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) | ||
210 | uart_write_wakeup(port); | ||
211 | } | ||
212 | |||
213 | static irqreturn_t sc26xx_interrupt(int irq, void *dev_id) | ||
214 | { | ||
215 | struct uart_sc26xx_port *up = dev_id; | ||
216 | struct tty_struct *tty; | ||
217 | unsigned long flags; | ||
218 | u8 isr; | ||
219 | |||
220 | spin_lock_irqsave(&up->port[0].lock, flags); | ||
221 | |||
222 | tty = NULL; | ||
223 | isr = READ_SC(&up->port[0], ISR); | ||
224 | if (isr & ISR_TXRDYA) | ||
225 | transmit_chars(&up->port[0]); | ||
226 | if (isr & ISR_RXRDYA) | ||
227 | tty = receive_chars(&up->port[0]); | ||
228 | |||
229 | spin_unlock(&up->port[0].lock); | ||
230 | |||
231 | if (tty) | ||
232 | tty_flip_buffer_push(tty); | ||
233 | |||
234 | spin_lock(&up->port[1].lock); | ||
235 | |||
236 | tty = NULL; | ||
237 | if (isr & ISR_TXRDYB) | ||
238 | transmit_chars(&up->port[1]); | ||
239 | if (isr & ISR_RXRDYB) | ||
240 | tty = receive_chars(&up->port[1]); | ||
241 | |||
242 | spin_unlock_irqrestore(&up->port[1].lock, flags); | ||
243 | |||
244 | if (tty) | ||
245 | tty_flip_buffer_push(tty); | ||
246 | |||
247 | return IRQ_HANDLED; | ||
248 | } | ||
249 | |||
250 | /* port->lock is not held. */ | ||
251 | static unsigned int sc26xx_tx_empty(struct uart_port *port) | ||
252 | { | ||
253 | return (READ_SC_PORT(port, SR) & SR_TXRDY) ? TIOCSER_TEMT : 0; | ||
254 | } | ||
255 | |||
256 | /* port->lock held by caller. */ | ||
257 | static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl) | ||
258 | { | ||
259 | struct uart_sc26xx_port *up; | ||
260 | int line = port->line; | ||
261 | |||
262 | port -= line; | ||
263 | up = container_of(port, struct uart_sc26xx_port, port[0]); | ||
264 | |||
265 | if (up->dtr_mask[line]) { | ||
266 | if (mctrl & TIOCM_DTR) | ||
267 | WRITE_SC(port, OPR_SET, up->dtr_mask[line]); | ||
268 | else | ||
269 | WRITE_SC(port, OPR_CLR, up->dtr_mask[line]); | ||
270 | } | ||
271 | if (up->rts_mask[line]) { | ||
272 | if (mctrl & TIOCM_RTS) | ||
273 | WRITE_SC(port, OPR_SET, up->rts_mask[line]); | ||
274 | else | ||
275 | WRITE_SC(port, OPR_CLR, up->rts_mask[line]); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | /* port->lock is held by caller and interrupts are disabled. */ | ||
280 | static unsigned int sc26xx_get_mctrl(struct uart_port *port) | ||
281 | { | ||
282 | struct uart_sc26xx_port *up; | ||
283 | int line = port->line; | ||
284 | unsigned int mctrl = TIOCM_DSR | TIOCM_CTS | TIOCM_CAR; | ||
285 | u8 ipr; | ||
286 | |||
287 | port -= line; | ||
288 | up = container_of(port, struct uart_sc26xx_port, port[0]); | ||
289 | ipr = READ_SC(port, IPR) ^ 0xff; | ||
290 | |||
291 | if (up->dsr_mask[line]) { | ||
292 | mctrl &= ~TIOCM_DSR; | ||
293 | mctrl |= ipr & up->dsr_mask[line] ? TIOCM_DSR : 0; | ||
294 | } | ||
295 | if (up->cts_mask[line]) { | ||
296 | mctrl &= ~TIOCM_CTS; | ||
297 | mctrl |= ipr & up->cts_mask[line] ? TIOCM_CTS : 0; | ||
298 | } | ||
299 | if (up->dcd_mask[line]) { | ||
300 | mctrl &= ~TIOCM_CAR; | ||
301 | mctrl |= ipr & up->dcd_mask[line] ? TIOCM_CAR : 0; | ||
302 | } | ||
303 | if (up->ri_mask[line]) { | ||
304 | mctrl &= ~TIOCM_RNG; | ||
305 | mctrl |= ipr & up->ri_mask[line] ? TIOCM_RNG : 0; | ||
306 | } | ||
307 | return mctrl; | ||
308 | } | ||
309 | |||
310 | /* port->lock held by caller. */ | ||
311 | static void sc26xx_stop_tx(struct uart_port *port) | ||
312 | { | ||
313 | return; | ||
314 | } | ||
315 | |||
316 | /* port->lock held by caller. */ | ||
317 | static void sc26xx_start_tx(struct uart_port *port) | ||
318 | { | ||
319 | struct circ_buf *xmit = &port->info->xmit; | ||
320 | |||
321 | while (!uart_circ_empty(xmit)) { | ||
322 | if (!(READ_SC_PORT(port, SR) & SR_TXRDY)) { | ||
323 | sc26xx_enable_irq(port, IMR_TXRDY); | ||
324 | break; | ||
325 | } | ||
326 | WRITE_SC_PORT(port, THR, xmit->buf[xmit->tail]); | ||
327 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | ||
328 | port->icount.tx++; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | /* port->lock held by caller. */ | ||
333 | static void sc26xx_stop_rx(struct uart_port *port) | ||
334 | { | ||
335 | } | ||
336 | |||
337 | /* port->lock held by caller. */ | ||
338 | static void sc26xx_enable_ms(struct uart_port *port) | ||
339 | { | ||
340 | } | ||
341 | |||
342 | /* port->lock is not held. */ | ||
343 | static void sc26xx_break_ctl(struct uart_port *port, int break_state) | ||
344 | { | ||
345 | if (break_state == -1) | ||
346 | WRITE_SC_PORT(port, CR, CR_STRT_BRK); | ||
347 | else | ||
348 | WRITE_SC_PORT(port, CR, CR_STOP_BRK); | ||
349 | } | ||
350 | |||
351 | /* port->lock is not held. */ | ||
352 | static int sc26xx_startup(struct uart_port *port) | ||
353 | { | ||
354 | sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | ||
355 | WRITE_SC(port, OPCR, 0); | ||
356 | |||
357 | /* reset tx and rx */ | ||
358 | WRITE_SC_PORT(port, CR, CR_RES_RX); | ||
359 | WRITE_SC_PORT(port, CR, CR_RES_TX); | ||
360 | |||
361 | /* start rx/tx */ | ||
362 | WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); | ||
363 | |||
364 | /* enable irqs */ | ||
365 | sc26xx_enable_irq(port, IMR_RXRDY); | ||
366 | return 0; | ||
367 | } | ||
368 | |||
369 | /* port->lock is not held. */ | ||
370 | static void sc26xx_shutdown(struct uart_port *port) | ||
371 | { | ||
372 | /* disable interrupst */ | ||
373 | sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); | ||
374 | |||
375 | /* stop tx/rx */ | ||
376 | WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX); | ||
377 | } | ||
378 | |||
379 | /* port->lock is not held. */ | ||
380 | static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios, | ||
381 | struct ktermios *old) | ||
382 | { | ||
383 | unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); | ||
384 | unsigned int quot = uart_get_divisor(port, baud); | ||
385 | unsigned int iflag, cflag; | ||
386 | unsigned long flags; | ||
387 | u8 mr1, mr2, csr; | ||
388 | |||
389 | spin_lock_irqsave(&port->lock, flags); | ||
390 | |||
391 | while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) | ||
392 | udelay(2); | ||
393 | |||
394 | WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX); | ||
395 | |||
396 | iflag = termios->c_iflag; | ||
397 | cflag = termios->c_cflag; | ||
398 | |||
399 | port->read_status_mask = SR_OVERRUN; | ||
400 | if (iflag & INPCK) | ||
401 | port->read_status_mask |= SR_PARITY | SR_FRAME; | ||
402 | if (iflag & (BRKINT | PARMRK)) | ||
403 | port->read_status_mask |= SR_BREAK; | ||
404 | |||
405 | port->ignore_status_mask = 0; | ||
406 | if (iflag & IGNBRK) | ||
407 | port->ignore_status_mask |= SR_BREAK; | ||
408 | if ((cflag & CREAD) == 0) | ||
409 | port->ignore_status_mask |= SR_BREAK | SR_FRAME | | ||
410 | SR_PARITY | SR_OVERRUN; | ||
411 | |||
412 | switch (cflag & CSIZE) { | ||
413 | case CS5: | ||
414 | mr1 = 0x00; | ||
415 | break; | ||
416 | case CS6: | ||
417 | mr1 = 0x01; | ||
418 | break; | ||
419 | case CS7: | ||
420 | mr1 = 0x02; | ||
421 | break; | ||
422 | default: | ||
423 | case CS8: | ||
424 | mr1 = 0x03; | ||
425 | break; | ||
426 | } | ||
427 | mr2 = 0x07; | ||
428 | if (cflag & CSTOPB) | ||
429 | mr2 = 0x0f; | ||
430 | if (cflag & PARENB) { | ||
431 | if (cflag & PARODD) | ||
432 | mr1 |= (1 << 2); | ||
433 | } else | ||
434 | mr1 |= (2 << 3); | ||
435 | |||
436 | switch (baud) { | ||
437 | case 50: | ||
438 | csr = 0x00; | ||
439 | break; | ||
440 | case 110: | ||
441 | csr = 0x11; | ||
442 | break; | ||
443 | case 134: | ||
444 | csr = 0x22; | ||
445 | break; | ||
446 | case 200: | ||
447 | csr = 0x33; | ||
448 | break; | ||
449 | case 300: | ||
450 | csr = 0x44; | ||
451 | break; | ||
452 | case 600: | ||
453 | csr = 0x55; | ||
454 | break; | ||
455 | case 1200: | ||
456 | csr = 0x66; | ||
457 | break; | ||
458 | case 2400: | ||
459 | csr = 0x88; | ||
460 | break; | ||
461 | case 4800: | ||
462 | csr = 0x99; | ||
463 | break; | ||
464 | default: | ||
465 | case 9600: | ||
466 | csr = 0xbb; | ||
467 | break; | ||
468 | case 19200: | ||
469 | csr = 0xcc; | ||
470 | break; | ||
471 | } | ||
472 | |||
473 | WRITE_SC_PORT(port, CR, CR_RES_MR); | ||
474 | WRITE_SC_PORT(port, MRx, mr1); | ||
475 | WRITE_SC_PORT(port, MRx, mr2); | ||
476 | |||
477 | WRITE_SC(port, ACR, 0x80); | ||
478 | WRITE_SC_PORT(port, CSR, csr); | ||
479 | |||
480 | /* reset tx and rx */ | ||
481 | WRITE_SC_PORT(port, CR, CR_RES_RX); | ||
482 | WRITE_SC_PORT(port, CR, CR_RES_TX); | ||
483 | |||
484 | WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); | ||
485 | while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) | ||
486 | udelay(2); | ||
487 | |||
488 | /* XXX */ | ||
489 | uart_update_timeout(port, cflag, | ||
490 | (port->uartclk / (16 * quot))); | ||
491 | |||
492 | spin_unlock_irqrestore(&port->lock, flags); | ||
493 | } | ||
494 | |||
495 | static const char *sc26xx_type(struct uart_port *port) | ||
496 | { | ||
497 | return "SC26XX"; | ||
498 | } | ||
499 | |||
500 | static void sc26xx_release_port(struct uart_port *port) | ||
501 | { | ||
502 | } | ||
503 | |||
504 | static int sc26xx_request_port(struct uart_port *port) | ||
505 | { | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static void sc26xx_config_port(struct uart_port *port, int flags) | ||
510 | { | ||
511 | } | ||
512 | |||
513 | static int sc26xx_verify_port(struct uart_port *port, struct serial_struct *ser) | ||
514 | { | ||
515 | return -EINVAL; | ||
516 | } | ||
517 | |||
518 | static struct uart_ops sc26xx_ops = { | ||
519 | .tx_empty = sc26xx_tx_empty, | ||
520 | .set_mctrl = sc26xx_set_mctrl, | ||
521 | .get_mctrl = sc26xx_get_mctrl, | ||
522 | .stop_tx = sc26xx_stop_tx, | ||
523 | .start_tx = sc26xx_start_tx, | ||
524 | .stop_rx = sc26xx_stop_rx, | ||
525 | .enable_ms = sc26xx_enable_ms, | ||
526 | .break_ctl = sc26xx_break_ctl, | ||
527 | .startup = sc26xx_startup, | ||
528 | .shutdown = sc26xx_shutdown, | ||
529 | .set_termios = sc26xx_set_termios, | ||
530 | .type = sc26xx_type, | ||
531 | .release_port = sc26xx_release_port, | ||
532 | .request_port = sc26xx_request_port, | ||
533 | .config_port = sc26xx_config_port, | ||
534 | .verify_port = sc26xx_verify_port, | ||
535 | }; | ||
536 | |||
537 | static struct uart_port *sc26xx_port; | ||
538 | |||
539 | #ifdef CONFIG_SERIAL_SC26XX_CONSOLE | ||
540 | static void sc26xx_console_putchar(struct uart_port *port, char c) | ||
541 | { | ||
542 | unsigned long flags; | ||
543 | int limit = 1000000; | ||
544 | |||
545 | spin_lock_irqsave(&port->lock, flags); | ||
546 | |||
547 | while (limit-- > 0) { | ||
548 | if (READ_SC_PORT(port, SR) & SR_TXRDY) { | ||
549 | WRITE_SC_PORT(port, THR, c); | ||
550 | break; | ||
551 | } | ||
552 | udelay(2); | ||
553 | } | ||
554 | |||
555 | spin_unlock_irqrestore(&port->lock, flags); | ||
556 | } | ||
557 | |||
558 | static void sc26xx_console_write(struct console *con, const char *s, unsigned n) | ||
559 | { | ||
560 | struct uart_port *port = sc26xx_port; | ||
561 | int i; | ||
562 | |||
563 | for (i = 0; i < n; i++) { | ||
564 | if (*s == '\n') | ||
565 | sc26xx_console_putchar(port, '\r'); | ||
566 | sc26xx_console_putchar(port, *s++); | ||
567 | } | ||
568 | } | ||
569 | |||
570 | static int __init sc26xx_console_setup(struct console *con, char *options) | ||
571 | { | ||
572 | struct uart_port *port = sc26xx_port; | ||
573 | int baud = 9600; | ||
574 | int bits = 8; | ||
575 | int parity = 'n'; | ||
576 | int flow = 'n'; | ||
577 | |||
578 | if (port->type != PORT_SC26XX) | ||
579 | return -1; | ||
580 | |||
581 | printk(KERN_INFO "Console: ttySC%d (SC26XX)\n", con->index); | ||
582 | if (options) | ||
583 | uart_parse_options(options, &baud, &parity, &bits, &flow); | ||
584 | |||
585 | return uart_set_options(port, con, baud, parity, bits, flow); | ||
586 | } | ||
587 | |||
588 | static struct uart_driver sc26xx_reg; | ||
589 | static struct console sc26xx_console = { | ||
590 | .name = "ttySC", | ||
591 | .write = sc26xx_console_write, | ||
592 | .device = uart_console_device, | ||
593 | .setup = sc26xx_console_setup, | ||
594 | .flags = CON_PRINTBUFFER, | ||
595 | .index = -1, | ||
596 | .data = &sc26xx_reg, | ||
597 | }; | ||
598 | #define SC26XX_CONSOLE &sc26xx_console | ||
599 | #else | ||
600 | #define SC26XX_CONSOLE NULL | ||
601 | #endif | ||
602 | |||
603 | static struct uart_driver sc26xx_reg = { | ||
604 | .owner = THIS_MODULE, | ||
605 | .driver_name = "SC26xx", | ||
606 | .dev_name = "ttySC", | ||
607 | .major = SC26XX_MAJOR, | ||
608 | .minor = SC26XX_MINOR_START, | ||
609 | .nr = SC26XX_NR, | ||
610 | .cons = SC26XX_CONSOLE, | ||
611 | }; | ||
612 | |||
613 | static u8 sc26xx_flags2mask(unsigned int flags, unsigned int bitpos) | ||
614 | { | ||
615 | unsigned int bit = (flags >> bitpos) & 15; | ||
616 | |||
617 | return bit ? (1 << (bit - 1)) : 0; | ||
618 | } | ||
619 | |||
620 | static void __devinit sc26xx_init_masks(struct uart_sc26xx_port *up, | ||
621 | int line, unsigned int data) | ||
622 | { | ||
623 | up->dtr_mask[line] = sc26xx_flags2mask(data, 0); | ||
624 | up->rts_mask[line] = sc26xx_flags2mask(data, 4); | ||
625 | up->dsr_mask[line] = sc26xx_flags2mask(data, 8); | ||
626 | up->cts_mask[line] = sc26xx_flags2mask(data, 12); | ||
627 | up->dcd_mask[line] = sc26xx_flags2mask(data, 16); | ||
628 | up->ri_mask[line] = sc26xx_flags2mask(data, 20); | ||
629 | } | ||
630 | |||
631 | static int __devinit sc26xx_probe(struct platform_device *dev) | ||
632 | { | ||
633 | struct resource *res; | ||
634 | struct uart_sc26xx_port *up; | ||
635 | unsigned int *sc26xx_data = dev->dev.platform_data; | ||
636 | int err; | ||
637 | |||
638 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
639 | if (!res) | ||
640 | return -ENODEV; | ||
641 | |||
642 | up = kzalloc(sizeof *up, GFP_KERNEL); | ||
643 | if (unlikely(!up)) | ||
644 | return -ENOMEM; | ||
645 | |||
646 | up->port[0].line = 0; | ||
647 | up->port[0].ops = &sc26xx_ops; | ||
648 | up->port[0].type = PORT_SC26XX; | ||
649 | up->port[0].uartclk = (29491200 / 16); /* arbitrary */ | ||
650 | |||
651 | up->port[0].mapbase = res->start; | ||
652 | up->port[0].membase = ioremap_nocache(up->port[0].mapbase, 0x40); | ||
653 | up->port[0].iotype = UPIO_MEM; | ||
654 | up->port[0].irq = platform_get_irq(dev, 0); | ||
655 | |||
656 | up->port[0].dev = &dev->dev; | ||
657 | |||
658 | sc26xx_init_masks(up, 0, sc26xx_data[0]); | ||
659 | |||
660 | sc26xx_port = &up->port[0]; | ||
661 | |||
662 | up->port[1].line = 1; | ||
663 | up->port[1].ops = &sc26xx_ops; | ||
664 | up->port[1].type = PORT_SC26XX; | ||
665 | up->port[1].uartclk = (29491200 / 16); /* arbitrary */ | ||
666 | |||
667 | up->port[1].mapbase = up->port[0].mapbase; | ||
668 | up->port[1].membase = up->port[0].membase; | ||
669 | up->port[1].iotype = UPIO_MEM; | ||
670 | up->port[1].irq = up->port[0].irq; | ||
671 | |||
672 | up->port[1].dev = &dev->dev; | ||
673 | |||
674 | sc26xx_init_masks(up, 1, sc26xx_data[1]); | ||
675 | |||
676 | err = uart_register_driver(&sc26xx_reg); | ||
677 | if (err) | ||
678 | goto out_free_port; | ||
679 | |||
680 | sc26xx_reg.tty_driver->name_base = sc26xx_reg.minor; | ||
681 | |||
682 | err = uart_add_one_port(&sc26xx_reg, &up->port[0]); | ||
683 | if (err) | ||
684 | goto out_unregister_driver; | ||
685 | |||
686 | err = uart_add_one_port(&sc26xx_reg, &up->port[1]); | ||
687 | if (err) | ||
688 | goto out_remove_port0; | ||
689 | |||
690 | err = request_irq(up->port[0].irq, sc26xx_interrupt, 0, "sc26xx", up); | ||
691 | if (err) | ||
692 | goto out_remove_ports; | ||
693 | |||
694 | dev_set_drvdata(&dev->dev, up); | ||
695 | return 0; | ||
696 | |||
697 | out_remove_ports: | ||
698 | uart_remove_one_port(&sc26xx_reg, &up->port[1]); | ||
699 | out_remove_port0: | ||
700 | uart_remove_one_port(&sc26xx_reg, &up->port[0]); | ||
701 | |||
702 | out_unregister_driver: | ||
703 | uart_unregister_driver(&sc26xx_reg); | ||
704 | |||
705 | out_free_port: | ||
706 | kfree(up); | ||
707 | sc26xx_port = NULL; | ||
708 | return err; | ||
709 | } | ||
710 | |||
711 | |||
712 | static int __exit sc26xx_driver_remove(struct platform_device *dev) | ||
713 | { | ||
714 | struct uart_sc26xx_port *up = dev_get_drvdata(&dev->dev); | ||
715 | |||
716 | free_irq(up->port[0].irq, up); | ||
717 | |||
718 | uart_remove_one_port(&sc26xx_reg, &up->port[0]); | ||
719 | uart_remove_one_port(&sc26xx_reg, &up->port[1]); | ||
720 | |||
721 | uart_unregister_driver(&sc26xx_reg); | ||
722 | |||
723 | kfree(up); | ||
724 | sc26xx_port = NULL; | ||
725 | |||
726 | dev_set_drvdata(&dev->dev, NULL); | ||
727 | return 0; | ||
728 | } | ||
729 | |||
730 | static struct platform_driver sc26xx_driver = { | ||
731 | .probe = sc26xx_probe, | ||
732 | .remove = __devexit_p(sc26xx_driver_remove), | ||
733 | .driver = { | ||
734 | .name = "SC26xx", | ||
735 | }, | ||
736 | }; | ||
737 | |||
738 | static int __init sc26xx_init(void) | ||
739 | { | ||
740 | return platform_driver_register(&sc26xx_driver); | ||
741 | } | ||
742 | |||
743 | static void __exit sc26xx_exit(void) | ||
744 | { | ||
745 | platform_driver_unregister(&sc26xx_driver); | ||
746 | } | ||
747 | |||
748 | module_init(sc26xx_init); | ||
749 | module_exit(sc26xx_exit); | ||
750 | |||
751 | |||
752 | MODULE_AUTHOR("Thomas Bogendörfer"); | ||
753 | MODULE_DESCRIPTION("SC681/SC2692 serial driver"); | ||
754 | MODULE_VERSION("1.0"); | ||
755 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c index 80943409edb0..bacf68dca01a 100644 --- a/drivers/serial/uartlite.c +++ b/drivers/serial/uartlite.c | |||
@@ -142,7 +142,7 @@ static int ulite_transmit(struct uart_port *port, int stat) | |||
142 | 142 | ||
143 | static irqreturn_t ulite_isr(int irq, void *dev_id) | 143 | static irqreturn_t ulite_isr(int irq, void *dev_id) |
144 | { | 144 | { |
145 | struct uart_port *port = (struct uart_port *)dev_id; | 145 | struct uart_port *port = dev_id; |
146 | int busy; | 146 | int busy; |
147 | 147 | ||
148 | do { | 148 | do { |
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index aaaea81e412a..d8107890db15 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig | |||
@@ -144,10 +144,10 @@ config SPI_OMAP_UWIRE | |||
144 | This hooks up to the MicroWire controller on OMAP1 chips. | 144 | This hooks up to the MicroWire controller on OMAP1 chips. |
145 | 145 | ||
146 | config SPI_OMAP24XX | 146 | config SPI_OMAP24XX |
147 | tristate "McSPI driver for OMAP24xx" | 147 | tristate "McSPI driver for OMAP24xx/OMAP34xx" |
148 | depends on SPI_MASTER && ARCH_OMAP24XX | 148 | depends on SPI_MASTER && (ARCH_OMAP24XX || ARCH_OMAP34XX) |
149 | help | 149 | help |
150 | SPI master controller for OMAP24xx Multichannel SPI | 150 | SPI master controller for OMAP24xx/OMAP34xx Multichannel SPI |
151 | (McSPI) modules. | 151 | (McSPI) modules. |
152 | 152 | ||
153 | config SPI_PXA2XX | 153 | config SPI_PXA2XX |
@@ -176,6 +176,13 @@ config SPI_S3C24XX_GPIO | |||
176 | the inbuilt hardware cannot provide the transfer mode, or | 176 | the inbuilt hardware cannot provide the transfer mode, or |
177 | where the board is using non hardware connected pins. | 177 | where the board is using non hardware connected pins. |
178 | 178 | ||
179 | config SPI_SH_SCI | ||
180 | tristate "SuperH SCI SPI controller" | ||
181 | depends on SPI_MASTER && SUPERH | ||
182 | select SPI_BITBANG | ||
183 | help | ||
184 | SPI driver for SuperH SCI blocks. | ||
185 | |||
179 | config SPI_TXX9 | 186 | config SPI_TXX9 |
180 | tristate "Toshiba TXx9 SPI controller" | 187 | tristate "Toshiba TXx9 SPI controller" |
181 | depends on SPI_MASTER && GENERIC_GPIO && CPU_TX49XX | 188 | depends on SPI_MASTER && GENERIC_GPIO && CPU_TX49XX |
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 41fbac45c323..7fca043ce723 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile | |||
@@ -27,6 +27,7 @@ obj-$(CONFIG_SPI_S3C24XX_GPIO) += spi_s3c24xx_gpio.o | |||
27 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o | 27 | obj-$(CONFIG_SPI_S3C24XX) += spi_s3c24xx.o |
28 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o | 28 | obj-$(CONFIG_SPI_TXX9) += spi_txx9.o |
29 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o | 29 | obj-$(CONFIG_SPI_XILINX) += xilinx_spi.o |
30 | obj-$(CONFIG_SPI_SH_SCI) += spi_sh_sci.o | ||
30 | # ... add above this line ... | 31 | # ... add above this line ... |
31 | 32 | ||
32 | # SPI protocol drivers (device/link on bus) | 33 | # SPI protocol drivers (device/link on bus) |
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index ff10808183a3..293b7cab3e57 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c | |||
@@ -51,7 +51,9 @@ struct atmel_spi { | |||
51 | u8 stopping; | 51 | u8 stopping; |
52 | struct list_head queue; | 52 | struct list_head queue; |
53 | struct spi_transfer *current_transfer; | 53 | struct spi_transfer *current_transfer; |
54 | unsigned long remaining_bytes; | 54 | unsigned long current_remaining_bytes; |
55 | struct spi_transfer *next_transfer; | ||
56 | unsigned long next_remaining_bytes; | ||
55 | 57 | ||
56 | void *buffer; | 58 | void *buffer; |
57 | dma_addr_t buffer_dma; | 59 | dma_addr_t buffer_dma; |
@@ -121,6 +123,48 @@ static void cs_deactivate(struct atmel_spi *as, struct spi_device *spi) | |||
121 | gpio_set_value(gpio, !active); | 123 | gpio_set_value(gpio, !active); |
122 | } | 124 | } |
123 | 125 | ||
126 | static inline int atmel_spi_xfer_is_last(struct spi_message *msg, | ||
127 | struct spi_transfer *xfer) | ||
128 | { | ||
129 | return msg->transfers.prev == &xfer->transfer_list; | ||
130 | } | ||
131 | |||
132 | static inline int atmel_spi_xfer_can_be_chained(struct spi_transfer *xfer) | ||
133 | { | ||
134 | return xfer->delay_usecs == 0 && !xfer->cs_change; | ||
135 | } | ||
136 | |||
137 | static void atmel_spi_next_xfer_data(struct spi_master *master, | ||
138 | struct spi_transfer *xfer, | ||
139 | dma_addr_t *tx_dma, | ||
140 | dma_addr_t *rx_dma, | ||
141 | u32 *plen) | ||
142 | { | ||
143 | struct atmel_spi *as = spi_master_get_devdata(master); | ||
144 | u32 len = *plen; | ||
145 | |||
146 | /* use scratch buffer only when rx or tx data is unspecified */ | ||
147 | if (xfer->rx_buf) | ||
148 | *rx_dma = xfer->rx_dma + xfer->len - len; | ||
149 | else { | ||
150 | *rx_dma = as->buffer_dma; | ||
151 | if (len > BUFFER_SIZE) | ||
152 | len = BUFFER_SIZE; | ||
153 | } | ||
154 | if (xfer->tx_buf) | ||
155 | *tx_dma = xfer->tx_dma + xfer->len - len; | ||
156 | else { | ||
157 | *tx_dma = as->buffer_dma; | ||
158 | if (len > BUFFER_SIZE) | ||
159 | len = BUFFER_SIZE; | ||
160 | memset(as->buffer, 0, len); | ||
161 | dma_sync_single_for_device(&as->pdev->dev, | ||
162 | as->buffer_dma, len, DMA_TO_DEVICE); | ||
163 | } | ||
164 | |||
165 | *plen = len; | ||
166 | } | ||
167 | |||
124 | /* | 168 | /* |
125 | * Submit next transfer for DMA. | 169 | * Submit next transfer for DMA. |
126 | * lock is held, spi irq is blocked | 170 | * lock is held, spi irq is blocked |
@@ -130,53 +174,78 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
130 | { | 174 | { |
131 | struct atmel_spi *as = spi_master_get_devdata(master); | 175 | struct atmel_spi *as = spi_master_get_devdata(master); |
132 | struct spi_transfer *xfer; | 176 | struct spi_transfer *xfer; |
133 | u32 len; | 177 | u32 len, remaining, total; |
134 | dma_addr_t tx_dma, rx_dma; | 178 | dma_addr_t tx_dma, rx_dma; |
135 | 179 | ||
136 | xfer = as->current_transfer; | 180 | if (!as->current_transfer) |
137 | if (!xfer || as->remaining_bytes == 0) { | 181 | xfer = list_entry(msg->transfers.next, |
138 | if (xfer) | 182 | struct spi_transfer, transfer_list); |
139 | xfer = list_entry(xfer->transfer_list.next, | 183 | else if (!as->next_transfer) |
140 | struct spi_transfer, transfer_list); | 184 | xfer = list_entry(as->current_transfer->transfer_list.next, |
141 | else | 185 | struct spi_transfer, transfer_list); |
142 | xfer = list_entry(msg->transfers.next, | 186 | else |
143 | struct spi_transfer, transfer_list); | 187 | xfer = NULL; |
144 | as->remaining_bytes = xfer->len; | ||
145 | as->current_transfer = xfer; | ||
146 | } | ||
147 | 188 | ||
148 | len = as->remaining_bytes; | 189 | if (xfer) { |
190 | len = xfer->len; | ||
191 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); | ||
192 | remaining = xfer->len - len; | ||
149 | 193 | ||
150 | tx_dma = xfer->tx_dma + xfer->len - len; | 194 | spi_writel(as, RPR, rx_dma); |
151 | rx_dma = xfer->rx_dma + xfer->len - len; | 195 | spi_writel(as, TPR, tx_dma); |
152 | 196 | ||
153 | /* use scratch buffer only when rx or tx data is unspecified */ | 197 | if (msg->spi->bits_per_word > 8) |
154 | if (!xfer->rx_buf) { | 198 | len >>= 1; |
155 | rx_dma = as->buffer_dma; | 199 | spi_writel(as, RCR, len); |
156 | if (len > BUFFER_SIZE) | 200 | spi_writel(as, TCR, len); |
157 | len = BUFFER_SIZE; | 201 | |
158 | } | 202 | dev_dbg(&msg->spi->dev, |
159 | if (!xfer->tx_buf) { | 203 | " start xfer %p: len %u tx %p/%08x rx %p/%08x\n", |
160 | tx_dma = as->buffer_dma; | 204 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, |
161 | if (len > BUFFER_SIZE) | 205 | xfer->rx_buf, xfer->rx_dma); |
162 | len = BUFFER_SIZE; | 206 | } else { |
163 | memset(as->buffer, 0, len); | 207 | xfer = as->next_transfer; |
164 | dma_sync_single_for_device(&as->pdev->dev, | 208 | remaining = as->next_remaining_bytes; |
165 | as->buffer_dma, len, DMA_TO_DEVICE); | ||
166 | } | 209 | } |
167 | 210 | ||
168 | spi_writel(as, RPR, rx_dma); | 211 | as->current_transfer = xfer; |
169 | spi_writel(as, TPR, tx_dma); | 212 | as->current_remaining_bytes = remaining; |
170 | 213 | ||
171 | as->remaining_bytes -= len; | 214 | if (remaining > 0) |
172 | if (msg->spi->bits_per_word > 8) | 215 | len = remaining; |
173 | len >>= 1; | 216 | else if (!atmel_spi_xfer_is_last(msg, xfer) |
217 | && atmel_spi_xfer_can_be_chained(xfer)) { | ||
218 | xfer = list_entry(xfer->transfer_list.next, | ||
219 | struct spi_transfer, transfer_list); | ||
220 | len = xfer->len; | ||
221 | } else | ||
222 | xfer = NULL; | ||
174 | 223 | ||
175 | /* REVISIT: when xfer->delay_usecs == 0, the PDC "next transfer" | 224 | as->next_transfer = xfer; |
176 | * mechanism might help avoid the IRQ latency between transfers | 225 | |
177 | * (and improve the nCS0 errata handling on at91rm9200 chips) | 226 | if (xfer) { |
178 | * | 227 | total = len; |
179 | * We're also waiting for ENDRX before we start the next | 228 | atmel_spi_next_xfer_data(master, xfer, &tx_dma, &rx_dma, &len); |
229 | as->next_remaining_bytes = total - len; | ||
230 | |||
231 | spi_writel(as, RNPR, rx_dma); | ||
232 | spi_writel(as, TNPR, tx_dma); | ||
233 | |||
234 | if (msg->spi->bits_per_word > 8) | ||
235 | len >>= 1; | ||
236 | spi_writel(as, RNCR, len); | ||
237 | spi_writel(as, TNCR, len); | ||
238 | |||
239 | dev_dbg(&msg->spi->dev, | ||
240 | " next xfer %p: len %u tx %p/%08x rx %p/%08x\n", | ||
241 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | ||
242 | xfer->rx_buf, xfer->rx_dma); | ||
243 | } else { | ||
244 | spi_writel(as, RNCR, 0); | ||
245 | spi_writel(as, TNCR, 0); | ||
246 | } | ||
247 | |||
248 | /* REVISIT: We're waiting for ENDRX before we start the next | ||
180 | * transfer because we need to handle some difficult timing | 249 | * transfer because we need to handle some difficult timing |
181 | * issues otherwise. If we wait for ENDTX in one transfer and | 250 | * issues otherwise. If we wait for ENDTX in one transfer and |
182 | * then starts waiting for ENDRX in the next, it's difficult | 251 | * then starts waiting for ENDRX in the next, it's difficult |
@@ -186,17 +255,7 @@ static void atmel_spi_next_xfer(struct spi_master *master, | |||
186 | * | 255 | * |
187 | * It should be doable, though. Just not now... | 256 | * It should be doable, though. Just not now... |
188 | */ | 257 | */ |
189 | spi_writel(as, TNCR, 0); | ||
190 | spi_writel(as, RNCR, 0); | ||
191 | spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); | 258 | spi_writel(as, IER, SPI_BIT(ENDRX) | SPI_BIT(OVRES)); |
192 | |||
193 | dev_dbg(&msg->spi->dev, | ||
194 | " start xfer %p: len %u tx %p/%08x rx %p/%08x imr %03x\n", | ||
195 | xfer, xfer->len, xfer->tx_buf, xfer->tx_dma, | ||
196 | xfer->rx_buf, xfer->rx_dma, spi_readl(as, IMR)); | ||
197 | |||
198 | spi_writel(as, RCR, len); | ||
199 | spi_writel(as, TCR, len); | ||
200 | spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); | 259 | spi_writel(as, PTCR, SPI_BIT(TXTEN) | SPI_BIT(RXTEN)); |
201 | } | 260 | } |
202 | 261 | ||
@@ -294,6 +353,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as, | |||
294 | spin_lock(&as->lock); | 353 | spin_lock(&as->lock); |
295 | 354 | ||
296 | as->current_transfer = NULL; | 355 | as->current_transfer = NULL; |
356 | as->next_transfer = NULL; | ||
297 | 357 | ||
298 | /* continue if needed */ | 358 | /* continue if needed */ |
299 | if (list_empty(&as->queue) || as->stopping) | 359 | if (list_empty(&as->queue) || as->stopping) |
@@ -377,7 +437,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
377 | 437 | ||
378 | spi_writel(as, IDR, pending); | 438 | spi_writel(as, IDR, pending); |
379 | 439 | ||
380 | if (as->remaining_bytes == 0) { | 440 | if (as->current_remaining_bytes == 0) { |
381 | msg->actual_length += xfer->len; | 441 | msg->actual_length += xfer->len; |
382 | 442 | ||
383 | if (!msg->is_dma_mapped) | 443 | if (!msg->is_dma_mapped) |
@@ -387,7 +447,7 @@ atmel_spi_interrupt(int irq, void *dev_id) | |||
387 | if (xfer->delay_usecs) | 447 | if (xfer->delay_usecs) |
388 | udelay(xfer->delay_usecs); | 448 | udelay(xfer->delay_usecs); |
389 | 449 | ||
390 | if (msg->transfers.prev == &xfer->transfer_list) { | 450 | if (atmel_spi_xfer_is_last(msg, xfer)) { |
391 | /* report completed message */ | 451 | /* report completed message */ |
392 | atmel_spi_msg_done(master, as, msg, 0, | 452 | atmel_spi_msg_done(master, as, msg, 0, |
393 | xfer->cs_change); | 453 | xfer->cs_change); |
@@ -490,9 +550,14 @@ static int atmel_spi_setup(struct spi_device *spi) | |||
490 | if (!(spi->mode & SPI_CPHA)) | 550 | if (!(spi->mode & SPI_CPHA)) |
491 | csr |= SPI_BIT(NCPHA); | 551 | csr |= SPI_BIT(NCPHA); |
492 | 552 | ||
493 | /* TODO: DLYBS and DLYBCT */ | 553 | /* DLYBS is mostly irrelevant since we manage chipselect using GPIOs. |
494 | csr |= SPI_BF(DLYBS, 10); | 554 | * |
495 | csr |= SPI_BF(DLYBCT, 10); | 555 | * DLYBCT would add delays between words, slowing down transfers. |
556 | * It could potentially be useful to cope with DMA bottlenecks, but | ||
557 | * in those cases it's probably best to just use a lower bitrate. | ||
558 | */ | ||
559 | csr |= SPI_BF(DLYBS, 0); | ||
560 | csr |= SPI_BF(DLYBCT, 0); | ||
496 | 561 | ||
497 | /* chipselect must have been muxed as GPIO (e.g. in board setup) */ | 562 | /* chipselect must have been muxed as GPIO (e.g. in board setup) */ |
498 | npcs_pin = (unsigned int)spi->controller_data; | 563 | npcs_pin = (unsigned int)spi->controller_data; |
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c index ea61724ae225..a6ba11afb03f 100644 --- a/drivers/spi/omap2_mcspi.c +++ b/drivers/spi/omap2_mcspi.c | |||
@@ -915,6 +915,28 @@ static u8 __initdata spi2_txdma_id[] = { | |||
915 | OMAP24XX_DMA_SPI2_TX1, | 915 | OMAP24XX_DMA_SPI2_TX1, |
916 | }; | 916 | }; |
917 | 917 | ||
918 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP34XX) | ||
919 | static u8 __initdata spi3_rxdma_id[] = { | ||
920 | OMAP24XX_DMA_SPI3_RX0, | ||
921 | OMAP24XX_DMA_SPI3_RX1, | ||
922 | }; | ||
923 | |||
924 | static u8 __initdata spi3_txdma_id[] = { | ||
925 | OMAP24XX_DMA_SPI3_TX0, | ||
926 | OMAP24XX_DMA_SPI3_TX1, | ||
927 | }; | ||
928 | #endif | ||
929 | |||
930 | #ifdef CONFIG_ARCH_OMAP3 | ||
931 | static u8 __initdata spi4_rxdma_id[] = { | ||
932 | OMAP34XX_DMA_SPI4_RX0, | ||
933 | }; | ||
934 | |||
935 | static u8 __initdata spi4_txdma_id[] = { | ||
936 | OMAP34XX_DMA_SPI4_TX0, | ||
937 | }; | ||
938 | #endif | ||
939 | |||
918 | static int __init omap2_mcspi_probe(struct platform_device *pdev) | 940 | static int __init omap2_mcspi_probe(struct platform_device *pdev) |
919 | { | 941 | { |
920 | struct spi_master *master; | 942 | struct spi_master *master; |
@@ -935,7 +957,20 @@ static int __init omap2_mcspi_probe(struct platform_device *pdev) | |||
935 | txdma_id = spi2_txdma_id; | 957 | txdma_id = spi2_txdma_id; |
936 | num_chipselect = 2; | 958 | num_chipselect = 2; |
937 | break; | 959 | break; |
938 | /* REVISIT omap2430 has a third McSPI ... */ | 960 | #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) |
961 | case 3: | ||
962 | rxdma_id = spi3_rxdma_id; | ||
963 | txdma_id = spi3_txdma_id; | ||
964 | num_chipselect = 2; | ||
965 | break; | ||
966 | #endif | ||
967 | #ifdef CONFIG_ARCH_OMAP3 | ||
968 | case 4: | ||
969 | rxdma_id = spi4_rxdma_id; | ||
970 | txdma_id = spi4_txdma_id; | ||
971 | num_chipselect = 1; | ||
972 | break; | ||
973 | #endif | ||
939 | default: | 974 | default: |
940 | return -EINVAL; | 975 | return -EINVAL; |
941 | } | 976 | } |
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c index eb817b8eb024..365e0e355aea 100644 --- a/drivers/spi/pxa2xx_spi.c +++ b/drivers/spi/pxa2xx_spi.c | |||
@@ -1526,17 +1526,6 @@ static void pxa2xx_spi_shutdown(struct platform_device *pdev) | |||
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | #ifdef CONFIG_PM | 1528 | #ifdef CONFIG_PM |
1529 | static int suspend_devices(struct device *dev, void *pm_message) | ||
1530 | { | ||
1531 | pm_message_t *state = pm_message; | ||
1532 | |||
1533 | if (dev->power.power_state.event != state->event) { | ||
1534 | dev_warn(dev, "pm state does not match request\n"); | ||
1535 | return -1; | ||
1536 | } | ||
1537 | |||
1538 | return 0; | ||
1539 | } | ||
1540 | 1529 | ||
1541 | static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | 1530 | static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) |
1542 | { | 1531 | { |
@@ -1544,12 +1533,6 @@ static int pxa2xx_spi_suspend(struct platform_device *pdev, pm_message_t state) | |||
1544 | struct ssp_device *ssp = drv_data->ssp; | 1533 | struct ssp_device *ssp = drv_data->ssp; |
1545 | int status = 0; | 1534 | int status = 0; |
1546 | 1535 | ||
1547 | /* Check all childern for current power state */ | ||
1548 | if (device_for_each_child(&pdev->dev, &state, suspend_devices) != 0) { | ||
1549 | dev_warn(&pdev->dev, "suspend aborted\n"); | ||
1550 | return -1; | ||
1551 | } | ||
1552 | |||
1553 | status = stop_queue(drv_data); | 1536 | status = stop_queue(drv_data); |
1554 | if (status != 0) | 1537 | if (status != 0) |
1555 | return status; | 1538 | return status; |
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 682a6a48fec3..1ad12afc6ba0 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c | |||
@@ -18,7 +18,6 @@ | |||
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/autoconf.h> | ||
22 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
23 | #include <linux/device.h> | 22 | #include <linux/device.h> |
24 | #include <linux/init.h> | 23 | #include <linux/init.h> |
@@ -77,39 +76,33 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
77 | 76 | ||
78 | #ifdef CONFIG_PM | 77 | #ifdef CONFIG_PM |
79 | 78 | ||
80 | /* | ||
81 | * NOTE: the suspend() method for an spi_master controller driver | ||
82 | * should verify that all its child devices are marked as suspended; | ||
83 | * suspend requests delivered through sysfs power/state files don't | ||
84 | * enforce such constraints. | ||
85 | */ | ||
86 | static int spi_suspend(struct device *dev, pm_message_t message) | 79 | static int spi_suspend(struct device *dev, pm_message_t message) |
87 | { | 80 | { |
88 | int value; | 81 | int value = 0; |
89 | struct spi_driver *drv = to_spi_driver(dev->driver); | 82 | struct spi_driver *drv = to_spi_driver(dev->driver); |
90 | 83 | ||
91 | if (!drv || !drv->suspend) | ||
92 | return 0; | ||
93 | |||
94 | /* suspend will stop irqs and dma; no more i/o */ | 84 | /* suspend will stop irqs and dma; no more i/o */ |
95 | value = drv->suspend(to_spi_device(dev), message); | 85 | if (drv) { |
96 | if (value == 0) | 86 | if (drv->suspend) |
97 | dev->power.power_state = message; | 87 | value = drv->suspend(to_spi_device(dev), message); |
88 | else | ||
89 | dev_dbg(dev, "... can't suspend\n"); | ||
90 | } | ||
98 | return value; | 91 | return value; |
99 | } | 92 | } |
100 | 93 | ||
101 | static int spi_resume(struct device *dev) | 94 | static int spi_resume(struct device *dev) |
102 | { | 95 | { |
103 | int value; | 96 | int value = 0; |
104 | struct spi_driver *drv = to_spi_driver(dev->driver); | 97 | struct spi_driver *drv = to_spi_driver(dev->driver); |
105 | 98 | ||
106 | if (!drv || !drv->resume) | ||
107 | return 0; | ||
108 | |||
109 | /* resume may restart the i/o queue */ | 99 | /* resume may restart the i/o queue */ |
110 | value = drv->resume(to_spi_device(dev)); | 100 | if (drv) { |
111 | if (value == 0) | 101 | if (drv->resume) |
112 | dev->power.power_state = PMSG_ON; | 102 | value = drv->resume(to_spi_device(dev)); |
103 | else | ||
104 | dev_dbg(dev, "... can't resume\n"); | ||
105 | } | ||
113 | return value; | 106 | return value; |
114 | } | 107 | } |
115 | 108 | ||
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c index 7ef39a6e8c06..d853fceb6bf0 100644 --- a/drivers/spi/spi_bfin5xx.c +++ b/drivers/spi/spi_bfin5xx.c | |||
@@ -1,37 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * File: drivers/spi/bfin5xx_spi.c | 2 | * Blackfin On-Chip SPI Driver |
3 | * Maintainer: | ||
4 | * Bryan Wu <bryan.wu@analog.com> | ||
5 | * Original Author: | ||
6 | * Luke Yang (Analog Devices Inc.) | ||
7 | * | ||
8 | * Created: March. 10th 2006 | ||
9 | * Description: SPI controller driver for Blackfin BF5xx | ||
10 | * Bugs: Enter bugs at http://blackfin.uclinux.org/ | ||
11 | * | ||
12 | * Modified: | ||
13 | * March 10, 2006 bfin5xx_spi.c Created. (Luke Yang) | ||
14 | * August 7, 2006 added full duplex mode (Axel Weiss & Luke Yang) | ||
15 | * July 17, 2007 add support for BF54x SPI0 controller (Bryan Wu) | ||
16 | * July 30, 2007 add platfrom_resource interface to support multi-port | ||
17 | * SPI controller (Bryan Wu) | ||
18 | * | 3 | * |
19 | * Copyright 2004-2007 Analog Devices Inc. | 4 | * Copyright 2004-2007 Analog Devices Inc. |
20 | * | 5 | * |
21 | * This program is free software ; you can redistribute it and/or modify | 6 | * Enter bugs at http://blackfin.uclinux.org/ |
22 | * it under the terms of the GNU General Public License as published by | ||
23 | * the Free Software Foundation ; either version 2, or (at your option) | ||
24 | * any later version. | ||
25 | * | ||
26 | * This program is distributed in the hope that it will be useful, | ||
27 | * but WITHOUT ANY WARRANTY ; without even the implied warranty of | ||
28 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
29 | * GNU General Public License for more details. | ||
30 | * | 7 | * |
31 | * You should have received a copy of the GNU General Public License | 8 | * Licensed under the GPL-2 or later. |
32 | * along with this program ; see the file COPYING. | ||
33 | * If not, write to the Free Software Foundation, | ||
34 | * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
35 | */ | 9 | */ |
36 | 10 | ||
37 | #include <linux/init.h> | 11 | #include <linux/init.h> |
@@ -223,10 +197,9 @@ static void cs_deactive(struct driver_data *drv_data, struct chip_data *chip) | |||
223 | #define MAX_SPI_SSEL 7 | 197 | #define MAX_SPI_SSEL 7 |
224 | 198 | ||
225 | /* stop controller and re-config current chip*/ | 199 | /* stop controller and re-config current chip*/ |
226 | static int restore_state(struct driver_data *drv_data) | 200 | static void restore_state(struct driver_data *drv_data) |
227 | { | 201 | { |
228 | struct chip_data *chip = drv_data->cur_chip; | 202 | struct chip_data *chip = drv_data->cur_chip; |
229 | int ret = 0; | ||
230 | 203 | ||
231 | /* Clear status and disable clock */ | 204 | /* Clear status and disable clock */ |
232 | write_STAT(drv_data, BIT_STAT_CLR); | 205 | write_STAT(drv_data, BIT_STAT_CLR); |
@@ -239,13 +212,6 @@ static int restore_state(struct driver_data *drv_data) | |||
239 | 212 | ||
240 | bfin_spi_enable(drv_data); | 213 | bfin_spi_enable(drv_data); |
241 | cs_active(drv_data, chip); | 214 | cs_active(drv_data, chip); |
242 | |||
243 | if (ret) | ||
244 | dev_dbg(&drv_data->pdev->dev, | ||
245 | ": request chip select number %d failed\n", | ||
246 | chip->chip_select_num); | ||
247 | |||
248 | return ret; | ||
249 | } | 215 | } |
250 | 216 | ||
251 | /* used to kick off transfer in rx mode */ | 217 | /* used to kick off transfer in rx mode */ |
@@ -286,32 +252,30 @@ static void u8_writer(struct driver_data *drv_data) | |||
286 | dev_dbg(&drv_data->pdev->dev, | 252 | dev_dbg(&drv_data->pdev->dev, |
287 | "cr8-s is 0x%x\n", read_STAT(drv_data)); | 253 | "cr8-s is 0x%x\n", read_STAT(drv_data)); |
288 | 254 | ||
289 | /* poll for SPI completion before start */ | ||
290 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
291 | cpu_relax(); | ||
292 | |||
293 | while (drv_data->tx < drv_data->tx_end) { | 255 | while (drv_data->tx < drv_data->tx_end) { |
294 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 256 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); |
295 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 257 | while (read_STAT(drv_data) & BIT_STAT_TXS) |
296 | cpu_relax(); | 258 | cpu_relax(); |
297 | ++drv_data->tx; | 259 | ++drv_data->tx; |
298 | } | 260 | } |
261 | |||
262 | /* poll for SPI completion before return */ | ||
263 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
264 | cpu_relax(); | ||
299 | } | 265 | } |
300 | 266 | ||
301 | static void u8_cs_chg_writer(struct driver_data *drv_data) | 267 | static void u8_cs_chg_writer(struct driver_data *drv_data) |
302 | { | 268 | { |
303 | struct chip_data *chip = drv_data->cur_chip; | 269 | struct chip_data *chip = drv_data->cur_chip; |
304 | 270 | ||
305 | /* poll for SPI completion before start */ | ||
306 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
307 | cpu_relax(); | ||
308 | |||
309 | while (drv_data->tx < drv_data->tx_end) { | 271 | while (drv_data->tx < drv_data->tx_end) { |
310 | cs_active(drv_data, chip); | 272 | cs_active(drv_data, chip); |
311 | 273 | ||
312 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 274 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); |
313 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 275 | while (read_STAT(drv_data) & BIT_STAT_TXS) |
314 | cpu_relax(); | 276 | cpu_relax(); |
277 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
278 | cpu_relax(); | ||
315 | 279 | ||
316 | cs_deactive(drv_data, chip); | 280 | cs_deactive(drv_data, chip); |
317 | 281 | ||
@@ -350,43 +314,28 @@ static void u8_cs_chg_reader(struct driver_data *drv_data) | |||
350 | { | 314 | { |
351 | struct chip_data *chip = drv_data->cur_chip; | 315 | struct chip_data *chip = drv_data->cur_chip; |
352 | 316 | ||
353 | /* poll for SPI completion before start */ | 317 | while (drv_data->rx < drv_data->rx_end) { |
354 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | 318 | cs_active(drv_data, chip); |
355 | cpu_relax(); | 319 | read_RDBR(drv_data); /* kick off */ |
356 | |||
357 | /* clear TDBR buffer before read(else it will be shifted out) */ | ||
358 | write_TDBR(drv_data, 0xFFFF); | ||
359 | 320 | ||
360 | cs_active(drv_data, chip); | 321 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
361 | dummy_read(drv_data); | 322 | cpu_relax(); |
323 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
324 | cpu_relax(); | ||
362 | 325 | ||
363 | while (drv_data->rx < drv_data->rx_end - 1) { | 326 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); |
364 | cs_deactive(drv_data, chip); | 327 | cs_deactive(drv_data, chip); |
365 | 328 | ||
366 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
367 | cpu_relax(); | ||
368 | cs_active(drv_data, chip); | ||
369 | *(u8 *) (drv_data->rx) = read_RDBR(drv_data); | ||
370 | ++drv_data->rx; | 329 | ++drv_data->rx; |
371 | } | 330 | } |
372 | cs_deactive(drv_data, chip); | ||
373 | |||
374 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | ||
375 | cpu_relax(); | ||
376 | *(u8 *) (drv_data->rx) = read_SHAW(drv_data); | ||
377 | ++drv_data->rx; | ||
378 | } | 331 | } |
379 | 332 | ||
380 | static void u8_duplex(struct driver_data *drv_data) | 333 | static void u8_duplex(struct driver_data *drv_data) |
381 | { | 334 | { |
382 | /* poll for SPI completion before start */ | ||
383 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
384 | cpu_relax(); | ||
385 | |||
386 | /* in duplex mode, clk is triggered by writing of TDBR */ | 335 | /* in duplex mode, clk is triggered by writing of TDBR */ |
387 | while (drv_data->rx < drv_data->rx_end) { | 336 | while (drv_data->rx < drv_data->rx_end) { |
388 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 337 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); |
389 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 338 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) |
390 | cpu_relax(); | 339 | cpu_relax(); |
391 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 340 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
392 | cpu_relax(); | 341 | cpu_relax(); |
@@ -400,15 +349,12 @@ static void u8_cs_chg_duplex(struct driver_data *drv_data) | |||
400 | { | 349 | { |
401 | struct chip_data *chip = drv_data->cur_chip; | 350 | struct chip_data *chip = drv_data->cur_chip; |
402 | 351 | ||
403 | /* poll for SPI completion before start */ | ||
404 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
405 | cpu_relax(); | ||
406 | |||
407 | while (drv_data->rx < drv_data->rx_end) { | 352 | while (drv_data->rx < drv_data->rx_end) { |
408 | cs_active(drv_data, chip); | 353 | cs_active(drv_data, chip); |
409 | 354 | ||
410 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); | 355 | write_TDBR(drv_data, (*(u8 *) (drv_data->tx))); |
411 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 356 | |
357 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
412 | cpu_relax(); | 358 | cpu_relax(); |
413 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 359 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
414 | cpu_relax(); | 360 | cpu_relax(); |
@@ -426,32 +372,30 @@ static void u16_writer(struct driver_data *drv_data) | |||
426 | dev_dbg(&drv_data->pdev->dev, | 372 | dev_dbg(&drv_data->pdev->dev, |
427 | "cr16 is 0x%x\n", read_STAT(drv_data)); | 373 | "cr16 is 0x%x\n", read_STAT(drv_data)); |
428 | 374 | ||
429 | /* poll for SPI completion before start */ | ||
430 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
431 | cpu_relax(); | ||
432 | |||
433 | while (drv_data->tx < drv_data->tx_end) { | 375 | while (drv_data->tx < drv_data->tx_end) { |
434 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 376 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
435 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | 377 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) |
436 | cpu_relax(); | 378 | cpu_relax(); |
437 | drv_data->tx += 2; | 379 | drv_data->tx += 2; |
438 | } | 380 | } |
381 | |||
382 | /* poll for SPI completion before return */ | ||
383 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
384 | cpu_relax(); | ||
439 | } | 385 | } |
440 | 386 | ||
441 | static void u16_cs_chg_writer(struct driver_data *drv_data) | 387 | static void u16_cs_chg_writer(struct driver_data *drv_data) |
442 | { | 388 | { |
443 | struct chip_data *chip = drv_data->cur_chip; | 389 | struct chip_data *chip = drv_data->cur_chip; |
444 | 390 | ||
445 | /* poll for SPI completion before start */ | ||
446 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
447 | cpu_relax(); | ||
448 | |||
449 | while (drv_data->tx < drv_data->tx_end) { | 391 | while (drv_data->tx < drv_data->tx_end) { |
450 | cs_active(drv_data, chip); | 392 | cs_active(drv_data, chip); |
451 | 393 | ||
452 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 394 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
453 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) | 395 | while ((read_STAT(drv_data) & BIT_STAT_TXS)) |
454 | cpu_relax(); | 396 | cpu_relax(); |
397 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
398 | cpu_relax(); | ||
455 | 399 | ||
456 | cs_deactive(drv_data, chip); | 400 | cs_deactive(drv_data, chip); |
457 | 401 | ||
@@ -519,14 +463,10 @@ static void u16_cs_chg_reader(struct driver_data *drv_data) | |||
519 | 463 | ||
520 | static void u16_duplex(struct driver_data *drv_data) | 464 | static void u16_duplex(struct driver_data *drv_data) |
521 | { | 465 | { |
522 | /* poll for SPI completion before start */ | ||
523 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
524 | cpu_relax(); | ||
525 | |||
526 | /* in duplex mode, clk is triggered by writing of TDBR */ | 466 | /* in duplex mode, clk is triggered by writing of TDBR */ |
527 | while (drv_data->tx < drv_data->tx_end) { | 467 | while (drv_data->tx < drv_data->tx_end) { |
528 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 468 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
529 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 469 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) |
530 | cpu_relax(); | 470 | cpu_relax(); |
531 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 471 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
532 | cpu_relax(); | 472 | cpu_relax(); |
@@ -540,15 +480,11 @@ static void u16_cs_chg_duplex(struct driver_data *drv_data) | |||
540 | { | 480 | { |
541 | struct chip_data *chip = drv_data->cur_chip; | 481 | struct chip_data *chip = drv_data->cur_chip; |
542 | 482 | ||
543 | /* poll for SPI completion before start */ | ||
544 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) | ||
545 | cpu_relax(); | ||
546 | |||
547 | while (drv_data->tx < drv_data->tx_end) { | 483 | while (drv_data->tx < drv_data->tx_end) { |
548 | cs_active(drv_data, chip); | 484 | cs_active(drv_data, chip); |
549 | 485 | ||
550 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); | 486 | write_TDBR(drv_data, (*(u16 *) (drv_data->tx))); |
551 | while (read_STAT(drv_data) & BIT_STAT_TXS) | 487 | while (!(read_STAT(drv_data) & BIT_STAT_SPIF)) |
552 | cpu_relax(); | 488 | cpu_relax(); |
553 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) | 489 | while (!(read_STAT(drv_data) & BIT_STAT_RXS)) |
554 | cpu_relax(); | 490 | cpu_relax(); |
@@ -616,7 +552,7 @@ static void giveback(struct driver_data *drv_data) | |||
616 | 552 | ||
617 | static irqreturn_t dma_irq_handler(int irq, void *dev_id) | 553 | static irqreturn_t dma_irq_handler(int irq, void *dev_id) |
618 | { | 554 | { |
619 | struct driver_data *drv_data = (struct driver_data *)dev_id; | 555 | struct driver_data *drv_data = dev_id; |
620 | struct chip_data *chip = drv_data->cur_chip; | 556 | struct chip_data *chip = drv_data->cur_chip; |
621 | struct spi_message *msg = drv_data->cur_msg; | 557 | struct spi_message *msg = drv_data->cur_msg; |
622 | 558 | ||
@@ -978,10 +914,7 @@ static void pump_messages(struct work_struct *work) | |||
978 | 914 | ||
979 | /* Setup the SSP using the per chip configuration */ | 915 | /* Setup the SSP using the per chip configuration */ |
980 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); | 916 | drv_data->cur_chip = spi_get_ctldata(drv_data->cur_msg->spi); |
981 | if (restore_state(drv_data)) { | 917 | restore_state(drv_data); |
982 | spin_unlock_irqrestore(&drv_data->lock, flags); | ||
983 | return; | ||
984 | }; | ||
985 | 918 | ||
986 | list_del_init(&drv_data->cur_msg->queue); | 919 | list_del_init(&drv_data->cur_msg->queue); |
987 | 920 | ||
@@ -1187,7 +1120,7 @@ static int setup(struct spi_device *spi) | |||
1187 | if ((chip->chip_select_num > 0) | 1120 | if ((chip->chip_select_num > 0) |
1188 | && (chip->chip_select_num <= spi->master->num_chipselect)) | 1121 | && (chip->chip_select_num <= spi->master->num_chipselect)) |
1189 | peripheral_request(ssel[spi->master->bus_num] | 1122 | peripheral_request(ssel[spi->master->bus_num] |
1190 | [chip->chip_select_num-1], DRV_NAME); | 1123 | [chip->chip_select_num-1], spi->modalias); |
1191 | 1124 | ||
1192 | cs_deactive(drv_data, chip); | 1125 | cs_deactive(drv_data, chip); |
1193 | 1126 | ||
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c index 639963eb1ac1..1b0647124933 100644 --- a/drivers/spi/spi_imx.c +++ b/drivers/spi/spi_imx.c | |||
@@ -1686,17 +1686,6 @@ static void spi_imx_shutdown(struct platform_device *pdev) | |||
1686 | } | 1686 | } |
1687 | 1687 | ||
1688 | #ifdef CONFIG_PM | 1688 | #ifdef CONFIG_PM |
1689 | static int suspend_devices(struct device *dev, void *pm_message) | ||
1690 | { | ||
1691 | pm_message_t *state = pm_message; | ||
1692 | |||
1693 | if (dev->power.power_state.event != state->event) { | ||
1694 | dev_warn(dev, "pm state does not match request\n"); | ||
1695 | return -1; | ||
1696 | } | ||
1697 | |||
1698 | return 0; | ||
1699 | } | ||
1700 | 1689 | ||
1701 | static int spi_imx_suspend(struct platform_device *pdev, pm_message_t state) | 1690 | static int spi_imx_suspend(struct platform_device *pdev, pm_message_t state) |
1702 | { | 1691 | { |
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c index 89d6685a5ca4..6e834b8b9d27 100644 --- a/drivers/spi/spi_s3c24xx.c +++ b/drivers/spi/spi_s3c24xx.c | |||
@@ -237,10 +237,8 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
237 | { | 237 | { |
238 | struct s3c24xx_spi *hw; | 238 | struct s3c24xx_spi *hw; |
239 | struct spi_master *master; | 239 | struct spi_master *master; |
240 | struct spi_board_info *bi; | ||
241 | struct resource *res; | 240 | struct resource *res; |
242 | int err = 0; | 241 | int err = 0; |
243 | int i; | ||
244 | 242 | ||
245 | master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); | 243 | master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); |
246 | if (master == NULL) { | 244 | if (master == NULL) { |
@@ -348,16 +346,6 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev) | |||
348 | goto err_register; | 346 | goto err_register; |
349 | } | 347 | } |
350 | 348 | ||
351 | /* register all the devices associated */ | ||
352 | |||
353 | bi = &hw->pdata->board_info[0]; | ||
354 | for (i = 0; i < hw->pdata->board_size; i++, bi++) { | ||
355 | dev_info(hw->dev, "registering %s\n", bi->modalias); | ||
356 | |||
357 | bi->controller_data = hw; | ||
358 | spi_new_device(master, bi); | ||
359 | } | ||
360 | |||
361 | return 0; | 349 | return 0; |
362 | 350 | ||
363 | err_register: | 351 | err_register: |
diff --git a/drivers/spi/spi_s3c24xx_gpio.c b/drivers/spi/spi_s3c24xx_gpio.c index 109d82c1abc0..82ae7d7eca38 100644 --- a/drivers/spi/spi_s3c24xx_gpio.c +++ b/drivers/spi/spi_s3c24xx_gpio.c | |||
@@ -100,7 +100,6 @@ static int s3c2410_spigpio_probe(struct platform_device *dev) | |||
100 | struct spi_master *master; | 100 | struct spi_master *master; |
101 | struct s3c2410_spigpio *sp; | 101 | struct s3c2410_spigpio *sp; |
102 | int ret; | 102 | int ret; |
103 | int i; | ||
104 | 103 | ||
105 | master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio)); | 104 | master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio)); |
106 | if (master == NULL) { | 105 | if (master == NULL) { |
@@ -143,17 +142,6 @@ static int s3c2410_spigpio_probe(struct platform_device *dev) | |||
143 | if (ret) | 142 | if (ret) |
144 | goto err_no_bitbang; | 143 | goto err_no_bitbang; |
145 | 144 | ||
146 | /* register the chips to go with the board */ | ||
147 | |||
148 | for (i = 0; i < sp->info->board_size; i++) { | ||
149 | dev_info(&dev->dev, "registering %p: %s\n", | ||
150 | &sp->info->board_info[i], | ||
151 | sp->info->board_info[i].modalias); | ||
152 | |||
153 | sp->info->board_info[i].controller_data = sp; | ||
154 | spi_new_device(master, sp->info->board_info + i); | ||
155 | } | ||
156 | |||
157 | return 0; | 145 | return 0; |
158 | 146 | ||
159 | err_no_bitbang: | 147 | err_no_bitbang: |
diff --git a/drivers/spi/spi_sh_sci.c b/drivers/spi/spi_sh_sci.c new file mode 100644 index 000000000000..3dbe71b16d60 --- /dev/null +++ b/drivers/spi/spi_sh_sci.c | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * SH SCI SPI interface | ||
3 | * | ||
4 | * Copyright (c) 2008 Magnus Damm | ||
5 | * | ||
6 | * Based on S3C24XX GPIO based SPI driver, which is: | ||
7 | * Copyright (c) 2006 Ben Dooks | ||
8 | * Copyright (c) 2006 Simtec Electronics | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/delay.h> | ||
19 | #include <linux/spinlock.h> | ||
20 | #include <linux/workqueue.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | |||
23 | #include <linux/spi/spi.h> | ||
24 | #include <linux/spi/spi_bitbang.h> | ||
25 | |||
26 | #include <asm/spi.h> | ||
27 | #include <asm/io.h> | ||
28 | |||
29 | struct sh_sci_spi { | ||
30 | struct spi_bitbang bitbang; | ||
31 | |||
32 | void __iomem *membase; | ||
33 | unsigned char val; | ||
34 | struct sh_spi_info *info; | ||
35 | struct platform_device *dev; | ||
36 | }; | ||
37 | |||
38 | #define SCSPTR(sp) (sp->membase + 0x1c) | ||
39 | #define PIN_SCK (1 << 2) | ||
40 | #define PIN_TXD (1 << 0) | ||
41 | #define PIN_RXD PIN_TXD | ||
42 | #define PIN_INIT ((1 << 1) | (1 << 3) | PIN_SCK | PIN_TXD) | ||
43 | |||
44 | static inline void setbits(struct sh_sci_spi *sp, int bits, int on) | ||
45 | { | ||
46 | /* | ||
47 | * We are the only user of SCSPTR so no locking is required. | ||
48 | * Reading bit 2 and 0 in SCSPTR gives pin state as input. | ||
49 | * Writing the same bits sets the output value. | ||
50 | * This makes regular read-modify-write difficult so we | ||
51 | * use sp->val to keep track of the latest register value. | ||
52 | */ | ||
53 | |||
54 | if (on) | ||
55 | sp->val |= bits; | ||
56 | else | ||
57 | sp->val &= ~bits; | ||
58 | |||
59 | iowrite8(sp->val, SCSPTR(sp)); | ||
60 | } | ||
61 | |||
62 | static inline void setsck(struct spi_device *dev, int on) | ||
63 | { | ||
64 | setbits(spi_master_get_devdata(dev->master), PIN_SCK, on); | ||
65 | } | ||
66 | |||
67 | static inline void setmosi(struct spi_device *dev, int on) | ||
68 | { | ||
69 | setbits(spi_master_get_devdata(dev->master), PIN_TXD, on); | ||
70 | } | ||
71 | |||
72 | static inline u32 getmiso(struct spi_device *dev) | ||
73 | { | ||
74 | struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); | ||
75 | |||
76 | return (ioread8(SCSPTR(sp)) & PIN_RXD) ? 1 : 0; | ||
77 | } | ||
78 | |||
79 | #define spidelay(x) ndelay(x) | ||
80 | |||
81 | #define EXPAND_BITBANG_TXRX | ||
82 | #include <linux/spi/spi_bitbang.h> | ||
83 | |||
84 | static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, | ||
85 | unsigned nsecs, u32 word, u8 bits) | ||
86 | { | ||
87 | return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits); | ||
88 | } | ||
89 | |||
90 | static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, | ||
91 | unsigned nsecs, u32 word, u8 bits) | ||
92 | { | ||
93 | return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits); | ||
94 | } | ||
95 | |||
96 | static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, | ||
97 | unsigned nsecs, u32 word, u8 bits) | ||
98 | { | ||
99 | return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits); | ||
100 | } | ||
101 | |||
102 | static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, | ||
103 | unsigned nsecs, u32 word, u8 bits) | ||
104 | { | ||
105 | return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits); | ||
106 | } | ||
107 | |||
108 | static void sh_sci_spi_chipselect(struct spi_device *dev, int value) | ||
109 | { | ||
110 | struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); | ||
111 | |||
112 | if (sp->info && sp->info->chip_select) | ||
113 | (sp->info->chip_select)(sp->info, dev->chip_select, value); | ||
114 | } | ||
115 | |||
116 | static int sh_sci_spi_probe(struct platform_device *dev) | ||
117 | { | ||
118 | struct resource *r; | ||
119 | struct spi_master *master; | ||
120 | struct sh_sci_spi *sp; | ||
121 | int ret; | ||
122 | |||
123 | master = spi_alloc_master(&dev->dev, sizeof(struct sh_sci_spi)); | ||
124 | if (master == NULL) { | ||
125 | dev_err(&dev->dev, "failed to allocate spi master\n"); | ||
126 | ret = -ENOMEM; | ||
127 | goto err0; | ||
128 | } | ||
129 | |||
130 | sp = spi_master_get_devdata(master); | ||
131 | |||
132 | platform_set_drvdata(dev, sp); | ||
133 | sp->info = dev->dev.platform_data; | ||
134 | |||
135 | /* setup spi bitbang adaptor */ | ||
136 | sp->bitbang.master = spi_master_get(master); | ||
137 | sp->bitbang.master->bus_num = sp->info->bus_num; | ||
138 | sp->bitbang.master->num_chipselect = sp->info->num_chipselect; | ||
139 | sp->bitbang.chipselect = sh_sci_spi_chipselect; | ||
140 | |||
141 | sp->bitbang.txrx_word[SPI_MODE_0] = sh_sci_spi_txrx_mode0; | ||
142 | sp->bitbang.txrx_word[SPI_MODE_1] = sh_sci_spi_txrx_mode1; | ||
143 | sp->bitbang.txrx_word[SPI_MODE_2] = sh_sci_spi_txrx_mode2; | ||
144 | sp->bitbang.txrx_word[SPI_MODE_3] = sh_sci_spi_txrx_mode3; | ||
145 | |||
146 | r = platform_get_resource(dev, IORESOURCE_MEM, 0); | ||
147 | if (r == NULL) { | ||
148 | ret = -ENOENT; | ||
149 | goto err1; | ||
150 | } | ||
151 | sp->membase = ioremap(r->start, r->end - r->start + 1); | ||
152 | if (!sp->membase) { | ||
153 | ret = -ENXIO; | ||
154 | goto err1; | ||
155 | } | ||
156 | sp->val = ioread8(SCSPTR(sp)); | ||
157 | setbits(sp, PIN_INIT, 1); | ||
158 | |||
159 | ret = spi_bitbang_start(&sp->bitbang); | ||
160 | if (!ret) | ||
161 | return 0; | ||
162 | |||
163 | setbits(sp, PIN_INIT, 0); | ||
164 | iounmap(sp->membase); | ||
165 | err1: | ||
166 | spi_master_put(sp->bitbang.master); | ||
167 | err0: | ||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | static int sh_sci_spi_remove(struct platform_device *dev) | ||
172 | { | ||
173 | struct sh_sci_spi *sp = platform_get_drvdata(dev); | ||
174 | |||
175 | iounmap(sp->membase); | ||
176 | setbits(sp, PIN_INIT, 0); | ||
177 | spi_bitbang_stop(&sp->bitbang); | ||
178 | spi_master_put(sp->bitbang.master); | ||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct platform_driver sh_sci_spi_drv = { | ||
183 | .probe = sh_sci_spi_probe, | ||
184 | .remove = sh_sci_spi_remove, | ||
185 | .driver = { | ||
186 | .name = "spi_sh_sci", | ||
187 | .owner = THIS_MODULE, | ||
188 | }, | ||
189 | }; | ||
190 | |||
191 | static int __init sh_sci_spi_init(void) | ||
192 | { | ||
193 | return platform_driver_register(&sh_sci_spi_drv); | ||
194 | } | ||
195 | module_init(sh_sci_spi_init); | ||
196 | |||
197 | static void __exit sh_sci_spi_exit(void) | ||
198 | { | ||
199 | platform_driver_unregister(&sh_sci_spi_drv); | ||
200 | } | ||
201 | module_exit(sh_sci_spi_exit); | ||
202 | |||
203 | MODULE_DESCRIPTION("SH SCI SPI Driver"); | ||
204 | MODULE_AUTHOR("Magnus Damm <damm@opensource.se>"); | ||
205 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index cc246faa3590..2a77e9d42c68 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -417,30 +417,28 @@ static void uio_vma_close(struct vm_area_struct *vma) | |||
417 | idev->vma_count--; | 417 | idev->vma_count--; |
418 | } | 418 | } |
419 | 419 | ||
420 | static struct page *uio_vma_nopage(struct vm_area_struct *vma, | 420 | static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
421 | unsigned long address, int *type) | ||
422 | { | 421 | { |
423 | struct uio_device *idev = vma->vm_private_data; | 422 | struct uio_device *idev = vma->vm_private_data; |
424 | struct page* page = NOPAGE_SIGBUS; | 423 | struct page *page; |
425 | 424 | ||
426 | int mi = uio_find_mem_index(vma); | 425 | int mi = uio_find_mem_index(vma); |
427 | if (mi < 0) | 426 | if (mi < 0) |
428 | return page; | 427 | return VM_FAULT_SIGBUS; |
429 | 428 | ||
430 | if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) | 429 | if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL) |
431 | page = virt_to_page(idev->info->mem[mi].addr); | 430 | page = virt_to_page(idev->info->mem[mi].addr); |
432 | else | 431 | else |
433 | page = vmalloc_to_page((void*)idev->info->mem[mi].addr); | 432 | page = vmalloc_to_page((void*)idev->info->mem[mi].addr); |
434 | get_page(page); | 433 | get_page(page); |
435 | if (type) | 434 | vmf->page = page; |
436 | *type = VM_FAULT_MINOR; | 435 | return 0; |
437 | return page; | ||
438 | } | 436 | } |
439 | 437 | ||
440 | static struct vm_operations_struct uio_vm_ops = { | 438 | static struct vm_operations_struct uio_vm_ops = { |
441 | .open = uio_vma_open, | 439 | .open = uio_vma_open, |
442 | .close = uio_vma_close, | 440 | .close = uio_vma_close, |
443 | .nopage = uio_vma_nopage, | 441 | .fault = uio_vma_fault, |
444 | }; | 442 | }; |
445 | 443 | ||
446 | static int uio_mmap_physical(struct vm_area_struct *vma) | 444 | static int uio_mmap_physical(struct vm_area_struct *vma) |
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index f8e711147501..fc65c02306dd 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/fb.h> | 16 | #include <linux/fb.h> |
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/delay.h> | 18 | #include <linux/delay.h> |
19 | #include <linux/backlight.h> | ||
19 | 20 | ||
20 | #include <asm/arch/board.h> | 21 | #include <asm/arch/board.h> |
21 | #include <asm/arch/cpu.h> | 22 | #include <asm/arch/cpu.h> |
@@ -69,6 +70,107 @@ static void atmel_lcdfb_update_dma2d(struct atmel_lcdfb_info *sinfo, | |||
69 | } | 70 | } |
70 | #endif | 71 | #endif |
71 | 72 | ||
73 | static const u32 contrast_ctr = ATMEL_LCDC_PS_DIV8 | ||
74 | | ATMEL_LCDC_POL_POSITIVE | ||
75 | | ATMEL_LCDC_ENA_PWMENABLE; | ||
76 | |||
77 | #ifdef CONFIG_BACKLIGHT_ATMEL_LCDC | ||
78 | |||
79 | /* some bl->props field just changed */ | ||
80 | static int atmel_bl_update_status(struct backlight_device *bl) | ||
81 | { | ||
82 | struct atmel_lcdfb_info *sinfo = bl_get_data(bl); | ||
83 | int power = sinfo->bl_power; | ||
84 | int brightness = bl->props.brightness; | ||
85 | |||
86 | /* REVISIT there may be a meaningful difference between | ||
87 | * fb_blank and power ... there seem to be some cases | ||
88 | * this doesn't handle correctly. | ||
89 | */ | ||
90 | if (bl->props.fb_blank != sinfo->bl_power) | ||
91 | power = bl->props.fb_blank; | ||
92 | else if (bl->props.power != sinfo->bl_power) | ||
93 | power = bl->props.power; | ||
94 | |||
95 | if (brightness < 0 && power == FB_BLANK_UNBLANK) | ||
96 | brightness = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); | ||
97 | else if (power != FB_BLANK_UNBLANK) | ||
98 | brightness = 0; | ||
99 | |||
100 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, brightness); | ||
101 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, | ||
102 | brightness ? contrast_ctr : 0); | ||
103 | |||
104 | bl->props.fb_blank = bl->props.power = sinfo->bl_power = power; | ||
105 | |||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static int atmel_bl_get_brightness(struct backlight_device *bl) | ||
110 | { | ||
111 | struct atmel_lcdfb_info *sinfo = bl_get_data(bl); | ||
112 | |||
113 | return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); | ||
114 | } | ||
115 | |||
116 | static struct backlight_ops atmel_lcdc_bl_ops = { | ||
117 | .update_status = atmel_bl_update_status, | ||
118 | .get_brightness = atmel_bl_get_brightness, | ||
119 | }; | ||
120 | |||
121 | static void init_backlight(struct atmel_lcdfb_info *sinfo) | ||
122 | { | ||
123 | struct backlight_device *bl; | ||
124 | |||
125 | sinfo->bl_power = FB_BLANK_UNBLANK; | ||
126 | |||
127 | if (sinfo->backlight) | ||
128 | return; | ||
129 | |||
130 | bl = backlight_device_register("backlight", &sinfo->pdev->dev, | ||
131 | sinfo, &atmel_lcdc_bl_ops); | ||
132 | if (IS_ERR(sinfo->backlight)) { | ||
133 | dev_err(&sinfo->pdev->dev, "error %ld on backlight register\n", | ||
134 | PTR_ERR(bl)); | ||
135 | return; | ||
136 | } | ||
137 | sinfo->backlight = bl; | ||
138 | |||
139 | bl->props.power = FB_BLANK_UNBLANK; | ||
140 | bl->props.fb_blank = FB_BLANK_UNBLANK; | ||
141 | bl->props.max_brightness = 0xff; | ||
142 | bl->props.brightness = atmel_bl_get_brightness(bl); | ||
143 | } | ||
144 | |||
145 | static void exit_backlight(struct atmel_lcdfb_info *sinfo) | ||
146 | { | ||
147 | if (sinfo->backlight) | ||
148 | backlight_device_unregister(sinfo->backlight); | ||
149 | } | ||
150 | |||
151 | #else | ||
152 | |||
153 | static void init_backlight(struct atmel_lcdfb_info *sinfo) | ||
154 | { | ||
155 | dev_warn(&sinfo->pdev->dev, "backlight control is not available\n"); | ||
156 | } | ||
157 | |||
158 | static void exit_backlight(struct atmel_lcdfb_info *sinfo) | ||
159 | { | ||
160 | } | ||
161 | |||
162 | #endif | ||
163 | |||
164 | static void init_contrast(struct atmel_lcdfb_info *sinfo) | ||
165 | { | ||
166 | /* have some default contrast/backlight settings */ | ||
167 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr); | ||
168 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); | ||
169 | |||
170 | if (sinfo->lcdcon_is_backlight) | ||
171 | init_backlight(sinfo); | ||
172 | } | ||
173 | |||
72 | 174 | ||
73 | static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { | 175 | static struct fb_fix_screeninfo atmel_lcdfb_fix __initdata = { |
74 | .type = FB_TYPE_PACKED_PIXELS, | 176 | .type = FB_TYPE_PACKED_PIXELS, |
@@ -203,6 +305,26 @@ static int atmel_lcdfb_check_var(struct fb_var_screeninfo *var, | |||
203 | var->transp.offset = var->transp.length = 0; | 305 | var->transp.offset = var->transp.length = 0; |
204 | var->xoffset = var->yoffset = 0; | 306 | var->xoffset = var->yoffset = 0; |
205 | 307 | ||
308 | /* Saturate vertical and horizontal timings at maximum values */ | ||
309 | var->vsync_len = min_t(u32, var->vsync_len, | ||
310 | (ATMEL_LCDC_VPW >> ATMEL_LCDC_VPW_OFFSET) + 1); | ||
311 | var->upper_margin = min_t(u32, var->upper_margin, | ||
312 | ATMEL_LCDC_VBP >> ATMEL_LCDC_VBP_OFFSET); | ||
313 | var->lower_margin = min_t(u32, var->lower_margin, | ||
314 | ATMEL_LCDC_VFP); | ||
315 | var->right_margin = min_t(u32, var->right_margin, | ||
316 | (ATMEL_LCDC_HFP >> ATMEL_LCDC_HFP_OFFSET) + 1); | ||
317 | var->hsync_len = min_t(u32, var->hsync_len, | ||
318 | (ATMEL_LCDC_HPW >> ATMEL_LCDC_HPW_OFFSET) + 1); | ||
319 | var->left_margin = min_t(u32, var->left_margin, | ||
320 | ATMEL_LCDC_HBP + 1); | ||
321 | |||
322 | /* Some parameters can't be zero */ | ||
323 | var->vsync_len = max_t(u32, var->vsync_len, 1); | ||
324 | var->right_margin = max_t(u32, var->right_margin, 1); | ||
325 | var->hsync_len = max_t(u32, var->hsync_len, 1); | ||
326 | var->left_margin = max_t(u32, var->left_margin, 1); | ||
327 | |||
206 | switch (var->bits_per_pixel) { | 328 | switch (var->bits_per_pixel) { |
207 | case 1: | 329 | case 1: |
208 | case 2: | 330 | case 2: |
@@ -370,10 +492,6 @@ static int atmel_lcdfb_set_par(struct fb_info *info) | |||
370 | /* Disable all interrupts */ | 492 | /* Disable all interrupts */ |
371 | lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); | 493 | lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL); |
372 | 494 | ||
373 | /* Set contrast */ | ||
374 | value = ATMEL_LCDC_PS_DIV8 | ATMEL_LCDC_POL_POSITIVE | ATMEL_LCDC_ENA_PWMENABLE; | ||
375 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, value); | ||
376 | lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_VAL, ATMEL_LCDC_CVAL_DEFAULT); | ||
377 | /* ...wait for DMA engine to become idle... */ | 495 | /* ...wait for DMA engine to become idle... */ |
378 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) | 496 | while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY) |
379 | msleep(10); | 497 | msleep(10); |
@@ -577,6 +695,7 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
577 | sinfo->default_monspecs = pdata_sinfo->default_monspecs; | 695 | sinfo->default_monspecs = pdata_sinfo->default_monspecs; |
578 | sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; | 696 | sinfo->atmel_lcdfb_power_control = pdata_sinfo->atmel_lcdfb_power_control; |
579 | sinfo->guard_time = pdata_sinfo->guard_time; | 697 | sinfo->guard_time = pdata_sinfo->guard_time; |
698 | sinfo->lcdcon_is_backlight = pdata_sinfo->lcdcon_is_backlight; | ||
580 | } else { | 699 | } else { |
581 | dev_err(dev, "cannot get default configuration\n"); | 700 | dev_err(dev, "cannot get default configuration\n"); |
582 | goto free_info; | 701 | goto free_info; |
@@ -670,6 +789,9 @@ static int __init atmel_lcdfb_probe(struct platform_device *pdev) | |||
670 | goto release_mem; | 789 | goto release_mem; |
671 | } | 790 | } |
672 | 791 | ||
792 | /* Initialize PWM for contrast or backlight ("off") */ | ||
793 | init_contrast(sinfo); | ||
794 | |||
673 | /* interrupt */ | 795 | /* interrupt */ |
674 | ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info); | 796 | ret = request_irq(sinfo->irq_base, atmel_lcdfb_interrupt, 0, pdev->name, info); |
675 | if (ret) { | 797 | if (ret) { |
@@ -721,6 +843,7 @@ free_cmap: | |||
721 | unregister_irqs: | 843 | unregister_irqs: |
722 | free_irq(sinfo->irq_base, info); | 844 | free_irq(sinfo->irq_base, info); |
723 | unmap_mmio: | 845 | unmap_mmio: |
846 | exit_backlight(sinfo); | ||
724 | iounmap(sinfo->mmio); | 847 | iounmap(sinfo->mmio); |
725 | release_mem: | 848 | release_mem: |
726 | release_mem_region(info->fix.mmio_start, info->fix.mmio_len); | 849 | release_mem_region(info->fix.mmio_start, info->fix.mmio_len); |
@@ -755,6 +878,7 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) | |||
755 | if (!sinfo) | 878 | if (!sinfo) |
756 | return 0; | 879 | return 0; |
757 | 880 | ||
881 | exit_backlight(sinfo); | ||
758 | if (sinfo->atmel_lcdfb_power_control) | 882 | if (sinfo->atmel_lcdfb_power_control) |
759 | sinfo->atmel_lcdfb_power_control(0); | 883 | sinfo->atmel_lcdfb_power_control(0); |
760 | unregister_framebuffer(info); | 884 | unregister_framebuffer(info); |
@@ -781,6 +905,9 @@ static int __exit atmel_lcdfb_remove(struct platform_device *pdev) | |||
781 | 905 | ||
782 | static struct platform_driver atmel_lcdfb_driver = { | 906 | static struct platform_driver atmel_lcdfb_driver = { |
783 | .remove = __exit_p(atmel_lcdfb_remove), | 907 | .remove = __exit_p(atmel_lcdfb_remove), |
908 | |||
909 | // FIXME need suspend, resume | ||
910 | |||
784 | .driver = { | 911 | .driver = { |
785 | .name = "atmel_lcdfb", | 912 | .name = "atmel_lcdfb", |
786 | .owner = THIS_MODULE, | 913 | .owner = THIS_MODULE, |
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 9609a6c676be..924e2551044a 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig | |||
@@ -50,6 +50,19 @@ config BACKLIGHT_CLASS_DEVICE | |||
50 | To have support for your specific LCD panel you will have to | 50 | To have support for your specific LCD panel you will have to |
51 | select the proper drivers which depend on this option. | 51 | select the proper drivers which depend on this option. |
52 | 52 | ||
53 | config BACKLIGHT_ATMEL_LCDC | ||
54 | bool "Atmel LCDC Contrast-as-Backlight control" | ||
55 | depends on BACKLIGHT_CLASS_DEVICE && FB_ATMEL | ||
56 | default y if MACH_SAM9261EK || MACH_SAM9263EK | ||
57 | help | ||
58 | This provides a backlight control internal to the Atmel LCDC | ||
59 | driver. If the LCD "contrast control" on your board is wired | ||
60 | so it controls the backlight brightness, select this option to | ||
61 | export this as a PWM-based backlight control. | ||
62 | |||
63 | If in doubt, it's safe to enable this option; it doesn't kick | ||
64 | in unless the board's description says it's wired that way. | ||
65 | |||
53 | config BACKLIGHT_CORGI | 66 | config BACKLIGHT_CORGI |
54 | tristate "Generic (aka Sharp Corgi) Backlight Driver" | 67 | tristate "Generic (aka Sharp Corgi) Backlight Driver" |
55 | depends on BACKLIGHT_CLASS_DEVICE | 68 | depends on BACKLIGHT_CLASS_DEVICE |
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c index c8e7427a0bc8..0ce791e6f79c 100644 --- a/drivers/video/bf54x-lq043fb.c +++ b/drivers/video/bf54x-lq043fb.c | |||
@@ -498,8 +498,7 @@ static struct lcd_device *lcd_dev; | |||
498 | 498 | ||
499 | static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) | 499 | static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id) |
500 | { | 500 | { |
501 | 501 | /*struct bfin_bf54xfb_info *info = dev_id;*/ | |
502 | /*struct bfin_bf54xfb_info *info = (struct bfin_bf54xfb_info *)dev_id;*/ | ||
503 | 502 | ||
504 | u16 status = bfin_read_EPPI0_STATUS(); | 503 | u16 status = bfin_read_EPPI0_STATUS(); |
505 | 504 | ||
diff --git a/drivers/video/console/bitblit.c b/drivers/video/console/bitblit.c index 308850df16fe..69864b1b3f9e 100644 --- a/drivers/video/console/bitblit.c +++ b/drivers/video/console/bitblit.c | |||
@@ -63,7 +63,7 @@ static void bit_clear(struct vc_data *vc, struct fb_info *info, int sy, | |||
63 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 63 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
64 | struct fb_fillrect region; | 64 | struct fb_fillrect region; |
65 | 65 | ||
66 | region.color = attr_bgcol_ec(bgshift, vc); | 66 | region.color = attr_bgcol_ec(bgshift, vc, info); |
67 | region.dx = sx * vc->vc_font.width; | 67 | region.dx = sx * vc->vc_font.width; |
68 | region.dy = sy * vc->vc_font.height; | 68 | region.dy = sy * vc->vc_font.height; |
69 | region.width = width * vc->vc_font.width; | 69 | region.width = width * vc->vc_font.width; |
@@ -213,7 +213,7 @@ static void bit_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
213 | unsigned int bs = info->var.yres - bh; | 213 | unsigned int bs = info->var.yres - bh; |
214 | struct fb_fillrect region; | 214 | struct fb_fillrect region; |
215 | 215 | ||
216 | region.color = attr_bgcol_ec(bgshift, vc); | 216 | region.color = attr_bgcol_ec(bgshift, vc, info); |
217 | region.rop = ROP_COPY; | 217 | region.rop = ROP_COPY; |
218 | 218 | ||
219 | if (rw && !bottom_only) { | 219 | if (rw && !bottom_only) { |
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 0f32f4a00b2d..022282494d3f 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #ifdef CONFIG_MAC | 84 | #ifdef CONFIG_MAC |
85 | #include <asm/macints.h> | 85 | #include <asm/macints.h> |
86 | #endif | 86 | #endif |
87 | #if defined(__mc68000__) || defined(CONFIG_APUS) | 87 | #if defined(__mc68000__) |
88 | #include <asm/machdep.h> | 88 | #include <asm/machdep.h> |
89 | #include <asm/setup.h> | 89 | #include <asm/setup.h> |
90 | #endif | 90 | #endif |
@@ -147,7 +147,7 @@ static char fontname[40]; | |||
147 | static int info_idx = -1; | 147 | static int info_idx = -1; |
148 | 148 | ||
149 | /* console rotation */ | 149 | /* console rotation */ |
150 | static int rotate; | 150 | static int initial_rotation; |
151 | static int fbcon_has_sysfs; | 151 | static int fbcon_has_sysfs; |
152 | 152 | ||
153 | static const struct consw fb_con; | 153 | static const struct consw fb_con; |
@@ -334,10 +334,7 @@ static inline int get_color(struct vc_data *vc, struct fb_info *info, | |||
334 | switch (depth) { | 334 | switch (depth) { |
335 | case 1: | 335 | case 1: |
336 | { | 336 | { |
337 | int col = ~(0xfff << (max(info->var.green.length, | 337 | int col = mono_col(info); |
338 | max(info->var.red.length, | ||
339 | info->var.blue.length)))) & 0xff; | ||
340 | |||
341 | /* 0 or 1 */ | 338 | /* 0 or 1 */ |
342 | int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0; | 339 | int fg = (info->fix.visual != FB_VISUAL_MONO01) ? col : 0; |
343 | int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col; | 340 | int bg = (info->fix.visual != FB_VISUAL_MONO01) ? 0 : col; |
@@ -537,9 +534,9 @@ static int __init fb_console_setup(char *this_opt) | |||
537 | if (!strncmp(options, "rotate:", 7)) { | 534 | if (!strncmp(options, "rotate:", 7)) { |
538 | options += 7; | 535 | options += 7; |
539 | if (*options) | 536 | if (*options) |
540 | rotate = simple_strtoul(options, &options, 0); | 537 | initial_rotation = simple_strtoul(options, &options, 0); |
541 | if (rotate > 3) | 538 | if (initial_rotation > 3) |
542 | rotate = 0; | 539 | initial_rotation = 0; |
543 | } | 540 | } |
544 | } | 541 | } |
545 | return 1; | 542 | return 1; |
@@ -989,7 +986,7 @@ static const char *fbcon_startup(void) | |||
989 | ops->graphics = 1; | 986 | ops->graphics = 1; |
990 | ops->cur_rotate = -1; | 987 | ops->cur_rotate = -1; |
991 | info->fbcon_par = ops; | 988 | info->fbcon_par = ops; |
992 | p->con_rotate = rotate; | 989 | p->con_rotate = initial_rotation; |
993 | set_blitting_type(vc, info); | 990 | set_blitting_type(vc, info); |
994 | 991 | ||
995 | if (info->fix.type != FB_TYPE_TEXT) { | 992 | if (info->fix.type != FB_TYPE_TEXT) { |
@@ -1176,7 +1173,7 @@ static void fbcon_init(struct vc_data *vc, int init) | |||
1176 | con_copy_unimap(vc, svc); | 1173 | con_copy_unimap(vc, svc); |
1177 | 1174 | ||
1178 | ops = info->fbcon_par; | 1175 | ops = info->fbcon_par; |
1179 | p->con_rotate = rotate; | 1176 | p->con_rotate = initial_rotation; |
1180 | set_blitting_type(vc, info); | 1177 | set_blitting_type(vc, info); |
1181 | 1178 | ||
1182 | cols = vc->vc_cols; | 1179 | cols = vc->vc_cols; |
@@ -2795,7 +2792,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2795 | { | 2792 | { |
2796 | struct fb_info *info = registered_fb[con2fb_map[fg_console]]; | 2793 | struct fb_info *info = registered_fb[con2fb_map[fg_console]]; |
2797 | struct fbcon_ops *ops = info->fbcon_par; | 2794 | struct fbcon_ops *ops = info->fbcon_par; |
2798 | struct display *p = &fb_display[fg_console]; | 2795 | struct display *disp = &fb_display[fg_console]; |
2799 | int offset, limit, scrollback_old; | 2796 | int offset, limit, scrollback_old; |
2800 | 2797 | ||
2801 | if (softback_top) { | 2798 | if (softback_top) { |
@@ -2833,7 +2830,7 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2833 | logo_shown = FBCON_LOGO_CANSHOW; | 2830 | logo_shown = FBCON_LOGO_CANSHOW; |
2834 | } | 2831 | } |
2835 | fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); | 2832 | fbcon_cursor(vc, CM_ERASE | CM_SOFTBACK); |
2836 | fbcon_redraw_softback(vc, p, lines); | 2833 | fbcon_redraw_softback(vc, disp, lines); |
2837 | fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); | 2834 | fbcon_cursor(vc, CM_DRAW | CM_SOFTBACK); |
2838 | return 0; | 2835 | return 0; |
2839 | } | 2836 | } |
@@ -2855,9 +2852,9 @@ static int fbcon_scrolldelta(struct vc_data *vc, int lines) | |||
2855 | 2852 | ||
2856 | fbcon_cursor(vc, CM_ERASE); | 2853 | fbcon_cursor(vc, CM_ERASE); |
2857 | 2854 | ||
2858 | offset = p->yscroll - scrollback_current; | 2855 | offset = disp->yscroll - scrollback_current; |
2859 | limit = p->vrows; | 2856 | limit = disp->vrows; |
2860 | switch (p->scrollmode) { | 2857 | switch (disp->scrollmode) { |
2861 | case SCROLL_WRAP_MOVE: | 2858 | case SCROLL_WRAP_MOVE: |
2862 | info->var.vmode |= FB_VMODE_YWRAP; | 2859 | info->var.vmode |= FB_VMODE_YWRAP; |
2863 | break; | 2860 | break; |
diff --git a/drivers/video/console/fbcon.h b/drivers/video/console/fbcon.h index 8e6ef4bc7a5c..3706307e70ed 100644 --- a/drivers/video/console/fbcon.h +++ b/drivers/video/console/fbcon.h | |||
@@ -93,10 +93,6 @@ struct fbcon_ops { | |||
93 | (((s) >> (fgshift)) & 0x0f) | 93 | (((s) >> (fgshift)) & 0x0f) |
94 | #define attr_bgcol(bgshift,s) \ | 94 | #define attr_bgcol(bgshift,s) \ |
95 | (((s) >> (bgshift)) & 0x0f) | 95 | (((s) >> (bgshift)) & 0x0f) |
96 | #define attr_bgcol_ec(bgshift,vc) \ | ||
97 | ((vc) ? (((vc)->vc_video_erase_char >> (bgshift)) & 0x0f) : 0) | ||
98 | #define attr_fgcol_ec(fgshift,vc) \ | ||
99 | ((vc) ? (((vc)->vc_video_erase_char >> (fgshift)) & 0x0f) : 0) | ||
100 | 96 | ||
101 | /* Monochrome */ | 97 | /* Monochrome */ |
102 | #define attr_bold(s) \ | 98 | #define attr_bold(s) \ |
@@ -108,6 +104,49 @@ struct fbcon_ops { | |||
108 | #define attr_blink(s) \ | 104 | #define attr_blink(s) \ |
109 | ((s) & 0x8000) | 105 | ((s) & 0x8000) |
110 | 106 | ||
107 | #define mono_col(info) \ | ||
108 | (~(0xfff << (max((info)->var.green.length, \ | ||
109 | max((info)->var.red.length, \ | ||
110 | (info)->var.blue.length)))) & 0xff) | ||
111 | |||
112 | static inline int attr_col_ec(int shift, struct vc_data *vc, | ||
113 | struct fb_info *info, int is_fg) | ||
114 | { | ||
115 | int is_mono01; | ||
116 | int col; | ||
117 | int fg; | ||
118 | int bg; | ||
119 | |||
120 | if (!vc) | ||
121 | return 0; | ||
122 | |||
123 | if (vc->vc_can_do_color) | ||
124 | return is_fg ? attr_fgcol(shift,vc->vc_video_erase_char) | ||
125 | : attr_bgcol(shift,vc->vc_video_erase_char); | ||
126 | |||
127 | if (!info) | ||
128 | return 0; | ||
129 | |||
130 | col = mono_col(info); | ||
131 | is_mono01 = info->fix.visual == FB_VISUAL_MONO01; | ||
132 | |||
133 | if (attr_reverse(vc->vc_video_erase_char)) { | ||
134 | fg = is_mono01 ? col : 0; | ||
135 | bg = is_mono01 ? 0 : col; | ||
136 | } | ||
137 | else { | ||
138 | fg = is_mono01 ? 0 : col; | ||
139 | bg = is_mono01 ? col : 0; | ||
140 | } | ||
141 | |||
142 | return is_fg ? fg : bg; | ||
143 | } | ||
144 | |||
145 | #define attr_bgcol_ec(bgshift,vc,info) \ | ||
146 | attr_col_ec(bgshift,vc,info,0); | ||
147 | #define attr_fgcol_ec(fgshift,vc,info) \ | ||
148 | attr_col_ec(fgshift,vc,info,1); | ||
149 | |||
111 | /* Font */ | 150 | /* Font */ |
112 | #define REFCOUNT(fd) (((int *)(fd))[-1]) | 151 | #define REFCOUNT(fd) (((int *)(fd))[-1]) |
113 | #define FNTSIZE(fd) (((int *)(fd))[-2]) | 152 | #define FNTSIZE(fd) (((int *)(fd))[-2]) |
diff --git a/drivers/video/console/fbcon_ccw.c b/drivers/video/console/fbcon_ccw.c index 825e6d6972a7..bdf913ecf001 100644 --- a/drivers/video/console/fbcon_ccw.c +++ b/drivers/video/console/fbcon_ccw.c | |||
@@ -84,7 +84,7 @@ static void ccw_clear(struct vc_data *vc, struct fb_info *info, int sy, | |||
84 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 84 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
85 | u32 vyres = GETVYRES(ops->p->scrollmode, info); | 85 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
86 | 86 | ||
87 | region.color = attr_bgcol_ec(bgshift,vc); | 87 | region.color = attr_bgcol_ec(bgshift,vc,info); |
88 | region.dx = sy * vc->vc_font.height; | 88 | region.dx = sy * vc->vc_font.height; |
89 | region.dy = vyres - ((sx + width) * vc->vc_font.width); | 89 | region.dy = vyres - ((sx + width) * vc->vc_font.width); |
90 | region.height = width * vc->vc_font.width; | 90 | region.height = width * vc->vc_font.width; |
@@ -198,7 +198,7 @@ static void ccw_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
198 | struct fb_fillrect region; | 198 | struct fb_fillrect region; |
199 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 199 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
200 | 200 | ||
201 | region.color = attr_bgcol_ec(bgshift,vc); | 201 | region.color = attr_bgcol_ec(bgshift,vc,info); |
202 | region.rop = ROP_COPY; | 202 | region.rop = ROP_COPY; |
203 | 203 | ||
204 | if (rw && !bottom_only) { | 204 | if (rw && !bottom_only) { |
diff --git a/drivers/video/console/fbcon_cw.c b/drivers/video/console/fbcon_cw.c index c637e6318803..a6819b9d1770 100644 --- a/drivers/video/console/fbcon_cw.c +++ b/drivers/video/console/fbcon_cw.c | |||
@@ -70,7 +70,7 @@ static void cw_clear(struct vc_data *vc, struct fb_info *info, int sy, | |||
70 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 70 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
71 | u32 vxres = GETVXRES(ops->p->scrollmode, info); | 71 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
72 | 72 | ||
73 | region.color = attr_bgcol_ec(bgshift,vc); | 73 | region.color = attr_bgcol_ec(bgshift,vc,info); |
74 | region.dx = vxres - ((sy + height) * vc->vc_font.height); | 74 | region.dx = vxres - ((sy + height) * vc->vc_font.height); |
75 | region.dy = sx * vc->vc_font.width; | 75 | region.dy = sx * vc->vc_font.width; |
76 | region.height = width * vc->vc_font.width; | 76 | region.height = width * vc->vc_font.width; |
@@ -182,7 +182,7 @@ static void cw_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
182 | struct fb_fillrect region; | 182 | struct fb_fillrect region; |
183 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 183 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
184 | 184 | ||
185 | region.color = attr_bgcol_ec(bgshift,vc); | 185 | region.color = attr_bgcol_ec(bgshift,vc,info); |
186 | region.rop = ROP_COPY; | 186 | region.rop = ROP_COPY; |
187 | 187 | ||
188 | if (rw && !bottom_only) { | 188 | if (rw && !bottom_only) { |
diff --git a/drivers/video/console/fbcon_ud.c b/drivers/video/console/fbcon_ud.c index 1473506df5d0..d9b5d6eb68a7 100644 --- a/drivers/video/console/fbcon_ud.c +++ b/drivers/video/console/fbcon_ud.c | |||
@@ -71,7 +71,7 @@ static void ud_clear(struct vc_data *vc, struct fb_info *info, int sy, | |||
71 | u32 vyres = GETVYRES(ops->p->scrollmode, info); | 71 | u32 vyres = GETVYRES(ops->p->scrollmode, info); |
72 | u32 vxres = GETVXRES(ops->p->scrollmode, info); | 72 | u32 vxres = GETVXRES(ops->p->scrollmode, info); |
73 | 73 | ||
74 | region.color = attr_bgcol_ec(bgshift,vc); | 74 | region.color = attr_bgcol_ec(bgshift,vc,info); |
75 | region.dy = vyres - ((sy + height) * vc->vc_font.height); | 75 | region.dy = vyres - ((sy + height) * vc->vc_font.height); |
76 | region.dx = vxres - ((sx + width) * vc->vc_font.width); | 76 | region.dx = vxres - ((sx + width) * vc->vc_font.width); |
77 | region.width = width * vc->vc_font.width; | 77 | region.width = width * vc->vc_font.width; |
@@ -228,7 +228,7 @@ static void ud_clear_margins(struct vc_data *vc, struct fb_info *info, | |||
228 | struct fb_fillrect region; | 228 | struct fb_fillrect region; |
229 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; | 229 | int bgshift = (vc->vc_hi_font_mask) ? 13 : 12; |
230 | 230 | ||
231 | region.color = attr_bgcol_ec(bgshift,vc); | 231 | region.color = attr_bgcol_ec(bgshift,vc,info); |
232 | region.rop = ROP_COPY; | 232 | region.rop = ROP_COPY; |
233 | 233 | ||
234 | if (rw && !bottom_only) { | 234 | if (rw && !bottom_only) { |
diff --git a/drivers/video/console/fonts.c b/drivers/video/console/fonts.c index 96979c377518..d0c03fd70871 100644 --- a/drivers/video/console/fonts.c +++ b/drivers/video/console/fonts.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #if defined(__mc68000__) || defined(CONFIG_APUS) | 18 | #if defined(__mc68000__) |
19 | #include <asm/setup.h> | 19 | #include <asm/setup.h> |
20 | #endif | 20 | #endif |
21 | #include <linux/font.h> | 21 | #include <linux/font.h> |
@@ -120,7 +120,7 @@ const struct font_desc *get_default_font(int xres, int yres, u32 font_w, | |||
120 | for(i=0; i<num_fonts; i++) { | 120 | for(i=0; i<num_fonts; i++) { |
121 | f = fonts[i]; | 121 | f = fonts[i]; |
122 | c = f->pref; | 122 | c = f->pref; |
123 | #if defined(__mc68000__) || defined(CONFIG_APUS) | 123 | #if defined(__mc68000__) |
124 | #ifdef CONFIG_FONT_PEARL_8x8 | 124 | #ifdef CONFIG_FONT_PEARL_8x8 |
125 | if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX) | 125 | if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX) |
126 | c = 100; | 126 | c = 100; |
diff --git a/drivers/video/console/tileblit.c b/drivers/video/console/tileblit.c index d981fe4d86c6..0056a41e5c35 100644 --- a/drivers/video/console/tileblit.c +++ b/drivers/video/console/tileblit.c | |||
@@ -40,8 +40,8 @@ static void tile_clear(struct vc_data *vc, struct fb_info *info, int sy, | |||
40 | 40 | ||
41 | rect.index = vc->vc_video_erase_char & | 41 | rect.index = vc->vc_video_erase_char & |
42 | ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); | 42 | ((vc->vc_hi_font_mask) ? 0x1ff : 0xff); |
43 | rect.fg = attr_fgcol_ec(fgshift, vc); | 43 | rect.fg = attr_fgcol_ec(fgshift, vc, info); |
44 | rect.bg = attr_bgcol_ec(bgshift, vc); | 44 | rect.bg = attr_bgcol_ec(bgshift, vc, info); |
45 | rect.sx = sx; | 45 | rect.sx = sx; |
46 | rect.sy = sy; | 46 | rect.sy = sy; |
47 | rect.width = width; | 47 | rect.width = width; |
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c index f65bcd314d54..6df29a62d720 100644 --- a/drivers/video/console/vgacon.c +++ b/drivers/video/console/vgacon.c | |||
@@ -1153,8 +1153,6 @@ static int vgacon_do_font_op(struct vgastate *state,char *arg,int set,int ch512) | |||
1153 | 1153 | ||
1154 | /* if 512 char mode is already enabled don't re-enable it. */ | 1154 | /* if 512 char mode is already enabled don't re-enable it. */ |
1155 | if ((set) && (ch512 != vga_512_chars)) { | 1155 | if ((set) && (ch512 != vga_512_chars)) { |
1156 | int i; | ||
1157 | |||
1158 | /* attribute controller */ | 1156 | /* attribute controller */ |
1159 | for (i = 0; i < MAX_NR_CONSOLES; i++) { | 1157 | for (i = 0; i < MAX_NR_CONSOLES; i++) { |
1160 | struct vc_data *c = vc_cons[i].d; | 1158 | struct vc_data *c = vc_cons[i].d; |
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c index a0c5d9d90d74..0f8cfb988c90 100644 --- a/drivers/video/fb_defio.c +++ b/drivers/video/fb_defio.c | |||
@@ -25,8 +25,8 @@ | |||
25 | #include <linux/pagemap.h> | 25 | #include <linux/pagemap.h> |
26 | 26 | ||
27 | /* this is to find and return the vmalloc-ed fb pages */ | 27 | /* this is to find and return the vmalloc-ed fb pages */ |
28 | static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma, | 28 | static int fb_deferred_io_fault(struct vm_area_struct *vma, |
29 | unsigned long vaddr, int *type) | 29 | struct vm_fault *vmf) |
30 | { | 30 | { |
31 | unsigned long offset; | 31 | unsigned long offset; |
32 | struct page *page; | 32 | struct page *page; |
@@ -34,18 +34,17 @@ static struct page* fb_deferred_io_nopage(struct vm_area_struct *vma, | |||
34 | /* info->screen_base is in System RAM */ | 34 | /* info->screen_base is in System RAM */ |
35 | void *screen_base = (void __force *) info->screen_base; | 35 | void *screen_base = (void __force *) info->screen_base; |
36 | 36 | ||
37 | offset = (vaddr - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | 37 | offset = vmf->pgoff << PAGE_SHIFT; |
38 | if (offset >= info->fix.smem_len) | 38 | if (offset >= info->fix.smem_len) |
39 | return NOPAGE_SIGBUS; | 39 | return VM_FAULT_SIGBUS; |
40 | 40 | ||
41 | page = vmalloc_to_page(screen_base + offset); | 41 | page = vmalloc_to_page(screen_base + offset); |
42 | if (!page) | 42 | if (!page) |
43 | return NOPAGE_OOM; | 43 | return VM_FAULT_SIGBUS; |
44 | 44 | ||
45 | get_page(page); | 45 | get_page(page); |
46 | if (type) | 46 | vmf->page = page; |
47 | *type = VM_FAULT_MINOR; | 47 | return 0; |
48 | return page; | ||
49 | } | 48 | } |
50 | 49 | ||
51 | int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) | 50 | int fb_deferred_io_fsync(struct file *file, struct dentry *dentry, int datasync) |
@@ -84,7 +83,7 @@ static int fb_deferred_io_mkwrite(struct vm_area_struct *vma, | |||
84 | } | 83 | } |
85 | 84 | ||
86 | static struct vm_operations_struct fb_deferred_io_vm_ops = { | 85 | static struct vm_operations_struct fb_deferred_io_vm_ops = { |
87 | .nopage = fb_deferred_io_nopage, | 86 | .fault = fb_deferred_io_fault, |
88 | .page_mkwrite = fb_deferred_io_mkwrite, | 87 | .page_mkwrite = fb_deferred_io_mkwrite, |
89 | }; | 88 | }; |
90 | 89 | ||
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h index cdafbe14ef1f..a2a0618d86a5 100644 --- a/drivers/video/fb_draw.h +++ b/drivers/video/fb_draw.h | |||
@@ -91,6 +91,7 @@ static inline unsigned long fb_rev_pixels_in_long(unsigned long val, | |||
91 | val = comp(val >> 2, val << 2, REV_PIXELS_MASK2); | 91 | val = comp(val >> 2, val << 2, REV_PIXELS_MASK2); |
92 | if (bswapmask & 3) | 92 | if (bswapmask & 3) |
93 | val = comp(val >> 4, val << 4, REV_PIXELS_MASK4); | 93 | val = comp(val >> 4, val << 4, REV_PIXELS_MASK4); |
94 | return val; | ||
94 | } | 95 | } |
95 | 96 | ||
96 | static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask) | 97 | static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask) |
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c index 4ba9c0894416..052e18058498 100644 --- a/drivers/video/fbmon.c +++ b/drivers/video/fbmon.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net> | 4 | * Copyright (C) 2002 James Simmons <jsimmons@users.sf.net> |
5 | * | 5 | * |
6 | * Credits: | 6 | * Credits: |
7 | * | 7 | * |
8 | * The EDID Parser is a conglomeration from the following sources: | 8 | * The EDID Parser is a conglomeration from the following sources: |
9 | * | 9 | * |
10 | * 1. SciTech SNAP Graphics Architecture | 10 | * 1. SciTech SNAP Graphics Architecture |
@@ -12,13 +12,13 @@ | |||
12 | * | 12 | * |
13 | * 2. XFree86 4.3.0, interpret_edid.c | 13 | * 2. XFree86 4.3.0, interpret_edid.c |
14 | * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> | 14 | * Copyright 1998 by Egbert Eich <Egbert.Eich@Physik.TU-Darmstadt.DE> |
15 | * | 15 | * |
16 | * 3. John Fremlin <vii@users.sourceforge.net> and | 16 | * 3. John Fremlin <vii@users.sourceforge.net> and |
17 | * Ani Joshi <ajoshi@unixbox.com> | 17 | * Ani Joshi <ajoshi@unixbox.com> |
18 | * | 18 | * |
19 | * Generalized Timing Formula is derived from: | 19 | * Generalized Timing Formula is derived from: |
20 | * | 20 | * |
21 | * GTF Spreadsheet by Andy Morrish (1/5/97) | 21 | * GTF Spreadsheet by Andy Morrish (1/5/97) |
22 | * available at http://www.vesa.org | 22 | * available at http://www.vesa.org |
23 | * | 23 | * |
24 | * This file is subject to the terms and conditions of the GNU General Public | 24 | * This file is subject to the terms and conditions of the GNU General Public |
@@ -36,7 +36,7 @@ | |||
36 | #endif | 36 | #endif |
37 | #include "edid.h" | 37 | #include "edid.h" |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * EDID parser | 40 | * EDID parser |
41 | */ | 41 | */ |
42 | 42 | ||
@@ -160,8 +160,8 @@ static int check_edid(unsigned char *edid) | |||
160 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { | 160 | for (i = 0; i < ARRAY_SIZE(brokendb); i++) { |
161 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && | 161 | if (!strncmp(manufacturer, brokendb[i].manufacturer, 4) && |
162 | brokendb[i].model == model) { | 162 | brokendb[i].model == model) { |
163 | fix = brokendb[i].fix; | 163 | fix = brokendb[i].fix; |
164 | break; | 164 | break; |
165 | } | 165 | } |
166 | } | 166 | } |
167 | 167 | ||
@@ -323,7 +323,7 @@ static void get_dpms_capabilities(unsigned char flags, | |||
323 | (flags & DPMS_SUSPEND) ? "yes" : "no", | 323 | (flags & DPMS_SUSPEND) ? "yes" : "no", |
324 | (flags & DPMS_STANDBY) ? "yes" : "no"); | 324 | (flags & DPMS_STANDBY) ? "yes" : "no"); |
325 | } | 325 | } |
326 | 326 | ||
327 | static void get_chroma(unsigned char *block, struct fb_monspecs *specs) | 327 | static void get_chroma(unsigned char *block, struct fb_monspecs *specs) |
328 | { | 328 | { |
329 | int tmp; | 329 | int tmp; |
@@ -365,7 +365,7 @@ static void get_chroma(unsigned char *block, struct fb_monspecs *specs) | |||
365 | tmp += 512; | 365 | tmp += 512; |
366 | specs->chroma.bluey = tmp/1024; | 366 | specs->chroma.bluey = tmp/1024; |
367 | DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); | 367 | DPRINTK("BlueY: 0.%03d\n", specs->chroma.bluey); |
368 | 368 | ||
369 | tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); | 369 | tmp = ((block[6] & (3 << 2)) >> 2) | (block[0xd] << 2); |
370 | tmp *= 1000; | 370 | tmp *= 1000; |
371 | tmp += 512; | 371 | tmp += 512; |
@@ -383,7 +383,7 @@ static void calc_mode_timings(int xres, int yres, int refresh, | |||
383 | struct fb_videomode *mode) | 383 | struct fb_videomode *mode) |
384 | { | 384 | { |
385 | struct fb_var_screeninfo *var; | 385 | struct fb_var_screeninfo *var; |
386 | 386 | ||
387 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); | 387 | var = kzalloc(sizeof(struct fb_var_screeninfo), GFP_KERNEL); |
388 | 388 | ||
389 | if (var) { | 389 | if (var) { |
@@ -451,11 +451,11 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) | |||
451 | 451 | ||
452 | c = block[1]; | 452 | c = block[1]; |
453 | if (c&0x80) { | 453 | if (c&0x80) { |
454 | mode[num++] = vesa_modes[9]; | 454 | mode[num++] = vesa_modes[9]; |
455 | DPRINTK(" 800x600@72Hz\n"); | 455 | DPRINTK(" 800x600@72Hz\n"); |
456 | } | 456 | } |
457 | if (c&0x40) { | 457 | if (c&0x40) { |
458 | mode[num++] = vesa_modes[10]; | 458 | mode[num++] = vesa_modes[10]; |
459 | DPRINTK(" 800x600@75Hz\n"); | 459 | DPRINTK(" 800x600@75Hz\n"); |
460 | } | 460 | } |
461 | if (c&0x20) { | 461 | if (c&0x20) { |
@@ -495,7 +495,7 @@ static int get_est_timing(unsigned char *block, struct fb_videomode *mode) | |||
495 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode) | 495 | static int get_std_timing(unsigned char *block, struct fb_videomode *mode) |
496 | { | 496 | { |
497 | int xres, yres = 0, refresh, ratio, i; | 497 | int xres, yres = 0, refresh, ratio, i; |
498 | 498 | ||
499 | xres = (block[0] + 31) * 8; | 499 | xres = (block[0] + 31) * 8; |
500 | if (xres <= 256) | 500 | if (xres <= 256) |
501 | return 0; | 501 | return 0; |
@@ -519,7 +519,7 @@ static int get_std_timing(unsigned char *block, struct fb_videomode *mode) | |||
519 | 519 | ||
520 | DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); | 520 | DPRINTK(" %dx%d@%dHz\n", xres, yres, refresh); |
521 | for (i = 0; i < VESA_MODEDB_SIZE; i++) { | 521 | for (i = 0; i < VESA_MODEDB_SIZE; i++) { |
522 | if (vesa_modes[i].xres == xres && | 522 | if (vesa_modes[i].xres == xres && |
523 | vesa_modes[i].yres == yres && | 523 | vesa_modes[i].yres == yres && |
524 | vesa_modes[i].refresh == refresh) { | 524 | vesa_modes[i].refresh == refresh) { |
525 | *mode = vesa_modes[i]; | 525 | *mode = vesa_modes[i]; |
@@ -536,13 +536,13 @@ static int get_dst_timing(unsigned char *block, | |||
536 | { | 536 | { |
537 | int j, num = 0; | 537 | int j, num = 0; |
538 | 538 | ||
539 | for (j = 0; j < 6; j++, block+= STD_TIMING_DESCRIPTION_SIZE) | 539 | for (j = 0; j < 6; j++, block += STD_TIMING_DESCRIPTION_SIZE) |
540 | num += get_std_timing(block, &mode[num]); | 540 | num += get_std_timing(block, &mode[num]); |
541 | 541 | ||
542 | return num; | 542 | return num; |
543 | } | 543 | } |
544 | 544 | ||
545 | static void get_detailed_timing(unsigned char *block, | 545 | static void get_detailed_timing(unsigned char *block, |
546 | struct fb_videomode *mode) | 546 | struct fb_videomode *mode) |
547 | { | 547 | { |
548 | mode->xres = H_ACTIVE; | 548 | mode->xres = H_ACTIVE; |
@@ -553,7 +553,7 @@ static void get_detailed_timing(unsigned char *block, | |||
553 | mode->right_margin = H_SYNC_OFFSET; | 553 | mode->right_margin = H_SYNC_OFFSET; |
554 | mode->left_margin = (H_ACTIVE + H_BLANKING) - | 554 | mode->left_margin = (H_ACTIVE + H_BLANKING) - |
555 | (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); | 555 | (H_ACTIVE + H_SYNC_OFFSET + H_SYNC_WIDTH); |
556 | mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - | 556 | mode->upper_margin = V_BLANKING - V_SYNC_OFFSET - |
557 | V_SYNC_WIDTH; | 557 | V_SYNC_WIDTH; |
558 | mode->lower_margin = V_SYNC_OFFSET; | 558 | mode->lower_margin = V_SYNC_OFFSET; |
559 | mode->hsync_len = H_SYNC_WIDTH; | 559 | mode->hsync_len = H_SYNC_WIDTH; |
@@ -597,7 +597,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | |||
597 | if (mode == NULL) | 597 | if (mode == NULL) |
598 | return NULL; | 598 | return NULL; |
599 | 599 | ||
600 | if (edid == NULL || !edid_checksum(edid) || | 600 | if (edid == NULL || !edid_checksum(edid) || |
601 | !edid_check_header(edid)) { | 601 | !edid_check_header(edid)) { |
602 | kfree(mode); | 602 | kfree(mode); |
603 | return NULL; | 603 | return NULL; |
@@ -632,7 +632,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize) | |||
632 | if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) | 632 | if (block[0] == 0x00 && block[1] == 0x00 && block[3] == 0xfa) |
633 | num += get_dst_timing(block + 5, &mode[num]); | 633 | num += get_dst_timing(block + 5, &mode[num]); |
634 | } | 634 | } |
635 | 635 | ||
636 | /* Yikes, EDID data is totally useless */ | 636 | /* Yikes, EDID data is totally useless */ |
637 | if (!num) { | 637 | if (!num) { |
638 | kfree(mode); | 638 | kfree(mode); |
@@ -686,7 +686,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) | |||
686 | /* estimate monitor limits based on modes supported */ | 686 | /* estimate monitor limits based on modes supported */ |
687 | if (retval) { | 687 | if (retval) { |
688 | struct fb_videomode *modes, *mode; | 688 | struct fb_videomode *modes, *mode; |
689 | int num_modes, i, hz, hscan, pixclock; | 689 | int num_modes, hz, hscan, pixclock; |
690 | int vtotal, htotal; | 690 | int vtotal, htotal; |
691 | 691 | ||
692 | modes = fb_create_modedb(edid, &num_modes); | 692 | modes = fb_create_modedb(edid, &num_modes); |
@@ -713,7 +713,7 @@ static int fb_get_monitor_limits(unsigned char *edid, struct fb_monspecs *specs) | |||
713 | hscan = (pixclock + htotal / 2) / htotal; | 713 | hscan = (pixclock + htotal / 2) / htotal; |
714 | hscan = (hscan + 500) / 1000 * 1000; | 714 | hscan = (hscan + 500) / 1000 * 1000; |
715 | hz = (hscan + vtotal / 2) / vtotal; | 715 | hz = (hscan + vtotal / 2) / vtotal; |
716 | 716 | ||
717 | if (specs->dclkmax == 0 || specs->dclkmax < pixclock) | 717 | if (specs->dclkmax == 0 || specs->dclkmax < pixclock) |
718 | specs->dclkmax = pixclock; | 718 | specs->dclkmax = pixclock; |
719 | 719 | ||
@@ -966,8 +966,8 @@ void fb_edid_to_monspecs(unsigned char *edid, struct fb_monspecs *specs) | |||
966 | DPRINTK("========================================\n"); | 966 | DPRINTK("========================================\n"); |
967 | } | 967 | } |
968 | 968 | ||
969 | /* | 969 | /* |
970 | * VESA Generalized Timing Formula (GTF) | 970 | * VESA Generalized Timing Formula (GTF) |
971 | */ | 971 | */ |
972 | 972 | ||
973 | #define FLYBACK 550 | 973 | #define FLYBACK 550 |
@@ -996,7 +996,7 @@ struct __fb_timings { | |||
996 | * @hfreq: horizontal freq | 996 | * @hfreq: horizontal freq |
997 | * | 997 | * |
998 | * DESCRIPTION: | 998 | * DESCRIPTION: |
999 | * vblank = right_margin + vsync_len + left_margin | 999 | * vblank = right_margin + vsync_len + left_margin |
1000 | * | 1000 | * |
1001 | * given: right_margin = 1 (V_FRONTPORCH) | 1001 | * given: right_margin = 1 (V_FRONTPORCH) |
1002 | * vsync_len = 3 | 1002 | * vsync_len = 3 |
@@ -1010,12 +1010,12 @@ static u32 fb_get_vblank(u32 hfreq) | |||
1010 | { | 1010 | { |
1011 | u32 vblank; | 1011 | u32 vblank; |
1012 | 1012 | ||
1013 | vblank = (hfreq * FLYBACK)/1000; | 1013 | vblank = (hfreq * FLYBACK)/1000; |
1014 | vblank = (vblank + 500)/1000; | 1014 | vblank = (vblank + 500)/1000; |
1015 | return (vblank + V_FRONTPORCH); | 1015 | return (vblank + V_FRONTPORCH); |
1016 | } | 1016 | } |
1017 | 1017 | ||
1018 | /** | 1018 | /** |
1019 | * fb_get_hblank_by_freq - get horizontal blank time given hfreq | 1019 | * fb_get_hblank_by_freq - get horizontal blank time given hfreq |
1020 | * @hfreq: horizontal freq | 1020 | * @hfreq: horizontal freq |
1021 | * @xres: horizontal resolution in pixels | 1021 | * @xres: horizontal resolution in pixels |
@@ -1031,7 +1031,7 @@ static u32 fb_get_vblank(u32 hfreq) | |||
1031 | * | 1031 | * |
1032 | * where: C = ((offset - scale factor) * blank_scale) | 1032 | * where: C = ((offset - scale factor) * blank_scale) |
1033 | * -------------------------------------- + scale factor | 1033 | * -------------------------------------- + scale factor |
1034 | * 256 | 1034 | * 256 |
1035 | * M = blank_scale * gradient | 1035 | * M = blank_scale * gradient |
1036 | * | 1036 | * |
1037 | */ | 1037 | */ |
@@ -1039,7 +1039,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1039 | { | 1039 | { |
1040 | u32 c_val, m_val, duty_cycle, hblank; | 1040 | u32 c_val, m_val, duty_cycle, hblank; |
1041 | 1041 | ||
1042 | c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + | 1042 | c_val = (((H_OFFSET - H_SCALEFACTOR) * H_BLANKSCALE)/256 + |
1043 | H_SCALEFACTOR) * 1000; | 1043 | H_SCALEFACTOR) * 1000; |
1044 | m_val = (H_BLANKSCALE * H_GRADIENT)/256; | 1044 | m_val = (H_BLANKSCALE * H_GRADIENT)/256; |
1045 | m_val = (m_val * 1000000)/hfreq; | 1045 | m_val = (m_val * 1000000)/hfreq; |
@@ -1048,7 +1048,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1048 | return (hblank); | 1048 | return (hblank); |
1049 | } | 1049 | } |
1050 | 1050 | ||
1051 | /** | 1051 | /** |
1052 | * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock | 1052 | * fb_get_hblank_by_dclk - get horizontal blank time given pixelclock |
1053 | * @dclk: pixelclock in Hz | 1053 | * @dclk: pixelclock in Hz |
1054 | * @xres: horizontal resolution in pixels | 1054 | * @xres: horizontal resolution in pixels |
@@ -1061,7 +1061,7 @@ static u32 fb_get_hblank_by_hfreq(u32 hfreq, u32 xres) | |||
1061 | * | 1061 | * |
1062 | * duty cycle = percent of htotal assigned to inactive display | 1062 | * duty cycle = percent of htotal assigned to inactive display |
1063 | * duty cycle = C - (M * h_period) | 1063 | * duty cycle = C - (M * h_period) |
1064 | * | 1064 | * |
1065 | * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100 | 1065 | * where: h_period = SQRT(100 - C + (0.4 * xres * M)/dclk) + C - 100 |
1066 | * ----------------------------------------------- | 1066 | * ----------------------------------------------- |
1067 | * 2 * M | 1067 | * 2 * M |
@@ -1077,11 +1077,11 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1077 | h_period = 100 - C_VAL; | 1077 | h_period = 100 - C_VAL; |
1078 | h_period *= h_period; | 1078 | h_period *= h_period; |
1079 | h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); | 1079 | h_period += (M_VAL * xres * 2 * 1000)/(5 * dclk); |
1080 | h_period *=10000; | 1080 | h_period *= 10000; |
1081 | 1081 | ||
1082 | h_period = int_sqrt(h_period); | 1082 | h_period = int_sqrt(h_period); |
1083 | h_period -= (100 - C_VAL) * 100; | 1083 | h_period -= (100 - C_VAL) * 100; |
1084 | h_period *= 1000; | 1084 | h_period *= 1000; |
1085 | h_period /= 2 * M_VAL; | 1085 | h_period /= 2 * M_VAL; |
1086 | 1086 | ||
1087 | duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; | 1087 | duty_cycle = C_VAL * 1000 - (M_VAL * h_period)/100; |
@@ -1089,7 +1089,7 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1089 | hblank &= ~15; | 1089 | hblank &= ~15; |
1090 | return (hblank); | 1090 | return (hblank); |
1091 | } | 1091 | } |
1092 | 1092 | ||
1093 | /** | 1093 | /** |
1094 | * fb_get_hfreq - estimate hsync | 1094 | * fb_get_hfreq - estimate hsync |
1095 | * @vfreq: vertical refresh rate | 1095 | * @vfreq: vertical refresh rate |
@@ -1100,13 +1100,13 @@ static u32 fb_get_hblank_by_dclk(u32 dclk, u32 xres) | |||
1100 | * (yres + front_port) * vfreq * 1000000 | 1100 | * (yres + front_port) * vfreq * 1000000 |
1101 | * hfreq = ------------------------------------- | 1101 | * hfreq = ------------------------------------- |
1102 | * (1000000 - (vfreq * FLYBACK) | 1102 | * (1000000 - (vfreq * FLYBACK) |
1103 | * | 1103 | * |
1104 | */ | 1104 | */ |
1105 | 1105 | ||
1106 | static u32 fb_get_hfreq(u32 vfreq, u32 yres) | 1106 | static u32 fb_get_hfreq(u32 vfreq, u32 yres) |
1107 | { | 1107 | { |
1108 | u32 divisor, hfreq; | 1108 | u32 divisor, hfreq; |
1109 | 1109 | ||
1110 | divisor = (1000000 - (vfreq * FLYBACK))/1000; | 1110 | divisor = (1000000 - (vfreq * FLYBACK))/1000; |
1111 | hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; | 1111 | hfreq = (yres + V_FRONTPORCH) * vfreq * 1000; |
1112 | return (hfreq/divisor); | 1112 | return (hfreq/divisor); |
@@ -1117,7 +1117,7 @@ static void fb_timings_vfreq(struct __fb_timings *timings) | |||
1117 | timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive); | 1117 | timings->hfreq = fb_get_hfreq(timings->vfreq, timings->vactive); |
1118 | timings->vblank = fb_get_vblank(timings->hfreq); | 1118 | timings->vblank = fb_get_vblank(timings->hfreq); |
1119 | timings->vtotal = timings->vactive + timings->vblank; | 1119 | timings->vtotal = timings->vactive + timings->vblank; |
1120 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, | 1120 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, |
1121 | timings->hactive); | 1121 | timings->hactive); |
1122 | timings->htotal = timings->hactive + timings->hblank; | 1122 | timings->htotal = timings->hactive + timings->hblank; |
1123 | timings->dclk = timings->htotal * timings->hfreq; | 1123 | timings->dclk = timings->htotal * timings->hfreq; |
@@ -1128,7 +1128,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings) | |||
1128 | timings->vblank = fb_get_vblank(timings->hfreq); | 1128 | timings->vblank = fb_get_vblank(timings->hfreq); |
1129 | timings->vtotal = timings->vactive + timings->vblank; | 1129 | timings->vtotal = timings->vactive + timings->vblank; |
1130 | timings->vfreq = timings->hfreq/timings->vtotal; | 1130 | timings->vfreq = timings->hfreq/timings->vtotal; |
1131 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, | 1131 | timings->hblank = fb_get_hblank_by_hfreq(timings->hfreq, |
1132 | timings->hactive); | 1132 | timings->hactive); |
1133 | timings->htotal = timings->hactive + timings->hblank; | 1133 | timings->htotal = timings->hactive + timings->hblank; |
1134 | timings->dclk = timings->htotal * timings->hfreq; | 1134 | timings->dclk = timings->htotal * timings->hfreq; |
@@ -1136,7 +1136,7 @@ static void fb_timings_hfreq(struct __fb_timings *timings) | |||
1136 | 1136 | ||
1137 | static void fb_timings_dclk(struct __fb_timings *timings) | 1137 | static void fb_timings_dclk(struct __fb_timings *timings) |
1138 | { | 1138 | { |
1139 | timings->hblank = fb_get_hblank_by_dclk(timings->dclk, | 1139 | timings->hblank = fb_get_hblank_by_dclk(timings->dclk, |
1140 | timings->hactive); | 1140 | timings->hactive); |
1141 | timings->htotal = timings->hactive + timings->hblank; | 1141 | timings->htotal = timings->hactive + timings->hblank; |
1142 | timings->hfreq = timings->dclk/timings->htotal; | 1142 | timings->hfreq = timings->dclk/timings->htotal; |
@@ -1156,29 +1156,29 @@ static void fb_timings_dclk(struct __fb_timings *timings) | |||
1156 | * @info: pointer to fb_info | 1156 | * @info: pointer to fb_info |
1157 | * | 1157 | * |
1158 | * DESCRIPTION: | 1158 | * DESCRIPTION: |
1159 | * Calculates video mode based on monitor specs using VESA GTF. | 1159 | * Calculates video mode based on monitor specs using VESA GTF. |
1160 | * The GTF is best for VESA GTF compliant monitors but is | 1160 | * The GTF is best for VESA GTF compliant monitors but is |
1161 | * specifically formulated to work for older monitors as well. | 1161 | * specifically formulated to work for older monitors as well. |
1162 | * | 1162 | * |
1163 | * If @flag==0, the function will attempt to maximize the | 1163 | * If @flag==0, the function will attempt to maximize the |
1164 | * refresh rate. Otherwise, it will calculate timings based on | 1164 | * refresh rate. Otherwise, it will calculate timings based on |
1165 | * the flag and accompanying value. | 1165 | * the flag and accompanying value. |
1166 | * | 1166 | * |
1167 | * If FB_IGNOREMON bit is set in @flags, monitor specs will be | 1167 | * If FB_IGNOREMON bit is set in @flags, monitor specs will be |
1168 | * ignored and @var will be filled with the calculated timings. | 1168 | * ignored and @var will be filled with the calculated timings. |
1169 | * | 1169 | * |
1170 | * All calculations are based on the VESA GTF Spreadsheet | 1170 | * All calculations are based on the VESA GTF Spreadsheet |
1171 | * available at VESA's public ftp (http://www.vesa.org). | 1171 | * available at VESA's public ftp (http://www.vesa.org). |
1172 | * | 1172 | * |
1173 | * NOTES: | 1173 | * NOTES: |
1174 | * The timings generated by the GTF will be different from VESA | 1174 | * The timings generated by the GTF will be different from VESA |
1175 | * DMT. It might be a good idea to keep a table of standard | 1175 | * DMT. It might be a good idea to keep a table of standard |
1176 | * VESA modes as well. The GTF may also not work for some displays, | 1176 | * VESA modes as well. The GTF may also not work for some displays, |
1177 | * such as, and especially, analog TV. | 1177 | * such as, and especially, analog TV. |
1178 | * | 1178 | * |
1179 | * REQUIRES: | 1179 | * REQUIRES: |
1180 | * A valid info->monspecs, otherwise 'safe numbers' will be used. | 1180 | * A valid info->monspecs, otherwise 'safe numbers' will be used. |
1181 | */ | 1181 | */ |
1182 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) | 1182 | int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_info *info) |
1183 | { | 1183 | { |
1184 | struct __fb_timings *timings; | 1184 | struct __fb_timings *timings; |
@@ -1191,7 +1191,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1191 | if (!timings) | 1191 | if (!timings) |
1192 | return -ENOMEM; | 1192 | return -ENOMEM; |
1193 | 1193 | ||
1194 | /* | 1194 | /* |
1195 | * If monspecs are invalid, use values that are enough | 1195 | * If monspecs are invalid, use values that are enough |
1196 | * for 640x480@60 | 1196 | * for 640x480@60 |
1197 | */ | 1197 | */ |
@@ -1214,7 +1214,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1214 | 1214 | ||
1215 | timings->hactive = var->xres; | 1215 | timings->hactive = var->xres; |
1216 | timings->vactive = var->yres; | 1216 | timings->vactive = var->yres; |
1217 | if (var->vmode & FB_VMODE_INTERLACED) { | 1217 | if (var->vmode & FB_VMODE_INTERLACED) { |
1218 | timings->vactive /= 2; | 1218 | timings->vactive /= 2; |
1219 | interlace = 2; | 1219 | interlace = 2; |
1220 | } | 1220 | } |
@@ -1250,9 +1250,9 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1250 | break; | 1250 | break; |
1251 | default: | 1251 | default: |
1252 | err = -EINVAL; | 1252 | err = -EINVAL; |
1253 | 1253 | ||
1254 | } | 1254 | } |
1255 | 1255 | ||
1256 | if (err || (!(flags & FB_IGNOREMON) && | 1256 | if (err || (!(flags & FB_IGNOREMON) && |
1257 | (timings->vfreq < vfmin || timings->vfreq > vfmax || | 1257 | (timings->vfreq < vfmin || timings->vfreq > vfmax || |
1258 | timings->hfreq < hfmin || timings->hfreq > hfmax || | 1258 | timings->hfreq < hfmin || timings->hfreq > hfmax || |
@@ -1269,7 +1269,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, struct fb_inf | |||
1269 | var->upper_margin = (timings->vblank * interlace)/dscan - | 1269 | var->upper_margin = (timings->vblank * interlace)/dscan - |
1270 | (var->vsync_len + var->lower_margin); | 1270 | (var->vsync_len + var->lower_margin); |
1271 | } | 1271 | } |
1272 | 1272 | ||
1273 | kfree(timings); | 1273 | kfree(timings); |
1274 | return err; | 1274 | return err; |
1275 | } | 1275 | } |
@@ -1291,7 +1291,7 @@ int fb_get_mode(int flags, u32 val, struct fb_var_screeninfo *var, | |||
1291 | return -EINVAL; | 1291 | return -EINVAL; |
1292 | } | 1292 | } |
1293 | #endif /* CONFIG_FB_MODE_HELPERS */ | 1293 | #endif /* CONFIG_FB_MODE_HELPERS */ |
1294 | 1294 | ||
1295 | /* | 1295 | /* |
1296 | * fb_validate_mode - validates var against monitor capabilities | 1296 | * fb_validate_mode - validates var against monitor capabilities |
1297 | * @var: pointer to fb_var_screeninfo | 1297 | * @var: pointer to fb_var_screeninfo |
@@ -1309,7 +1309,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1309 | u32 hfreq, vfreq, htotal, vtotal, pixclock; | 1309 | u32 hfreq, vfreq, htotal, vtotal, pixclock; |
1310 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; | 1310 | u32 hfmin, hfmax, vfmin, vfmax, dclkmin, dclkmax; |
1311 | 1311 | ||
1312 | /* | 1312 | /* |
1313 | * If monspecs are invalid, use values that are enough | 1313 | * If monspecs are invalid, use values that are enough |
1314 | * for 640x480@60 | 1314 | * for 640x480@60 |
1315 | */ | 1315 | */ |
@@ -1333,10 +1333,10 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1333 | if (!var->pixclock) | 1333 | if (!var->pixclock) |
1334 | return -EINVAL; | 1334 | return -EINVAL; |
1335 | pixclock = PICOS2KHZ(var->pixclock) * 1000; | 1335 | pixclock = PICOS2KHZ(var->pixclock) * 1000; |
1336 | 1336 | ||
1337 | htotal = var->xres + var->right_margin + var->hsync_len + | 1337 | htotal = var->xres + var->right_margin + var->hsync_len + |
1338 | var->left_margin; | 1338 | var->left_margin; |
1339 | vtotal = var->yres + var->lower_margin + var->vsync_len + | 1339 | vtotal = var->yres + var->lower_margin + var->vsync_len + |
1340 | var->upper_margin; | 1340 | var->upper_margin; |
1341 | 1341 | ||
1342 | if (var->vmode & FB_VMODE_INTERLACED) | 1342 | if (var->vmode & FB_VMODE_INTERLACED) |
@@ -1349,7 +1349,7 @@ int fb_validate_mode(const struct fb_var_screeninfo *var, struct fb_info *info) | |||
1349 | 1349 | ||
1350 | vfreq = hfreq/vtotal; | 1350 | vfreq = hfreq/vtotal; |
1351 | 1351 | ||
1352 | return (vfreq < vfmin || vfreq > vfmax || | 1352 | return (vfreq < vfmin || vfreq > vfmax || |
1353 | hfreq < hfmin || hfreq > hfmax || | 1353 | hfreq < hfmin || hfreq > hfmax || |
1354 | pixclock < dclkmin || pixclock > dclkmax) ? | 1354 | pixclock < dclkmin || pixclock > dclkmax) ? |
1355 | -EINVAL : 0; | 1355 | -EINVAL : 0; |
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c index 583185fd7c94..eb6b88171538 100644 --- a/drivers/video/geode/lxfb_core.c +++ b/drivers/video/geode/lxfb_core.c | |||
@@ -34,7 +34,7 @@ static int fbsize; | |||
34 | * we try to make it something sane - 640x480-60 is sane | 34 | * we try to make it something sane - 640x480-60 is sane |
35 | */ | 35 | */ |
36 | 36 | ||
37 | const struct fb_videomode geode_modedb[] __initdata = { | 37 | static const struct fb_videomode geode_modedb[] __initdata = { |
38 | /* 640x480-60 */ | 38 | /* 640x480-60 */ |
39 | { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2, | 39 | { NULL, 60, 640, 480, 39682, 48, 8, 25, 2, 88, 2, |
40 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, | 40 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, |
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c index b18486ad8e17..2eb4fb159084 100644 --- a/drivers/video/hpfb.c +++ b/drivers/video/hpfb.c | |||
@@ -207,7 +207,8 @@ static struct fb_ops hpfb_ops = { | |||
207 | #define HPFB_FBOMSB 0x5d /* Frame buffer offset */ | 207 | #define HPFB_FBOMSB 0x5d /* Frame buffer offset */ |
208 | #define HPFB_FBOLSB 0x5f | 208 | #define HPFB_FBOLSB 0x5f |
209 | 209 | ||
210 | static int __init hpfb_init_one(unsigned long phys_base, unsigned long virt_base) | 210 | static int __devinit hpfb_init_one(unsigned long phys_base, |
211 | unsigned long virt_base) | ||
211 | { | 212 | { |
212 | unsigned long fboff, fb_width, fb_height, fb_start; | 213 | unsigned long fboff, fb_width, fb_height, fb_start; |
213 | 214 | ||
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/i810/i810_main.c index 1a7d7789d877..1d13dd099af8 100644 --- a/drivers/video/i810/i810_main.c +++ b/drivers/video/i810/i810_main.c | |||
@@ -1476,7 +1476,7 @@ static int i810fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | |||
1476 | struct i810fb_par *par = info->par; | 1476 | struct i810fb_par *par = info->par; |
1477 | u8 __iomem *mmio = par->mmio_start_virtual; | 1477 | u8 __iomem *mmio = par->mmio_start_virtual; |
1478 | 1478 | ||
1479 | if (!par->dev_flags & LOCKUP) | 1479 | if (!(par->dev_flags & LOCKUP)) |
1480 | return -ENXIO; | 1480 | return -ENXIO; |
1481 | 1481 | ||
1482 | if (cursor->image.width > 64 || cursor->image.height > 64) | 1482 | if (cursor->image.width > 64 || cursor->image.height > 64) |
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c index b87ea21d3d78..3a81060137a2 100644 --- a/drivers/video/igafb.c +++ b/drivers/video/igafb.c | |||
@@ -400,6 +400,7 @@ int __init igafb_init(void) | |||
400 | info = kzalloc(size, GFP_ATOMIC); | 400 | info = kzalloc(size, GFP_ATOMIC); |
401 | if (!info) { | 401 | if (!info) { |
402 | printk("igafb_init: can't alloc fb_info\n"); | 402 | printk("igafb_init: can't alloc fb_info\n"); |
403 | pci_dev_put(pdev); | ||
403 | return -ENOMEM; | 404 | return -ENOMEM; |
404 | } | 405 | } |
405 | 406 | ||
@@ -409,12 +410,14 @@ int __init igafb_init(void) | |||
409 | if ((addr = pdev->resource[0].start) == 0) { | 410 | if ((addr = pdev->resource[0].start) == 0) { |
410 | printk("igafb_init: no memory start\n"); | 411 | printk("igafb_init: no memory start\n"); |
411 | kfree(info); | 412 | kfree(info); |
413 | pci_dev_put(pdev); | ||
412 | return -ENXIO; | 414 | return -ENXIO; |
413 | } | 415 | } |
414 | 416 | ||
415 | if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) { | 417 | if ((info->screen_base = ioremap(addr, 1024*1024*2)) == 0) { |
416 | printk("igafb_init: can't remap %lx[2M]\n", addr); | 418 | printk("igafb_init: can't remap %lx[2M]\n", addr); |
417 | kfree(info); | 419 | kfree(info); |
420 | pci_dev_put(pdev); | ||
418 | return -ENXIO; | 421 | return -ENXIO; |
419 | } | 422 | } |
420 | 423 | ||
@@ -449,6 +452,7 @@ int __init igafb_init(void) | |||
449 | printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start); | 452 | printk("igafb_init: can't remap %lx[4K]\n", igafb_fix.mmio_start); |
450 | iounmap((void *)info->screen_base); | 453 | iounmap((void *)info->screen_base); |
451 | kfree(info); | 454 | kfree(info); |
455 | pci_dev_put(pdev); | ||
452 | return -ENXIO; | 456 | return -ENXIO; |
453 | } | 457 | } |
454 | 458 | ||
@@ -466,6 +470,7 @@ int __init igafb_init(void) | |||
466 | iounmap((void *)par->io_base); | 470 | iounmap((void *)par->io_base); |
467 | iounmap(info->screen_base); | 471 | iounmap(info->screen_base); |
468 | kfree(info); | 472 | kfree(info); |
473 | pci_dev_put(pdev); | ||
469 | return -ENOMEM; | 474 | return -ENOMEM; |
470 | } | 475 | } |
471 | 476 | ||
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 5f6fb7d2c408..fa1fff553565 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -1971,7 +1971,7 @@ void intelfbhw_cursor_reset(struct intelfb_info *dinfo) | |||
1971 | static irqreturn_t intelfbhw_irq(int irq, void *dev_id) | 1971 | static irqreturn_t intelfbhw_irq(int irq, void *dev_id) |
1972 | { | 1972 | { |
1973 | u16 tmp; | 1973 | u16 tmp; |
1974 | struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; | 1974 | struct intelfb_info *dinfo = dev_id; |
1975 | 1975 | ||
1976 | spin_lock(&dinfo->int_lock); | 1976 | spin_lock(&dinfo->int_lock); |
1977 | 1977 | ||
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c index 4b6a99b5be0d..5246b0402d76 100644 --- a/drivers/video/neofb.c +++ b/drivers/video/neofb.c | |||
@@ -2066,40 +2066,49 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st | |||
2066 | 2066 | ||
2067 | switch (info->fix.accel) { | 2067 | switch (info->fix.accel) { |
2068 | case FB_ACCEL_NEOMAGIC_NM2070: | 2068 | case FB_ACCEL_NEOMAGIC_NM2070: |
2069 | sprintf(info->fix.id, "MagicGraph 128"); | 2069 | snprintf(info->fix.id, sizeof(info->fix.id), |
2070 | "MagicGraph 128"); | ||
2070 | break; | 2071 | break; |
2071 | case FB_ACCEL_NEOMAGIC_NM2090: | 2072 | case FB_ACCEL_NEOMAGIC_NM2090: |
2072 | sprintf(info->fix.id, "MagicGraph 128V"); | 2073 | snprintf(info->fix.id, sizeof(info->fix.id), |
2074 | "MagicGraph 128V"); | ||
2073 | break; | 2075 | break; |
2074 | case FB_ACCEL_NEOMAGIC_NM2093: | 2076 | case FB_ACCEL_NEOMAGIC_NM2093: |
2075 | sprintf(info->fix.id, "MagicGraph 128ZV"); | 2077 | snprintf(info->fix.id, sizeof(info->fix.id), |
2078 | "MagicGraph 128ZV"); | ||
2076 | break; | 2079 | break; |
2077 | case FB_ACCEL_NEOMAGIC_NM2097: | 2080 | case FB_ACCEL_NEOMAGIC_NM2097: |
2078 | sprintf(info->fix.id, "MagicGraph 128ZV+"); | 2081 | snprintf(info->fix.id, sizeof(info->fix.id), |
2082 | "MagicGraph 128ZV+"); | ||
2079 | break; | 2083 | break; |
2080 | case FB_ACCEL_NEOMAGIC_NM2160: | 2084 | case FB_ACCEL_NEOMAGIC_NM2160: |
2081 | sprintf(info->fix.id, "MagicGraph 128XD"); | 2085 | snprintf(info->fix.id, sizeof(info->fix.id), |
2086 | "MagicGraph 128XD"); | ||
2082 | break; | 2087 | break; |
2083 | case FB_ACCEL_NEOMAGIC_NM2200: | 2088 | case FB_ACCEL_NEOMAGIC_NM2200: |
2084 | sprintf(info->fix.id, "MagicGraph 256AV"); | 2089 | snprintf(info->fix.id, sizeof(info->fix.id), |
2090 | "MagicGraph 256AV"); | ||
2085 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | | 2091 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | |
2086 | FBINFO_HWACCEL_COPYAREA | | 2092 | FBINFO_HWACCEL_COPYAREA | |
2087 | FBINFO_HWACCEL_FILLRECT; | 2093 | FBINFO_HWACCEL_FILLRECT; |
2088 | break; | 2094 | break; |
2089 | case FB_ACCEL_NEOMAGIC_NM2230: | 2095 | case FB_ACCEL_NEOMAGIC_NM2230: |
2090 | sprintf(info->fix.id, "MagicGraph 256AV+"); | 2096 | snprintf(info->fix.id, sizeof(info->fix.id), |
2097 | "MagicGraph 256AV+"); | ||
2091 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | | 2098 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | |
2092 | FBINFO_HWACCEL_COPYAREA | | 2099 | FBINFO_HWACCEL_COPYAREA | |
2093 | FBINFO_HWACCEL_FILLRECT; | 2100 | FBINFO_HWACCEL_FILLRECT; |
2094 | break; | 2101 | break; |
2095 | case FB_ACCEL_NEOMAGIC_NM2360: | 2102 | case FB_ACCEL_NEOMAGIC_NM2360: |
2096 | sprintf(info->fix.id, "MagicGraph 256ZX"); | 2103 | snprintf(info->fix.id, sizeof(info->fix.id), |
2104 | "MagicGraph 256ZX"); | ||
2097 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | | 2105 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | |
2098 | FBINFO_HWACCEL_COPYAREA | | 2106 | FBINFO_HWACCEL_COPYAREA | |
2099 | FBINFO_HWACCEL_FILLRECT; | 2107 | FBINFO_HWACCEL_FILLRECT; |
2100 | break; | 2108 | break; |
2101 | case FB_ACCEL_NEOMAGIC_NM2380: | 2109 | case FB_ACCEL_NEOMAGIC_NM2380: |
2102 | sprintf(info->fix.id, "MagicGraph 256XL+"); | 2110 | snprintf(info->fix.id, sizeof(info->fix.id), |
2111 | "MagicGraph 256XL+"); | ||
2103 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | | 2112 | info->flags |= FBINFO_HWACCEL_IMAGEBLIT | |
2104 | FBINFO_HWACCEL_COPYAREA | | 2113 | FBINFO_HWACCEL_COPYAREA | |
2105 | FBINFO_HWACCEL_FILLRECT; | 2114 | FBINFO_HWACCEL_FILLRECT; |
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 30e14eb1f51e..74517b1b26a6 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c | |||
@@ -849,9 +849,27 @@ static int nvidiafb_check_var(struct fb_var_screeninfo *var, | |||
849 | if (!mode_valid && info->monspecs.modedb_len) | 849 | if (!mode_valid && info->monspecs.modedb_len) |
850 | return -EINVAL; | 850 | return -EINVAL; |
851 | 851 | ||
852 | /* | ||
853 | * If we're on a flat panel, check if the mode is outside of the | ||
854 | * panel dimensions. If so, cap it and try for the next best mode | ||
855 | * before bailing out. | ||
856 | */ | ||
852 | if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || | 857 | if (par->fpWidth && par->fpHeight && (par->fpWidth < var->xres || |
853 | par->fpHeight < var->yres)) | 858 | par->fpHeight < var->yres)) { |
854 | return -EINVAL; | 859 | const struct fb_videomode *mode; |
860 | |||
861 | var->xres = par->fpWidth; | ||
862 | var->yres = par->fpHeight; | ||
863 | |||
864 | mode = fb_find_best_mode(var, &info->modelist); | ||
865 | if (!mode) { | ||
866 | printk(KERN_ERR PFX "mode out of range of flat " | ||
867 | "panel dimensions\n"); | ||
868 | return -EINVAL; | ||
869 | } | ||
870 | |||
871 | fb_videomode_to_var(var, mode); | ||
872 | } | ||
855 | 873 | ||
856 | if (var->yres_virtual < var->yres) | 874 | if (var->yres_virtual < var->yres) |
857 | var->yres_virtual = var->yres; | 875 | var->yres_virtual = var->yres; |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 5591dfb22b18..30181b593829 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -1159,6 +1159,11 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1159 | u32 fgx, bgx; | 1159 | u32 fgx, bgx; |
1160 | const u32 *src = (const u32 *)image->data; | 1160 | const u32 *src = (const u32 *)image->data; |
1161 | u32 xres = (info->var.xres + 31) & ~31; | 1161 | u32 xres = (info->var.xres + 31) & ~31; |
1162 | int raster_mode = 1; /* invert bits */ | ||
1163 | |||
1164 | #ifdef __LITTLE_ENDIAN | ||
1165 | raster_mode |= 3 << 7; /* reverse byte order */ | ||
1166 | #endif | ||
1162 | 1167 | ||
1163 | if (info->state != FBINFO_STATE_RUNNING) | 1168 | if (info->state != FBINFO_STATE_RUNNING) |
1164 | return; | 1169 | return; |
@@ -1208,9 +1213,8 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1208 | pm2_WR(par, PM2R_RENDER, | 1213 | pm2_WR(par, PM2R_RENDER, |
1209 | PM2F_RENDER_RECTANGLE | | 1214 | PM2F_RENDER_RECTANGLE | |
1210 | PM2F_INCREASE_X | PM2F_INCREASE_Y); | 1215 | PM2F_INCREASE_X | PM2F_INCREASE_Y); |
1211 | /* BitMapPackEachScanline & invert bits and byte order*/ | 1216 | /* BitMapPackEachScanline */ |
1212 | /* force background */ | 1217 | pm2_WR(par, PM2R_RASTERIZER_MODE, raster_mode | (1 << 9)); |
1213 | pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7)); | ||
1214 | pm2_WR(par, PM2R_CONSTANT_COLOR, fgx); | 1218 | pm2_WR(par, PM2R_CONSTANT_COLOR, fgx); |
1215 | pm2_WR(par, PM2R_RENDER, | 1219 | pm2_WR(par, PM2R_RENDER, |
1216 | PM2F_RENDER_RECTANGLE | | 1220 | PM2F_RENDER_RECTANGLE | |
@@ -1224,8 +1228,7 @@ static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image) | |||
1224 | PM2F_RENDER_RECTANGLE | | 1228 | PM2F_RENDER_RECTANGLE | |
1225 | PM2F_RENDER_FASTFILL | | 1229 | PM2F_RENDER_FASTFILL | |
1226 | PM2F_INCREASE_X | PM2F_INCREASE_Y); | 1230 | PM2F_INCREASE_X | PM2F_INCREASE_Y); |
1227 | /* invert bits and byte order*/ | 1231 | pm2_WR(par, PM2R_RASTERIZER_MODE, raster_mode); |
1228 | pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7)); | ||
1229 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx); | 1232 | pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx); |
1230 | pm2_WR(par, PM2R_RENDER, | 1233 | pm2_WR(par, PM2R_RENDER, |
1231 | PM2F_RENDER_RECTANGLE | | 1234 | PM2F_RENDER_RECTANGLE | |
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c index 070659992c18..5dba8cdd0517 100644 --- a/drivers/video/pm3fb.c +++ b/drivers/video/pm3fb.c | |||
@@ -1227,7 +1227,7 @@ static struct fb_ops pm3fb_ops = { | |||
1227 | 1227 | ||
1228 | /* mmio register are already mapped when this function is called */ | 1228 | /* mmio register are already mapped when this function is called */ |
1229 | /* the pm3fb_fix.smem_start is also set */ | 1229 | /* the pm3fb_fix.smem_start is also set */ |
1230 | static unsigned long pm3fb_size_memory(struct pm3_par *par) | 1230 | static unsigned long __devinit pm3fb_size_memory(struct pm3_par *par) |
1231 | { | 1231 | { |
1232 | unsigned long memsize = 0; | 1232 | unsigned long memsize = 0; |
1233 | unsigned long tempBypass, i, temp1, temp2; | 1233 | unsigned long tempBypass, i, temp1, temp2; |
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/pmag-aa-fb.c index a864438b6008..6515ec11c16b 100644 --- a/drivers/video/pmag-aa-fb.c +++ b/drivers/video/pmag-aa-fb.c | |||
@@ -150,7 +150,7 @@ static int aafbcon_set_font(struct display *disp, int width, int height) | |||
150 | { | 150 | { |
151 | struct aafb_info *info = (struct aafb_info *)disp->fb_info; | 151 | struct aafb_info *info = (struct aafb_info *)disp->fb_info; |
152 | struct aafb_cursor *c = &info->cursor; | 152 | struct aafb_cursor *c = &info->cursor; |
153 | u8 fgc = ~attr_bgcol_ec(disp, disp->conp); | 153 | u8 fgc = ~attr_bgcol_ec(disp, disp->conp, &info->info); |
154 | 154 | ||
155 | if (width > 64 || height > 64 || width < 0 || height < 0) | 155 | if (width > 64 || height > 64 || width < 0 || height < 0) |
156 | return -EINVAL; | 156 | return -EINVAL; |
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c index 044a423a72cb..dc3af1c78c56 100644 --- a/drivers/video/ps3fb.c +++ b/drivers/video/ps3fb.c | |||
@@ -57,8 +57,6 @@ | |||
57 | #define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64) | 57 | #define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64) |
58 | #define GPU_MAX_LINE_LENGTH (65536 - 64) | 58 | #define GPU_MAX_LINE_LENGTH (65536 - 64) |
59 | 59 | ||
60 | #define PS3FB_FULL_MODE_BIT 0x80 | ||
61 | |||
62 | #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */ | 60 | #define GPU_INTR_STATUS_VSYNC_0 0 /* vsync on head A */ |
63 | #define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */ | 61 | #define GPU_INTR_STATUS_VSYNC_1 1 /* vsync on head B */ |
64 | #define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */ | 62 | #define GPU_INTR_STATUS_FLIP_0 3 /* flip head A */ |
@@ -118,8 +116,6 @@ struct ps3fb_priv { | |||
118 | unsigned int irq_no; | 116 | unsigned int irq_no; |
119 | 117 | ||
120 | u64 context_handle, memory_handle; | 118 | u64 context_handle, memory_handle; |
121 | void *xdr_ea; | ||
122 | size_t xdr_size; | ||
123 | struct gpu_driver_info *dinfo; | 119 | struct gpu_driver_info *dinfo; |
124 | 120 | ||
125 | u64 vblank_count; /* frame count */ | 121 | u64 vblank_count; /* frame count */ |
@@ -136,42 +132,19 @@ static struct ps3fb_priv ps3fb; | |||
136 | struct ps3fb_par { | 132 | struct ps3fb_par { |
137 | u32 pseudo_palette[16]; | 133 | u32 pseudo_palette[16]; |
138 | int mode_id, new_mode_id; | 134 | int mode_id, new_mode_id; |
139 | int res_index; | ||
140 | unsigned int num_frames; /* num of frame buffers */ | 135 | unsigned int num_frames; /* num of frame buffers */ |
141 | unsigned int width; | 136 | unsigned int width; |
142 | unsigned int height; | 137 | unsigned int height; |
143 | unsigned long full_offset; /* start of fullscreen DDR fb */ | 138 | unsigned int ddr_line_length; |
144 | unsigned long fb_offset; /* start of actual DDR fb */ | 139 | unsigned int ddr_frame_size; |
145 | unsigned long pan_offset; | 140 | unsigned int xdr_frame_size; |
141 | unsigned int full_offset; /* start of fullscreen DDR fb */ | ||
142 | unsigned int fb_offset; /* start of actual DDR fb */ | ||
143 | unsigned int pan_offset; | ||
146 | }; | 144 | }; |
147 | 145 | ||
148 | struct ps3fb_res_table { | 146 | |
149 | u32 xres; | 147 | #define FIRST_NATIVE_MODE_INDEX 10 |
150 | u32 yres; | ||
151 | u32 xoff; | ||
152 | u32 yoff; | ||
153 | u32 type; | ||
154 | }; | ||
155 | #define PS3FB_RES_FULL 1 | ||
156 | static const struct ps3fb_res_table ps3fb_res[] = { | ||
157 | /* res_x,y margin_x,y full */ | ||
158 | { 720, 480, 72, 48 , 0}, | ||
159 | { 720, 576, 72, 58 , 0}, | ||
160 | { 1280, 720, 78, 38 , 0}, | ||
161 | { 1920, 1080, 116, 58 , 0}, | ||
162 | /* full mode */ | ||
163 | { 720, 480, 0, 0 , PS3FB_RES_FULL}, | ||
164 | { 720, 576, 0, 0 , PS3FB_RES_FULL}, | ||
165 | { 1280, 720, 0, 0 , PS3FB_RES_FULL}, | ||
166 | { 1920, 1080, 0, 0 , PS3FB_RES_FULL}, | ||
167 | /* vesa: normally full mode */ | ||
168 | { 1280, 768, 0, 0 , 0}, | ||
169 | { 1280, 1024, 0, 0 , 0}, | ||
170 | { 1920, 1200, 0, 0 , 0}, | ||
171 | { 0, 0, 0, 0 , 0} }; | ||
172 | |||
173 | /* default resolution */ | ||
174 | #define GPU_RES_INDEX 0 /* 720 x 480 */ | ||
175 | 148 | ||
176 | static const struct fb_videomode ps3fb_modedb[] = { | 149 | static const struct fb_videomode ps3fb_modedb[] = { |
177 | /* 60 Hz broadcast modes (modes "1" to "5") */ | 150 | /* 60 Hz broadcast modes (modes "1" to "5") */ |
@@ -211,7 +184,7 @@ static const struct fb_videomode ps3fb_modedb[] = { | |||
211 | "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5, | 184 | "720p", 50, 1124, 644, 13468, 298, 478, 57, 44, 80, 5, |
212 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | 185 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED |
213 | }, { | 186 | }, { |
214 | /* 1080 */ | 187 | /* 1080i */ |
215 | "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5, | 188 | "1080i", 50, 1688, 964, 13468, 264, 600, 94, 62, 88, 5, |
216 | FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | 189 | FB_SYNC_BROADCAST, FB_VMODE_INTERLACED |
217 | }, { | 190 | }, { |
@@ -220,24 +193,7 @@ static const struct fb_videomode ps3fb_modedb[] = { | |||
220 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | 193 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED |
221 | }, | 194 | }, |
222 | 195 | ||
223 | /* VESA modes (modes "11" to "13") */ | 196 | [FIRST_NATIVE_MODE_INDEX] = |
224 | { | ||
225 | /* WXGA */ | ||
226 | "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6, | ||
227 | 0, FB_VMODE_NONINTERLACED, | ||
228 | FB_MODE_IS_VESA | ||
229 | }, { | ||
230 | /* SXGA */ | ||
231 | "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, | ||
232 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, | ||
233 | FB_MODE_IS_VESA | ||
234 | }, { | ||
235 | /* WUXGA */ | ||
236 | "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6, | ||
237 | FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, | ||
238 | FB_MODE_IS_VESA | ||
239 | }, | ||
240 | |||
241 | /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */ | 197 | /* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */ |
242 | { | 198 | { |
243 | /* 480if */ | 199 | /* 480if */ |
@@ -276,12 +232,30 @@ static const struct fb_videomode ps3fb_modedb[] = { | |||
276 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | 232 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED |
277 | }, { | 233 | }, { |
278 | /* 1080if */ | 234 | /* 1080if */ |
279 | "1080f", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5, | 235 | "1080if", 50, 1920, 1080, 13468, 148, 484, 36, 4, 88, 5, |
280 | FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | 236 | FB_SYNC_BROADCAST, FB_VMODE_INTERLACED |
281 | }, { | 237 | }, { |
282 | /* 1080pf */ | 238 | /* 1080pf */ |
283 | "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5, | 239 | "1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5, |
284 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | 240 | FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED |
241 | }, | ||
242 | |||
243 | /* VESA modes (modes "11" to "13") */ | ||
244 | { | ||
245 | /* WXGA */ | ||
246 | "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6, | ||
247 | 0, FB_VMODE_NONINTERLACED, | ||
248 | FB_MODE_IS_VESA | ||
249 | }, { | ||
250 | /* SXGA */ | ||
251 | "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3, | ||
252 | FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, | ||
253 | FB_MODE_IS_VESA | ||
254 | }, { | ||
255 | /* WUXGA */ | ||
256 | "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6, | ||
257 | FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED, | ||
258 | FB_MODE_IS_VESA | ||
285 | } | 259 | } |
286 | }; | 260 | }; |
287 | 261 | ||
@@ -289,110 +263,188 @@ static const struct fb_videomode ps3fb_modedb[] = { | |||
289 | #define HEAD_A | 263 | #define HEAD_A |
290 | #define HEAD_B | 264 | #define HEAD_B |
291 | 265 | ||
292 | #define X_OFF(i) (ps3fb_res[i].xoff) /* left/right margin (pixel) */ | ||
293 | #define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */ | ||
294 | #define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */ | ||
295 | #define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */ | ||
296 | #define BPP 4 /* number of bytes per pixel */ | 266 | #define BPP 4 /* number of bytes per pixel */ |
297 | 267 | ||
298 | /* Start of the virtual frame buffer (relative to fullscreen ) */ | ||
299 | #define VP_OFF(i) ((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP) | ||
300 | |||
301 | 268 | ||
302 | static int ps3fb_mode; | 269 | static int ps3fb_mode; |
303 | module_param(ps3fb_mode, int, 0); | 270 | module_param(ps3fb_mode, int, 0); |
304 | 271 | ||
305 | static char *mode_option __devinitdata; | 272 | static char *mode_option __devinitdata; |
306 | 273 | ||
307 | static int ps3fb_get_res_table(u32 xres, u32 yres, int mode) | 274 | static int ps3fb_cmp_mode(const struct fb_videomode *vmode, |
275 | const struct fb_var_screeninfo *var) | ||
308 | { | 276 | { |
309 | int full_mode; | 277 | long xres, yres, left_margin, right_margin, upper_margin, lower_margin; |
310 | unsigned int i; | 278 | long dx, dy; |
311 | u32 x, y, f; | 279 | |
312 | 280 | /* maximum values */ | |
313 | full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0; | 281 | if (var->xres > vmode->xres || var->yres > vmode->yres || |
314 | for (i = 0;; i++) { | 282 | var->pixclock > vmode->pixclock || |
315 | x = ps3fb_res[i].xres; | 283 | var->hsync_len > vmode->hsync_len || |
316 | y = ps3fb_res[i].yres; | 284 | var->vsync_len > vmode->vsync_len) |
317 | f = ps3fb_res[i].type; | 285 | return -1; |
318 | |||
319 | if (!x) { | ||
320 | pr_debug("ERROR: ps3fb_get_res_table()\n"); | ||
321 | return -1; | ||
322 | } | ||
323 | 286 | ||
324 | if (full_mode == PS3FB_RES_FULL && f != PS3FB_RES_FULL) | 287 | /* progressive/interlaced must match */ |
325 | continue; | 288 | if ((var->vmode & FB_VMODE_MASK) != vmode->vmode) |
289 | return -1; | ||
326 | 290 | ||
327 | if (x == xres && (yres == 0 || y == yres)) | 291 | /* minimum resolution */ |
328 | break; | 292 | xres = max(var->xres, 1U); |
293 | yres = max(var->yres, 1U); | ||
294 | |||
295 | /* minimum margins */ | ||
296 | left_margin = max(var->left_margin, vmode->left_margin); | ||
297 | right_margin = max(var->right_margin, vmode->right_margin); | ||
298 | upper_margin = max(var->upper_margin, vmode->upper_margin); | ||
299 | lower_margin = max(var->lower_margin, vmode->lower_margin); | ||
300 | |||
301 | /* resolution + margins may not exceed native parameters */ | ||
302 | dx = ((long)vmode->left_margin + (long)vmode->xres + | ||
303 | (long)vmode->right_margin) - | ||
304 | (left_margin + xres + right_margin); | ||
305 | if (dx < 0) | ||
306 | return -1; | ||
329 | 307 | ||
330 | x = x - 2 * ps3fb_res[i].xoff; | 308 | dy = ((long)vmode->upper_margin + (long)vmode->yres + |
331 | y = y - 2 * ps3fb_res[i].yoff; | 309 | (long)vmode->lower_margin) - |
332 | if (x == xres && (yres == 0 || y == yres)) | 310 | (upper_margin + yres + lower_margin); |
333 | break; | 311 | if (dy < 0) |
312 | return -1; | ||
313 | |||
314 | /* exact match */ | ||
315 | if (!dx && !dy) | ||
316 | return 0; | ||
317 | |||
318 | /* resolution difference */ | ||
319 | return (vmode->xres - xres) * (vmode->yres - yres); | ||
320 | } | ||
321 | |||
322 | static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id) | ||
323 | { | ||
324 | return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1]; | ||
325 | } | ||
326 | |||
327 | static const struct fb_videomode *ps3fb_vmode(int id) | ||
328 | { | ||
329 | u32 mode = id & PS3AV_MODE_MASK; | ||
330 | |||
331 | if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA) | ||
332 | return NULL; | ||
333 | |||
334 | if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) { | ||
335 | /* Non-fullscreen broadcast mode */ | ||
336 | return &ps3fb_modedb[mode - 1]; | ||
334 | } | 337 | } |
335 | return i; | 338 | |
339 | return ps3fb_native_vmode(mode); | ||
336 | } | 340 | } |
337 | 341 | ||
338 | static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var, | 342 | static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var, |
339 | u32 *ddr_line_length, u32 *xdr_line_length) | 343 | u32 *ddr_line_length, u32 *xdr_line_length) |
340 | { | 344 | { |
341 | unsigned int i, mode; | 345 | unsigned int id, best_id; |
342 | 346 | int diff, best_diff; | |
343 | for (i = 0; i < ARRAY_SIZE(ps3fb_modedb); i++) | 347 | const struct fb_videomode *vmode; |
344 | if (var->xres == ps3fb_modedb[i].xres && | 348 | long gap; |
345 | var->yres == ps3fb_modedb[i].yres && | 349 | |
346 | var->pixclock == ps3fb_modedb[i].pixclock && | 350 | best_id = 0; |
347 | var->hsync_len == ps3fb_modedb[i].hsync_len && | 351 | best_diff = INT_MAX; |
348 | var->vsync_len == ps3fb_modedb[i].vsync_len && | 352 | pr_debug("%s: wanted %u [%u] %u x %u [%u] %u\n", __func__, |
349 | var->left_margin == ps3fb_modedb[i].left_margin && | 353 | var->left_margin, var->xres, var->right_margin, |
350 | var->right_margin == ps3fb_modedb[i].right_margin && | 354 | var->upper_margin, var->yres, var->lower_margin); |
351 | var->upper_margin == ps3fb_modedb[i].upper_margin && | 355 | for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) { |
352 | var->lower_margin == ps3fb_modedb[i].lower_margin && | 356 | vmode = ps3fb_native_vmode(id); |
353 | var->sync == ps3fb_modedb[i].sync && | 357 | diff = ps3fb_cmp_mode(vmode, var); |
354 | (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) | 358 | pr_debug("%s: mode %u: %u [%u] %u x %u [%u] %u: diff = %d\n", |
355 | goto found; | 359 | __func__, id, vmode->left_margin, vmode->xres, |
356 | 360 | vmode->right_margin, vmode->upper_margin, | |
357 | pr_debug("ps3fb_find_mode: mode not found\n"); | 361 | vmode->yres, vmode->lower_margin, diff); |
358 | return 0; | 362 | if (diff < 0) |
363 | continue; | ||
364 | if (diff < best_diff) { | ||
365 | best_id = id; | ||
366 | if (!diff) | ||
367 | break; | ||
368 | best_diff = diff; | ||
369 | } | ||
370 | } | ||
359 | 371 | ||
360 | found: | 372 | if (!best_id) { |
361 | /* Cropped broadcast modes use the full line length */ | 373 | pr_debug("%s: no suitable mode found\n", __func__); |
362 | *ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP; | 374 | return 0; |
375 | } | ||
363 | 376 | ||
364 | if (ps3_compare_firmware_version(1, 9, 0) >= 0) { | 377 | id = best_id; |
365 | *xdr_line_length = GPU_ALIGN_UP(max(var->xres, | 378 | vmode = ps3fb_native_vmode(id); |
366 | var->xres_virtual) * BPP); | ||
367 | if (*xdr_line_length > GPU_MAX_LINE_LENGTH) | ||
368 | *xdr_line_length = GPU_MAX_LINE_LENGTH; | ||
369 | } else | ||
370 | *xdr_line_length = *ddr_line_length; | ||
371 | 379 | ||
372 | /* Full broadcast modes have the full mode bit set */ | 380 | *ddr_line_length = vmode->xres * BPP; |
373 | mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1; | ||
374 | 381 | ||
375 | pr_debug("ps3fb_find_mode: mode %u\n", mode); | 382 | /* minimum resolution */ |
383 | if (!var->xres) | ||
384 | var->xres = 1; | ||
385 | if (!var->yres) | ||
386 | var->yres = 1; | ||
376 | 387 | ||
377 | return mode; | 388 | /* minimum virtual resolution */ |
378 | } | 389 | if (var->xres_virtual < var->xres) |
390 | var->xres_virtual = var->xres; | ||
391 | if (var->yres_virtual < var->yres) | ||
392 | var->yres_virtual = var->yres; | ||
379 | 393 | ||
380 | static const struct fb_videomode *ps3fb_default_mode(int id) | 394 | /* minimum margins */ |
381 | { | 395 | if (var->left_margin < vmode->left_margin) |
382 | u32 mode = id & PS3AV_MODE_MASK; | 396 | var->left_margin = vmode->left_margin; |
383 | u32 flags; | 397 | if (var->right_margin < vmode->right_margin) |
398 | var->right_margin = vmode->right_margin; | ||
399 | if (var->upper_margin < vmode->upper_margin) | ||
400 | var->upper_margin = vmode->upper_margin; | ||
401 | if (var->lower_margin < vmode->lower_margin) | ||
402 | var->lower_margin = vmode->lower_margin; | ||
403 | |||
404 | /* extra margins */ | ||
405 | gap = ((long)vmode->left_margin + (long)vmode->xres + | ||
406 | (long)vmode->right_margin) - | ||
407 | ((long)var->left_margin + (long)var->xres + | ||
408 | (long)var->right_margin); | ||
409 | if (gap > 0) { | ||
410 | var->left_margin += gap/2; | ||
411 | var->right_margin += (gap+1)/2; | ||
412 | pr_debug("%s: rounded up H to %u [%u] %u\n", __func__, | ||
413 | var->left_margin, var->xres, var->right_margin); | ||
414 | } | ||
384 | 415 | ||
385 | if (mode < 1 || mode > 13) | 416 | gap = ((long)vmode->upper_margin + (long)vmode->yres + |
386 | return NULL; | 417 | (long)vmode->lower_margin) - |
418 | ((long)var->upper_margin + (long)var->yres + | ||
419 | (long)var->lower_margin); | ||
420 | if (gap > 0) { | ||
421 | var->upper_margin += gap/2; | ||
422 | var->lower_margin += (gap+1)/2; | ||
423 | pr_debug("%s: rounded up V to %u [%u] %u\n", __func__, | ||
424 | var->upper_margin, var->yres, var->lower_margin); | ||
425 | } | ||
426 | |||
427 | /* fixed fields */ | ||
428 | var->pixclock = vmode->pixclock; | ||
429 | var->hsync_len = vmode->hsync_len; | ||
430 | var->vsync_len = vmode->vsync_len; | ||
431 | var->sync = vmode->sync; | ||
387 | 432 | ||
388 | flags = id & ~PS3AV_MODE_MASK; | 433 | if (ps3_compare_firmware_version(1, 9, 0) >= 0) { |
434 | *xdr_line_length = GPU_ALIGN_UP(var->xres_virtual * BPP); | ||
435 | if (*xdr_line_length > GPU_MAX_LINE_LENGTH) | ||
436 | *xdr_line_length = GPU_MAX_LINE_LENGTH; | ||
437 | } else | ||
438 | *xdr_line_length = *ddr_line_length; | ||
389 | 439 | ||
390 | if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) { | 440 | if (vmode->sync & FB_SYNC_BROADCAST) { |
391 | /* Full broadcast mode */ | 441 | /* Full broadcast modes have the full mode bit set */ |
392 | return &ps3fb_modedb[mode + 12]; | 442 | if (vmode->xres == var->xres && vmode->yres == var->yres) |
443 | id |= PS3AV_MODE_FULL; | ||
393 | } | 444 | } |
394 | 445 | ||
395 | return &ps3fb_modedb[mode - 1]; | 446 | pr_debug("%s: mode %u\n", __func__, id); |
447 | return id; | ||
396 | } | 448 | } |
397 | 449 | ||
398 | static void ps3fb_sync_image(struct device *dev, u64 frame_offset, | 450 | static void ps3fb_sync_image(struct device *dev, u64 frame_offset, |
@@ -439,8 +491,7 @@ static void ps3fb_sync_image(struct device *dev, u64 frame_offset, | |||
439 | static int ps3fb_sync(struct fb_info *info, u32 frame) | 491 | static int ps3fb_sync(struct fb_info *info, u32 frame) |
440 | { | 492 | { |
441 | struct ps3fb_par *par = info->par; | 493 | struct ps3fb_par *par = info->par; |
442 | int i, error = 0; | 494 | int error = 0; |
443 | u32 ddr_line_length, xdr_line_length; | ||
444 | u64 ddr_base, xdr_base; | 495 | u64 ddr_base, xdr_base; |
445 | 496 | ||
446 | if (frame > par->num_frames - 1) { | 497 | if (frame > par->num_frames - 1) { |
@@ -450,16 +501,13 @@ static int ps3fb_sync(struct fb_info *info, u32 frame) | |||
450 | goto out; | 501 | goto out; |
451 | } | 502 | } |
452 | 503 | ||
453 | i = par->res_index; | 504 | xdr_base = frame * par->xdr_frame_size; |
454 | xdr_line_length = info->fix.line_length; | 505 | ddr_base = frame * par->ddr_frame_size; |
455 | ddr_line_length = ps3fb_res[i].xres * BPP; | ||
456 | xdr_base = frame * info->var.yres_virtual * xdr_line_length; | ||
457 | ddr_base = frame * ps3fb_res[i].yres * ddr_line_length; | ||
458 | 506 | ||
459 | ps3fb_sync_image(info->device, ddr_base + par->full_offset, | 507 | ps3fb_sync_image(info->device, ddr_base + par->full_offset, |
460 | ddr_base + par->fb_offset, xdr_base + par->pan_offset, | 508 | ddr_base + par->fb_offset, xdr_base + par->pan_offset, |
461 | par->width, par->height, ddr_line_length, | 509 | par->width, par->height, par->ddr_line_length, |
462 | xdr_line_length); | 510 | info->fix.line_length); |
463 | 511 | ||
464 | out: | 512 | out: |
465 | return error; | 513 | return error; |
@@ -498,22 +546,11 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
498 | u32 xdr_line_length, ddr_line_length; | 546 | u32 xdr_line_length, ddr_line_length; |
499 | int mode; | 547 | int mode; |
500 | 548 | ||
501 | dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres, | ||
502 | info->var.xres); | ||
503 | dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres, | ||
504 | info->var.yres); | ||
505 | |||
506 | /* FIXME For now we do exact matches only */ | ||
507 | mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length); | 549 | mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length); |
508 | if (!mode) | 550 | if (!mode) |
509 | return -EINVAL; | 551 | return -EINVAL; |
510 | 552 | ||
511 | /* Virtual screen */ | 553 | /* Virtual screen */ |
512 | if (var->xres_virtual < var->xres) | ||
513 | var->xres_virtual = var->xres; | ||
514 | if (var->yres_virtual < var->yres) | ||
515 | var->yres_virtual = var->yres; | ||
516 | |||
517 | if (var->xres_virtual > xdr_line_length / BPP) { | 554 | if (var->xres_virtual > xdr_line_length / BPP) { |
518 | dev_dbg(info->device, | 555 | dev_dbg(info->device, |
519 | "Horizontal virtual screen size too large\n"); | 556 | "Horizontal virtual screen size too large\n"); |
@@ -559,7 +596,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
559 | } | 596 | } |
560 | 597 | ||
561 | /* Memory limit */ | 598 | /* Memory limit */ |
562 | if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) { | 599 | if (var->yres_virtual * xdr_line_length > info->fix.smem_len) { |
563 | dev_dbg(info->device, "Not enough memory\n"); | 600 | dev_dbg(info->device, "Not enough memory\n"); |
564 | return -ENOMEM; | 601 | return -ENOMEM; |
565 | } | 602 | } |
@@ -578,39 +615,38 @@ static int ps3fb_set_par(struct fb_info *info) | |||
578 | { | 615 | { |
579 | struct ps3fb_par *par = info->par; | 616 | struct ps3fb_par *par = info->par; |
580 | unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines; | 617 | unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines; |
581 | int i; | 618 | unsigned int ddr_xoff, ddr_yoff, offset; |
582 | unsigned long offset; | 619 | const struct fb_videomode *vmode; |
583 | u64 dst; | 620 | u64 dst; |
584 | 621 | ||
585 | dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n", | ||
586 | info->var.xres, info->var.xres_virtual, | ||
587 | info->var.yres, info->var.yres_virtual, info->var.pixclock); | ||
588 | |||
589 | mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length); | 622 | mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length); |
590 | if (!mode) | 623 | if (!mode) |
591 | return -EINVAL; | 624 | return -EINVAL; |
592 | 625 | ||
593 | i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode); | 626 | vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK); |
594 | par->res_index = i; | ||
595 | 627 | ||
596 | info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); | ||
597 | info->fix.smem_len = ps3fb.xdr_size; | ||
598 | info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; | 628 | info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0; |
599 | info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; | 629 | info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0; |
600 | info->fix.line_length = xdr_line_length; | 630 | info->fix.line_length = xdr_line_length; |
601 | 631 | ||
602 | info->screen_base = (char __iomem *)ps3fb.xdr_ea; | 632 | par->ddr_line_length = ddr_line_length; |
633 | par->ddr_frame_size = vmode->yres * ddr_line_length; | ||
634 | par->xdr_frame_size = info->var.yres_virtual * xdr_line_length; | ||
603 | 635 | ||
604 | par->num_frames = ps3fb.xdr_size / | 636 | par->num_frames = info->fix.smem_len / |
605 | max(ps3fb_res[i].yres * ddr_line_length, | 637 | max(par->ddr_frame_size, par->xdr_frame_size); |
606 | info->var.yres_virtual * xdr_line_length); | ||
607 | 638 | ||
608 | /* Keep the special bits we cannot set using fb_var_screeninfo */ | 639 | /* Keep the special bits we cannot set using fb_var_screeninfo */ |
609 | par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode; | 640 | par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode; |
610 | 641 | ||
611 | par->width = info->var.xres; | 642 | par->width = info->var.xres; |
612 | par->height = info->var.yres; | 643 | par->height = info->var.yres; |
613 | offset = VP_OFF(i); | 644 | |
645 | /* Start of the virtual frame buffer (relative to fullscreen) */ | ||
646 | ddr_xoff = info->var.left_margin - vmode->left_margin; | ||
647 | ddr_yoff = info->var.upper_margin - vmode->upper_margin; | ||
648 | offset = ddr_yoff * ddr_line_length + ddr_xoff * BPP; | ||
649 | |||
614 | par->fb_offset = GPU_ALIGN_UP(offset); | 650 | par->fb_offset = GPU_ALIGN_UP(offset); |
615 | par->full_offset = par->fb_offset - offset; | 651 | par->full_offset = par->fb_offset - offset; |
616 | par->pan_offset = info->var.yoffset * xdr_line_length + | 652 | par->pan_offset = info->var.yoffset * xdr_line_length + |
@@ -625,16 +661,16 @@ static int ps3fb_set_par(struct fb_info *info) | |||
625 | } | 661 | } |
626 | 662 | ||
627 | /* Clear XDR frame buffer memory */ | 663 | /* Clear XDR frame buffer memory */ |
628 | memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size); | 664 | memset((void __force *)info->screen_base, 0, info->fix.smem_len); |
629 | 665 | ||
630 | /* Clear DDR frame buffer memory */ | 666 | /* Clear DDR frame buffer memory */ |
631 | lines = ps3fb_res[i].yres * par->num_frames; | 667 | lines = vmode->yres * par->num_frames; |
632 | if (par->full_offset) | 668 | if (par->full_offset) |
633 | lines++; | 669 | lines++; |
634 | maxlines = ps3fb.xdr_size / ddr_line_length; | 670 | maxlines = info->fix.smem_len / ddr_line_length; |
635 | for (dst = 0; lines; dst += maxlines * ddr_line_length) { | 671 | for (dst = 0; lines; dst += maxlines * ddr_line_length) { |
636 | unsigned int l = min(lines, maxlines); | 672 | unsigned int l = min(lines, maxlines); |
637 | ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l, | 673 | ps3fb_sync_image(info->device, 0, dst, 0, vmode->xres, l, |
638 | ddr_line_length, ddr_line_length); | 674 | ddr_line_length, ddr_line_length); |
639 | lines -= l; | 675 | lines -= l; |
640 | } | 676 | } |
@@ -797,7 +833,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
797 | case PS3FB_IOCTL_SETMODE: | 833 | case PS3FB_IOCTL_SETMODE: |
798 | { | 834 | { |
799 | struct ps3fb_par *par = info->par; | 835 | struct ps3fb_par *par = info->par; |
800 | const struct fb_videomode *mode; | 836 | const struct fb_videomode *vmode; |
801 | struct fb_var_screeninfo var; | 837 | struct fb_var_screeninfo var; |
802 | 838 | ||
803 | if (copy_from_user(&val, argp, sizeof(val))) | 839 | if (copy_from_user(&val, argp, sizeof(val))) |
@@ -810,10 +846,10 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
810 | } | 846 | } |
811 | dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val); | 847 | dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val); |
812 | retval = -EINVAL; | 848 | retval = -EINVAL; |
813 | mode = ps3fb_default_mode(val); | 849 | vmode = ps3fb_vmode(val); |
814 | if (mode) { | 850 | if (vmode) { |
815 | var = info->var; | 851 | var = info->var; |
816 | fb_videomode_to_var(&var, mode); | 852 | fb_videomode_to_var(&var, vmode); |
817 | acquire_console_sem(); | 853 | acquire_console_sem(); |
818 | info->flags |= FBINFO_MISC_USEREVENT; | 854 | info->flags |= FBINFO_MISC_USEREVENT; |
819 | /* Force, in case only special bits changed */ | 855 | /* Force, in case only special bits changed */ |
@@ -975,10 +1011,9 @@ static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev) | |||
975 | __func__, status); | 1011 | __func__, status); |
976 | return -ENXIO; | 1012 | return -ENXIO; |
977 | } | 1013 | } |
978 | dev_dbg(dev, | 1014 | dev_dbg(dev, "video:%p ioif:%lx lpar:%lx size:%lx\n", |
979 | "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", | 1015 | ps3fb_videomemory.address, GPU_IOIF, xdr_lpar, |
980 | ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar, | 1016 | ps3fb_videomemory.size); |
981 | virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size); | ||
982 | 1017 | ||
983 | status = lv1_gpu_context_attribute(ps3fb.context_handle, | 1018 | status = lv1_gpu_context_attribute(ps3fb.context_handle, |
984 | L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, | 1019 | L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, |
@@ -1055,14 +1090,14 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1055 | struct fb_info *info; | 1090 | struct fb_info *info; |
1056 | struct ps3fb_par *par; | 1091 | struct ps3fb_par *par; |
1057 | int retval = -ENOMEM; | 1092 | int retval = -ENOMEM; |
1058 | u32 xres, yres; | ||
1059 | u64 ddr_lpar = 0; | 1093 | u64 ddr_lpar = 0; |
1060 | u64 lpar_dma_control = 0; | 1094 | u64 lpar_dma_control = 0; |
1061 | u64 lpar_driver_info = 0; | 1095 | u64 lpar_driver_info = 0; |
1062 | u64 lpar_reports = 0; | 1096 | u64 lpar_reports = 0; |
1063 | u64 lpar_reports_size = 0; | 1097 | u64 lpar_reports_size = 0; |
1064 | u64 xdr_lpar; | 1098 | u64 xdr_lpar; |
1065 | int status, res_index; | 1099 | void *fb_start; |
1100 | int status; | ||
1066 | struct task_struct *task; | 1101 | struct task_struct *task; |
1067 | unsigned long max_ps3fb_size; | 1102 | unsigned long max_ps3fb_size; |
1068 | 1103 | ||
@@ -1080,14 +1115,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1080 | 1115 | ||
1081 | if (!ps3fb_mode) | 1116 | if (!ps3fb_mode) |
1082 | ps3fb_mode = ps3av_get_mode(); | 1117 | ps3fb_mode = ps3av_get_mode(); |
1083 | dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode); | 1118 | dev_dbg(&dev->core, "ps3fb_mode: %d\n", ps3fb_mode); |
1084 | |||
1085 | if (ps3fb_mode > 0 && | ||
1086 | !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) { | ||
1087 | res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode); | ||
1088 | dev_dbg(&dev->core, "res_index:%d\n", res_index); | ||
1089 | } else | ||
1090 | res_index = GPU_RES_INDEX; | ||
1091 | 1119 | ||
1092 | atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ | 1120 | atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ |
1093 | atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ | 1121 | atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ |
@@ -1124,7 +1152,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1124 | } | 1152 | } |
1125 | 1153 | ||
1126 | /* vsync interrupt */ | 1154 | /* vsync interrupt */ |
1127 | ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); | 1155 | ps3fb.dinfo = (void __force *)ioremap(lpar_driver_info, 128 * 1024); |
1128 | if (!ps3fb.dinfo) { | 1156 | if (!ps3fb.dinfo) { |
1129 | dev_err(&dev->core, "%s: ioremap failed\n", __func__); | 1157 | dev_err(&dev->core, "%s: ioremap failed\n", __func__); |
1130 | goto err_gpu_context_free; | 1158 | goto err_gpu_context_free; |
@@ -1134,22 +1162,10 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1134 | if (retval) | 1162 | if (retval) |
1135 | goto err_iounmap_dinfo; | 1163 | goto err_iounmap_dinfo; |
1136 | 1164 | ||
1137 | /* XDR frame buffer */ | ||
1138 | ps3fb.xdr_ea = ps3fb_videomemory.address; | ||
1139 | xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea)); | ||
1140 | |||
1141 | /* Clear memory to prevent kernel info leakage into userspace */ | 1165 | /* Clear memory to prevent kernel info leakage into userspace */ |
1142 | memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); | 1166 | memset(ps3fb_videomemory.address, 0, ps3fb_videomemory.size); |
1143 | |||
1144 | /* | ||
1145 | * The GPU command buffer is at the start of video memory | ||
1146 | * As we don't use the full command buffer, we can put the actual | ||
1147 | * frame buffer at offset GPU_FB_START and save some precious XDR | ||
1148 | * memory | ||
1149 | */ | ||
1150 | ps3fb.xdr_ea += GPU_FB_START; | ||
1151 | ps3fb.xdr_size = ps3fb_videomemory.size - GPU_FB_START; | ||
1152 | 1167 | ||
1168 | xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb_videomemory.address)); | ||
1153 | retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); | 1169 | retval = ps3fb_xdr_settings(xdr_lpar, &dev->core); |
1154 | if (retval) | 1170 | if (retval) |
1155 | goto err_free_irq; | 1171 | goto err_free_irq; |
@@ -1161,15 +1177,22 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1161 | par = info->par; | 1177 | par = info->par; |
1162 | par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ | 1178 | par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */ |
1163 | par->new_mode_id = ps3fb_mode; | 1179 | par->new_mode_id = ps3fb_mode; |
1164 | par->res_index = res_index; | ||
1165 | par->num_frames = 1; | 1180 | par->num_frames = 1; |
1166 | 1181 | ||
1167 | info->screen_base = (char __iomem *)ps3fb.xdr_ea; | ||
1168 | info->fbops = &ps3fb_ops; | 1182 | info->fbops = &ps3fb_ops; |
1169 | |||
1170 | info->fix = ps3fb_fix; | 1183 | info->fix = ps3fb_fix; |
1171 | info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); | 1184 | |
1172 | info->fix.smem_len = ps3fb.xdr_size; | 1185 | /* |
1186 | * The GPU command buffer is at the start of video memory | ||
1187 | * As we don't use the full command buffer, we can put the actual | ||
1188 | * frame buffer at offset GPU_FB_START and save some precious XDR | ||
1189 | * memory | ||
1190 | */ | ||
1191 | fb_start = ps3fb_videomemory.address + GPU_FB_START; | ||
1192 | info->screen_base = (char __force __iomem *)fb_start; | ||
1193 | info->fix.smem_start = virt_to_abs(fb_start); | ||
1194 | info->fix.smem_len = ps3fb_videomemory.size - GPU_FB_START; | ||
1195 | |||
1173 | info->pseudo_palette = par->pseudo_palette; | 1196 | info->pseudo_palette = par->pseudo_palette; |
1174 | info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST | | 1197 | info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST | |
1175 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; | 1198 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; |
@@ -1180,7 +1203,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1180 | 1203 | ||
1181 | if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, | 1204 | if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, |
1182 | ARRAY_SIZE(ps3fb_modedb), | 1205 | ARRAY_SIZE(ps3fb_modedb), |
1183 | ps3fb_default_mode(par->new_mode_id), 32)) { | 1206 | ps3fb_vmode(par->new_mode_id), 32)) { |
1184 | retval = -EINVAL; | 1207 | retval = -EINVAL; |
1185 | goto err_fb_dealloc; | 1208 | goto err_fb_dealloc; |
1186 | } | 1209 | } |
@@ -1194,9 +1217,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) | |||
1194 | 1217 | ||
1195 | dev->core.driver_data = info; | 1218 | dev->core.driver_data = info; |
1196 | 1219 | ||
1197 | dev_info(info->device, "%s %s, using %lu KiB of video memory\n", | 1220 | dev_info(info->device, "%s %s, using %u KiB of video memory\n", |
1198 | dev_driver_string(info->dev), info->dev->bus_id, | 1221 | dev_driver_string(info->dev), info->dev->bus_id, |
1199 | ps3fb.xdr_size >> 10); | 1222 | info->fix.smem_len >> 10); |
1200 | 1223 | ||
1201 | task = kthread_run(ps3fbd, info, DEVICE_NAME); | 1224 | task = kthread_run(ps3fbd, info, DEVICE_NAME); |
1202 | if (IS_ERR(task)) { | 1225 | if (IS_ERR(task)) { |
@@ -1219,7 +1242,7 @@ err_free_irq: | |||
1219 | free_irq(ps3fb.irq_no, &dev->core); | 1242 | free_irq(ps3fb.irq_no, &dev->core); |
1220 | ps3_irq_plug_destroy(ps3fb.irq_no); | 1243 | ps3_irq_plug_destroy(ps3fb.irq_no); |
1221 | err_iounmap_dinfo: | 1244 | err_iounmap_dinfo: |
1222 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1245 | iounmap((u8 __force __iomem *)ps3fb.dinfo); |
1223 | err_gpu_context_free: | 1246 | err_gpu_context_free: |
1224 | lv1_gpu_context_free(ps3fb.context_handle); | 1247 | lv1_gpu_context_free(ps3fb.context_handle); |
1225 | err_gpu_memory_free: | 1248 | err_gpu_memory_free: |
@@ -1254,7 +1277,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev) | |||
1254 | framebuffer_release(info); | 1277 | framebuffer_release(info); |
1255 | info = dev->core.driver_data = NULL; | 1278 | info = dev->core.driver_data = NULL; |
1256 | } | 1279 | } |
1257 | iounmap((u8 __iomem *)ps3fb.dinfo); | 1280 | iounmap((u8 __force __iomem *)ps3fb.dinfo); |
1258 | 1281 | ||
1259 | status = lv1_gpu_context_free(ps3fb.context_handle); | 1282 | status = lv1_gpu_context_free(ps3fb.context_handle); |
1260 | if (status) | 1283 | if (status) |
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c index b3c31d9dc591..71fa6edb5c47 100644 --- a/drivers/video/s3c2410fb.c +++ b/drivers/video/s3c2410fb.c | |||
@@ -110,6 +110,11 @@ static int debug = 0; | |||
110 | 110 | ||
111 | /* useful functions */ | 111 | /* useful functions */ |
112 | 112 | ||
113 | static int is_s3c2412(struct s3c2410fb_info *fbi) | ||
114 | { | ||
115 | return (fbi->drv_type == DRV_S3C2412); | ||
116 | } | ||
117 | |||
113 | /* s3c2410fb_set_lcdaddr | 118 | /* s3c2410fb_set_lcdaddr |
114 | * | 119 | * |
115 | * initialise lcd controller address pointers | 120 | * initialise lcd controller address pointers |
@@ -501,7 +506,7 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi, | |||
501 | { | 506 | { |
502 | unsigned long flags; | 507 | unsigned long flags; |
503 | unsigned long irqen; | 508 | unsigned long irqen; |
504 | void __iomem *regs = fbi->io; | 509 | void __iomem *irq_base = fbi->irq_base; |
505 | 510 | ||
506 | local_irq_save(flags); | 511 | local_irq_save(flags); |
507 | 512 | ||
@@ -511,9 +516,9 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi, | |||
511 | fbi->palette_ready = 1; | 516 | fbi->palette_ready = 1; |
512 | 517 | ||
513 | /* enable IRQ */ | 518 | /* enable IRQ */ |
514 | irqen = readl(regs + S3C2410_LCDINTMSK); | 519 | irqen = readl(irq_base + S3C24XX_LCDINTMSK); |
515 | irqen &= ~S3C2410_LCDINT_FRSYNC; | 520 | irqen &= ~S3C2410_LCDINT_FRSYNC; |
516 | writel(irqen, regs + S3C2410_LCDINTMSK); | 521 | writel(irqen, irq_base + S3C24XX_LCDINTMSK); |
517 | } | 522 | } |
518 | 523 | ||
519 | local_irq_restore(flags); | 524 | local_irq_restore(flags); |
@@ -594,15 +599,17 @@ static int s3c2410fb_setcolreg(unsigned regno, | |||
594 | static int s3c2410fb_blank(int blank_mode, struct fb_info *info) | 599 | static int s3c2410fb_blank(int blank_mode, struct fb_info *info) |
595 | { | 600 | { |
596 | struct s3c2410fb_info *fbi = info->par; | 601 | struct s3c2410fb_info *fbi = info->par; |
597 | void __iomem *regs = fbi->io; | 602 | void __iomem *tpal_reg = fbi->io; |
598 | 603 | ||
599 | dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); | 604 | dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); |
600 | 605 | ||
606 | tpal_reg += is_s3c2412(fbi) ? S3C2412_TPAL : S3C2410_TPAL; | ||
607 | |||
601 | if (blank_mode == FB_BLANK_UNBLANK) | 608 | if (blank_mode == FB_BLANK_UNBLANK) |
602 | writel(0x0, regs + S3C2410_TPAL); | 609 | writel(0x0, tpal_reg); |
603 | else { | 610 | else { |
604 | dprintk("setting TPAL to output 0x000000\n"); | 611 | dprintk("setting TPAL to output 0x000000\n"); |
605 | writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL); | 612 | writel(S3C2410_TPAL_EN, tpal_reg); |
606 | } | 613 | } |
607 | 614 | ||
608 | return 0; | 615 | return 0; |
@@ -663,7 +670,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info) | |||
663 | dma_addr_t map_dma; | 670 | dma_addr_t map_dma; |
664 | unsigned map_size = PAGE_ALIGN(info->fix.smem_len); | 671 | unsigned map_size = PAGE_ALIGN(info->fix.smem_len); |
665 | 672 | ||
666 | dprintk("map_video_memory(fbi=%p)\n", fbi); | 673 | dprintk("map_video_memory(fbi=%p) map_size %u\n", fbi, map_size); |
667 | 674 | ||
668 | info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, | 675 | info->screen_base = dma_alloc_writecombine(fbi->dev, map_size, |
669 | &map_dma, GFP_KERNEL); | 676 | &map_dma, GFP_KERNEL); |
@@ -672,7 +679,7 @@ static int __init s3c2410fb_map_video_memory(struct fb_info *info) | |||
672 | /* prevent initial garbage on screen */ | 679 | /* prevent initial garbage on screen */ |
673 | dprintk("map_video_memory: clear %p:%08x\n", | 680 | dprintk("map_video_memory: clear %p:%08x\n", |
674 | info->screen_base, map_size); | 681 | info->screen_base, map_size); |
675 | memset(info->screen_base, 0xf0, map_size); | 682 | memset(info->screen_base, 0x00, map_size); |
676 | 683 | ||
677 | info->fix.smem_start = map_dma; | 684 | info->fix.smem_start = map_dma; |
678 | 685 | ||
@@ -709,6 +716,16 @@ static int s3c2410fb_init_registers(struct fb_info *info) | |||
709 | struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; | 716 | struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data; |
710 | unsigned long flags; | 717 | unsigned long flags; |
711 | void __iomem *regs = fbi->io; | 718 | void __iomem *regs = fbi->io; |
719 | void __iomem *tpal; | ||
720 | void __iomem *lpcsel; | ||
721 | |||
722 | if (is_s3c2412(fbi)) { | ||
723 | tpal = regs + S3C2412_TPAL; | ||
724 | lpcsel = regs + S3C2412_TCONSEL; | ||
725 | } else { | ||
726 | tpal = regs + S3C2410_TPAL; | ||
727 | lpcsel = regs + S3C2410_LPCSEL; | ||
728 | } | ||
712 | 729 | ||
713 | /* Initialise LCD with values from haret */ | 730 | /* Initialise LCD with values from haret */ |
714 | 731 | ||
@@ -724,12 +741,12 @@ static int s3c2410fb_init_registers(struct fb_info *info) | |||
724 | local_irq_restore(flags); | 741 | local_irq_restore(flags); |
725 | 742 | ||
726 | dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); | 743 | dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); |
727 | writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); | 744 | writel(mach_info->lpcsel, lpcsel); |
728 | 745 | ||
729 | dprintk("replacing TPAL %08x\n", readl(regs + S3C2410_TPAL)); | 746 | dprintk("replacing TPAL %08x\n", readl(tpal)); |
730 | 747 | ||
731 | /* ensure temporary palette disabled */ | 748 | /* ensure temporary palette disabled */ |
732 | writel(0x00, regs + S3C2410_TPAL); | 749 | writel(0x00, tpal); |
733 | 750 | ||
734 | return 0; | 751 | return 0; |
735 | } | 752 | } |
@@ -763,15 +780,15 @@ static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) | |||
763 | static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | 780 | static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) |
764 | { | 781 | { |
765 | struct s3c2410fb_info *fbi = dev_id; | 782 | struct s3c2410fb_info *fbi = dev_id; |
766 | void __iomem *regs = fbi->io; | 783 | void __iomem *irq_base = fbi->irq_base; |
767 | unsigned long lcdirq = readl(regs + S3C2410_LCDINTPND); | 784 | unsigned long lcdirq = readl(irq_base + S3C24XX_LCDINTPND); |
768 | 785 | ||
769 | if (lcdirq & S3C2410_LCDINT_FRSYNC) { | 786 | if (lcdirq & S3C2410_LCDINT_FRSYNC) { |
770 | if (fbi->palette_ready) | 787 | if (fbi->palette_ready) |
771 | s3c2410fb_write_palette(fbi); | 788 | s3c2410fb_write_palette(fbi); |
772 | 789 | ||
773 | writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDINTPND); | 790 | writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDINTPND); |
774 | writel(S3C2410_LCDINT_FRSYNC, regs + S3C2410_LCDSRCPND); | 791 | writel(S3C2410_LCDINT_FRSYNC, irq_base + S3C24XX_LCDSRCPND); |
775 | } | 792 | } |
776 | 793 | ||
777 | return IRQ_HANDLED; | 794 | return IRQ_HANDLED; |
@@ -779,7 +796,8 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id) | |||
779 | 796 | ||
780 | static char driver_name[] = "s3c2410fb"; | 797 | static char driver_name[] = "s3c2410fb"; |
781 | 798 | ||
782 | static int __init s3c2410fb_probe(struct platform_device *pdev) | 799 | static int __init s3c24xxfb_probe(struct platform_device *pdev, |
800 | enum s3c_drv_type drv_type) | ||
783 | { | 801 | { |
784 | struct s3c2410fb_info *info; | 802 | struct s3c2410fb_info *info; |
785 | struct s3c2410fb_display *display; | 803 | struct s3c2410fb_display *display; |
@@ -799,6 +817,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
799 | return -EINVAL; | 817 | return -EINVAL; |
800 | } | 818 | } |
801 | 819 | ||
820 | if (mach_info->default_display >= mach_info->num_displays) { | ||
821 | dev_err(&pdev->dev, "default is %d but only %d displays\n", | ||
822 | mach_info->default_display, mach_info->num_displays); | ||
823 | return -EINVAL; | ||
824 | } | ||
825 | |||
802 | display = mach_info->displays + mach_info->default_display; | 826 | display = mach_info->displays + mach_info->default_display; |
803 | 827 | ||
804 | irq = platform_get_irq(pdev, 0); | 828 | irq = platform_get_irq(pdev, 0); |
@@ -815,6 +839,7 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
815 | 839 | ||
816 | info = fbinfo->par; | 840 | info = fbinfo->par; |
817 | info->dev = &pdev->dev; | 841 | info->dev = &pdev->dev; |
842 | info->drv_type = drv_type; | ||
818 | 843 | ||
819 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 844 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
820 | if (res == NULL) { | 845 | if (res == NULL) { |
@@ -838,6 +863,8 @@ static int __init s3c2410fb_probe(struct platform_device *pdev) | |||
838 | goto release_mem; | 863 | goto release_mem; |
839 | } | 864 | } |
840 | 865 | ||
866 | info->irq_base = info->io + ((drv_type == DRV_S3C2412) ? S3C2412_LCDINTBASE : S3C2410_LCDINTBASE); | ||
867 | |||
841 | dprintk("devinit\n"); | 868 | dprintk("devinit\n"); |
842 | 869 | ||
843 | strcpy(fbinfo->fix.id, driver_name); | 870 | strcpy(fbinfo->fix.id, driver_name); |
@@ -946,6 +973,16 @@ dealloc_fb: | |||
946 | return ret; | 973 | return ret; |
947 | } | 974 | } |
948 | 975 | ||
976 | static int __init s3c2410fb_probe(struct platform_device *pdev) | ||
977 | { | ||
978 | return s3c24xxfb_probe(pdev, DRV_S3C2410); | ||
979 | } | ||
980 | |||
981 | static int __init s3c2412fb_probe(struct platform_device *pdev) | ||
982 | { | ||
983 | return s3c24xxfb_probe(pdev, DRV_S3C2412); | ||
984 | } | ||
985 | |||
949 | /* s3c2410fb_stop_lcd | 986 | /* s3c2410fb_stop_lcd |
950 | * | 987 | * |
951 | * shutdown the lcd controller | 988 | * shutdown the lcd controller |
@@ -1047,14 +1084,31 @@ static struct platform_driver s3c2410fb_driver = { | |||
1047 | }, | 1084 | }, |
1048 | }; | 1085 | }; |
1049 | 1086 | ||
1087 | static struct platform_driver s3c2412fb_driver = { | ||
1088 | .probe = s3c2412fb_probe, | ||
1089 | .remove = s3c2410fb_remove, | ||
1090 | .suspend = s3c2410fb_suspend, | ||
1091 | .resume = s3c2410fb_resume, | ||
1092 | .driver = { | ||
1093 | .name = "s3c2412-lcd", | ||
1094 | .owner = THIS_MODULE, | ||
1095 | }, | ||
1096 | }; | ||
1097 | |||
1050 | int __init s3c2410fb_init(void) | 1098 | int __init s3c2410fb_init(void) |
1051 | { | 1099 | { |
1052 | return platform_driver_register(&s3c2410fb_driver); | 1100 | int ret = platform_driver_register(&s3c2410fb_driver); |
1101 | |||
1102 | if (ret == 0) | ||
1103 | ret = platform_driver_register(&s3c2412fb_driver);; | ||
1104 | |||
1105 | return ret; | ||
1053 | } | 1106 | } |
1054 | 1107 | ||
1055 | static void __exit s3c2410fb_cleanup(void) | 1108 | static void __exit s3c2410fb_cleanup(void) |
1056 | { | 1109 | { |
1057 | platform_driver_unregister(&s3c2410fb_driver); | 1110 | platform_driver_unregister(&s3c2410fb_driver); |
1111 | platform_driver_unregister(&s3c2412fb_driver); | ||
1058 | } | 1112 | } |
1059 | 1113 | ||
1060 | module_init(s3c2410fb_init); | 1114 | module_init(s3c2410fb_init); |
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h index 6ce5dc26c5f7..dbb73b95e2ef 100644 --- a/drivers/video/s3c2410fb.h +++ b/drivers/video/s3c2410fb.h | |||
@@ -25,13 +25,20 @@ | |||
25 | #ifndef __S3C2410FB_H | 25 | #ifndef __S3C2410FB_H |
26 | #define __S3C2410FB_H | 26 | #define __S3C2410FB_H |
27 | 27 | ||
28 | enum s3c_drv_type { | ||
29 | DRV_S3C2410, | ||
30 | DRV_S3C2412, | ||
31 | }; | ||
32 | |||
28 | struct s3c2410fb_info { | 33 | struct s3c2410fb_info { |
29 | struct device *dev; | 34 | struct device *dev; |
30 | struct clk *clk; | 35 | struct clk *clk; |
31 | 36 | ||
32 | struct resource *mem; | 37 | struct resource *mem; |
33 | void __iomem *io; | 38 | void __iomem *io; |
39 | void __iomem *irq_base; | ||
34 | 40 | ||
41 | enum s3c_drv_type drv_type; | ||
35 | struct s3c2410fb_hw regs; | 42 | struct s3c2410fb_hw regs; |
36 | 43 | ||
37 | unsigned int palette_ready; | 44 | unsigned int palette_ready; |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index 93ae747440cb..73803624c131 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -427,7 +427,7 @@ sisfb_interpret_edid(struct sisfb_monitor *monitor, u8 *buffer) | |||
427 | 427 | ||
428 | monitor->feature = buffer[0x18]; | 428 | monitor->feature = buffer[0x18]; |
429 | 429 | ||
430 | if(!buffer[0x14] & 0x80) { | 430 | if(!(buffer[0x14] & 0x80)) { |
431 | if(!(buffer[0x14] & 0x08)) { | 431 | if(!(buffer[0x14] & 0x08)) { |
432 | printk(KERN_INFO | 432 | printk(KERN_INFO |
433 | "sisfb: WARNING: Monitor does not support separate syncs\n"); | 433 | "sisfb: WARNING: Monitor does not support separate syncs\n"); |
@@ -4621,9 +4621,9 @@ sisfb_find_host_bridge(struct sis_video_info *ivideo, struct pci_dev *mypdev, | |||
4621 | 4621 | ||
4622 | while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { | 4622 | while((pdev = pci_get_class(PCI_CLASS_BRIDGE_HOST, pdev))) { |
4623 | temp = pdev->vendor; | 4623 | temp = pdev->vendor; |
4624 | pci_dev_put(pdev); | ||
4625 | if(temp == pcivendor) { | 4624 | if(temp == pcivendor) { |
4626 | ret = 1; | 4625 | ret = 1; |
4626 | pci_dev_put(pdev); | ||
4627 | break; | 4627 | break; |
4628 | } | 4628 | } |
4629 | } | 4629 | } |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 58f200c69be3..e83dfba7e636 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -641,6 +641,7 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
641 | { | 641 | { |
642 | unsigned long control; | 642 | unsigned long control; |
643 | void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; | 643 | void __iomem *ctrl_reg = fbi->regs + SM501_DC_PANEL_CONTROL; |
644 | struct sm501_platdata_fbsub *pd = fbi->pdata->fb_pnl; | ||
644 | 645 | ||
645 | control = readl(ctrl_reg); | 646 | control = readl(ctrl_reg); |
646 | 647 | ||
@@ -657,26 +658,34 @@ static void sm501fb_panel_power(struct sm501fb_info *fbi, int to) | |||
657 | sm501fb_sync_regs(fbi); | 658 | sm501fb_sync_regs(fbi); |
658 | mdelay(10); | 659 | mdelay(10); |
659 | 660 | ||
660 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ | 661 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { |
661 | writel(control, ctrl_reg); | 662 | control |= SM501_DC_PANEL_CONTROL_BIAS; /* VBIASEN */ |
662 | sm501fb_sync_regs(fbi); | 663 | writel(control, ctrl_reg); |
663 | mdelay(10); | 664 | sm501fb_sync_regs(fbi); |
664 | 665 | mdelay(10); | |
665 | control |= SM501_DC_PANEL_CONTROL_FPEN; | 666 | } |
666 | writel(control, ctrl_reg); | ||
667 | 667 | ||
668 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | ||
669 | control |= SM501_DC_PANEL_CONTROL_FPEN; | ||
670 | writel(control, ctrl_reg); | ||
671 | sm501fb_sync_regs(fbi); | ||
672 | mdelay(10); | ||
673 | } | ||
668 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { | 674 | } else if (!to && (control & SM501_DC_PANEL_CONTROL_VDD) != 0) { |
669 | /* disable panel power */ | 675 | /* disable panel power */ |
676 | if (pd->flags & SM501FB_FLAG_PANEL_USE_FPEN) { | ||
677 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | ||
678 | writel(control, ctrl_reg); | ||
679 | sm501fb_sync_regs(fbi); | ||
680 | mdelay(10); | ||
681 | } | ||
670 | 682 | ||
671 | control &= ~SM501_DC_PANEL_CONTROL_FPEN; | 683 | if (pd->flags & SM501FB_FLAG_PANEL_USE_VBIASEN) { |
672 | writel(control, ctrl_reg); | 684 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; |
673 | sm501fb_sync_regs(fbi); | 685 | writel(control, ctrl_reg); |
674 | mdelay(10); | 686 | sm501fb_sync_regs(fbi); |
675 | 687 | mdelay(10); | |
676 | control &= ~SM501_DC_PANEL_CONTROL_BIAS; | 688 | } |
677 | writel(control, ctrl_reg); | ||
678 | sm501fb_sync_regs(fbi); | ||
679 | mdelay(10); | ||
680 | 689 | ||
681 | control &= ~SM501_DC_PANEL_CONTROL_DATA; | 690 | control &= ~SM501_DC_PANEL_CONTROL_DATA; |
682 | writel(control, ctrl_reg); | 691 | writel(control, ctrl_reg); |
@@ -1267,6 +1276,7 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1267 | { | 1276 | { |
1268 | struct resource *res; | 1277 | struct resource *res; |
1269 | struct device *dev; | 1278 | struct device *dev; |
1279 | int k; | ||
1270 | int ret; | 1280 | int ret; |
1271 | 1281 | ||
1272 | info->dev = dev = &pdev->dev; | 1282 | info->dev = dev = &pdev->dev; |
@@ -1328,6 +1338,13 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1328 | 1338 | ||
1329 | info->fbmem_len = (res->end - res->start)+1; | 1339 | info->fbmem_len = (res->end - res->start)+1; |
1330 | 1340 | ||
1341 | /* clear framebuffer memory - avoids garbage data on unused fb */ | ||
1342 | memset(info->fbmem, 0, info->fbmem_len); | ||
1343 | |||
1344 | /* clear palette ram - undefined at power on */ | ||
1345 | for (k = 0; k < (256 * 3); k++) | ||
1346 | writel(0, info->regs + SM501_DC_PANEL_PALETTE + (k * 4)); | ||
1347 | |||
1331 | /* enable display controller */ | 1348 | /* enable display controller */ |
1332 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); | 1349 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); |
1333 | 1350 | ||
@@ -1681,6 +1698,15 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info, | |||
1681 | if (par->screen.size == 0) | 1698 | if (par->screen.size == 0) |
1682 | return 0; | 1699 | return 0; |
1683 | 1700 | ||
1701 | /* blank the relevant interface to ensure unit power minimised */ | ||
1702 | (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); | ||
1703 | |||
1704 | /* tell console/fb driver we are suspending */ | ||
1705 | |||
1706 | acquire_console_sem(); | ||
1707 | fb_set_suspend(fbi, 1); | ||
1708 | release_console_sem(); | ||
1709 | |||
1684 | /* backup copies in case chip is powered down over suspend */ | 1710 | /* backup copies in case chip is powered down over suspend */ |
1685 | 1711 | ||
1686 | par->store_fb = vmalloc(par->screen.size); | 1712 | par->store_fb = vmalloc(par->screen.size); |
@@ -1700,12 +1726,6 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info, | |||
1700 | 1726 | ||
1701 | memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); | 1727 | memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); |
1702 | memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); | 1728 | memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); |
1703 | /* blank the relevant interface to ensure unit power minimised */ | ||
1704 | (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); | ||
1705 | |||
1706 | acquire_console_sem(); | ||
1707 | fb_set_suspend(fbi, 1); | ||
1708 | release_console_sem(); | ||
1709 | 1729 | ||
1710 | return 0; | 1730 | return 0; |
1711 | 1731 | ||
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c index 057bdd593800..71e179ea5f95 100644 --- a/drivers/video/tdfxfb.c +++ b/drivers/video/tdfxfb.c | |||
@@ -1342,7 +1342,7 @@ out_err: | |||
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | #ifndef MODULE | 1344 | #ifndef MODULE |
1345 | static void tdfxfb_setup(char *options) | 1345 | static void __init tdfxfb_setup(char *options) |
1346 | { | 1346 | { |
1347 | char *this_opt; | 1347 | char *this_opt; |
1348 | 1348 | ||
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c index a14ef894d571..be27b9c1ed72 100644 --- a/drivers/video/uvesafb.c +++ b/drivers/video/uvesafb.c | |||
@@ -2003,12 +2003,12 @@ static void __devexit uvesafb_exit(void) | |||
2003 | 2003 | ||
2004 | module_exit(uvesafb_exit); | 2004 | module_exit(uvesafb_exit); |
2005 | 2005 | ||
2006 | static inline int param_get_scroll(char *buffer, struct kernel_param *kp) | 2006 | static int param_get_scroll(char *buffer, struct kernel_param *kp) |
2007 | { | 2007 | { |
2008 | return 0; | 2008 | return 0; |
2009 | } | 2009 | } |
2010 | 2010 | ||
2011 | static inline int param_set_scroll(const char *val, struct kernel_param *kp) | 2011 | static int param_set_scroll(const char *val, struct kernel_param *kp) |
2012 | { | 2012 | { |
2013 | ypan = 0; | 2013 | ypan = 0; |
2014 | 2014 | ||
@@ -2022,11 +2022,11 @@ static inline int param_set_scroll(const char *val, struct kernel_param *kp) | |||
2022 | return 0; | 2022 | return 0; |
2023 | } | 2023 | } |
2024 | 2024 | ||
2025 | #define param_check_scroll(name, p) __param_check(name, p, void); | 2025 | #define param_check_scroll(name, p) __param_check(name, p, void) |
2026 | 2026 | ||
2027 | module_param_named(scroll, ypan, scroll, 0); | 2027 | module_param_named(scroll, ypan, scroll, 0); |
2028 | MODULE_PARM_DESC(scroll, | 2028 | MODULE_PARM_DESC(scroll, |
2029 | "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'"); | 2029 | "Scrolling mode, set to 'redraw', 'ypan', or 'ywrap'"); |
2030 | module_param_named(vgapal, pmi_setpal, invbool, 0); | 2030 | module_param_named(vgapal, pmi_setpal, invbool, 0); |
2031 | MODULE_PARM_DESC(vgapal, "Set palette using VGA registers"); | 2031 | MODULE_PARM_DESC(vgapal, "Set palette using VGA registers"); |
2032 | module_param_named(pmipal, pmi_setpal, bool, 0); | 2032 | module_param_named(pmipal, pmi_setpal, bool, 0); |
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c index 1c656667b937..2aa71eb67c2b 100644 --- a/drivers/video/vermilion/vermilion.c +++ b/drivers/video/vermilion/vermilion.c | |||
@@ -651,7 +651,7 @@ static int vmlfb_check_var_locked(struct fb_var_screeninfo *var, | |||
651 | return -EINVAL; | 651 | return -EINVAL; |
652 | } | 652 | } |
653 | 653 | ||
654 | pitch = __ALIGN_MASK((var->xres * var->bits_per_pixel) >> 3, 0x3F); | 654 | pitch = ALIGN((var->xres * var->bits_per_pixel) >> 3, 0x40); |
655 | mem = pitch * var->yres_virtual; | 655 | mem = pitch * var->yres_virtual; |
656 | if (mem > vinfo->vram_contig_size) { | 656 | if (mem > vinfo->vram_contig_size) { |
657 | return -ENOMEM; | 657 | return -ENOMEM; |
@@ -785,8 +785,7 @@ static int vmlfb_set_par_locked(struct vml_info *vinfo) | |||
785 | int clock; | 785 | int clock; |
786 | 786 | ||
787 | vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; | 787 | vinfo->bytes_per_pixel = var->bits_per_pixel >> 3; |
788 | vinfo->stride = | 788 | vinfo->stride = ALIGN(var->xres_virtual * vinfo->bytes_per_pixel, 0x40); |
789 | __ALIGN_MASK(var->xres_virtual * vinfo->bytes_per_pixel, 0x3F); | ||
790 | info->fix.line_length = vinfo->stride; | 789 | info->fix.line_length = vinfo->stride; |
791 | 790 | ||
792 | if (!subsys) | 791 | if (!subsys) |
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index 622aece1acce..c8a4332d1132 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/swap.h> | 23 | #include <linux/swap.h> |
24 | #include <linux/kthread.h> | 24 | #include <linux/kthread.h> |
25 | #include <linux/freezer.h> | 25 | #include <linux/freezer.h> |
26 | #include <linux/delay.h> | ||
26 | 27 | ||
27 | struct virtio_balloon | 28 | struct virtio_balloon |
28 | { | 29 | { |
diff --git a/drivers/w1/masters/Kconfig b/drivers/w1/masters/Kconfig index 8236d447adf5..c4493091c655 100644 --- a/drivers/w1/masters/Kconfig +++ b/drivers/w1/masters/Kconfig | |||
@@ -42,5 +42,15 @@ config W1_MASTER_DS1WM | |||
42 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like | 42 | in HP iPAQ devices like h5xxx, h2200, and ASIC3-based like |
43 | hx4700. | 43 | hx4700. |
44 | 44 | ||
45 | config W1_MASTER_GPIO | ||
46 | tristate "GPIO 1-wire busmaster" | ||
47 | depends on GENERIC_GPIO | ||
48 | help | ||
49 | Say Y here if you want to communicate with your 1-wire devices using | ||
50 | GPIO pins. This driver uses the GPIO API to control the wire. | ||
51 | |||
52 | This support is also available as a module. If so, the module | ||
53 | will be called w1-gpio.ko. | ||
54 | |||
45 | endmenu | 55 | endmenu |
46 | 56 | ||
diff --git a/drivers/w1/masters/Makefile b/drivers/w1/masters/Makefile index 11551b328186..1420b5bbdda8 100644 --- a/drivers/w1/masters/Makefile +++ b/drivers/w1/masters/Makefile | |||
@@ -6,3 +6,4 @@ obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o | |||
6 | obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o | 6 | obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o |
7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o | 7 | obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o |
8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o | 8 | obj-$(CONFIG_W1_MASTER_DS1WM) += ds1wm.o |
9 | obj-$(CONFIG_W1_MASTER_GPIO) += w1-gpio.o | ||
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c new file mode 100644 index 000000000000..9e1138a75e8b --- /dev/null +++ b/drivers/w1/masters/w1-gpio.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * w1-gpio - GPIO w1 bus master driver | ||
3 | * | ||
4 | * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/platform_device.h> | ||
14 | #include <linux/w1-gpio.h> | ||
15 | |||
16 | #include "../w1.h" | ||
17 | #include "../w1_int.h" | ||
18 | |||
19 | #include <asm/gpio.h> | ||
20 | |||
21 | static void w1_gpio_write_bit_dir(void *data, u8 bit) | ||
22 | { | ||
23 | struct w1_gpio_platform_data *pdata = data; | ||
24 | |||
25 | if (bit) | ||
26 | gpio_direction_input(pdata->pin); | ||
27 | else | ||
28 | gpio_direction_output(pdata->pin, 0); | ||
29 | } | ||
30 | |||
31 | static void w1_gpio_write_bit_val(void *data, u8 bit) | ||
32 | { | ||
33 | struct w1_gpio_platform_data *pdata = data; | ||
34 | |||
35 | gpio_set_value(pdata->pin, bit); | ||
36 | } | ||
37 | |||
38 | static u8 w1_gpio_read_bit(void *data) | ||
39 | { | ||
40 | struct w1_gpio_platform_data *pdata = data; | ||
41 | |||
42 | return gpio_get_value(pdata->pin); | ||
43 | } | ||
44 | |||
45 | static int __init w1_gpio_probe(struct platform_device *pdev) | ||
46 | { | ||
47 | struct w1_bus_master *master; | ||
48 | struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; | ||
49 | int err; | ||
50 | |||
51 | if (!pdata) | ||
52 | return -ENXIO; | ||
53 | |||
54 | master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL); | ||
55 | if (!master) | ||
56 | return -ENOMEM; | ||
57 | |||
58 | err = gpio_request(pdata->pin, "w1"); | ||
59 | if (err) | ||
60 | goto free_master; | ||
61 | |||
62 | master->data = pdata; | ||
63 | master->read_bit = w1_gpio_read_bit; | ||
64 | |||
65 | if (pdata->is_open_drain) { | ||
66 | gpio_direction_output(pdata->pin, 1); | ||
67 | master->write_bit = w1_gpio_write_bit_val; | ||
68 | } else { | ||
69 | gpio_direction_input(pdata->pin); | ||
70 | master->write_bit = w1_gpio_write_bit_dir; | ||
71 | } | ||
72 | |||
73 | err = w1_add_master_device(master); | ||
74 | if (err) | ||
75 | goto free_gpio; | ||
76 | |||
77 | platform_set_drvdata(pdev, master); | ||
78 | |||
79 | return 0; | ||
80 | |||
81 | free_gpio: | ||
82 | gpio_free(pdata->pin); | ||
83 | free_master: | ||
84 | kfree(master); | ||
85 | |||
86 | return err; | ||
87 | } | ||
88 | |||
89 | static int __exit w1_gpio_remove(struct platform_device *pdev) | ||
90 | { | ||
91 | struct w1_bus_master *master = platform_get_drvdata(pdev); | ||
92 | struct w1_gpio_platform_data *pdata = pdev->dev.platform_data; | ||
93 | |||
94 | w1_remove_master_device(master); | ||
95 | gpio_free(pdata->pin); | ||
96 | kfree(master); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static struct platform_driver w1_gpio_driver = { | ||
102 | .driver = { | ||
103 | .name = "w1-gpio", | ||
104 | .owner = THIS_MODULE, | ||
105 | }, | ||
106 | .remove = __exit_p(w1_gpio_remove), | ||
107 | }; | ||
108 | |||
109 | static int __init w1_gpio_init(void) | ||
110 | { | ||
111 | return platform_driver_probe(&w1_gpio_driver, w1_gpio_probe); | ||
112 | } | ||
113 | |||
114 | static void __exit w1_gpio_exit(void) | ||
115 | { | ||
116 | platform_driver_unregister(&w1_gpio_driver); | ||
117 | } | ||
118 | |||
119 | module_init(w1_gpio_init); | ||
120 | module_exit(w1_gpio_exit); | ||
121 | |||
122 | MODULE_DESCRIPTION("GPIO w1 bus master driver"); | ||
123 | MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>"); | ||
124 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 112f4ec59035..fb28acaeed6c 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -92,6 +92,7 @@ struct w1_therm_family_converter | |||
92 | int (*convert)(u8 rom[9]); | 92 | int (*convert)(u8 rom[9]); |
93 | }; | 93 | }; |
94 | 94 | ||
95 | /* The return value is millidegrees Centigrade. */ | ||
95 | static inline int w1_DS18B20_convert_temp(u8 rom[9]); | 96 | static inline int w1_DS18B20_convert_temp(u8 rom[9]); |
96 | static inline int w1_DS18S20_convert_temp(u8 rom[9]); | 97 | static inline int w1_DS18S20_convert_temp(u8 rom[9]); |
97 | 98 | ||
@@ -113,7 +114,7 @@ static struct w1_therm_family_converter w1_therm_families[] = { | |||
113 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) | 114 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) |
114 | { | 115 | { |
115 | s16 t = (rom[1] << 8) | rom[0]; | 116 | s16 t = (rom[1] << 8) | rom[0]; |
116 | t /= 16; | 117 | t = t*1000/16; |
117 | return t; | 118 | return t; |
118 | } | 119 | } |
119 | 120 | ||
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 33e50310e9e0..7293c9b11f91 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -675,7 +675,6 @@ static void w1_slave_found(void *data, u64 rn) | |||
675 | struct w1_slave *sl; | 675 | struct w1_slave *sl; |
676 | struct list_head *ent; | 676 | struct list_head *ent; |
677 | struct w1_reg_num *tmp; | 677 | struct w1_reg_num *tmp; |
678 | int family_found = 0; | ||
679 | struct w1_master *dev; | 678 | struct w1_master *dev; |
680 | u64 rn_le = cpu_to_le64(rn); | 679 | u64 rn_le = cpu_to_le64(rn); |
681 | 680 | ||
@@ -698,9 +697,6 @@ static void w1_slave_found(void *data, u64 rn) | |||
698 | sl->reg_num.crc == tmp->crc) { | 697 | sl->reg_num.crc == tmp->crc) { |
699 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); | 698 | set_bit(W1_SLAVE_ACTIVE, (long *)&sl->flags); |
700 | break; | 699 | break; |
701 | } else if (sl->reg_num.family == tmp->family) { | ||
702 | family_found = 1; | ||
703 | break; | ||
704 | } | 700 | } |
705 | 701 | ||
706 | slave_count++; | 702 | slave_count++; |
diff --git a/fs/Kconfig b/fs/Kconfig index 987b5d7cb21a..ea5b35947623 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -1152,7 +1152,7 @@ config BEFS_DEBUG | |||
1152 | depends on BEFS_FS | 1152 | depends on BEFS_FS |
1153 | help | 1153 | help |
1154 | If you say Y here, you can use the 'debug' mount option to enable | 1154 | If you say Y here, you can use the 'debug' mount option to enable |
1155 | debugging output from the driver. | 1155 | debugging output from the driver. |
1156 | 1156 | ||
1157 | config BFS_FS | 1157 | config BFS_FS |
1158 | tristate "BFS file system support (EXPERIMENTAL)" | 1158 | tristate "BFS file system support (EXPERIMENTAL)" |
@@ -1263,7 +1263,7 @@ config JFFS2_FS_XATTR | |||
1263 | Extended attributes are name:value pairs associated with inodes by | 1263 | Extended attributes are name:value pairs associated with inodes by |
1264 | the kernel or by users (see the attr(5) manual page, or visit | 1264 | the kernel or by users (see the attr(5) manual page, or visit |
1265 | <http://acl.bestbits.at/> for details). | 1265 | <http://acl.bestbits.at/> for details). |
1266 | 1266 | ||
1267 | If unsure, say N. | 1267 | If unsure, say N. |
1268 | 1268 | ||
1269 | config JFFS2_FS_POSIX_ACL | 1269 | config JFFS2_FS_POSIX_ACL |
@@ -1274,10 +1274,10 @@ config JFFS2_FS_POSIX_ACL | |||
1274 | help | 1274 | help |
1275 | Posix Access Control Lists (ACLs) support permissions for users and | 1275 | Posix Access Control Lists (ACLs) support permissions for users and |
1276 | groups beyond the owner/group/world scheme. | 1276 | groups beyond the owner/group/world scheme. |
1277 | 1277 | ||
1278 | To learn more about Access Control Lists, visit the Posix ACLs for | 1278 | To learn more about Access Control Lists, visit the Posix ACLs for |
1279 | Linux website <http://acl.bestbits.at/>. | 1279 | Linux website <http://acl.bestbits.at/>. |
1280 | 1280 | ||
1281 | If you don't know what Access Control Lists are, say N | 1281 | If you don't know what Access Control Lists are, say N |
1282 | 1282 | ||
1283 | config JFFS2_FS_SECURITY | 1283 | config JFFS2_FS_SECURITY |
@@ -1289,7 +1289,7 @@ config JFFS2_FS_SECURITY | |||
1289 | implemented by security modules like SELinux. This option | 1289 | implemented by security modules like SELinux. This option |
1290 | enables an extended attribute handler for file security | 1290 | enables an extended attribute handler for file security |
1291 | labels in the jffs2 filesystem. | 1291 | labels in the jffs2 filesystem. |
1292 | 1292 | ||
1293 | If you are not using a security module that requires using | 1293 | If you are not using a security module that requires using |
1294 | extended attributes for file security labels, say N. | 1294 | extended attributes for file security labels, say N. |
1295 | 1295 | ||
@@ -1835,7 +1835,7 @@ config RPCSEC_GSS_SPKM3 | |||
1835 | If unsure, say N. | 1835 | If unsure, say N. |
1836 | 1836 | ||
1837 | config SMB_FS | 1837 | config SMB_FS |
1838 | tristate "SMB file system support (to mount Windows shares etc.)" | 1838 | tristate "SMB file system support (OBSOLETE, please use CIFS)" |
1839 | depends on INET | 1839 | depends on INET |
1840 | select NLS | 1840 | select NLS |
1841 | help | 1841 | help |
@@ -1858,8 +1858,8 @@ config SMB_FS | |||
1858 | General information about how to connect Linux, Windows machines and | 1858 | General information about how to connect Linux, Windows machines and |
1859 | Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. | 1859 | Macs is on the WWW at <http://www.eats.com/linux_mac_win.html>. |
1860 | 1860 | ||
1861 | To compile the SMB support as a module, choose M here: the module will | 1861 | To compile the SMB support as a module, choose M here: |
1862 | be called smbfs. Most people say N, however. | 1862 | the module will be called smbfs. Most people say N, however. |
1863 | 1863 | ||
1864 | config SMB_NLS_DEFAULT | 1864 | config SMB_NLS_DEFAULT |
1865 | bool "Use a default NLS" | 1865 | bool "Use a default NLS" |
@@ -1891,7 +1891,7 @@ config SMB_NLS_REMOTE | |||
1891 | smbmount from samba 2.2.0 or later supports this. | 1891 | smbmount from samba 2.2.0 or later supports this. |
1892 | 1892 | ||
1893 | config CIFS | 1893 | config CIFS |
1894 | tristate "CIFS support (advanced network filesystem for Samba, Window and other CIFS compliant servers)" | 1894 | tristate "CIFS support (advanced network filesystem, SMBFS successor)" |
1895 | depends on INET | 1895 | depends on INET |
1896 | select NLS | 1896 | select NLS |
1897 | help | 1897 | help |
@@ -1949,16 +1949,16 @@ config CIFS_WEAK_PW_HASH | |||
1949 | LANMAN based servers such as OS/2 and Windows 95, but such | 1949 | LANMAN based servers such as OS/2 and Windows 95, but such |
1950 | mounts may be less secure than mounts using NTLM or more recent | 1950 | mounts may be less secure than mounts using NTLM or more recent |
1951 | security mechanisms if you are on a public network. Unless you | 1951 | security mechanisms if you are on a public network. Unless you |
1952 | have a need to access old SMB servers (and are on a private | 1952 | have a need to access old SMB servers (and are on a private |
1953 | network) you probably want to say N. Even if this support | 1953 | network) you probably want to say N. Even if this support |
1954 | is enabled in the kernel build, LANMAN authentication will not be | 1954 | is enabled in the kernel build, LANMAN authentication will not be |
1955 | used automatically. At runtime LANMAN mounts are disabled but | 1955 | used automatically. At runtime LANMAN mounts are disabled but |
1956 | can be set to required (or optional) either in | 1956 | can be set to required (or optional) either in |
1957 | /proc/fs/cifs (see fs/cifs/README for more detail) or via an | 1957 | /proc/fs/cifs (see fs/cifs/README for more detail) or via an |
1958 | option on the mount command. This support is disabled by | 1958 | option on the mount command. This support is disabled by |
1959 | default in order to reduce the possibility of a downgrade | 1959 | default in order to reduce the possibility of a downgrade |
1960 | attack. | 1960 | attack. |
1961 | 1961 | ||
1962 | If unsure, say N. | 1962 | If unsure, say N. |
1963 | 1963 | ||
1964 | config CIFS_XATTR | 1964 | config CIFS_XATTR |
@@ -1999,7 +1999,7 @@ config CIFS_DEBUG2 | |||
1999 | messages in some error paths, slowing performance. This | 1999 | messages in some error paths, slowing performance. This |
2000 | option can be turned off unless you are debugging | 2000 | option can be turned off unless you are debugging |
2001 | cifs problems. If unsure, say N. | 2001 | cifs problems. If unsure, say N. |
2002 | 2002 | ||
2003 | config CIFS_EXPERIMENTAL | 2003 | config CIFS_EXPERIMENTAL |
2004 | bool "CIFS Experimental Features (EXPERIMENTAL)" | 2004 | bool "CIFS Experimental Features (EXPERIMENTAL)" |
2005 | depends on CIFS && EXPERIMENTAL | 2005 | depends on CIFS && EXPERIMENTAL |
@@ -2090,7 +2090,7 @@ config CODA_FS_OLD_API | |||
2090 | However this new API is not backward compatible with older | 2090 | However this new API is not backward compatible with older |
2091 | clients. If you really need to run the old Coda userspace | 2091 | clients. If you really need to run the old Coda userspace |
2092 | cache manager then say Y. | 2092 | cache manager then say Y. |
2093 | 2093 | ||
2094 | For most cases you probably want to say N. | 2094 | For most cases you probably want to say N. |
2095 | 2095 | ||
2096 | config AFS_FS | 2096 | config AFS_FS |
diff --git a/fs/block_dev.c b/fs/block_dev.c index e48a630ae266..e63067d25cdb 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -534,7 +534,6 @@ void __init bdev_cache_init(void) | |||
534 | if (err) | 534 | if (err) |
535 | panic("Cannot register bdev pseudo-fs"); | 535 | panic("Cannot register bdev pseudo-fs"); |
536 | bd_mnt = kern_mount(&bd_type); | 536 | bd_mnt = kern_mount(&bd_type); |
537 | err = PTR_ERR(bd_mnt); | ||
538 | if (IS_ERR(bd_mnt)) | 537 | if (IS_ERR(bd_mnt)) |
539 | panic("Cannot create bdev pseudo-fs"); | 538 | panic("Cannot create bdev pseudo-fs"); |
540 | blockdev_superblock = bd_mnt->mnt_sb; /* For writeback */ | 539 | blockdev_superblock = bd_mnt->mnt_sb; /* For writeback */ |
diff --git a/fs/compat.c b/fs/compat.c index 69baca5ad608..ee80ff341d37 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -2083,51 +2083,6 @@ long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2) | |||
2083 | 2083 | ||
2084 | #ifdef CONFIG_EPOLL | 2084 | #ifdef CONFIG_EPOLL |
2085 | 2085 | ||
2086 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2087 | asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd, | ||
2088 | struct compat_epoll_event __user *event) | ||
2089 | { | ||
2090 | long err = 0; | ||
2091 | struct compat_epoll_event user; | ||
2092 | struct epoll_event __user *kernel = NULL; | ||
2093 | |||
2094 | if (event) { | ||
2095 | if (copy_from_user(&user, event, sizeof(user))) | ||
2096 | return -EFAULT; | ||
2097 | kernel = compat_alloc_user_space(sizeof(struct epoll_event)); | ||
2098 | err |= __put_user(user.events, &kernel->events); | ||
2099 | err |= __put_user(user.data, &kernel->data); | ||
2100 | } | ||
2101 | |||
2102 | return err ? err : sys_epoll_ctl(epfd, op, fd, kernel); | ||
2103 | } | ||
2104 | |||
2105 | |||
2106 | asmlinkage long compat_sys_epoll_wait(int epfd, | ||
2107 | struct compat_epoll_event __user *events, | ||
2108 | int maxevents, int timeout) | ||
2109 | { | ||
2110 | long i, ret, err = 0; | ||
2111 | struct epoll_event __user *kbuf; | ||
2112 | struct epoll_event ev; | ||
2113 | |||
2114 | if ((maxevents <= 0) || | ||
2115 | (maxevents > (INT_MAX / sizeof(struct epoll_event)))) | ||
2116 | return -EINVAL; | ||
2117 | kbuf = compat_alloc_user_space(sizeof(struct epoll_event) * maxevents); | ||
2118 | ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); | ||
2119 | for (i = 0; i < ret; i++) { | ||
2120 | err |= __get_user(ev.events, &kbuf[i].events); | ||
2121 | err |= __get_user(ev.data, &kbuf[i].data); | ||
2122 | err |= __put_user(ev.events, &events->events); | ||
2123 | err |= __put_user_unaligned(ev.data, &events->data); | ||
2124 | events++; | ||
2125 | } | ||
2126 | |||
2127 | return err ? -EFAULT: ret; | ||
2128 | } | ||
2129 | #endif /* CONFIG_HAS_COMPAT_EPOLL_EVENT */ | ||
2130 | |||
2131 | #ifdef TIF_RESTORE_SIGMASK | 2086 | #ifdef TIF_RESTORE_SIGMASK |
2132 | asmlinkage long compat_sys_epoll_pwait(int epfd, | 2087 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
2133 | struct compat_epoll_event __user *events, | 2088 | struct compat_epoll_event __user *events, |
@@ -2153,11 +2108,7 @@ asmlinkage long compat_sys_epoll_pwait(int epfd, | |||
2153 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | 2108 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); |
2154 | } | 2109 | } |
2155 | 2110 | ||
2156 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2157 | err = compat_sys_epoll_wait(epfd, events, maxevents, timeout); | ||
2158 | #else | ||
2159 | err = sys_epoll_wait(epfd, events, maxevents, timeout); | 2111 | err = sys_epoll_wait(epfd, events, maxevents, timeout); |
2160 | #endif | ||
2161 | 2112 | ||
2162 | /* | 2113 | /* |
2163 | * If we changed the signal mask, we need to restore the original one. | 2114 | * If we changed the signal mask, we need to restore the original one. |
diff --git a/fs/dcache.c b/fs/dcache.c index d9ca1e5ceb92..44f6cf23b70e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -89,7 +89,7 @@ static void d_free(struct dentry *dentry) | |||
89 | if (dentry->d_op && dentry->d_op->d_release) | 89 | if (dentry->d_op && dentry->d_op->d_release) |
90 | dentry->d_op->d_release(dentry); | 90 | dentry->d_op->d_release(dentry); |
91 | /* if dentry was never inserted into hash, immediate free is OK */ | 91 | /* if dentry was never inserted into hash, immediate free is OK */ |
92 | if (dentry->d_hash.pprev == NULL) | 92 | if (hlist_unhashed(&dentry->d_hash)) |
93 | __d_free(dentry); | 93 | __d_free(dentry); |
94 | else | 94 | else |
95 | call_rcu(&dentry->d_u.d_rcu, d_callback); | 95 | call_rcu(&dentry->d_u.d_rcu, d_callback); |
@@ -1408,9 +1408,6 @@ void d_delete(struct dentry * dentry) | |||
1408 | if (atomic_read(&dentry->d_count) == 1) { | 1408 | if (atomic_read(&dentry->d_count) == 1) { |
1409 | dentry_iput(dentry); | 1409 | dentry_iput(dentry); |
1410 | fsnotify_nameremove(dentry, isdir); | 1410 | fsnotify_nameremove(dentry, isdir); |
1411 | |||
1412 | /* remove this and other inotify debug checks after 2.6.18 */ | ||
1413 | dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED; | ||
1414 | return; | 1411 | return; |
1415 | } | 1412 | } |
1416 | 1413 | ||
diff --git a/fs/dquot.c b/fs/dquot.c index cee7c6f428f0..def4e969df77 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -696,9 +696,8 @@ static int dqinit_needed(struct inode *inode, int type) | |||
696 | /* This routine is guarded by dqonoff_mutex mutex */ | 696 | /* This routine is guarded by dqonoff_mutex mutex */ |
697 | static void add_dquot_ref(struct super_block *sb, int type) | 697 | static void add_dquot_ref(struct super_block *sb, int type) |
698 | { | 698 | { |
699 | struct inode *inode; | 699 | struct inode *inode, *old_inode = NULL; |
700 | 700 | ||
701 | restart: | ||
702 | spin_lock(&inode_lock); | 701 | spin_lock(&inode_lock); |
703 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { | 702 | list_for_each_entry(inode, &sb->s_inodes, i_sb_list) { |
704 | if (!atomic_read(&inode->i_writecount)) | 703 | if (!atomic_read(&inode->i_writecount)) |
@@ -711,12 +710,18 @@ restart: | |||
711 | __iget(inode); | 710 | __iget(inode); |
712 | spin_unlock(&inode_lock); | 711 | spin_unlock(&inode_lock); |
713 | 712 | ||
713 | iput(old_inode); | ||
714 | sb->dq_op->initialize(inode, type); | 714 | sb->dq_op->initialize(inode, type); |
715 | iput(inode); | 715 | /* We hold a reference to 'inode' so it couldn't have been |
716 | /* As we may have blocked we had better restart... */ | 716 | * removed from s_inodes list while we dropped the inode_lock. |
717 | goto restart; | 717 | * We cannot iput the inode now as we can be holding the last |
718 | * reference and we cannot iput it under inode_lock. So we | ||
719 | * keep the reference and iput it later. */ | ||
720 | old_inode = inode; | ||
721 | spin_lock(&inode_lock); | ||
718 | } | 722 | } |
719 | spin_unlock(&inode_lock); | 723 | spin_unlock(&inode_lock); |
724 | iput(old_inode); | ||
720 | } | 725 | } |
721 | 726 | ||
722 | /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ | 727 | /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ |
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c index f8ef0af919e7..a066e109ad9c 100644 --- a/fs/ecryptfs/crypto.c +++ b/fs/ecryptfs/crypto.c | |||
@@ -355,8 +355,11 @@ static int encrypt_scatterlist(struct ecryptfs_crypt_stat *crypt_stat, | |||
355 | } | 355 | } |
356 | /* Consider doing this once, when the file is opened */ | 356 | /* Consider doing this once, when the file is opened */ |
357 | mutex_lock(&crypt_stat->cs_tfm_mutex); | 357 | mutex_lock(&crypt_stat->cs_tfm_mutex); |
358 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, | 358 | if (!(crypt_stat->flags & ECRYPTFS_KEY_SET)) { |
359 | crypt_stat->key_size); | 359 | rc = crypto_blkcipher_setkey(crypt_stat->tfm, crypt_stat->key, |
360 | crypt_stat->key_size); | ||
361 | crypt_stat->flags |= ECRYPTFS_KEY_SET; | ||
362 | } | ||
360 | if (rc) { | 363 | if (rc) { |
361 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", | 364 | ecryptfs_printk(KERN_ERR, "Error setting key; rc = [%d]\n", |
362 | rc); | 365 | rc); |
@@ -376,11 +379,10 @@ out: | |||
376 | * | 379 | * |
377 | * Convert an eCryptfs page index into a lower byte offset | 380 | * Convert an eCryptfs page index into a lower byte offset |
378 | */ | 381 | */ |
379 | void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, | 382 | static void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, |
380 | struct ecryptfs_crypt_stat *crypt_stat) | 383 | struct ecryptfs_crypt_stat *crypt_stat) |
381 | { | 384 | { |
382 | (*offset) = ((crypt_stat->extent_size | 385 | (*offset) = (crypt_stat->num_header_bytes_at_front |
383 | * crypt_stat->num_header_extents_at_front) | ||
384 | + (crypt_stat->extent_size * extent_num)); | 386 | + (crypt_stat->extent_size * extent_num)); |
385 | } | 387 | } |
386 | 388 | ||
@@ -842,15 +844,13 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat) | |||
842 | set_extent_mask_and_shift(crypt_stat); | 844 | set_extent_mask_and_shift(crypt_stat); |
843 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; | 845 | crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; |
844 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 846 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
845 | crypt_stat->num_header_extents_at_front = 0; | 847 | crypt_stat->num_header_bytes_at_front = 0; |
846 | else { | 848 | else { |
847 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) | 849 | if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) |
848 | crypt_stat->num_header_extents_at_front = | 850 | crypt_stat->num_header_bytes_at_front = |
849 | (ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE | 851 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; |
850 | / crypt_stat->extent_size); | ||
851 | else | 852 | else |
852 | crypt_stat->num_header_extents_at_front = | 853 | crypt_stat->num_header_bytes_at_front = PAGE_CACHE_SIZE; |
853 | (PAGE_CACHE_SIZE / crypt_stat->extent_size); | ||
854 | } | 854 | } |
855 | } | 855 | } |
856 | 856 | ||
@@ -1128,7 +1128,7 @@ write_ecryptfs_flags(char *page_virt, struct ecryptfs_crypt_stat *crypt_stat, | |||
1128 | 1128 | ||
1129 | struct ecryptfs_cipher_code_str_map_elem { | 1129 | struct ecryptfs_cipher_code_str_map_elem { |
1130 | char cipher_str[16]; | 1130 | char cipher_str[16]; |
1131 | u16 cipher_code; | 1131 | u8 cipher_code; |
1132 | }; | 1132 | }; |
1133 | 1133 | ||
1134 | /* Add support for additional ciphers by adding elements here. The | 1134 | /* Add support for additional ciphers by adding elements here. The |
@@ -1152,10 +1152,10 @@ ecryptfs_cipher_code_str_map[] = { | |||
1152 | * | 1152 | * |
1153 | * Returns zero on no match, or the cipher code on match | 1153 | * Returns zero on no match, or the cipher code on match |
1154 | */ | 1154 | */ |
1155 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | 1155 | u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) |
1156 | { | 1156 | { |
1157 | int i; | 1157 | int i; |
1158 | u16 code = 0; | 1158 | u8 code = 0; |
1159 | struct ecryptfs_cipher_code_str_map_elem *map = | 1159 | struct ecryptfs_cipher_code_str_map_elem *map = |
1160 | ecryptfs_cipher_code_str_map; | 1160 | ecryptfs_cipher_code_str_map; |
1161 | 1161 | ||
@@ -1187,7 +1187,7 @@ u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat) | |||
1187 | * | 1187 | * |
1188 | * Returns zero on success | 1188 | * Returns zero on success |
1189 | */ | 1189 | */ |
1190 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code) | 1190 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code) |
1191 | { | 1191 | { |
1192 | int rc = 0; | 1192 | int rc = 0; |
1193 | int i; | 1193 | int i; |
@@ -1236,7 +1236,8 @@ ecryptfs_write_header_metadata(char *virt, | |||
1236 | 1236 | ||
1237 | header_extent_size = (u32)crypt_stat->extent_size; | 1237 | header_extent_size = (u32)crypt_stat->extent_size; |
1238 | num_header_extents_at_front = | 1238 | num_header_extents_at_front = |
1239 | (u16)crypt_stat->num_header_extents_at_front; | 1239 | (u16)(crypt_stat->num_header_bytes_at_front |
1240 | / crypt_stat->extent_size); | ||
1240 | header_extent_size = cpu_to_be32(header_extent_size); | 1241 | header_extent_size = cpu_to_be32(header_extent_size); |
1241 | memcpy(virt, &header_extent_size, 4); | 1242 | memcpy(virt, &header_extent_size, 4); |
1242 | virt += 4; | 1243 | virt += 4; |
@@ -1311,40 +1312,16 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size, | |||
1311 | static int | 1312 | static int |
1312 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, | 1313 | ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, |
1313 | struct dentry *ecryptfs_dentry, | 1314 | struct dentry *ecryptfs_dentry, |
1314 | char *page_virt) | 1315 | char *virt) |
1315 | { | 1316 | { |
1316 | int current_header_page; | ||
1317 | int header_pages; | ||
1318 | int rc; | 1317 | int rc; |
1319 | 1318 | ||
1320 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt, | 1319 | rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, virt, |
1321 | 0, PAGE_CACHE_SIZE); | 1320 | 0, crypt_stat->num_header_bytes_at_front); |
1322 | if (rc) { | 1321 | if (rc) |
1323 | printk(KERN_ERR "%s: Error attempting to write header " | 1322 | printk(KERN_ERR "%s: Error attempting to write header " |
1324 | "information to lower file; rc = [%d]\n", __FUNCTION__, | 1323 | "information to lower file; rc = [%d]\n", __FUNCTION__, |
1325 | rc); | 1324 | rc); |
1326 | goto out; | ||
1327 | } | ||
1328 | header_pages = ((crypt_stat->extent_size | ||
1329 | * crypt_stat->num_header_extents_at_front) | ||
1330 | / PAGE_CACHE_SIZE); | ||
1331 | memset(page_virt, 0, PAGE_CACHE_SIZE); | ||
1332 | current_header_page = 1; | ||
1333 | while (current_header_page < header_pages) { | ||
1334 | loff_t offset; | ||
1335 | |||
1336 | offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT); | ||
1337 | if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, | ||
1338 | page_virt, offset, | ||
1339 | PAGE_CACHE_SIZE))) { | ||
1340 | printk(KERN_ERR "%s: Error attempting to write header " | ||
1341 | "information to lower file; rc = [%d]\n", | ||
1342 | __FUNCTION__, rc); | ||
1343 | goto out; | ||
1344 | } | ||
1345 | current_header_page++; | ||
1346 | } | ||
1347 | out: | ||
1348 | return rc; | 1325 | return rc; |
1349 | } | 1326 | } |
1350 | 1327 | ||
@@ -1370,15 +1347,13 @@ ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, | |||
1370 | * retrieved via a prompt. Exactly what happens at this point should | 1347 | * retrieved via a prompt. Exactly what happens at this point should |
1371 | * be policy-dependent. | 1348 | * be policy-dependent. |
1372 | * | 1349 | * |
1373 | * TODO: Support header information spanning multiple pages | ||
1374 | * | ||
1375 | * Returns zero on success; non-zero on error | 1350 | * Returns zero on success; non-zero on error |
1376 | */ | 1351 | */ |
1377 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | 1352 | int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) |
1378 | { | 1353 | { |
1379 | struct ecryptfs_crypt_stat *crypt_stat = | 1354 | struct ecryptfs_crypt_stat *crypt_stat = |
1380 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; | 1355 | &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; |
1381 | char *page_virt; | 1356 | char *virt; |
1382 | size_t size = 0; | 1357 | size_t size = 0; |
1383 | int rc = 0; | 1358 | int rc = 0; |
1384 | 1359 | ||
@@ -1389,40 +1364,39 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry) | |||
1389 | goto out; | 1364 | goto out; |
1390 | } | 1365 | } |
1391 | } else { | 1366 | } else { |
1367 | printk(KERN_WARNING "%s: Encrypted flag not set\n", | ||
1368 | __FUNCTION__); | ||
1392 | rc = -EINVAL; | 1369 | rc = -EINVAL; |
1393 | ecryptfs_printk(KERN_WARNING, | ||
1394 | "Called with crypt_stat->encrypted == 0\n"); | ||
1395 | goto out; | 1370 | goto out; |
1396 | } | 1371 | } |
1397 | /* Released in this function */ | 1372 | /* Released in this function */ |
1398 | page_virt = kmem_cache_zalloc(ecryptfs_header_cache_0, GFP_USER); | 1373 | virt = kzalloc(crypt_stat->num_header_bytes_at_front, GFP_KERNEL); |
1399 | if (!page_virt) { | 1374 | if (!virt) { |
1400 | ecryptfs_printk(KERN_ERR, "Out of memory\n"); | 1375 | printk(KERN_ERR "%s: Out of memory\n", __FUNCTION__); |
1401 | rc = -ENOMEM; | 1376 | rc = -ENOMEM; |
1402 | goto out; | 1377 | goto out; |
1403 | } | 1378 | } |
1404 | rc = ecryptfs_write_headers_virt(page_virt, &size, crypt_stat, | 1379 | rc = ecryptfs_write_headers_virt(virt, &size, crypt_stat, |
1405 | ecryptfs_dentry); | 1380 | ecryptfs_dentry); |
1406 | if (unlikely(rc)) { | 1381 | if (unlikely(rc)) { |
1407 | ecryptfs_printk(KERN_ERR, "Error whilst writing headers\n"); | 1382 | printk(KERN_ERR "%s: Error whilst writing headers; rc = [%d]\n", |
1408 | memset(page_virt, 0, PAGE_CACHE_SIZE); | 1383 | __FUNCTION__, rc); |
1409 | goto out_free; | 1384 | goto out_free; |
1410 | } | 1385 | } |
1411 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 1386 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
1412 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, | 1387 | rc = ecryptfs_write_metadata_to_xattr(ecryptfs_dentry, |
1413 | crypt_stat, page_virt, | 1388 | crypt_stat, virt, size); |
1414 | size); | ||
1415 | else | 1389 | else |
1416 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, | 1390 | rc = ecryptfs_write_metadata_to_contents(crypt_stat, |
1417 | ecryptfs_dentry, | 1391 | ecryptfs_dentry, virt); |
1418 | page_virt); | ||
1419 | if (rc) { | 1392 | if (rc) { |
1420 | printk(KERN_ERR "Error writing metadata out to lower file; " | 1393 | printk(KERN_ERR "%s: Error writing metadata out to lower file; " |
1421 | "rc = [%d]\n", rc); | 1394 | "rc = [%d]\n", __FUNCTION__, rc); |
1422 | goto out_free; | 1395 | goto out_free; |
1423 | } | 1396 | } |
1424 | out_free: | 1397 | out_free: |
1425 | kmem_cache_free(ecryptfs_header_cache_0, page_virt); | 1398 | memset(virt, 0, crypt_stat->num_header_bytes_at_front); |
1399 | kfree(virt); | ||
1426 | out: | 1400 | out: |
1427 | return rc; | 1401 | return rc; |
1428 | } | 1402 | } |
@@ -1442,16 +1416,16 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1442 | virt += sizeof(u32); | 1416 | virt += sizeof(u32); |
1443 | memcpy(&num_header_extents_at_front, virt, sizeof(u16)); | 1417 | memcpy(&num_header_extents_at_front, virt, sizeof(u16)); |
1444 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); | 1418 | num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); |
1445 | crypt_stat->num_header_extents_at_front = | 1419 | crypt_stat->num_header_bytes_at_front = |
1446 | (int)num_header_extents_at_front; | 1420 | (((size_t)num_header_extents_at_front |
1421 | * (size_t)header_extent_size)); | ||
1447 | (*bytes_read) = (sizeof(u32) + sizeof(u16)); | 1422 | (*bytes_read) = (sizeof(u32) + sizeof(u16)); |
1448 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) | 1423 | if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) |
1449 | && ((crypt_stat->extent_size | 1424 | && (crypt_stat->num_header_bytes_at_front |
1450 | * crypt_stat->num_header_extents_at_front) | ||
1451 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { | 1425 | < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { |
1452 | rc = -EINVAL; | 1426 | rc = -EINVAL; |
1453 | printk(KERN_WARNING "Invalid number of header extents: [%zd]\n", | 1427 | printk(KERN_WARNING "Invalid header size: [%zd]\n", |
1454 | crypt_stat->num_header_extents_at_front); | 1428 | crypt_stat->num_header_bytes_at_front); |
1455 | } | 1429 | } |
1456 | return rc; | 1430 | return rc; |
1457 | } | 1431 | } |
@@ -1466,7 +1440,8 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat, | |||
1466 | */ | 1440 | */ |
1467 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) | 1441 | static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) |
1468 | { | 1442 | { |
1469 | crypt_stat->num_header_extents_at_front = 2; | 1443 | crypt_stat->num_header_bytes_at_front = |
1444 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
1470 | } | 1445 | } |
1471 | 1446 | ||
1472 | /** | 1447 | /** |
@@ -1552,9 +1527,10 @@ int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode) | |||
1552 | size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME, | 1527 | size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME, |
1553 | page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); | 1528 | page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); |
1554 | if (size < 0) { | 1529 | if (size < 0) { |
1555 | printk(KERN_ERR "Error attempting to read the [%s] " | 1530 | if (unlikely(ecryptfs_verbosity > 0)) |
1556 | "xattr from the lower file; return value = [%zd]\n", | 1531 | printk(KERN_INFO "Error attempting to read the [%s] " |
1557 | ECRYPTFS_XATTR_NAME, size); | 1532 | "xattr from the lower file; return value = " |
1533 | "[%zd]\n", ECRYPTFS_XATTR_NAME, size); | ||
1558 | rc = -EINVAL; | 1534 | rc = -EINVAL; |
1559 | goto out; | 1535 | goto out; |
1560 | } | 1536 | } |
@@ -1802,7 +1778,7 @@ out: | |||
1802 | } | 1778 | } |
1803 | 1779 | ||
1804 | struct kmem_cache *ecryptfs_key_tfm_cache; | 1780 | struct kmem_cache *ecryptfs_key_tfm_cache; |
1805 | struct list_head key_tfm_list; | 1781 | static struct list_head key_tfm_list; |
1806 | struct mutex key_tfm_list_mutex; | 1782 | struct mutex key_tfm_list_mutex; |
1807 | 1783 | ||
1808 | int ecryptfs_init_crypto(void) | 1784 | int ecryptfs_init_crypto(void) |
@@ -1812,6 +1788,11 @@ int ecryptfs_init_crypto(void) | |||
1812 | return 0; | 1788 | return 0; |
1813 | } | 1789 | } |
1814 | 1790 | ||
1791 | /** | ||
1792 | * ecryptfs_destroy_crypto - free all cached key_tfms on key_tfm_list | ||
1793 | * | ||
1794 | * Called only at module unload time | ||
1795 | */ | ||
1815 | int ecryptfs_destroy_crypto(void) | 1796 | int ecryptfs_destroy_crypto(void) |
1816 | { | 1797 | { |
1817 | struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp; | 1798 | struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp; |
@@ -1835,6 +1816,8 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, | |||
1835 | struct ecryptfs_key_tfm *tmp_tfm; | 1816 | struct ecryptfs_key_tfm *tmp_tfm; |
1836 | int rc = 0; | 1817 | int rc = 0; |
1837 | 1818 | ||
1819 | BUG_ON(!mutex_is_locked(&key_tfm_list_mutex)); | ||
1820 | |||
1838 | tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL); | 1821 | tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL); |
1839 | if (key_tfm != NULL) | 1822 | if (key_tfm != NULL) |
1840 | (*key_tfm) = tmp_tfm; | 1823 | (*key_tfm) = tmp_tfm; |
@@ -1861,13 +1844,50 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, | |||
1861 | (*key_tfm) = NULL; | 1844 | (*key_tfm) = NULL; |
1862 | goto out; | 1845 | goto out; |
1863 | } | 1846 | } |
1864 | mutex_lock(&key_tfm_list_mutex); | ||
1865 | list_add(&tmp_tfm->key_tfm_list, &key_tfm_list); | 1847 | list_add(&tmp_tfm->key_tfm_list, &key_tfm_list); |
1866 | mutex_unlock(&key_tfm_list_mutex); | ||
1867 | out: | 1848 | out: |
1868 | return rc; | 1849 | return rc; |
1869 | } | 1850 | } |
1870 | 1851 | ||
1852 | /** | ||
1853 | * ecryptfs_tfm_exists - Search for existing tfm for cipher_name. | ||
1854 | * @cipher_name: the name of the cipher to search for | ||
1855 | * @key_tfm: set to corresponding tfm if found | ||
1856 | * | ||
1857 | * Searches for cached key_tfm matching @cipher_name | ||
1858 | * Must be called with &key_tfm_list_mutex held | ||
1859 | * Returns 1 if found, with @key_tfm set | ||
1860 | * Returns 0 if not found, with @key_tfm set to NULL | ||
1861 | */ | ||
1862 | int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm) | ||
1863 | { | ||
1864 | struct ecryptfs_key_tfm *tmp_key_tfm; | ||
1865 | |||
1866 | BUG_ON(!mutex_is_locked(&key_tfm_list_mutex)); | ||
1867 | |||
1868 | list_for_each_entry(tmp_key_tfm, &key_tfm_list, key_tfm_list) { | ||
1869 | if (strcmp(tmp_key_tfm->cipher_name, cipher_name) == 0) { | ||
1870 | if (key_tfm) | ||
1871 | (*key_tfm) = tmp_key_tfm; | ||
1872 | return 1; | ||
1873 | } | ||
1874 | } | ||
1875 | if (key_tfm) | ||
1876 | (*key_tfm) = NULL; | ||
1877 | return 0; | ||
1878 | } | ||
1879 | |||
1880 | /** | ||
1881 | * ecryptfs_get_tfm_and_mutex_for_cipher_name | ||
1882 | * | ||
1883 | * @tfm: set to cached tfm found, or new tfm created | ||
1884 | * @tfm_mutex: set to mutex for cached tfm found, or new tfm created | ||
1885 | * @cipher_name: the name of the cipher to search for and/or add | ||
1886 | * | ||
1887 | * Sets pointers to @tfm & @tfm_mutex matching @cipher_name. | ||
1888 | * Searches for cached item first, and creates new if not found. | ||
1889 | * Returns 0 on success, non-zero if adding new cipher failed | ||
1890 | */ | ||
1871 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | 1891 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, |
1872 | struct mutex **tfm_mutex, | 1892 | struct mutex **tfm_mutex, |
1873 | char *cipher_name) | 1893 | char *cipher_name) |
@@ -1877,22 +1897,17 @@ int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | |||
1877 | 1897 | ||
1878 | (*tfm) = NULL; | 1898 | (*tfm) = NULL; |
1879 | (*tfm_mutex) = NULL; | 1899 | (*tfm_mutex) = NULL; |
1900 | |||
1880 | mutex_lock(&key_tfm_list_mutex); | 1901 | mutex_lock(&key_tfm_list_mutex); |
1881 | list_for_each_entry(key_tfm, &key_tfm_list, key_tfm_list) { | 1902 | if (!ecryptfs_tfm_exists(cipher_name, &key_tfm)) { |
1882 | if (strcmp(key_tfm->cipher_name, cipher_name) == 0) { | 1903 | rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0); |
1883 | (*tfm) = key_tfm->key_tfm; | 1904 | if (rc) { |
1884 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; | 1905 | printk(KERN_ERR "Error adding new key_tfm to list; " |
1885 | mutex_unlock(&key_tfm_list_mutex); | 1906 | "rc = [%d]\n", rc); |
1886 | goto out; | 1907 | goto out; |
1887 | } | 1908 | } |
1888 | } | 1909 | } |
1889 | mutex_unlock(&key_tfm_list_mutex); | 1910 | mutex_unlock(&key_tfm_list_mutex); |
1890 | rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0); | ||
1891 | if (rc) { | ||
1892 | printk(KERN_ERR "Error adding new key_tfm to list; rc = [%d]\n", | ||
1893 | rc); | ||
1894 | goto out; | ||
1895 | } | ||
1896 | (*tfm) = key_tfm->key_tfm; | 1911 | (*tfm) = key_tfm->key_tfm; |
1897 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; | 1912 | (*tfm_mutex) = &key_tfm->key_tfm_mutex; |
1898 | out: | 1913 | out: |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index ce7a5d4aec36..5007f788da01 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -234,10 +234,11 @@ struct ecryptfs_crypt_stat { | |||
234 | #define ECRYPTFS_KEY_VALID 0x00000080 | 234 | #define ECRYPTFS_KEY_VALID 0x00000080 |
235 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 | 235 | #define ECRYPTFS_METADATA_IN_XATTR 0x00000100 |
236 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 | 236 | #define ECRYPTFS_VIEW_AS_ENCRYPTED 0x00000200 |
237 | #define ECRYPTFS_KEY_SET 0x00000400 | ||
237 | u32 flags; | 238 | u32 flags; |
238 | unsigned int file_version; | 239 | unsigned int file_version; |
239 | size_t iv_bytes; | 240 | size_t iv_bytes; |
240 | size_t num_header_extents_at_front; | 241 | size_t num_header_bytes_at_front; |
241 | size_t extent_size; /* Data extent size; default is 4096 */ | 242 | size_t extent_size; /* Data extent size; default is 4096 */ |
242 | size_t key_size; | 243 | size_t key_size; |
243 | size_t extent_shift; | 244 | size_t extent_shift; |
@@ -322,7 +323,6 @@ struct ecryptfs_key_tfm { | |||
322 | unsigned char cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; | 323 | unsigned char cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1]; |
323 | }; | 324 | }; |
324 | 325 | ||
325 | extern struct list_head key_tfm_list; | ||
326 | extern struct mutex key_tfm_list_mutex; | 326 | extern struct mutex key_tfm_list_mutex; |
327 | 327 | ||
328 | /** | 328 | /** |
@@ -521,11 +521,9 @@ extern struct kmem_cache *ecryptfs_file_info_cache; | |||
521 | extern struct kmem_cache *ecryptfs_dentry_info_cache; | 521 | extern struct kmem_cache *ecryptfs_dentry_info_cache; |
522 | extern struct kmem_cache *ecryptfs_inode_info_cache; | 522 | extern struct kmem_cache *ecryptfs_inode_info_cache; |
523 | extern struct kmem_cache *ecryptfs_sb_info_cache; | 523 | extern struct kmem_cache *ecryptfs_sb_info_cache; |
524 | extern struct kmem_cache *ecryptfs_header_cache_0; | ||
525 | extern struct kmem_cache *ecryptfs_header_cache_1; | 524 | extern struct kmem_cache *ecryptfs_header_cache_1; |
526 | extern struct kmem_cache *ecryptfs_header_cache_2; | 525 | extern struct kmem_cache *ecryptfs_header_cache_2; |
527 | extern struct kmem_cache *ecryptfs_xattr_cache; | 526 | extern struct kmem_cache *ecryptfs_xattr_cache; |
528 | extern struct kmem_cache *ecryptfs_lower_page_cache; | ||
529 | extern struct kmem_cache *ecryptfs_key_record_cache; | 527 | extern struct kmem_cache *ecryptfs_key_record_cache; |
530 | extern struct kmem_cache *ecryptfs_key_sig_cache; | 528 | extern struct kmem_cache *ecryptfs_key_sig_cache; |
531 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; | 529 | extern struct kmem_cache *ecryptfs_global_auth_tok_cache; |
@@ -562,8 +560,8 @@ int ecryptfs_read_and_validate_header_region(char *data, | |||
562 | struct inode *ecryptfs_inode); | 560 | struct inode *ecryptfs_inode); |
563 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, | 561 | int ecryptfs_read_and_validate_xattr_region(char *page_virt, |
564 | struct dentry *ecryptfs_dentry); | 562 | struct dentry *ecryptfs_dentry); |
565 | u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); | 563 | u8 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); |
566 | int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code); | 564 | int ecryptfs_cipher_code_to_string(char *str, u8 cipher_code); |
567 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); | 565 | void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat); |
568 | int ecryptfs_generate_key_packet_set(char *dest_base, | 566 | int ecryptfs_generate_key_packet_set(char *dest_base, |
569 | struct ecryptfs_crypt_stat *crypt_stat, | 567 | struct ecryptfs_crypt_stat *crypt_stat, |
@@ -576,8 +574,6 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); | |||
576 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); | 574 | int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); |
577 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); | 575 | int ecryptfs_inode_set(struct inode *inode, void *lower_inode); |
578 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); | 576 | void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); |
579 | ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | ||
580 | size_t size); | ||
581 | ssize_t | 577 | ssize_t |
582 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, | 578 | ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name, |
583 | void *value, size_t size); | 579 | void *value, size_t size); |
@@ -623,6 +619,7 @@ ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name, | |||
623 | size_t key_size); | 619 | size_t key_size); |
624 | int ecryptfs_init_crypto(void); | 620 | int ecryptfs_init_crypto(void); |
625 | int ecryptfs_destroy_crypto(void); | 621 | int ecryptfs_destroy_crypto(void); |
622 | int ecryptfs_tfm_exists(char *cipher_name, struct ecryptfs_key_tfm **key_tfm); | ||
626 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, | 623 | int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm, |
627 | struct mutex **tfm_mutex, | 624 | struct mutex **tfm_mutex, |
628 | char *cipher_name); | 625 | char *cipher_name); |
@@ -631,8 +628,6 @@ int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key, | |||
631 | char *sig); | 628 | char *sig); |
632 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, | 629 | int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, |
633 | int num_zeros); | 630 | int num_zeros); |
634 | void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num, | ||
635 | struct ecryptfs_crypt_stat *crypt_stat); | ||
636 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, | 631 | int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data, |
637 | loff_t offset, size_t size); | 632 | loff_t offset, size_t size); |
638 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, | 633 | int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode, |
@@ -646,8 +641,6 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
646 | pgoff_t page_index, | 641 | pgoff_t page_index, |
647 | size_t offset_in_page, size_t size, | 642 | size_t offset_in_page, size_t size, |
648 | struct inode *ecryptfs_inode); | 643 | struct inode *ecryptfs_inode); |
649 | int ecryptfs_read(char *data, loff_t offset, size_t size, | ||
650 | struct file *ecryptfs_file); | ||
651 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); | 644 | struct page *ecryptfs_get_locked_page(struct file *file, loff_t index); |
652 | 645 | ||
653 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ | 646 | #endif /* #ifndef ECRYPTFS_KERNEL_H */ |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index c98c4690a771..2b8f5ed4adea 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -209,9 +209,10 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
209 | if (!(mount_crypt_stat->flags | 209 | if (!(mount_crypt_stat->flags |
210 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 210 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
211 | rc = -EIO; | 211 | rc = -EIO; |
212 | printk(KERN_WARNING "Attempt to read file that " | 212 | printk(KERN_WARNING "Either the lower file " |
213 | "is not in a valid eCryptfs format, " | 213 | "is not in a valid eCryptfs format, " |
214 | "and plaintext passthrough mode is not " | 214 | "or the key could not be retrieved. " |
215 | "Plaintext passthrough mode is not " | ||
215 | "enabled; returning -EIO\n"); | 216 | "enabled; returning -EIO\n"); |
216 | mutex_unlock(&crypt_stat->cs_mutex); | 217 | mutex_unlock(&crypt_stat->cs_mutex); |
217 | goto out_free; | 218 | goto out_free; |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 5a719180983c..edd1e44e9d47 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -365,8 +365,7 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry, | |||
365 | dentry->d_sb)->mount_crypt_stat; | 365 | dentry->d_sb)->mount_crypt_stat; |
366 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { | 366 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { |
367 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) | 367 | if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) |
368 | file_size = ((crypt_stat->extent_size | 368 | file_size = (crypt_stat->num_header_bytes_at_front |
369 | * crypt_stat->num_header_extents_at_front) | ||
370 | + i_size_read(lower_dentry->d_inode)); | 369 | + i_size_read(lower_dentry->d_inode)); |
371 | else | 370 | else |
372 | file_size = i_size_read(lower_dentry->d_inode); | 371 | file_size = i_size_read(lower_dentry->d_inode); |
@@ -685,7 +684,7 @@ ecryptfs_put_link(struct dentry *dentry, struct nameidata *nd, void *ptr) | |||
685 | * @crypt_stat: Crypt_stat associated with file | 684 | * @crypt_stat: Crypt_stat associated with file |
686 | * @upper_size: Size of the upper file | 685 | * @upper_size: Size of the upper file |
687 | * | 686 | * |
688 | * Calculate the requried size of the lower file based on the | 687 | * Calculate the required size of the lower file based on the |
689 | * specified size of the upper file. This calculation is based on the | 688 | * specified size of the upper file. This calculation is based on the |
690 | * number of headers in the underlying file and the extent size. | 689 | * number of headers in the underlying file and the extent size. |
691 | * | 690 | * |
@@ -697,8 +696,7 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat, | |||
697 | { | 696 | { |
698 | loff_t lower_size; | 697 | loff_t lower_size; |
699 | 698 | ||
700 | lower_size = (crypt_stat->extent_size | 699 | lower_size = crypt_stat->num_header_bytes_at_front; |
701 | * crypt_stat->num_header_extents_at_front); | ||
702 | if (upper_size != 0) { | 700 | if (upper_size != 0) { |
703 | loff_t num_extents; | 701 | loff_t num_extents; |
704 | 702 | ||
@@ -875,11 +873,11 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
875 | if (!(mount_crypt_stat->flags | 873 | if (!(mount_crypt_stat->flags |
876 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | 874 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { |
877 | rc = -EIO; | 875 | rc = -EIO; |
878 | printk(KERN_WARNING "Attempt to read file that " | 876 | printk(KERN_WARNING "Either the lower file " |
879 | "is not in a valid eCryptfs format, " | 877 | "is not in a valid eCryptfs format, " |
880 | "and plaintext passthrough mode is not " | 878 | "or the key could not be retrieved. " |
879 | "Plaintext passthrough mode is not " | ||
881 | "enabled; returning -EIO\n"); | 880 | "enabled; returning -EIO\n"); |
882 | |||
883 | mutex_unlock(&crypt_stat->cs_mutex); | 881 | mutex_unlock(&crypt_stat->cs_mutex); |
884 | goto out; | 882 | goto out; |
885 | } | 883 | } |
@@ -954,7 +952,7 @@ out: | |||
954 | return rc; | 952 | return rc; |
955 | } | 953 | } |
956 | 954 | ||
957 | ssize_t | 955 | static ssize_t |
958 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, | 956 | ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, |
959 | size_t size) | 957 | size_t size) |
960 | { | 958 | { |
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c index f458c1f35565..682b1b2482c2 100644 --- a/fs/ecryptfs/keystore.c +++ b/fs/ecryptfs/keystore.c | |||
@@ -189,7 +189,7 @@ out: | |||
189 | } | 189 | } |
190 | 190 | ||
191 | static int | 191 | static int |
192 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u16 *cipher_code, | 192 | parse_tag_65_packet(struct ecryptfs_session_key *session_key, u8 *cipher_code, |
193 | struct ecryptfs_message *msg) | 193 | struct ecryptfs_message *msg) |
194 | { | 194 | { |
195 | size_t i = 0; | 195 | size_t i = 0; |
@@ -275,7 +275,7 @@ out: | |||
275 | 275 | ||
276 | 276 | ||
277 | static int | 277 | static int |
278 | write_tag_66_packet(char *signature, size_t cipher_code, | 278 | write_tag_66_packet(char *signature, u8 cipher_code, |
279 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, | 279 | struct ecryptfs_crypt_stat *crypt_stat, char **packet, |
280 | size_t *packet_len) | 280 | size_t *packet_len) |
281 | { | 281 | { |
@@ -428,7 +428,7 @@ static int | |||
428 | decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, | 428 | decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok, |
429 | struct ecryptfs_crypt_stat *crypt_stat) | 429 | struct ecryptfs_crypt_stat *crypt_stat) |
430 | { | 430 | { |
431 | u16 cipher_code = 0; | 431 | u8 cipher_code = 0; |
432 | struct ecryptfs_msg_ctx *msg_ctx; | 432 | struct ecryptfs_msg_ctx *msg_ctx; |
433 | struct ecryptfs_message *msg = NULL; | 433 | struct ecryptfs_message *msg = NULL; |
434 | char *auth_tok_sig; | 434 | char *auth_tok_sig; |
@@ -1537,7 +1537,7 @@ write_tag_3_packet(char *dest, size_t *remaining_bytes, | |||
1537 | struct scatterlist dst_sg; | 1537 | struct scatterlist dst_sg; |
1538 | struct scatterlist src_sg; | 1538 | struct scatterlist src_sg; |
1539 | struct mutex *tfm_mutex = NULL; | 1539 | struct mutex *tfm_mutex = NULL; |
1540 | size_t cipher_code; | 1540 | u8 cipher_code; |
1541 | size_t packet_size_length; | 1541 | size_t packet_size_length; |
1542 | size_t max_packet_size; | 1542 | size_t max_packet_size; |
1543 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 1543 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 0249aa4ae181..778c420e4cac 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -117,7 +117,7 @@ void __ecryptfs_printk(const char *fmt, ...) | |||
117 | * | 117 | * |
118 | * Returns zero on success; non-zero otherwise | 118 | * Returns zero on success; non-zero otherwise |
119 | */ | 119 | */ |
120 | int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | 120 | static int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) |
121 | { | 121 | { |
122 | struct ecryptfs_inode_info *inode_info = | 122 | struct ecryptfs_inode_info *inode_info = |
123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); | 123 | ecryptfs_inode_to_private(ecryptfs_dentry->d_inode); |
@@ -226,17 +226,15 @@ out: | |||
226 | return rc; | 226 | return rc; |
227 | } | 227 | } |
228 | 228 | ||
229 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, ecryptfs_opt_debug, | 229 | enum { ecryptfs_opt_sig, ecryptfs_opt_ecryptfs_sig, |
230 | ecryptfs_opt_ecryptfs_debug, ecryptfs_opt_cipher, | 230 | ecryptfs_opt_cipher, ecryptfs_opt_ecryptfs_cipher, |
231 | ecryptfs_opt_ecryptfs_cipher, ecryptfs_opt_ecryptfs_key_bytes, | 231 | ecryptfs_opt_ecryptfs_key_bytes, |
232 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, | 232 | ecryptfs_opt_passthrough, ecryptfs_opt_xattr_metadata, |
233 | ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; | 233 | ecryptfs_opt_encrypted_view, ecryptfs_opt_err }; |
234 | 234 | ||
235 | static match_table_t tokens = { | 235 | static match_table_t tokens = { |
236 | {ecryptfs_opt_sig, "sig=%s"}, | 236 | {ecryptfs_opt_sig, "sig=%s"}, |
237 | {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"}, | 237 | {ecryptfs_opt_ecryptfs_sig, "ecryptfs_sig=%s"}, |
238 | {ecryptfs_opt_debug, "debug=%u"}, | ||
239 | {ecryptfs_opt_ecryptfs_debug, "ecryptfs_debug=%u"}, | ||
240 | {ecryptfs_opt_cipher, "cipher=%s"}, | 238 | {ecryptfs_opt_cipher, "cipher=%s"}, |
241 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, | 239 | {ecryptfs_opt_ecryptfs_cipher, "ecryptfs_cipher=%s"}, |
242 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, | 240 | {ecryptfs_opt_ecryptfs_key_bytes, "ecryptfs_key_bytes=%u"}, |
@@ -313,7 +311,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
313 | substring_t args[MAX_OPT_ARGS]; | 311 | substring_t args[MAX_OPT_ARGS]; |
314 | int token; | 312 | int token; |
315 | char *sig_src; | 313 | char *sig_src; |
316 | char *debug_src; | ||
317 | char *cipher_name_dst; | 314 | char *cipher_name_dst; |
318 | char *cipher_name_src; | 315 | char *cipher_name_src; |
319 | char *cipher_key_bytes_src; | 316 | char *cipher_key_bytes_src; |
@@ -341,16 +338,6 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
341 | } | 338 | } |
342 | sig_set = 1; | 339 | sig_set = 1; |
343 | break; | 340 | break; |
344 | case ecryptfs_opt_debug: | ||
345 | case ecryptfs_opt_ecryptfs_debug: | ||
346 | debug_src = args[0].from; | ||
347 | ecryptfs_verbosity = | ||
348 | (int)simple_strtol(debug_src, &debug_src, | ||
349 | 0); | ||
350 | ecryptfs_printk(KERN_DEBUG, | ||
351 | "Verbosity set to [%d]" "\n", | ||
352 | ecryptfs_verbosity); | ||
353 | break; | ||
354 | case ecryptfs_opt_cipher: | 341 | case ecryptfs_opt_cipher: |
355 | case ecryptfs_opt_ecryptfs_cipher: | 342 | case ecryptfs_opt_ecryptfs_cipher: |
356 | cipher_name_src = args[0].from; | 343 | cipher_name_src = args[0].from; |
@@ -423,9 +410,13 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
423 | if (!cipher_key_bytes_set) { | 410 | if (!cipher_key_bytes_set) { |
424 | mount_crypt_stat->global_default_cipher_key_size = 0; | 411 | mount_crypt_stat->global_default_cipher_key_size = 0; |
425 | } | 412 | } |
426 | rc = ecryptfs_add_new_key_tfm( | 413 | mutex_lock(&key_tfm_list_mutex); |
427 | NULL, mount_crypt_stat->global_default_cipher_name, | 414 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, |
428 | mount_crypt_stat->global_default_cipher_key_size); | 415 | NULL)) |
416 | rc = ecryptfs_add_new_key_tfm( | ||
417 | NULL, mount_crypt_stat->global_default_cipher_name, | ||
418 | mount_crypt_stat->global_default_cipher_key_size); | ||
419 | mutex_unlock(&key_tfm_list_mutex); | ||
429 | if (rc) { | 420 | if (rc) { |
430 | printk(KERN_ERR "Error attempting to initialize cipher with " | 421 | printk(KERN_ERR "Error attempting to initialize cipher with " |
431 | "name = [%s] and key size = [%td]; rc = [%d]\n", | 422 | "name = [%s] and key size = [%td]; rc = [%d]\n", |
@@ -654,11 +645,6 @@ static struct ecryptfs_cache_info { | |||
654 | .size = sizeof(struct ecryptfs_sb_info), | 645 | .size = sizeof(struct ecryptfs_sb_info), |
655 | }, | 646 | }, |
656 | { | 647 | { |
657 | .cache = &ecryptfs_header_cache_0, | ||
658 | .name = "ecryptfs_headers_0", | ||
659 | .size = PAGE_CACHE_SIZE, | ||
660 | }, | ||
661 | { | ||
662 | .cache = &ecryptfs_header_cache_1, | 648 | .cache = &ecryptfs_header_cache_1, |
663 | .name = "ecryptfs_headers_1", | 649 | .name = "ecryptfs_headers_1", |
664 | .size = PAGE_CACHE_SIZE, | 650 | .size = PAGE_CACHE_SIZE, |
@@ -821,6 +807,10 @@ static int __init ecryptfs_init(void) | |||
821 | "rc = [%d]\n", rc); | 807 | "rc = [%d]\n", rc); |
822 | goto out_release_messaging; | 808 | goto out_release_messaging; |
823 | } | 809 | } |
810 | if (ecryptfs_verbosity > 0) | ||
811 | printk(KERN_CRIT "eCryptfs verbosity set to %d. Secret values " | ||
812 | "will be written to the syslog!\n", ecryptfs_verbosity); | ||
813 | |||
824 | goto out; | 814 | goto out; |
825 | out_release_messaging: | 815 | out_release_messaging: |
826 | ecryptfs_release_messaging(ecryptfs_transport); | 816 | ecryptfs_release_messaging(ecryptfs_transport); |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index 0535412d8c64..dc74b186145d 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #include <linux/scatterlist.h> | 34 | #include <linux/scatterlist.h> |
35 | #include "ecryptfs_kernel.h" | 35 | #include "ecryptfs_kernel.h" |
36 | 36 | ||
37 | struct kmem_cache *ecryptfs_lower_page_cache; | ||
38 | |||
39 | /** | 37 | /** |
40 | * ecryptfs_get_locked_page | 38 | * ecryptfs_get_locked_page |
41 | * | 39 | * |
@@ -102,13 +100,14 @@ static void set_header_info(char *page_virt, | |||
102 | struct ecryptfs_crypt_stat *crypt_stat) | 100 | struct ecryptfs_crypt_stat *crypt_stat) |
103 | { | 101 | { |
104 | size_t written; | 102 | size_t written; |
105 | int save_num_header_extents_at_front = | 103 | size_t save_num_header_bytes_at_front = |
106 | crypt_stat->num_header_extents_at_front; | 104 | crypt_stat->num_header_bytes_at_front; |
107 | 105 | ||
108 | crypt_stat->num_header_extents_at_front = 1; | 106 | crypt_stat->num_header_bytes_at_front = |
107 | ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE; | ||
109 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); | 108 | ecryptfs_write_header_metadata(page_virt + 20, crypt_stat, &written); |
110 | crypt_stat->num_header_extents_at_front = | 109 | crypt_stat->num_header_bytes_at_front = |
111 | save_num_header_extents_at_front; | 110 | save_num_header_bytes_at_front; |
112 | } | 111 | } |
113 | 112 | ||
114 | /** | 113 | /** |
@@ -134,8 +133,11 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
134 | loff_t view_extent_num = ((((loff_t)page->index) | 133 | loff_t view_extent_num = ((((loff_t)page->index) |
135 | * num_extents_per_page) | 134 | * num_extents_per_page) |
136 | + extent_num_in_page); | 135 | + extent_num_in_page); |
136 | size_t num_header_extents_at_front = | ||
137 | (crypt_stat->num_header_bytes_at_front | ||
138 | / crypt_stat->extent_size); | ||
137 | 139 | ||
138 | if (view_extent_num < crypt_stat->num_header_extents_at_front) { | 140 | if (view_extent_num < num_header_extents_at_front) { |
139 | /* This is a header extent */ | 141 | /* This is a header extent */ |
140 | char *page_virt; | 142 | char *page_virt; |
141 | 143 | ||
@@ -157,9 +159,8 @@ ecryptfs_copy_up_encrypted_with_header(struct page *page, | |||
157 | } else { | 159 | } else { |
158 | /* This is an encrypted data extent */ | 160 | /* This is an encrypted data extent */ |
159 | loff_t lower_offset = | 161 | loff_t lower_offset = |
160 | ((view_extent_num - | 162 | ((view_extent_num * crypt_stat->extent_size) |
161 | crypt_stat->num_header_extents_at_front) | 163 | - crypt_stat->num_header_bytes_at_front); |
162 | * crypt_stat->extent_size); | ||
163 | 164 | ||
164 | rc = ecryptfs_read_lower_page_segment( | 165 | rc = ecryptfs_read_lower_page_segment( |
165 | page, (lower_offset >> PAGE_CACHE_SHIFT), | 166 | page, (lower_offset >> PAGE_CACHE_SHIFT), |
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c index 948f57624c05..0c4928623bbc 100644 --- a/fs/ecryptfs/read_write.c +++ b/fs/ecryptfs/read_write.c | |||
@@ -293,6 +293,7 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
293 | return rc; | 293 | return rc; |
294 | } | 294 | } |
295 | 295 | ||
296 | #if 0 | ||
296 | /** | 297 | /** |
297 | * ecryptfs_read | 298 | * ecryptfs_read |
298 | * @data: The virtual address into which to write the data read (and | 299 | * @data: The virtual address into which to write the data read (and |
@@ -371,3 +372,4 @@ int ecryptfs_read(char *data, loff_t offset, size_t size, | |||
371 | out: | 372 | out: |
372 | return rc; | 373 | return rc; |
373 | } | 374 | } |
375 | #endif /* 0 */ | ||
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c index 4859c4eecd65..c27ac2b358a1 100644 --- a/fs/ecryptfs/super.c +++ b/fs/ecryptfs/super.c | |||
@@ -156,32 +156,38 @@ static void ecryptfs_clear_inode(struct inode *inode) | |||
156 | /** | 156 | /** |
157 | * ecryptfs_show_options | 157 | * ecryptfs_show_options |
158 | * | 158 | * |
159 | * Prints the directory we are currently mounted over. | 159 | * Prints the mount options for a given superblock. |
160 | * Returns zero on success; non-zero otherwise | 160 | * Returns zero; does not fail. |
161 | */ | 161 | */ |
162 | static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) | 162 | static int ecryptfs_show_options(struct seq_file *m, struct vfsmount *mnt) |
163 | { | 163 | { |
164 | struct super_block *sb = mnt->mnt_sb; | 164 | struct super_block *sb = mnt->mnt_sb; |
165 | struct dentry *lower_root_dentry = ecryptfs_dentry_to_lower(sb->s_root); | 165 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
166 | struct vfsmount *lower_mnt = ecryptfs_dentry_to_lower_mnt(sb->s_root); | 166 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; |
167 | char *tmp_page; | 167 | struct ecryptfs_global_auth_tok *walker; |
168 | char *path; | 168 | |
169 | int rc = 0; | 169 | mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex); |
170 | 170 | list_for_each_entry(walker, | |
171 | tmp_page = (char *)__get_free_page(GFP_KERNEL); | 171 | &mount_crypt_stat->global_auth_tok_list, |
172 | if (!tmp_page) { | 172 | mount_crypt_stat_list) { |
173 | rc = -ENOMEM; | 173 | seq_printf(m, ",ecryptfs_sig=%s", walker->sig); |
174 | goto out; | ||
175 | } | ||
176 | path = d_path(lower_root_dentry, lower_mnt, tmp_page, PAGE_SIZE); | ||
177 | if (IS_ERR(path)) { | ||
178 | rc = PTR_ERR(path); | ||
179 | goto out; | ||
180 | } | 174 | } |
181 | seq_printf(m, ",dir=%s", path); | 175 | mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex); |
182 | free_page((unsigned long)tmp_page); | 176 | |
183 | out: | 177 | seq_printf(m, ",ecryptfs_cipher=%s", |
184 | return rc; | 178 | mount_crypt_stat->global_default_cipher_name); |
179 | |||
180 | if (mount_crypt_stat->global_default_cipher_key_size) | ||
181 | seq_printf(m, ",ecryptfs_key_bytes=%zd", | ||
182 | mount_crypt_stat->global_default_cipher_key_size); | ||
183 | if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) | ||
184 | seq_printf(m, ",ecryptfs_passthrough"); | ||
185 | if (mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) | ||
186 | seq_printf(m, ",ecryptfs_xattr_metadata"); | ||
187 | if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) | ||
188 | seq_printf(m, ",ecryptfs_encrypted_view"); | ||
189 | |||
190 | return 0; | ||
185 | } | 191 | } |
186 | 192 | ||
187 | const struct super_operations ecryptfs_sops = { | 193 | const struct super_operations ecryptfs_sops = { |
diff --git a/fs/eventfd.c b/fs/eventfd.c index 2ce19c000d2a..a9f130cd50ac 100644 --- a/fs/eventfd.c +++ b/fs/eventfd.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
16 | #include <linux/anon_inodes.h> | 16 | #include <linux/anon_inodes.h> |
17 | #include <linux/eventfd.h> | 17 | #include <linux/eventfd.h> |
18 | #include <linux/syscalls.h> | ||
18 | 19 | ||
19 | struct eventfd_ctx { | 20 | struct eventfd_ctx { |
20 | wait_queue_head_t wqh; | 21 | wait_queue_head_t wqh; |
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 377ad172d74b..e7b2bafa1dd9 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -69,9 +69,53 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, | |||
69 | return desc + offset; | 69 | return desc + offset; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int ext2_valid_block_bitmap(struct super_block *sb, | ||
73 | struct ext2_group_desc *desc, | ||
74 | unsigned int block_group, | ||
75 | struct buffer_head *bh) | ||
76 | { | ||
77 | ext2_grpblk_t offset; | ||
78 | ext2_grpblk_t next_zero_bit; | ||
79 | ext2_fsblk_t bitmap_blk; | ||
80 | ext2_fsblk_t group_first_block; | ||
81 | |||
82 | group_first_block = ext2_group_first_block_no(sb, block_group); | ||
83 | |||
84 | /* check whether block bitmap block number is set */ | ||
85 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | ||
86 | offset = bitmap_blk - group_first_block; | ||
87 | if (!ext2_test_bit(offset, bh->b_data)) | ||
88 | /* bad block bitmap */ | ||
89 | goto err_out; | ||
90 | |||
91 | /* check whether the inode bitmap block number is set */ | ||
92 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
93 | offset = bitmap_blk - group_first_block; | ||
94 | if (!ext2_test_bit(offset, bh->b_data)) | ||
95 | /* bad block bitmap */ | ||
96 | goto err_out; | ||
97 | |||
98 | /* check whether the inode table block number is set */ | ||
99 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
100 | offset = bitmap_blk - group_first_block; | ||
101 | next_zero_bit = ext2_find_next_zero_bit(bh->b_data, | ||
102 | offset + EXT2_SB(sb)->s_itb_per_group, | ||
103 | offset); | ||
104 | if (next_zero_bit >= offset + EXT2_SB(sb)->s_itb_per_group) | ||
105 | /* good bitmap for inode tables */ | ||
106 | return 1; | ||
107 | |||
108 | err_out: | ||
109 | ext2_error(sb, __FUNCTION__, | ||
110 | "Invalid block bitmap - " | ||
111 | "block_group = %d, block = %lu", | ||
112 | block_group, bitmap_blk); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
72 | /* | 116 | /* |
73 | * Read the bitmap for a given block_group, reading into the specified | 117 | * Read the bitmap for a given block_group,and validate the |
74 | * slot in the superblock's bitmap cache. | 118 | * bits for block/inode/inode tables are set in the bitmaps |
75 | * | 119 | * |
76 | * Return buffer_head on success or NULL in case of failure. | 120 | * Return buffer_head on success or NULL in case of failure. |
77 | */ | 121 | */ |
@@ -80,17 +124,36 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
80 | { | 124 | { |
81 | struct ext2_group_desc * desc; | 125 | struct ext2_group_desc * desc; |
82 | struct buffer_head * bh = NULL; | 126 | struct buffer_head * bh = NULL; |
83 | 127 | ext2_fsblk_t bitmap_blk; | |
84 | desc = ext2_get_group_desc (sb, block_group, NULL); | 128 | |
129 | desc = ext2_get_group_desc(sb, block_group, NULL); | ||
85 | if (!desc) | 130 | if (!desc) |
86 | goto error_out; | 131 | return NULL; |
87 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); | 132 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); |
88 | if (!bh) | 133 | bh = sb_getblk(sb, bitmap_blk); |
89 | ext2_error (sb, "read_block_bitmap", | 134 | if (unlikely(!bh)) { |
135 | ext2_error(sb, __FUNCTION__, | ||
136 | "Cannot read block bitmap - " | ||
137 | "block_group = %d, block_bitmap = %u", | ||
138 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | ||
139 | return NULL; | ||
140 | } | ||
141 | if (likely(bh_uptodate_or_lock(bh))) | ||
142 | return bh; | ||
143 | |||
144 | if (bh_submit_read(bh) < 0) { | ||
145 | brelse(bh); | ||
146 | ext2_error(sb, __FUNCTION__, | ||
90 | "Cannot read block bitmap - " | 147 | "Cannot read block bitmap - " |
91 | "block_group = %d, block_bitmap = %u", | 148 | "block_group = %d, block_bitmap = %u", |
92 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 149 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
93 | error_out: | 150 | return NULL; |
151 | } | ||
152 | if (!ext2_valid_block_bitmap(sb, desc, block_group, bh)) { | ||
153 | brelse(bh); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
94 | return bh; | 157 | return bh; |
95 | } | 158 | } |
96 | 159 | ||
@@ -474,11 +537,13 @@ do_more: | |||
474 | in_range (block, le32_to_cpu(desc->bg_inode_table), | 537 | in_range (block, le32_to_cpu(desc->bg_inode_table), |
475 | sbi->s_itb_per_group) || | 538 | sbi->s_itb_per_group) || |
476 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), | 539 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), |
477 | sbi->s_itb_per_group)) | 540 | sbi->s_itb_per_group)) { |
478 | ext2_error (sb, "ext2_free_blocks", | 541 | ext2_error (sb, "ext2_free_blocks", |
479 | "Freeing blocks in system zones - " | 542 | "Freeing blocks in system zones - " |
480 | "Block = %lu, count = %lu", | 543 | "Block = %lu, count = %lu", |
481 | block, count); | 544 | block, count); |
545 | goto error_return; | ||
546 | } | ||
482 | 547 | ||
483 | for (i = 0, group_freed = 0; i < count; i++) { | 548 | for (i = 0, group_freed = 0; i < count; i++) { |
484 | if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 549 | if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), |
@@ -1250,8 +1315,8 @@ retry_alloc: | |||
1250 | smp_rmb(); | 1315 | smp_rmb(); |
1251 | 1316 | ||
1252 | /* | 1317 | /* |
1253 | * Now search the rest of the groups. We assume that | 1318 | * Now search the rest of the groups. We assume that |
1254 | * i and gdp correctly point to the last group visited. | 1319 | * group_no and gdp correctly point to the last group visited. |
1255 | */ | 1320 | */ |
1256 | for (bgi = 0; bgi < ngroups; bgi++) { | 1321 | for (bgi = 0; bgi < ngroups; bgi++) { |
1257 | group_no++; | 1322 | group_no++; |
@@ -1311,11 +1376,13 @@ allocated: | |||
1311 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), | 1376 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), |
1312 | EXT2_SB(sb)->s_itb_per_group) || | 1377 | EXT2_SB(sb)->s_itb_per_group) || |
1313 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | 1378 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), |
1314 | EXT2_SB(sb)->s_itb_per_group)) | 1379 | EXT2_SB(sb)->s_itb_per_group)) { |
1315 | ext2_error(sb, "ext2_new_blocks", | 1380 | ext2_error(sb, "ext2_new_blocks", |
1316 | "Allocating block in system zone - " | 1381 | "Allocating block in system zone - " |
1317 | "blocks from "E2FSBLK", length %lu", | 1382 | "blocks from "E2FSBLK", length %lu", |
1318 | ret_block, num); | 1383 | ret_block, num); |
1384 | goto out; | ||
1385 | } | ||
1319 | 1386 | ||
1320 | performed_allocation = 1; | 1387 | performed_allocation = 1; |
1321 | 1388 | ||
@@ -1466,9 +1533,6 @@ int ext2_bg_has_super(struct super_block *sb, int group) | |||
1466 | */ | 1533 | */ |
1467 | unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) | 1534 | unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) |
1468 | { | 1535 | { |
1469 | if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&& | 1536 | return ext2_bg_has_super(sb, group) ? EXT2_SB(sb)->s_gdb_count : 0; |
1470 | !ext2_group_sparse(group)) | ||
1471 | return 0; | ||
1472 | return EXT2_SB(sb)->s_gdb_count; | ||
1473 | } | 1537 | } |
1474 | 1538 | ||
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index d868e26c15eb..8dededd80fe2 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -703,7 +703,7 @@ const struct file_operations ext2_dir_operations = { | |||
703 | .llseek = generic_file_llseek, | 703 | .llseek = generic_file_llseek, |
704 | .read = generic_read_dir, | 704 | .read = generic_read_dir, |
705 | .readdir = ext2_readdir, | 705 | .readdir = ext2_readdir, |
706 | .ioctl = ext2_ioctl, | 706 | .unlocked_ioctl = ext2_ioctl, |
707 | #ifdef CONFIG_COMPAT | 707 | #ifdef CONFIG_COMPAT |
708 | .compat_ioctl = ext2_compat_ioctl, | 708 | .compat_ioctl = ext2_compat_ioctl, |
709 | #endif | 709 | #endif |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index c87ae29c19cb..bb9948cdd50f 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -139,8 +139,7 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping, | |||
139 | struct page **pagep, void **fsdata); | 139 | struct page **pagep, void **fsdata); |
140 | 140 | ||
141 | /* ioctl.c */ | 141 | /* ioctl.c */ |
142 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, | 142 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); |
143 | unsigned long); | ||
144 | extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); | 143 | extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); |
145 | 144 | ||
146 | /* namei.c */ | 145 | /* namei.c */ |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index c051798459a1..5f2fa9c36293 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -48,7 +48,7 @@ const struct file_operations ext2_file_operations = { | |||
48 | .write = do_sync_write, | 48 | .write = do_sync_write, |
49 | .aio_read = generic_file_aio_read, | 49 | .aio_read = generic_file_aio_read, |
50 | .aio_write = generic_file_aio_write, | 50 | .aio_write = generic_file_aio_write, |
51 | .ioctl = ext2_ioctl, | 51 | .unlocked_ioctl = ext2_ioctl, |
52 | #ifdef CONFIG_COMPAT | 52 | #ifdef CONFIG_COMPAT |
53 | .compat_ioctl = ext2_compat_ioctl, | 53 | .compat_ioctl = ext2_compat_ioctl, |
54 | #endif | 54 | #endif |
@@ -65,7 +65,7 @@ const struct file_operations ext2_xip_file_operations = { | |||
65 | .llseek = generic_file_llseek, | 65 | .llseek = generic_file_llseek, |
66 | .read = xip_file_read, | 66 | .read = xip_file_read, |
67 | .write = xip_file_write, | 67 | .write = xip_file_write, |
68 | .ioctl = ext2_ioctl, | 68 | .unlocked_ioctl = ext2_ioctl, |
69 | #ifdef CONFIG_COMPAT | 69 | #ifdef CONFIG_COMPAT |
70 | .compat_ioctl = ext2_compat_ioctl, | 70 | .compat_ioctl = ext2_compat_ioctl, |
71 | #endif | 71 | #endif |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b1ab32ab5a77..03978ec2a91c 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -286,15 +286,12 @@ static unsigned long ext2_find_near(struct inode *inode, Indirect *ind) | |||
286 | * ext2_find_goal - find a prefered place for allocation. | 286 | * ext2_find_goal - find a prefered place for allocation. |
287 | * @inode: owner | 287 | * @inode: owner |
288 | * @block: block we want | 288 | * @block: block we want |
289 | * @chain: chain of indirect blocks | ||
290 | * @partial: pointer to the last triple within a chain | 289 | * @partial: pointer to the last triple within a chain |
291 | * | 290 | * |
292 | * Returns preferred place for a block (the goal). | 291 | * Returns preferred place for a block (the goal). |
293 | */ | 292 | */ |
294 | 293 | ||
295 | static inline int ext2_find_goal(struct inode *inode, | 294 | static inline int ext2_find_goal(struct inode *inode, long block, |
296 | long block, | ||
297 | Indirect chain[4], | ||
298 | Indirect *partial) | 295 | Indirect *partial) |
299 | { | 296 | { |
300 | struct ext2_block_alloc_info *block_i; | 297 | struct ext2_block_alloc_info *block_i; |
@@ -569,7 +566,6 @@ static void ext2_splice_branch(struct inode *inode, | |||
569 | * | 566 | * |
570 | * `handle' can be NULL if create == 0. | 567 | * `handle' can be NULL if create == 0. |
571 | * | 568 | * |
572 | * The BKL may not be held on entry here. Be sure to take it early. | ||
573 | * return > 0, # of blocks mapped or allocated. | 569 | * return > 0, # of blocks mapped or allocated. |
574 | * return = 0, if plain lookup failed. | 570 | * return = 0, if plain lookup failed. |
575 | * return < 0, error case. | 571 | * return < 0, error case. |
@@ -639,7 +635,7 @@ reread: | |||
639 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) | 635 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) |
640 | ext2_init_block_alloc_info(inode); | 636 | ext2_init_block_alloc_info(inode); |
641 | 637 | ||
642 | goal = ext2_find_goal(inode, iblock, chain, partial); | 638 | goal = ext2_find_goal(inode, iblock, partial); |
643 | 639 | ||
644 | /* the number of blocks need to allocate for [d,t]indirect blocks */ | 640 | /* the number of blocks need to allocate for [d,t]indirect blocks */ |
645 | indirect_blks = (chain + depth) - partial - 1; | 641 | indirect_blks = (chain + depth) - partial - 1; |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 320b2cb3d4d2..b8ea11fee5c6 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -17,9 +17,9 @@ | |||
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | 18 | ||
19 | 19 | ||
20 | int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | 20 | long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
21 | unsigned long arg) | ||
22 | { | 21 | { |
22 | struct inode *inode = filp->f_dentry->d_inode; | ||
23 | struct ext2_inode_info *ei = EXT2_I(inode); | 23 | struct ext2_inode_info *ei = EXT2_I(inode); |
24 | unsigned int flags; | 24 | unsigned int flags; |
25 | unsigned short rsv_window_size; | 25 | unsigned short rsv_window_size; |
@@ -141,9 +141,6 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
141 | #ifdef CONFIG_COMPAT | 141 | #ifdef CONFIG_COMPAT |
142 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 142 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
143 | { | 143 | { |
144 | struct inode *inode = file->f_path.dentry->d_inode; | ||
145 | int ret; | ||
146 | |||
147 | /* These are just misnamed, they actually get/put from/to user an int */ | 144 | /* These are just misnamed, they actually get/put from/to user an int */ |
148 | switch (cmd) { | 145 | switch (cmd) { |
149 | case EXT2_IOC32_GETFLAGS: | 146 | case EXT2_IOC32_GETFLAGS: |
@@ -161,9 +158,6 @@ long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
161 | default: | 158 | default: |
162 | return -ENOIOCTLCMD; | 159 | return -ENOIOCTLCMD; |
163 | } | 160 | } |
164 | lock_kernel(); | 161 | return ext2_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); |
165 | ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
166 | unlock_kernel(); | ||
167 | return ret; | ||
168 | } | 162 | } |
169 | #endif | 163 | #endif |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 6abaf75163f0..1ba18b72d43a 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -234,16 +234,16 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
234 | le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { | 234 | le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { |
235 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); | 235 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); |
236 | } | 236 | } |
237 | if (test_opt(sb, ERRORS_CONT)) { | 237 | if (test_opt(sb, ERRORS_RO)) { |
238 | int def_errors = le16_to_cpu(es->s_errors); | 238 | int def_errors = le16_to_cpu(es->s_errors); |
239 | 239 | ||
240 | if (def_errors == EXT2_ERRORS_PANIC || | 240 | if (def_errors == EXT2_ERRORS_PANIC || |
241 | def_errors == EXT2_ERRORS_RO) { | 241 | def_errors == EXT2_ERRORS_CONTINUE) { |
242 | seq_puts(seq, ",errors=continue"); | 242 | seq_puts(seq, ",errors=remount-ro"); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | if (test_opt(sb, ERRORS_RO)) | 245 | if (test_opt(sb, ERRORS_CONT)) |
246 | seq_puts(seq, ",errors=remount-ro"); | 246 | seq_puts(seq, ",errors=continue"); |
247 | if (test_opt(sb, ERRORS_PANIC)) | 247 | if (test_opt(sb, ERRORS_PANIC)) |
248 | seq_puts(seq, ",errors=panic"); | 248 | seq_puts(seq, ",errors=panic"); |
249 | if (test_opt(sb, NO_UID32)) | 249 | if (test_opt(sb, NO_UID32)) |
@@ -617,27 +617,24 @@ static int ext2_setup_super (struct super_block * sb, | |||
617 | return res; | 617 | return res; |
618 | } | 618 | } |
619 | 619 | ||
620 | static int ext2_check_descriptors (struct super_block * sb) | 620 | static int ext2_check_descriptors(struct super_block *sb) |
621 | { | 621 | { |
622 | int i; | 622 | int i; |
623 | int desc_block = 0; | ||
624 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 623 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
625 | unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 624 | unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
626 | unsigned long last_block; | 625 | unsigned long last_block; |
627 | struct ext2_group_desc * gdp = NULL; | ||
628 | 626 | ||
629 | ext2_debug ("Checking group descriptors"); | 627 | ext2_debug ("Checking group descriptors"); |
630 | 628 | ||
631 | for (i = 0; i < sbi->s_groups_count; i++) | 629 | for (i = 0; i < sbi->s_groups_count; i++) { |
632 | { | 630 | struct ext2_group_desc *gdp = ext2_get_group_desc(sb, i, NULL); |
631 | |||
633 | if (i == sbi->s_groups_count - 1) | 632 | if (i == sbi->s_groups_count - 1) |
634 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; | 633 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; |
635 | else | 634 | else |
636 | last_block = first_block + | 635 | last_block = first_block + |
637 | (EXT2_BLOCKS_PER_GROUP(sb) - 1); | 636 | (EXT2_BLOCKS_PER_GROUP(sb) - 1); |
638 | 637 | ||
639 | if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) | ||
640 | gdp = (struct ext2_group_desc *) sbi->s_group_desc[desc_block++]->b_data; | ||
641 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || | 638 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || |
642 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) | 639 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) |
643 | { | 640 | { |
@@ -667,7 +664,6 @@ static int ext2_check_descriptors (struct super_block * sb) | |||
667 | return 0; | 664 | return 0; |
668 | } | 665 | } |
669 | first_block += EXT2_BLOCKS_PER_GROUP(sb); | 666 | first_block += EXT2_BLOCKS_PER_GROUP(sb); |
670 | gdp++; | ||
671 | } | 667 | } |
672 | return 1; | 668 | return 1; |
673 | } | 669 | } |
@@ -820,10 +816,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
820 | 816 | ||
821 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC) | 817 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC) |
822 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 818 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
823 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO) | 819 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE) |
824 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
825 | else | ||
826 | set_opt(sbi->s_mount_opt, ERRORS_CONT); | 820 | set_opt(sbi->s_mount_opt, ERRORS_CONT); |
821 | else | ||
822 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
827 | 823 | ||
828 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); | 824 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); |
829 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 825 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); |
@@ -868,8 +864,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
868 | 864 | ||
869 | blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); | 865 | blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); |
870 | 866 | ||
871 | if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) || | 867 | if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) { |
872 | (sb->s_blocksize != blocksize))) { | ||
873 | if (!silent) | 868 | if (!silent) |
874 | printk("XIP: Unsupported blocksize\n"); | 869 | printk("XIP: Unsupported blocksize\n"); |
875 | goto failed_mount; | 870 | goto failed_mount; |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index a8ba7e831278..a75713031105 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -80,13 +80,57 @@ struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, | |||
80 | return desc + offset; | 80 | return desc + offset; |
81 | } | 81 | } |
82 | 82 | ||
83 | static int ext3_valid_block_bitmap(struct super_block *sb, | ||
84 | struct ext3_group_desc *desc, | ||
85 | unsigned int block_group, | ||
86 | struct buffer_head *bh) | ||
87 | { | ||
88 | ext3_grpblk_t offset; | ||
89 | ext3_grpblk_t next_zero_bit; | ||
90 | ext3_fsblk_t bitmap_blk; | ||
91 | ext3_fsblk_t group_first_block; | ||
92 | |||
93 | group_first_block = ext3_group_first_block_no(sb, block_group); | ||
94 | |||
95 | /* check whether block bitmap block number is set */ | ||
96 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | ||
97 | offset = bitmap_blk - group_first_block; | ||
98 | if (!ext3_test_bit(offset, bh->b_data)) | ||
99 | /* bad block bitmap */ | ||
100 | goto err_out; | ||
101 | |||
102 | /* check whether the inode bitmap block number is set */ | ||
103 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
104 | offset = bitmap_blk - group_first_block; | ||
105 | if (!ext3_test_bit(offset, bh->b_data)) | ||
106 | /* bad block bitmap */ | ||
107 | goto err_out; | ||
108 | |||
109 | /* check whether the inode table block number is set */ | ||
110 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
111 | offset = bitmap_blk - group_first_block; | ||
112 | next_zero_bit = ext3_find_next_zero_bit(bh->b_data, | ||
113 | offset + EXT3_SB(sb)->s_itb_per_group, | ||
114 | offset); | ||
115 | if (next_zero_bit >= offset + EXT3_SB(sb)->s_itb_per_group) | ||
116 | /* good bitmap for inode tables */ | ||
117 | return 1; | ||
118 | |||
119 | err_out: | ||
120 | ext3_error(sb, __FUNCTION__, | ||
121 | "Invalid block bitmap - " | ||
122 | "block_group = %d, block = %lu", | ||
123 | block_group, bitmap_blk); | ||
124 | return 0; | ||
125 | } | ||
126 | |||
83 | /** | 127 | /** |
84 | * read_block_bitmap() | 128 | * read_block_bitmap() |
85 | * @sb: super block | 129 | * @sb: super block |
86 | * @block_group: given block group | 130 | * @block_group: given block group |
87 | * | 131 | * |
88 | * Read the bitmap for a given block_group, reading into the specified | 132 | * Read the bitmap for a given block_group,and validate the |
89 | * slot in the superblock's bitmap cache. | 133 | * bits for block/inode/inode tables are set in the bitmaps |
90 | * | 134 | * |
91 | * Return buffer_head on success or NULL in case of failure. | 135 | * Return buffer_head on success or NULL in case of failure. |
92 | */ | 136 | */ |
@@ -95,17 +139,35 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
95 | { | 139 | { |
96 | struct ext3_group_desc * desc; | 140 | struct ext3_group_desc * desc; |
97 | struct buffer_head * bh = NULL; | 141 | struct buffer_head * bh = NULL; |
142 | ext3_fsblk_t bitmap_blk; | ||
98 | 143 | ||
99 | desc = ext3_get_group_desc (sb, block_group, NULL); | 144 | desc = ext3_get_group_desc(sb, block_group, NULL); |
100 | if (!desc) | 145 | if (!desc) |
101 | goto error_out; | 146 | return NULL; |
102 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); | 147 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); |
103 | if (!bh) | 148 | bh = sb_getblk(sb, bitmap_blk); |
104 | ext3_error (sb, "read_block_bitmap", | 149 | if (unlikely(!bh)) { |
150 | ext3_error(sb, __FUNCTION__, | ||
105 | "Cannot read block bitmap - " | 151 | "Cannot read block bitmap - " |
106 | "block_group = %d, block_bitmap = %u", | 152 | "block_group = %d, block_bitmap = %u", |
107 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 153 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
108 | error_out: | 154 | return NULL; |
155 | } | ||
156 | if (likely(bh_uptodate_or_lock(bh))) | ||
157 | return bh; | ||
158 | |||
159 | if (bh_submit_read(bh) < 0) { | ||
160 | brelse(bh); | ||
161 | ext3_error(sb, __FUNCTION__, | ||
162 | "Cannot read block bitmap - " | ||
163 | "block_group = %d, block_bitmap = %u", | ||
164 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | ||
165 | return NULL; | ||
166 | } | ||
167 | if (!ext3_valid_block_bitmap(sb, desc, block_group, bh)) { | ||
168 | brelse(bh); | ||
169 | return NULL; | ||
170 | } | ||
109 | return bh; | 171 | return bh; |
110 | } | 172 | } |
111 | /* | 173 | /* |
@@ -468,11 +530,13 @@ do_more: | |||
468 | in_range (block, le32_to_cpu(desc->bg_inode_table), | 530 | in_range (block, le32_to_cpu(desc->bg_inode_table), |
469 | sbi->s_itb_per_group) || | 531 | sbi->s_itb_per_group) || |
470 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), | 532 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), |
471 | sbi->s_itb_per_group)) | 533 | sbi->s_itb_per_group)) { |
472 | ext3_error (sb, "ext3_free_blocks", | 534 | ext3_error (sb, "ext3_free_blocks", |
473 | "Freeing blocks in system zones - " | 535 | "Freeing blocks in system zones - " |
474 | "Block = "E3FSBLK", count = %lu", | 536 | "Block = "E3FSBLK", count = %lu", |
475 | block, count); | 537 | block, count); |
538 | goto error_return; | ||
539 | } | ||
476 | 540 | ||
477 | /* | 541 | /* |
478 | * We are about to start releasing blocks in the bitmap, | 542 | * We are about to start releasing blocks in the bitmap, |
@@ -1508,7 +1572,7 @@ retry_alloc: | |||
1508 | 1572 | ||
1509 | /* | 1573 | /* |
1510 | * Now search the rest of the groups. We assume that | 1574 | * Now search the rest of the groups. We assume that |
1511 | * i and gdp correctly point to the last group visited. | 1575 | * group_no and gdp correctly point to the last group visited. |
1512 | */ | 1576 | */ |
1513 | for (bgi = 0; bgi < ngroups; bgi++) { | 1577 | for (bgi = 0; bgi < ngroups; bgi++) { |
1514 | group_no++; | 1578 | group_no++; |
@@ -1575,11 +1639,13 @@ allocated: | |||
1575 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), | 1639 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), |
1576 | EXT3_SB(sb)->s_itb_per_group) || | 1640 | EXT3_SB(sb)->s_itb_per_group) || |
1577 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | 1641 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), |
1578 | EXT3_SB(sb)->s_itb_per_group)) | 1642 | EXT3_SB(sb)->s_itb_per_group)) { |
1579 | ext3_error(sb, "ext3_new_block", | 1643 | ext3_error(sb, "ext3_new_block", |
1580 | "Allocating block in system zone - " | 1644 | "Allocating block in system zone - " |
1581 | "blocks from "E3FSBLK", length %lu", | 1645 | "blocks from "E3FSBLK", length %lu", |
1582 | ret_block, num); | 1646 | ret_block, num); |
1647 | goto out; | ||
1648 | } | ||
1583 | 1649 | ||
1584 | performed_allocation = 1; | 1650 | performed_allocation = 1; |
1585 | 1651 | ||
@@ -1782,11 +1848,7 @@ static unsigned long ext3_bg_num_gdb_meta(struct super_block *sb, int group) | |||
1782 | 1848 | ||
1783 | static unsigned long ext3_bg_num_gdb_nometa(struct super_block *sb, int group) | 1849 | static unsigned long ext3_bg_num_gdb_nometa(struct super_block *sb, int group) |
1784 | { | 1850 | { |
1785 | if (EXT3_HAS_RO_COMPAT_FEATURE(sb, | 1851 | return ext3_bg_has_super(sb, group) ? EXT3_SB(sb)->s_gdb_count : 0; |
1786 | EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER) && | ||
1787 | !ext3_group_sparse(group)) | ||
1788 | return 0; | ||
1789 | return EXT3_SB(sb)->s_gdb_count; | ||
1790 | } | 1852 | } |
1791 | 1853 | ||
1792 | /** | 1854 | /** |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 077535439288..8a9ce2d09bde 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -439,16 +439,14 @@ static ext3_fsblk_t ext3_find_near(struct inode *inode, Indirect *ind) | |||
439 | * ext3_find_goal - find a prefered place for allocation. | 439 | * ext3_find_goal - find a prefered place for allocation. |
440 | * @inode: owner | 440 | * @inode: owner |
441 | * @block: block we want | 441 | * @block: block we want |
442 | * @chain: chain of indirect blocks | ||
443 | * @partial: pointer to the last triple within a chain | 442 | * @partial: pointer to the last triple within a chain |
444 | * @goal: place to store the result. | ||
445 | * | 443 | * |
446 | * Normally this function find the prefered place for block allocation, | 444 | * Normally this function find the prefered place for block allocation, |
447 | * stores it in *@goal and returns zero. | 445 | * returns it. |
448 | */ | 446 | */ |
449 | 447 | ||
450 | static ext3_fsblk_t ext3_find_goal(struct inode *inode, long block, | 448 | static ext3_fsblk_t ext3_find_goal(struct inode *inode, long block, |
451 | Indirect chain[4], Indirect *partial) | 449 | Indirect *partial) |
452 | { | 450 | { |
453 | struct ext3_block_alloc_info *block_i; | 451 | struct ext3_block_alloc_info *block_i; |
454 | 452 | ||
@@ -884,7 +882,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
884 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) | 882 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) |
885 | ext3_init_block_alloc_info(inode); | 883 | ext3_init_block_alloc_info(inode); |
886 | 884 | ||
887 | goal = ext3_find_goal(inode, iblock, chain, partial); | 885 | goal = ext3_find_goal(inode, iblock, partial); |
888 | 886 | ||
889 | /* the number of blocks need to allocate for [d,t]indirect blocks */ | 887 | /* the number of blocks need to allocate for [d,t]indirect blocks */ |
890 | indirect_blks = (chain + depth) - partial - 1; | 888 | indirect_blks = (chain + depth) - partial - 1; |
@@ -941,55 +939,45 @@ out: | |||
941 | return err; | 939 | return err; |
942 | } | 940 | } |
943 | 941 | ||
944 | #define DIO_CREDITS (EXT3_RESERVE_TRANS_BLOCKS + 32) | 942 | /* Maximum number of blocks we map for direct IO at once. */ |
943 | #define DIO_MAX_BLOCKS 4096 | ||
944 | /* | ||
945 | * Number of credits we need for writing DIO_MAX_BLOCKS: | ||
946 | * We need sb + group descriptor + bitmap + inode -> 4 | ||
947 | * For B blocks with A block pointers per block we need: | ||
948 | * 1 (triple ind.) + (B/A/A + 2) (doubly ind.) + (B/A + 2) (indirect). | ||
949 | * If we plug in 4096 for B and 256 for A (for 1KB block size), we get 25. | ||
950 | */ | ||
951 | #define DIO_CREDITS 25 | ||
945 | 952 | ||
946 | static int ext3_get_block(struct inode *inode, sector_t iblock, | 953 | static int ext3_get_block(struct inode *inode, sector_t iblock, |
947 | struct buffer_head *bh_result, int create) | 954 | struct buffer_head *bh_result, int create) |
948 | { | 955 | { |
949 | handle_t *handle = ext3_journal_current_handle(); | 956 | handle_t *handle = ext3_journal_current_handle(); |
950 | int ret = 0; | 957 | int ret = 0, started = 0; |
951 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; | 958 | unsigned max_blocks = bh_result->b_size >> inode->i_blkbits; |
952 | 959 | ||
953 | if (!create) | 960 | if (create && !handle) { /* Direct IO write... */ |
954 | goto get_block; /* A read */ | 961 | if (max_blocks > DIO_MAX_BLOCKS) |
955 | 962 | max_blocks = DIO_MAX_BLOCKS; | |
956 | if (max_blocks == 1) | 963 | handle = ext3_journal_start(inode, DIO_CREDITS + |
957 | goto get_block; /* A single block get */ | 964 | 2 * EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb)); |
958 | 965 | if (IS_ERR(handle)) { | |
959 | if (handle->h_transaction->t_state == T_LOCKED) { | ||
960 | /* | ||
961 | * Huge direct-io writes can hold off commits for long | ||
962 | * periods of time. Let this commit run. | ||
963 | */ | ||
964 | ext3_journal_stop(handle); | ||
965 | handle = ext3_journal_start(inode, DIO_CREDITS); | ||
966 | if (IS_ERR(handle)) | ||
967 | ret = PTR_ERR(handle); | 966 | ret = PTR_ERR(handle); |
968 | goto get_block; | 967 | goto out; |
969 | } | ||
970 | |||
971 | if (handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) { | ||
972 | /* | ||
973 | * Getting low on buffer credits... | ||
974 | */ | ||
975 | ret = ext3_journal_extend(handle, DIO_CREDITS); | ||
976 | if (ret > 0) { | ||
977 | /* | ||
978 | * Couldn't extend the transaction. Start a new one. | ||
979 | */ | ||
980 | ret = ext3_journal_restart(handle, DIO_CREDITS); | ||
981 | } | 968 | } |
969 | started = 1; | ||
982 | } | 970 | } |
983 | 971 | ||
984 | get_block: | 972 | ret = ext3_get_blocks_handle(handle, inode, iblock, |
985 | if (ret == 0) { | ||
986 | ret = ext3_get_blocks_handle(handle, inode, iblock, | ||
987 | max_blocks, bh_result, create, 0); | 973 | max_blocks, bh_result, create, 0); |
988 | if (ret > 0) { | 974 | if (ret > 0) { |
989 | bh_result->b_size = (ret << inode->i_blkbits); | 975 | bh_result->b_size = (ret << inode->i_blkbits); |
990 | ret = 0; | 976 | ret = 0; |
991 | } | ||
992 | } | 977 | } |
978 | if (started) | ||
979 | ext3_journal_stop(handle); | ||
980 | out: | ||
993 | return ret; | 981 | return ret; |
994 | } | 982 | } |
995 | 983 | ||
@@ -1680,7 +1668,8 @@ static int ext3_releasepage(struct page *page, gfp_t wait) | |||
1680 | * if the machine crashes during the write. | 1668 | * if the machine crashes during the write. |
1681 | * | 1669 | * |
1682 | * If the O_DIRECT write is intantiating holes inside i_size and the machine | 1670 | * If the O_DIRECT write is intantiating holes inside i_size and the machine |
1683 | * crashes then stale disk data _may_ be exposed inside the file. | 1671 | * crashes then stale disk data _may_ be exposed inside the file. But current |
1672 | * VFS code falls back into buffered path in that case so we are safe. | ||
1684 | */ | 1673 | */ |
1685 | static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | 1674 | static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, |
1686 | const struct iovec *iov, loff_t offset, | 1675 | const struct iovec *iov, loff_t offset, |
@@ -1689,7 +1678,7 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1689 | struct file *file = iocb->ki_filp; | 1678 | struct file *file = iocb->ki_filp; |
1690 | struct inode *inode = file->f_mapping->host; | 1679 | struct inode *inode = file->f_mapping->host; |
1691 | struct ext3_inode_info *ei = EXT3_I(inode); | 1680 | struct ext3_inode_info *ei = EXT3_I(inode); |
1692 | handle_t *handle = NULL; | 1681 | handle_t *handle; |
1693 | ssize_t ret; | 1682 | ssize_t ret; |
1694 | int orphan = 0; | 1683 | int orphan = 0; |
1695 | size_t count = iov_length(iov, nr_segs); | 1684 | size_t count = iov_length(iov, nr_segs); |
@@ -1697,17 +1686,21 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1697 | if (rw == WRITE) { | 1686 | if (rw == WRITE) { |
1698 | loff_t final_size = offset + count; | 1687 | loff_t final_size = offset + count; |
1699 | 1688 | ||
1700 | handle = ext3_journal_start(inode, DIO_CREDITS); | ||
1701 | if (IS_ERR(handle)) { | ||
1702 | ret = PTR_ERR(handle); | ||
1703 | goto out; | ||
1704 | } | ||
1705 | if (final_size > inode->i_size) { | 1689 | if (final_size > inode->i_size) { |
1690 | /* Credits for sb + inode write */ | ||
1691 | handle = ext3_journal_start(inode, 2); | ||
1692 | if (IS_ERR(handle)) { | ||
1693 | ret = PTR_ERR(handle); | ||
1694 | goto out; | ||
1695 | } | ||
1706 | ret = ext3_orphan_add(handle, inode); | 1696 | ret = ext3_orphan_add(handle, inode); |
1707 | if (ret) | 1697 | if (ret) { |
1708 | goto out_stop; | 1698 | ext3_journal_stop(handle); |
1699 | goto out; | ||
1700 | } | ||
1709 | orphan = 1; | 1701 | orphan = 1; |
1710 | ei->i_disksize = inode->i_size; | 1702 | ei->i_disksize = inode->i_size; |
1703 | ext3_journal_stop(handle); | ||
1711 | } | 1704 | } |
1712 | } | 1705 | } |
1713 | 1706 | ||
@@ -1715,18 +1708,21 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1715 | offset, nr_segs, | 1708 | offset, nr_segs, |
1716 | ext3_get_block, NULL); | 1709 | ext3_get_block, NULL); |
1717 | 1710 | ||
1718 | /* | 1711 | if (orphan) { |
1719 | * Reacquire the handle: ext3_get_block() can restart the transaction | ||
1720 | */ | ||
1721 | handle = ext3_journal_current_handle(); | ||
1722 | |||
1723 | out_stop: | ||
1724 | if (handle) { | ||
1725 | int err; | 1712 | int err; |
1726 | 1713 | ||
1727 | if (orphan && inode->i_nlink) | 1714 | /* Credits for sb + inode write */ |
1715 | handle = ext3_journal_start(inode, 2); | ||
1716 | if (IS_ERR(handle)) { | ||
1717 | /* This is really bad luck. We've written the data | ||
1718 | * but cannot extend i_size. Bail out and pretend | ||
1719 | * the write failed... */ | ||
1720 | ret = PTR_ERR(handle); | ||
1721 | goto out; | ||
1722 | } | ||
1723 | if (inode->i_nlink) | ||
1728 | ext3_orphan_del(handle, inode); | 1724 | ext3_orphan_del(handle, inode); |
1729 | if (orphan && ret > 0) { | 1725 | if (ret > 0) { |
1730 | loff_t end = offset + ret; | 1726 | loff_t end = offset + ret; |
1731 | if (end > inode->i_size) { | 1727 | if (end > inode->i_size) { |
1732 | ei->i_disksize = end; | 1728 | ei->i_disksize = end; |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index 4ab6f76e63d0..92b83b004dd8 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -860,14 +860,10 @@ static struct buffer_head * ext3_find_entry (struct dentry *dentry, | |||
860 | int nblocks, i, err; | 860 | int nblocks, i, err; |
861 | struct inode *dir = dentry->d_parent->d_inode; | 861 | struct inode *dir = dentry->d_parent->d_inode; |
862 | int namelen; | 862 | int namelen; |
863 | const u8 *name; | ||
864 | unsigned blocksize; | ||
865 | 863 | ||
866 | *res_dir = NULL; | 864 | *res_dir = NULL; |
867 | sb = dir->i_sb; | 865 | sb = dir->i_sb; |
868 | blocksize = sb->s_blocksize; | ||
869 | namelen = dentry->d_name.len; | 866 | namelen = dentry->d_name.len; |
870 | name = dentry->d_name.name; | ||
871 | if (namelen > EXT3_NAME_LEN) | 867 | if (namelen > EXT3_NAME_LEN) |
872 | return NULL; | 868 | return NULL; |
873 | if (is_dx(dir)) { | 869 | if (is_dx(dir)) { |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index f3675cc630e9..343677e8c350 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -575,16 +575,16 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
575 | le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) { | 575 | le16_to_cpu(es->s_def_resgid) != EXT3_DEF_RESGID) { |
576 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); | 576 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); |
577 | } | 577 | } |
578 | if (test_opt(sb, ERRORS_CONT)) { | 578 | if (test_opt(sb, ERRORS_RO)) { |
579 | int def_errors = le16_to_cpu(es->s_errors); | 579 | int def_errors = le16_to_cpu(es->s_errors); |
580 | 580 | ||
581 | if (def_errors == EXT3_ERRORS_PANIC || | 581 | if (def_errors == EXT3_ERRORS_PANIC || |
582 | def_errors == EXT3_ERRORS_RO) { | 582 | def_errors == EXT3_ERRORS_CONTINUE) { |
583 | seq_puts(seq, ",errors=continue"); | 583 | seq_puts(seq, ",errors=remount-ro"); |
584 | } | 584 | } |
585 | } | 585 | } |
586 | if (test_opt(sb, ERRORS_RO)) | 586 | if (test_opt(sb, ERRORS_CONT)) |
587 | seq_puts(seq, ",errors=remount-ro"); | 587 | seq_puts(seq, ",errors=continue"); |
588 | if (test_opt(sb, ERRORS_PANIC)) | 588 | if (test_opt(sb, ERRORS_PANIC)) |
589 | seq_puts(seq, ",errors=panic"); | 589 | seq_puts(seq, ",errors=panic"); |
590 | if (test_opt(sb, NO_UID32)) | 590 | if (test_opt(sb, NO_UID32)) |
@@ -1252,28 +1252,24 @@ static int ext3_setup_super(struct super_block *sb, struct ext3_super_block *es, | |||
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | /* Called at mount-time, super-block is locked */ | 1254 | /* Called at mount-time, super-block is locked */ |
1255 | static int ext3_check_descriptors (struct super_block * sb) | 1255 | static int ext3_check_descriptors(struct super_block *sb) |
1256 | { | 1256 | { |
1257 | struct ext3_sb_info *sbi = EXT3_SB(sb); | 1257 | struct ext3_sb_info *sbi = EXT3_SB(sb); |
1258 | ext3_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 1258 | ext3_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
1259 | ext3_fsblk_t last_block; | 1259 | ext3_fsblk_t last_block; |
1260 | struct ext3_group_desc * gdp = NULL; | ||
1261 | int desc_block = 0; | ||
1262 | int i; | 1260 | int i; |
1263 | 1261 | ||
1264 | ext3_debug ("Checking group descriptors"); | 1262 | ext3_debug ("Checking group descriptors"); |
1265 | 1263 | ||
1266 | for (i = 0; i < sbi->s_groups_count; i++) | 1264 | for (i = 0; i < sbi->s_groups_count; i++) { |
1267 | { | 1265 | struct ext3_group_desc *gdp = ext3_get_group_desc(sb, i, NULL); |
1266 | |||
1268 | if (i == sbi->s_groups_count - 1) | 1267 | if (i == sbi->s_groups_count - 1) |
1269 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; | 1268 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; |
1270 | else | 1269 | else |
1271 | last_block = first_block + | 1270 | last_block = first_block + |
1272 | (EXT3_BLOCKS_PER_GROUP(sb) - 1); | 1271 | (EXT3_BLOCKS_PER_GROUP(sb) - 1); |
1273 | 1272 | ||
1274 | if ((i % EXT3_DESC_PER_BLOCK(sb)) == 0) | ||
1275 | gdp = (struct ext3_group_desc *) | ||
1276 | sbi->s_group_desc[desc_block++]->b_data; | ||
1277 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || | 1273 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || |
1278 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) | 1274 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) |
1279 | { | 1275 | { |
@@ -1306,7 +1302,6 @@ static int ext3_check_descriptors (struct super_block * sb) | |||
1306 | return 0; | 1302 | return 0; |
1307 | } | 1303 | } |
1308 | first_block += EXT3_BLOCKS_PER_GROUP(sb); | 1304 | first_block += EXT3_BLOCKS_PER_GROUP(sb); |
1309 | gdp++; | ||
1310 | } | 1305 | } |
1311 | 1306 | ||
1312 | sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb)); | 1307 | sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb)); |
@@ -1583,10 +1578,10 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
1583 | 1578 | ||
1584 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC) | 1579 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_PANIC) |
1585 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 1580 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
1586 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_RO) | 1581 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT3_ERRORS_CONTINUE) |
1587 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
1588 | else | ||
1589 | set_opt(sbi->s_mount_opt, ERRORS_CONT); | 1582 | set_opt(sbi->s_mount_opt, ERRORS_CONT); |
1583 | else | ||
1584 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
1590 | 1585 | ||
1591 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); | 1586 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); |
1592 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 1587 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index ac75ea953d83..0737e05ba3dd 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -1700,7 +1700,7 @@ retry_alloc: | |||
1700 | 1700 | ||
1701 | /* | 1701 | /* |
1702 | * Now search the rest of the groups. We assume that | 1702 | * Now search the rest of the groups. We assume that |
1703 | * i and gdp correctly point to the last group visited. | 1703 | * group_no and gdp correctly point to the last group visited. |
1704 | */ | 1704 | */ |
1705 | for (bgi = 0; bgi < ngroups; bgi++) { | 1705 | for (bgi = 0; bgi < ngroups; bgi++) { |
1706 | group_no++; | 1706 | group_no++; |
@@ -2011,11 +2011,7 @@ static unsigned long ext4_bg_num_gdb_meta(struct super_block *sb, | |||
2011 | static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, | 2011 | static unsigned long ext4_bg_num_gdb_nometa(struct super_block *sb, |
2012 | ext4_group_t group) | 2012 | ext4_group_t group) |
2013 | { | 2013 | { |
2014 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | 2014 | return ext4_bg_has_super(sb, group) ? EXT4_SB(sb)->s_gdb_count : 0; |
2015 | EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER) && | ||
2016 | !ext4_group_sparse(group)) | ||
2017 | return 0; | ||
2018 | return EXT4_SB(sb)->s_gdb_count; | ||
2019 | } | 2015 | } |
2020 | 2016 | ||
2021 | /** | 2017 | /** |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 05c4145dd27d..0e9055cf700e 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -429,16 +429,13 @@ static ext4_fsblk_t ext4_find_near(struct inode *inode, Indirect *ind) | |||
429 | * ext4_find_goal - find a prefered place for allocation. | 429 | * ext4_find_goal - find a prefered place for allocation. |
430 | * @inode: owner | 430 | * @inode: owner |
431 | * @block: block we want | 431 | * @block: block we want |
432 | * @chain: chain of indirect blocks | ||
433 | * @partial: pointer to the last triple within a chain | 432 | * @partial: pointer to the last triple within a chain |
434 | * @goal: place to store the result. | ||
435 | * | 433 | * |
436 | * Normally this function find the prefered place for block allocation, | 434 | * Normally this function find the prefered place for block allocation, |
437 | * stores it in *@goal and returns zero. | 435 | * returns it. |
438 | */ | 436 | */ |
439 | |||
440 | static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, | 437 | static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, |
441 | Indirect chain[4], Indirect *partial) | 438 | Indirect *partial) |
442 | { | 439 | { |
443 | struct ext4_block_alloc_info *block_i; | 440 | struct ext4_block_alloc_info *block_i; |
444 | 441 | ||
@@ -839,7 +836,7 @@ int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
839 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) | 836 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) |
840 | ext4_init_block_alloc_info(inode); | 837 | ext4_init_block_alloc_info(inode); |
841 | 838 | ||
842 | goal = ext4_find_goal(inode, iblock, chain, partial); | 839 | goal = ext4_find_goal(inode, iblock, partial); |
843 | 840 | ||
844 | /* the number of blocks need to allocate for [d,t]indirect blocks */ | 841 | /* the number of blocks need to allocate for [d,t]indirect blocks */ |
845 | indirect_blks = (chain + depth) - partial - 1; | 842 | indirect_blks = (chain + depth) - partial - 1; |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 055a0cd0168e..c89bb8797765 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -1458,7 +1458,7 @@ int ext4_group_desc_csum_verify(struct ext4_sb_info *sbi, __u32 block_group, | |||
1458 | } | 1458 | } |
1459 | 1459 | ||
1460 | /* Called at mount-time, super-block is locked */ | 1460 | /* Called at mount-time, super-block is locked */ |
1461 | static int ext4_check_descriptors (struct super_block * sb) | 1461 | static int ext4_check_descriptors(struct super_block *sb) |
1462 | { | 1462 | { |
1463 | struct ext4_sb_info *sbi = EXT4_SB(sb); | 1463 | struct ext4_sb_info *sbi = EXT4_SB(sb); |
1464 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 1464 | ext4_fsblk_t first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
@@ -1466,8 +1466,6 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1466 | ext4_fsblk_t block_bitmap; | 1466 | ext4_fsblk_t block_bitmap; |
1467 | ext4_fsblk_t inode_bitmap; | 1467 | ext4_fsblk_t inode_bitmap; |
1468 | ext4_fsblk_t inode_table; | 1468 | ext4_fsblk_t inode_table; |
1469 | struct ext4_group_desc * gdp = NULL; | ||
1470 | int desc_block = 0; | ||
1471 | int flexbg_flag = 0; | 1469 | int flexbg_flag = 0; |
1472 | ext4_group_t i; | 1470 | ext4_group_t i; |
1473 | 1471 | ||
@@ -1476,17 +1474,15 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1476 | 1474 | ||
1477 | ext4_debug ("Checking group descriptors"); | 1475 | ext4_debug ("Checking group descriptors"); |
1478 | 1476 | ||
1479 | for (i = 0; i < sbi->s_groups_count; i++) | 1477 | for (i = 0; i < sbi->s_groups_count; i++) { |
1480 | { | 1478 | struct ext4_group_desc *gdp = ext4_get_group_desc(sb, i, NULL); |
1479 | |||
1481 | if (i == sbi->s_groups_count - 1 || flexbg_flag) | 1480 | if (i == sbi->s_groups_count - 1 || flexbg_flag) |
1482 | last_block = ext4_blocks_count(sbi->s_es) - 1; | 1481 | last_block = ext4_blocks_count(sbi->s_es) - 1; |
1483 | else | 1482 | else |
1484 | last_block = first_block + | 1483 | last_block = first_block + |
1485 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); | 1484 | (EXT4_BLOCKS_PER_GROUP(sb) - 1); |
1486 | 1485 | ||
1487 | if ((i % EXT4_DESC_PER_BLOCK(sb)) == 0) | ||
1488 | gdp = (struct ext4_group_desc *) | ||
1489 | sbi->s_group_desc[desc_block++]->b_data; | ||
1490 | block_bitmap = ext4_block_bitmap(sb, gdp); | 1486 | block_bitmap = ext4_block_bitmap(sb, gdp); |
1491 | if (block_bitmap < first_block || block_bitmap > last_block) | 1487 | if (block_bitmap < first_block || block_bitmap > last_block) |
1492 | { | 1488 | { |
@@ -1524,8 +1520,6 @@ static int ext4_check_descriptors (struct super_block * sb) | |||
1524 | } | 1520 | } |
1525 | if (!flexbg_flag) | 1521 | if (!flexbg_flag) |
1526 | first_block += EXT4_BLOCKS_PER_GROUP(sb); | 1522 | first_block += EXT4_BLOCKS_PER_GROUP(sb); |
1527 | gdp = (struct ext4_group_desc *) | ||
1528 | ((__u8 *)gdp + EXT4_DESC_SIZE(sb)); | ||
1529 | } | 1523 | } |
1530 | 1524 | ||
1531 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); | 1525 | ext4_free_blocks_count_set(sbi->s_es, ext4_count_free_blocks(sb)); |
diff --git a/fs/fat/file.c b/fs/fat/file.c index 69a83b59dce8..c614175876e0 100644 --- a/fs/fat/file.c +++ b/fs/fat/file.c | |||
@@ -155,6 +155,42 @@ out: | |||
155 | return err; | 155 | return err; |
156 | } | 156 | } |
157 | 157 | ||
158 | static int check_mode(const struct msdos_sb_info *sbi, mode_t mode) | ||
159 | { | ||
160 | mode_t req = mode & ~S_IFMT; | ||
161 | |||
162 | /* | ||
163 | * Of the r and x bits, all (subject to umask) must be present. Of the | ||
164 | * w bits, either all (subject to umask) or none must be present. | ||
165 | */ | ||
166 | |||
167 | if (S_ISREG(mode)) { | ||
168 | req &= ~sbi->options.fs_fmask; | ||
169 | |||
170 | if ((req & (S_IRUGO | S_IXUGO)) != | ||
171 | ((S_IRUGO | S_IXUGO) & ~sbi->options.fs_fmask)) | ||
172 | return -EPERM; | ||
173 | |||
174 | if ((req & S_IWUGO) != 0 && | ||
175 | (req & S_IWUGO) != (S_IWUGO & ~sbi->options.fs_fmask)) | ||
176 | return -EPERM; | ||
177 | } else if (S_ISDIR(mode)) { | ||
178 | req &= ~sbi->options.fs_dmask; | ||
179 | |||
180 | if ((req & (S_IRUGO | S_IXUGO)) != | ||
181 | ((S_IRUGO | S_IXUGO) & ~sbi->options.fs_dmask)) | ||
182 | return -EPERM; | ||
183 | |||
184 | if ((req & S_IWUGO) != 0 && | ||
185 | (req & S_IWUGO) != (S_IWUGO & ~sbi->options.fs_dmask)) | ||
186 | return -EPERM; | ||
187 | } else { | ||
188 | return -EPERM; | ||
189 | } | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
158 | int fat_notify_change(struct dentry *dentry, struct iattr *attr) | 194 | int fat_notify_change(struct dentry *dentry, struct iattr *attr) |
159 | { | 195 | { |
160 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); | 196 | struct msdos_sb_info *sbi = MSDOS_SB(dentry->d_sb); |
@@ -186,9 +222,7 @@ int fat_notify_change(struct dentry *dentry, struct iattr *attr) | |||
186 | if (((attr->ia_valid & ATTR_UID) && | 222 | if (((attr->ia_valid & ATTR_UID) && |
187 | (attr->ia_uid != sbi->options.fs_uid)) || | 223 | (attr->ia_uid != sbi->options.fs_uid)) || |
188 | ((attr->ia_valid & ATTR_GID) && | 224 | ((attr->ia_valid & ATTR_GID) && |
189 | (attr->ia_gid != sbi->options.fs_gid)) || | 225 | (attr->ia_gid != sbi->options.fs_gid))) |
190 | ((attr->ia_valid & ATTR_MODE) && | ||
191 | (attr->ia_mode & ~MSDOS_VALID_MODE))) | ||
192 | error = -EPERM; | 226 | error = -EPERM; |
193 | 227 | ||
194 | if (error) { | 228 | if (error) { |
@@ -196,6 +230,13 @@ int fat_notify_change(struct dentry *dentry, struct iattr *attr) | |||
196 | error = 0; | 230 | error = 0; |
197 | goto out; | 231 | goto out; |
198 | } | 232 | } |
233 | |||
234 | if (attr->ia_valid & ATTR_MODE) { | ||
235 | error = check_mode(sbi, attr->ia_mode); | ||
236 | if (error != 0 && !sbi->options.quiet) | ||
237 | goto out; | ||
238 | } | ||
239 | |||
199 | error = inode_setattr(inode, attr); | 240 | error = inode_setattr(inode, attr); |
200 | if (error) | 241 | if (error) |
201 | goto out; | 242 | goto out; |
diff --git a/fs/fat/inode.c b/fs/fat/inode.c index 920a576e1c25..24c0aaa5ae80 100644 --- a/fs/fat/inode.c +++ b/fs/fat/inode.c | |||
@@ -1295,10 +1295,8 @@ int fat_fill_super(struct super_block *sb, void *data, int silent, | |||
1295 | 1295 | ||
1296 | fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data; | 1296 | fsinfo = (struct fat_boot_fsinfo *)fsinfo_bh->b_data; |
1297 | if (!IS_FSINFO(fsinfo)) { | 1297 | if (!IS_FSINFO(fsinfo)) { |
1298 | printk(KERN_WARNING | 1298 | printk(KERN_WARNING "FAT: Invalid FSINFO signature: " |
1299 | "FAT: Did not find valid FSINFO signature.\n" | 1299 | "0x%08x, 0x%08x (sector = %lu)\n", |
1300 | " Found signature1 0x%08x signature2 0x%08x" | ||
1301 | " (sector = %lu)\n", | ||
1302 | le32_to_cpu(fsinfo->signature1), | 1300 | le32_to_cpu(fsinfo->signature1), |
1303 | le32_to_cpu(fsinfo->signature2), | 1301 | le32_to_cpu(fsinfo->signature2), |
1304 | sbi->fsinfo_sector); | 1302 | sbi->fsinfo_sector); |
diff --git a/fs/fat/misc.c b/fs/fat/misc.c index 308f2b6b5026..61f23511eacf 100644 --- a/fs/fat/misc.c +++ b/fs/fat/misc.c | |||
@@ -55,9 +55,8 @@ void fat_clusters_flush(struct super_block *sb) | |||
55 | fsinfo = (struct fat_boot_fsinfo *)bh->b_data; | 55 | fsinfo = (struct fat_boot_fsinfo *)bh->b_data; |
56 | /* Sanity check */ | 56 | /* Sanity check */ |
57 | if (!IS_FSINFO(fsinfo)) { | 57 | if (!IS_FSINFO(fsinfo)) { |
58 | printk(KERN_ERR "FAT: Did not find valid FSINFO signature.\n" | 58 | printk(KERN_ERR "FAT: Invalid FSINFO signature: " |
59 | " Found signature1 0x%08x signature2 0x%08x" | 59 | "0x%08x, 0x%08x (sector = %lu)\n", |
60 | " (sector = %lu)\n", | ||
61 | le32_to_cpu(fsinfo->signature1), | 60 | le32_to_cpu(fsinfo->signature1), |
62 | le32_to_cpu(fsinfo->signature2), | 61 | le32_to_cpu(fsinfo->signature2), |
63 | sbi->fsinfo_sector); | 62 | sbi->fsinfo_sector); |
@@ -24,6 +24,8 @@ struct fdtable_defer { | |||
24 | struct fdtable *next; | 24 | struct fdtable *next; |
25 | }; | 25 | }; |
26 | 26 | ||
27 | int sysctl_nr_open __read_mostly = 1024*1024; | ||
28 | |||
27 | /* | 29 | /* |
28 | * We use this list to defer free fdtables that have vmalloced | 30 | * We use this list to defer free fdtables that have vmalloced |
29 | * sets/arrays. By keeping a per-cpu list, we avoid having to embed | 31 | * sets/arrays. By keeping a per-cpu list, we avoid having to embed |
@@ -147,8 +149,8 @@ static struct fdtable * alloc_fdtable(unsigned int nr) | |||
147 | nr /= (1024 / sizeof(struct file *)); | 149 | nr /= (1024 / sizeof(struct file *)); |
148 | nr = roundup_pow_of_two(nr + 1); | 150 | nr = roundup_pow_of_two(nr + 1); |
149 | nr *= (1024 / sizeof(struct file *)); | 151 | nr *= (1024 / sizeof(struct file *)); |
150 | if (nr > NR_OPEN) | 152 | if (nr > sysctl_nr_open) |
151 | nr = NR_OPEN; | 153 | nr = sysctl_nr_open; |
152 | 154 | ||
153 | fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); | 155 | fdt = kmalloc(sizeof(struct fdtable), GFP_KERNEL); |
154 | if (!fdt) | 156 | if (!fdt) |
@@ -233,7 +235,7 @@ int expand_files(struct files_struct *files, int nr) | |||
233 | if (nr < fdt->max_fds) | 235 | if (nr < fdt->max_fds) |
234 | return 0; | 236 | return 0; |
235 | /* Can we expand? */ | 237 | /* Can we expand? */ |
236 | if (nr >= NR_OPEN) | 238 | if (nr >= sysctl_nr_open) |
237 | return -EMFILE; | 239 | return -EMFILE; |
238 | 240 | ||
239 | /* All good, so we try */ | 241 | /* All good, so we try */ |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 0b3064079fa5..db80ce9eb1d0 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -515,8 +515,7 @@ writeback_inodes(struct writeback_control *wbc) | |||
515 | might_sleep(); | 515 | might_sleep(); |
516 | spin_lock(&sb_lock); | 516 | spin_lock(&sb_lock); |
517 | restart: | 517 | restart: |
518 | sb = sb_entry(super_blocks.prev); | 518 | list_for_each_entry_reverse(sb, &super_blocks, s_list) { |
519 | for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) { | ||
520 | if (sb_has_dirty_inodes(sb)) { | 519 | if (sb_has_dirty_inodes(sb)) { |
521 | /* we're making our own get_super here */ | 520 | /* we're making our own get_super here */ |
522 | sb->s_count++; | 521 | sb->s_count++; |
@@ -581,10 +580,8 @@ static void set_sb_syncing(int val) | |||
581 | { | 580 | { |
582 | struct super_block *sb; | 581 | struct super_block *sb; |
583 | spin_lock(&sb_lock); | 582 | spin_lock(&sb_lock); |
584 | sb = sb_entry(super_blocks.prev); | 583 | list_for_each_entry_reverse(sb, &super_blocks, s_list) |
585 | for (; sb != sb_entry(&super_blocks); sb = sb_entry(sb->s_list.prev)) { | ||
586 | sb->s_syncing = val; | 584 | sb->s_syncing = val; |
587 | } | ||
588 | spin_unlock(&sb_lock); | 585 | spin_unlock(&sb_lock); |
589 | } | 586 | } |
590 | 587 | ||
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index db534bcde45f..af639807524e 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -201,6 +201,55 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | |||
201 | } | 201 | } |
202 | } | 202 | } |
203 | 203 | ||
204 | static unsigned len_args(unsigned numargs, struct fuse_arg *args) | ||
205 | { | ||
206 | unsigned nbytes = 0; | ||
207 | unsigned i; | ||
208 | |||
209 | for (i = 0; i < numargs; i++) | ||
210 | nbytes += args[i].size; | ||
211 | |||
212 | return nbytes; | ||
213 | } | ||
214 | |||
215 | static u64 fuse_get_unique(struct fuse_conn *fc) | ||
216 | { | ||
217 | fc->reqctr++; | ||
218 | /* zero is special */ | ||
219 | if (fc->reqctr == 0) | ||
220 | fc->reqctr = 1; | ||
221 | |||
222 | return fc->reqctr; | ||
223 | } | ||
224 | |||
225 | static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | ||
226 | { | ||
227 | req->in.h.unique = fuse_get_unique(fc); | ||
228 | req->in.h.len = sizeof(struct fuse_in_header) + | ||
229 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); | ||
230 | list_add_tail(&req->list, &fc->pending); | ||
231 | req->state = FUSE_REQ_PENDING; | ||
232 | if (!req->waiting) { | ||
233 | req->waiting = 1; | ||
234 | atomic_inc(&fc->num_waiting); | ||
235 | } | ||
236 | wake_up(&fc->waitq); | ||
237 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
238 | } | ||
239 | |||
240 | static void flush_bg_queue(struct fuse_conn *fc) | ||
241 | { | ||
242 | while (fc->active_background < FUSE_MAX_BACKGROUND && | ||
243 | !list_empty(&fc->bg_queue)) { | ||
244 | struct fuse_req *req; | ||
245 | |||
246 | req = list_entry(fc->bg_queue.next, struct fuse_req, list); | ||
247 | list_del(&req->list); | ||
248 | fc->active_background++; | ||
249 | queue_request(fc, req); | ||
250 | } | ||
251 | } | ||
252 | |||
204 | /* | 253 | /* |
205 | * This function is called when a request is finished. Either a reply | 254 | * This function is called when a request is finished. Either a reply |
206 | * has arrived or it was aborted (and not yet sent) or some error | 255 | * has arrived or it was aborted (and not yet sent) or some error |
@@ -229,6 +278,8 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) | |||
229 | clear_bdi_congested(&fc->bdi, WRITE); | 278 | clear_bdi_congested(&fc->bdi, WRITE); |
230 | } | 279 | } |
231 | fc->num_background--; | 280 | fc->num_background--; |
281 | fc->active_background--; | ||
282 | flush_bg_queue(fc); | ||
232 | } | 283 | } |
233 | spin_unlock(&fc->lock); | 284 | spin_unlock(&fc->lock); |
234 | wake_up(&req->waitq); | 285 | wake_up(&req->waitq); |
@@ -320,42 +371,6 @@ static void request_wait_answer(struct fuse_conn *fc, struct fuse_req *req) | |||
320 | } | 371 | } |
321 | } | 372 | } |
322 | 373 | ||
323 | static unsigned len_args(unsigned numargs, struct fuse_arg *args) | ||
324 | { | ||
325 | unsigned nbytes = 0; | ||
326 | unsigned i; | ||
327 | |||
328 | for (i = 0; i < numargs; i++) | ||
329 | nbytes += args[i].size; | ||
330 | |||
331 | return nbytes; | ||
332 | } | ||
333 | |||
334 | static u64 fuse_get_unique(struct fuse_conn *fc) | ||
335 | { | ||
336 | fc->reqctr++; | ||
337 | /* zero is special */ | ||
338 | if (fc->reqctr == 0) | ||
339 | fc->reqctr = 1; | ||
340 | |||
341 | return fc->reqctr; | ||
342 | } | ||
343 | |||
344 | static void queue_request(struct fuse_conn *fc, struct fuse_req *req) | ||
345 | { | ||
346 | req->in.h.unique = fuse_get_unique(fc); | ||
347 | req->in.h.len = sizeof(struct fuse_in_header) + | ||
348 | len_args(req->in.numargs, (struct fuse_arg *) req->in.args); | ||
349 | list_add_tail(&req->list, &fc->pending); | ||
350 | req->state = FUSE_REQ_PENDING; | ||
351 | if (!req->waiting) { | ||
352 | req->waiting = 1; | ||
353 | atomic_inc(&fc->num_waiting); | ||
354 | } | ||
355 | wake_up(&fc->waitq); | ||
356 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | ||
357 | } | ||
358 | |||
359 | void request_send(struct fuse_conn *fc, struct fuse_req *req) | 374 | void request_send(struct fuse_conn *fc, struct fuse_req *req) |
360 | { | 375 | { |
361 | req->isreply = 1; | 376 | req->isreply = 1; |
@@ -375,20 +390,26 @@ void request_send(struct fuse_conn *fc, struct fuse_req *req) | |||
375 | spin_unlock(&fc->lock); | 390 | spin_unlock(&fc->lock); |
376 | } | 391 | } |
377 | 392 | ||
393 | static void request_send_nowait_locked(struct fuse_conn *fc, | ||
394 | struct fuse_req *req) | ||
395 | { | ||
396 | req->background = 1; | ||
397 | fc->num_background++; | ||
398 | if (fc->num_background == FUSE_MAX_BACKGROUND) | ||
399 | fc->blocked = 1; | ||
400 | if (fc->num_background == FUSE_CONGESTION_THRESHOLD) { | ||
401 | set_bdi_congested(&fc->bdi, READ); | ||
402 | set_bdi_congested(&fc->bdi, WRITE); | ||
403 | } | ||
404 | list_add_tail(&req->list, &fc->bg_queue); | ||
405 | flush_bg_queue(fc); | ||
406 | } | ||
407 | |||
378 | static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) | 408 | static void request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) |
379 | { | 409 | { |
380 | spin_lock(&fc->lock); | 410 | spin_lock(&fc->lock); |
381 | if (fc->connected) { | 411 | if (fc->connected) { |
382 | req->background = 1; | 412 | request_send_nowait_locked(fc, req); |
383 | fc->num_background++; | ||
384 | if (fc->num_background == FUSE_MAX_BACKGROUND) | ||
385 | fc->blocked = 1; | ||
386 | if (fc->num_background == FUSE_CONGESTION_THRESHOLD) { | ||
387 | set_bdi_congested(&fc->bdi, READ); | ||
388 | set_bdi_congested(&fc->bdi, WRITE); | ||
389 | } | ||
390 | |||
391 | queue_request(fc, req); | ||
392 | spin_unlock(&fc->lock); | 413 | spin_unlock(&fc->lock); |
393 | } else { | 414 | } else { |
394 | req->out.h.error = -ENOTCONN; | 415 | req->out.h.error = -ENOTCONN; |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 80d2f5292cf9..f56f91bd38be 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -416,6 +416,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, | |||
416 | fuse_put_request(fc, forget_req); | 416 | fuse_put_request(fc, forget_req); |
417 | d_instantiate(entry, inode); | 417 | d_instantiate(entry, inode); |
418 | fuse_change_entry_timeout(entry, &outentry); | 418 | fuse_change_entry_timeout(entry, &outentry); |
419 | fuse_invalidate_attr(dir); | ||
419 | file = lookup_instantiate_filp(nd, entry, generic_file_open); | 420 | file = lookup_instantiate_filp(nd, entry, generic_file_open); |
420 | if (IS_ERR(file)) { | 421 | if (IS_ERR(file)) { |
421 | ff->fh = outopen.fh; | 422 | ff->fh = outopen.fh; |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index bb05d227cf30..676b0bc8a86d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -77,8 +77,8 @@ static struct fuse_file *fuse_file_get(struct fuse_file *ff) | |||
77 | 77 | ||
78 | static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) | 78 | static void fuse_release_end(struct fuse_conn *fc, struct fuse_req *req) |
79 | { | 79 | { |
80 | dput(req->dentry); | 80 | dput(req->misc.release.dentry); |
81 | mntput(req->vfsmount); | 81 | mntput(req->misc.release.vfsmount); |
82 | fuse_put_request(fc, req); | 82 | fuse_put_request(fc, req); |
83 | } | 83 | } |
84 | 84 | ||
@@ -86,7 +86,8 @@ static void fuse_file_put(struct fuse_file *ff) | |||
86 | { | 86 | { |
87 | if (atomic_dec_and_test(&ff->count)) { | 87 | if (atomic_dec_and_test(&ff->count)) { |
88 | struct fuse_req *req = ff->reserved_req; | 88 | struct fuse_req *req = ff->reserved_req; |
89 | struct fuse_conn *fc = get_fuse_conn(req->dentry->d_inode); | 89 | struct inode *inode = req->misc.release.dentry->d_inode; |
90 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
90 | req->end = fuse_release_end; | 91 | req->end = fuse_release_end; |
91 | request_send_background(fc, req); | 92 | request_send_background(fc, req); |
92 | kfree(ff); | 93 | kfree(ff); |
@@ -137,7 +138,7 @@ int fuse_open_common(struct inode *inode, struct file *file, int isdir) | |||
137 | void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode) | 138 | void fuse_release_fill(struct fuse_file *ff, u64 nodeid, int flags, int opcode) |
138 | { | 139 | { |
139 | struct fuse_req *req = ff->reserved_req; | 140 | struct fuse_req *req = ff->reserved_req; |
140 | struct fuse_release_in *inarg = &req->misc.release_in; | 141 | struct fuse_release_in *inarg = &req->misc.release.in; |
141 | 142 | ||
142 | inarg->fh = ff->fh; | 143 | inarg->fh = ff->fh; |
143 | inarg->flags = flags; | 144 | inarg->flags = flags; |
@@ -153,13 +154,14 @@ int fuse_release_common(struct inode *inode, struct file *file, int isdir) | |||
153 | struct fuse_file *ff = file->private_data; | 154 | struct fuse_file *ff = file->private_data; |
154 | if (ff) { | 155 | if (ff) { |
155 | struct fuse_conn *fc = get_fuse_conn(inode); | 156 | struct fuse_conn *fc = get_fuse_conn(inode); |
157 | struct fuse_req *req = ff->reserved_req; | ||
156 | 158 | ||
157 | fuse_release_fill(ff, get_node_id(inode), file->f_flags, | 159 | fuse_release_fill(ff, get_node_id(inode), file->f_flags, |
158 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); | 160 | isdir ? FUSE_RELEASEDIR : FUSE_RELEASE); |
159 | 161 | ||
160 | /* Hold vfsmount and dentry until release is finished */ | 162 | /* Hold vfsmount and dentry until release is finished */ |
161 | ff->reserved_req->vfsmount = mntget(file->f_path.mnt); | 163 | req->misc.release.vfsmount = mntget(file->f_path.mnt); |
162 | ff->reserved_req->dentry = dget(file->f_path.dentry); | 164 | req->misc.release.dentry = dget(file->f_path.dentry); |
163 | 165 | ||
164 | spin_lock(&fc->lock); | 166 | spin_lock(&fc->lock); |
165 | list_del(&ff->write_entry); | 167 | list_del(&ff->write_entry); |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 3ab8a3048e8b..67aaf6ee38ea 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -215,7 +215,11 @@ struct fuse_req { | |||
215 | /** Data for asynchronous requests */ | 215 | /** Data for asynchronous requests */ |
216 | union { | 216 | union { |
217 | struct fuse_forget_in forget_in; | 217 | struct fuse_forget_in forget_in; |
218 | struct fuse_release_in release_in; | 218 | struct { |
219 | struct fuse_release_in in; | ||
220 | struct vfsmount *vfsmount; | ||
221 | struct dentry *dentry; | ||
222 | } release; | ||
219 | struct fuse_init_in init_in; | 223 | struct fuse_init_in init_in; |
220 | struct fuse_init_out init_out; | 224 | struct fuse_init_out init_out; |
221 | struct fuse_read_in read_in; | 225 | struct fuse_read_in read_in; |
@@ -238,12 +242,6 @@ struct fuse_req { | |||
238 | /** File used in the request (or NULL) */ | 242 | /** File used in the request (or NULL) */ |
239 | struct fuse_file *ff; | 243 | struct fuse_file *ff; |
240 | 244 | ||
241 | /** vfsmount used in release */ | ||
242 | struct vfsmount *vfsmount; | ||
243 | |||
244 | /** dentry used in release */ | ||
245 | struct dentry *dentry; | ||
246 | |||
247 | /** Request completion callback */ | 245 | /** Request completion callback */ |
248 | void (*end)(struct fuse_conn *, struct fuse_req *); | 246 | void (*end)(struct fuse_conn *, struct fuse_req *); |
249 | 247 | ||
@@ -298,6 +296,12 @@ struct fuse_conn { | |||
298 | /** Number of requests currently in the background */ | 296 | /** Number of requests currently in the background */ |
299 | unsigned num_background; | 297 | unsigned num_background; |
300 | 298 | ||
299 | /** Number of background requests currently queued for userspace */ | ||
300 | unsigned active_background; | ||
301 | |||
302 | /** The list of background requests set aside for later queuing */ | ||
303 | struct list_head bg_queue; | ||
304 | |||
301 | /** Pending interrupts */ | 305 | /** Pending interrupts */ |
302 | struct list_head interrupts; | 306 | struct list_head interrupts; |
303 | 307 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index e5e80d1a4687..c90f633d0b57 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -465,6 +465,7 @@ static struct fuse_conn *new_conn(void) | |||
465 | INIT_LIST_HEAD(&fc->processing); | 465 | INIT_LIST_HEAD(&fc->processing); |
466 | INIT_LIST_HEAD(&fc->io); | 466 | INIT_LIST_HEAD(&fc->io); |
467 | INIT_LIST_HEAD(&fc->interrupts); | 467 | INIT_LIST_HEAD(&fc->interrupts); |
468 | INIT_LIST_HEAD(&fc->bg_queue); | ||
468 | atomic_set(&fc->num_waiting, 0); | 469 | atomic_set(&fc->num_waiting, 0); |
469 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; | 470 | fc->bdi.ra_pages = (VM_MAX_READAHEAD * 1024) / PAGE_CACHE_SIZE; |
470 | fc->bdi.unplug_io_fn = default_unplug_io_fn; | 471 | fc->bdi.unplug_io_fn = default_unplug_io_fn; |
diff --git a/fs/hfs/bfind.c b/fs/hfs/bfind.c index f8452a0eab56..4129cdb3f0d8 100644 --- a/fs/hfs/bfind.c +++ b/fs/hfs/bfind.c | |||
@@ -52,9 +52,9 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd) | |||
52 | rec = (e + b) / 2; | 52 | rec = (e + b) / 2; |
53 | len = hfs_brec_lenoff(bnode, rec, &off); | 53 | len = hfs_brec_lenoff(bnode, rec, &off); |
54 | keylen = hfs_brec_keylen(bnode, rec); | 54 | keylen = hfs_brec_keylen(bnode, rec); |
55 | if (keylen == HFS_BAD_KEYLEN) { | 55 | if (keylen == 0) { |
56 | res = -EINVAL; | 56 | res = -EINVAL; |
57 | goto done; | 57 | goto fail; |
58 | } | 58 | } |
59 | hfs_bnode_read(bnode, fd->key, off, keylen); | 59 | hfs_bnode_read(bnode, fd->key, off, keylen); |
60 | cmpval = bnode->tree->keycmp(fd->key, fd->search_key); | 60 | cmpval = bnode->tree->keycmp(fd->key, fd->search_key); |
@@ -71,9 +71,9 @@ int __hfs_brec_find(struct hfs_bnode *bnode, struct hfs_find_data *fd) | |||
71 | if (rec != e && e >= 0) { | 71 | if (rec != e && e >= 0) { |
72 | len = hfs_brec_lenoff(bnode, e, &off); | 72 | len = hfs_brec_lenoff(bnode, e, &off); |
73 | keylen = hfs_brec_keylen(bnode, e); | 73 | keylen = hfs_brec_keylen(bnode, e); |
74 | if (keylen == HFS_BAD_KEYLEN) { | 74 | if (keylen == 0) { |
75 | res = -EINVAL; | 75 | res = -EINVAL; |
76 | goto done; | 76 | goto fail; |
77 | } | 77 | } |
78 | hfs_bnode_read(bnode, fd->key, off, keylen); | 78 | hfs_bnode_read(bnode, fd->key, off, keylen); |
79 | } | 79 | } |
@@ -83,6 +83,7 @@ done: | |||
83 | fd->keylength = keylen; | 83 | fd->keylength = keylen; |
84 | fd->entryoffset = off + keylen; | 84 | fd->entryoffset = off + keylen; |
85 | fd->entrylength = len - keylen; | 85 | fd->entrylength = len - keylen; |
86 | fail: | ||
86 | return res; | 87 | return res; |
87 | } | 88 | } |
88 | 89 | ||
@@ -206,7 +207,7 @@ int hfs_brec_goto(struct hfs_find_data *fd, int cnt) | |||
206 | 207 | ||
207 | len = hfs_brec_lenoff(bnode, fd->record, &off); | 208 | len = hfs_brec_lenoff(bnode, fd->record, &off); |
208 | keylen = hfs_brec_keylen(bnode, fd->record); | 209 | keylen = hfs_brec_keylen(bnode, fd->record); |
209 | if (keylen == HFS_BAD_KEYLEN) { | 210 | if (keylen == 0) { |
210 | res = -EINVAL; | 211 | res = -EINVAL; |
211 | goto out; | 212 | goto out; |
212 | } | 213 | } |
diff --git a/fs/hfs/brec.c b/fs/hfs/brec.c index 8626ee375ea8..878bf25dbc6a 100644 --- a/fs/hfs/brec.c +++ b/fs/hfs/brec.c | |||
@@ -49,14 +49,14 @@ u16 hfs_brec_keylen(struct hfs_bnode *node, u16 rec) | |||
49 | if (retval > node->tree->max_key_len + 2) { | 49 | if (retval > node->tree->max_key_len + 2) { |
50 | printk(KERN_ERR "hfs: keylen %d too large\n", | 50 | printk(KERN_ERR "hfs: keylen %d too large\n", |
51 | retval); | 51 | retval); |
52 | retval = HFS_BAD_KEYLEN; | 52 | retval = 0; |
53 | } | 53 | } |
54 | } else { | 54 | } else { |
55 | retval = (hfs_bnode_read_u8(node, recoff) | 1) + 1; | 55 | retval = (hfs_bnode_read_u8(node, recoff) | 1) + 1; |
56 | if (retval > node->tree->max_key_len + 1) { | 56 | if (retval > node->tree->max_key_len + 1) { |
57 | printk(KERN_ERR "hfs: keylen %d too large\n", | 57 | printk(KERN_ERR "hfs: keylen %d too large\n", |
58 | retval); | 58 | retval); |
59 | retval = HFS_BAD_KEYLEN; | 59 | retval = 0; |
60 | } | 60 | } |
61 | } | 61 | } |
62 | } | 62 | } |
diff --git a/fs/hfs/btree.c b/fs/hfs/btree.c index 110dd3515dc8..24cf6fc43021 100644 --- a/fs/hfs/btree.c +++ b/fs/hfs/btree.c | |||
@@ -81,15 +81,23 @@ struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id, btree_keycmp ke | |||
81 | goto fail_page; | 81 | goto fail_page; |
82 | if (!tree->node_count) | 82 | if (!tree->node_count) |
83 | goto fail_page; | 83 | goto fail_page; |
84 | if ((id == HFS_EXT_CNID) && (tree->max_key_len != HFS_MAX_EXT_KEYLEN)) { | 84 | switch (id) { |
85 | printk(KERN_ERR "hfs: invalid extent max_key_len %d\n", | 85 | case HFS_EXT_CNID: |
86 | tree->max_key_len); | 86 | if (tree->max_key_len != HFS_MAX_EXT_KEYLEN) { |
87 | goto fail_page; | 87 | printk(KERN_ERR "hfs: invalid extent max_key_len %d\n", |
88 | } | 88 | tree->max_key_len); |
89 | if ((id == HFS_CAT_CNID) && (tree->max_key_len != HFS_MAX_CAT_KEYLEN)) { | 89 | goto fail_page; |
90 | printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n", | 90 | } |
91 | tree->max_key_len); | 91 | break; |
92 | goto fail_page; | 92 | case HFS_CAT_CNID: |
93 | if (tree->max_key_len != HFS_MAX_CAT_KEYLEN) { | ||
94 | printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n", | ||
95 | tree->max_key_len); | ||
96 | goto fail_page; | ||
97 | } | ||
98 | break; | ||
99 | default: | ||
100 | BUG(); | ||
93 | } | 101 | } |
94 | 102 | ||
95 | tree->node_size_shift = ffs(size) - 1; | 103 | tree->node_size_shift = ffs(size) - 1; |
diff --git a/fs/hfs/hfs.h b/fs/hfs/hfs.h index c6aae61adfe6..6f194d0768b6 100644 --- a/fs/hfs/hfs.h +++ b/fs/hfs/hfs.h | |||
@@ -28,8 +28,6 @@ | |||
28 | #define HFS_MAX_NAMELEN 128 | 28 | #define HFS_MAX_NAMELEN 128 |
29 | #define HFS_MAX_VALENCE 32767U | 29 | #define HFS_MAX_VALENCE 32767U |
30 | 30 | ||
31 | #define HFS_BAD_KEYLEN 0xFF | ||
32 | |||
33 | /* Meanings of the drAtrb field of the MDB, | 31 | /* Meanings of the drAtrb field of the MDB, |
34 | * Reference: _Inside Macintosh: Files_ p. 2-61 | 32 | * Reference: _Inside Macintosh: Files_ p. 2-61 |
35 | */ | 33 | */ |
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 16cbd902f8b9..32de44ed0021 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * This file may be distributed under the terms of the GNU General Public License. | 6 | * This file may be distributed under the terms of the GNU General Public License. |
7 | * | 7 | * |
8 | * This file contains hfs_read_super(), some of the super_ops and | 8 | * This file contains hfs_read_super(), some of the super_ops and |
9 | * init_module() and cleanup_module(). The remaining super_ops are in | 9 | * init_hfs_fs() and exit_hfs_fs(). The remaining super_ops are in |
10 | * inode.c since they deal with inodes. | 10 | * inode.c since they deal with inodes. |
11 | * | 11 | * |
12 | * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds | 12 | * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds |
diff --git a/fs/inotify.c b/fs/inotify.c index 2c5b92152876..690e72595e6e 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -168,20 +168,14 @@ static void set_dentry_child_flags(struct inode *inode, int watched) | |||
168 | struct dentry *child; | 168 | struct dentry *child; |
169 | 169 | ||
170 | list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { | 170 | list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) { |
171 | if (!child->d_inode) { | 171 | if (!child->d_inode) |
172 | WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); | ||
173 | continue; | 172 | continue; |
174 | } | 173 | |
175 | spin_lock(&child->d_lock); | 174 | spin_lock(&child->d_lock); |
176 | if (watched) { | 175 | if (watched) |
177 | WARN_ON(child->d_flags & | ||
178 | DCACHE_INOTIFY_PARENT_WATCHED); | ||
179 | child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; | 176 | child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED; |
180 | } else { | 177 | else |
181 | WARN_ON(!(child->d_flags & | 178 | child->d_flags &=~DCACHE_INOTIFY_PARENT_WATCHED; |
182 | DCACHE_INOTIFY_PARENT_WATCHED)); | ||
183 | child->d_flags&=~DCACHE_INOTIFY_PARENT_WATCHED; | ||
184 | } | ||
185 | spin_unlock(&child->d_lock); | 179 | spin_unlock(&child->d_lock); |
186 | } | 180 | } |
187 | } | 181 | } |
@@ -253,7 +247,6 @@ void inotify_d_instantiate(struct dentry *entry, struct inode *inode) | |||
253 | if (!inode) | 247 | if (!inode) |
254 | return; | 248 | return; |
255 | 249 | ||
256 | WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED); | ||
257 | spin_lock(&entry->d_lock); | 250 | spin_lock(&entry->d_lock); |
258 | parent = entry->d_parent; | 251 | parent = entry->d_parent; |
259 | if (parent->d_inode && inotify_inode_watched(parent->d_inode)) | 252 | if (parent->d_inode && inotify_inode_watched(parent->d_inode)) |
@@ -627,6 +620,7 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
627 | struct inode *inode, u32 mask) | 620 | struct inode *inode, u32 mask) |
628 | { | 621 | { |
629 | int ret = 0; | 622 | int ret = 0; |
623 | int newly_watched; | ||
630 | 624 | ||
631 | /* don't allow invalid bits: we don't want flags set */ | 625 | /* don't allow invalid bits: we don't want flags set */ |
632 | mask &= IN_ALL_EVENTS | IN_ONESHOT; | 626 | mask &= IN_ALL_EVENTS | IN_ONESHOT; |
@@ -653,12 +647,18 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
653 | */ | 647 | */ |
654 | watch->inode = igrab(inode); | 648 | watch->inode = igrab(inode); |
655 | 649 | ||
656 | if (!inotify_inode_watched(inode)) | ||
657 | set_dentry_child_flags(inode, 1); | ||
658 | |||
659 | /* Add the watch to the handle's and the inode's list */ | 650 | /* Add the watch to the handle's and the inode's list */ |
651 | newly_watched = !inotify_inode_watched(inode); | ||
660 | list_add(&watch->h_list, &ih->watches); | 652 | list_add(&watch->h_list, &ih->watches); |
661 | list_add(&watch->i_list, &inode->inotify_watches); | 653 | list_add(&watch->i_list, &inode->inotify_watches); |
654 | /* | ||
655 | * Set child flags _after_ adding the watch, so there is no race | ||
656 | * windows where newly instantiated children could miss their parent's | ||
657 | * watched flag. | ||
658 | */ | ||
659 | if (newly_watched) | ||
660 | set_dentry_child_flags(inode, 1); | ||
661 | |||
662 | out: | 662 | out: |
663 | mutex_unlock(&ih->mutex); | 663 | mutex_unlock(&ih->mutex); |
664 | mutex_unlock(&inode->inotify_mutex); | 664 | mutex_unlock(&inode->inotify_mutex); |
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 5e009331c01f..a336c9709f3c 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -79,6 +79,7 @@ struct inotify_device { | |||
79 | atomic_t count; /* reference count */ | 79 | atomic_t count; /* reference count */ |
80 | struct user_struct *user; /* user who opened this dev */ | 80 | struct user_struct *user; /* user who opened this dev */ |
81 | struct inotify_handle *ih; /* inotify handle */ | 81 | struct inotify_handle *ih; /* inotify handle */ |
82 | struct fasync_struct *fa; /* async notification */ | ||
82 | unsigned int queue_size; /* size of the queue (bytes) */ | 83 | unsigned int queue_size; /* size of the queue (bytes) */ |
83 | unsigned int event_count; /* number of pending events */ | 84 | unsigned int event_count; /* number of pending events */ |
84 | unsigned int max_events; /* maximum number of events */ | 85 | unsigned int max_events; /* maximum number of events */ |
@@ -248,6 +249,19 @@ inotify_dev_get_event(struct inotify_device *dev) | |||
248 | } | 249 | } |
249 | 250 | ||
250 | /* | 251 | /* |
252 | * inotify_dev_get_last_event - return the last event in the given dev's queue | ||
253 | * | ||
254 | * Caller must hold dev->ev_mutex. | ||
255 | */ | ||
256 | static inline struct inotify_kernel_event * | ||
257 | inotify_dev_get_last_event(struct inotify_device *dev) | ||
258 | { | ||
259 | if (list_empty(&dev->events)) | ||
260 | return NULL; | ||
261 | return list_entry(dev->events.prev, struct inotify_kernel_event, list); | ||
262 | } | ||
263 | |||
264 | /* | ||
251 | * inotify_dev_queue_event - event handler registered with core inotify, adds | 265 | * inotify_dev_queue_event - event handler registered with core inotify, adds |
252 | * a new event to the given device | 266 | * a new event to the given device |
253 | * | 267 | * |
@@ -273,7 +287,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask, | |||
273 | put_inotify_watch(w); /* final put */ | 287 | put_inotify_watch(w); /* final put */ |
274 | 288 | ||
275 | /* coalescing: drop this event if it is a dupe of the previous */ | 289 | /* coalescing: drop this event if it is a dupe of the previous */ |
276 | last = inotify_dev_get_event(dev); | 290 | last = inotify_dev_get_last_event(dev); |
277 | if (last && last->event.mask == mask && last->event.wd == wd && | 291 | if (last && last->event.mask == mask && last->event.wd == wd && |
278 | last->event.cookie == cookie) { | 292 | last->event.cookie == cookie) { |
279 | const char *lastname = last->name; | 293 | const char *lastname = last->name; |
@@ -302,6 +316,7 @@ static void inotify_dev_queue_event(struct inotify_watch *w, u32 wd, u32 mask, | |||
302 | dev->queue_size += sizeof(struct inotify_event) + kevent->event.len; | 316 | dev->queue_size += sizeof(struct inotify_event) + kevent->event.len; |
303 | list_add_tail(&kevent->list, &dev->events); | 317 | list_add_tail(&kevent->list, &dev->events); |
304 | wake_up_interruptible(&dev->wq); | 318 | wake_up_interruptible(&dev->wq); |
319 | kill_fasync(&dev->fa, SIGIO, POLL_IN); | ||
305 | 320 | ||
306 | out: | 321 | out: |
307 | mutex_unlock(&dev->ev_mutex); | 322 | mutex_unlock(&dev->ev_mutex); |
@@ -490,6 +505,13 @@ static ssize_t inotify_read(struct file *file, char __user *buf, | |||
490 | return ret; | 505 | return ret; |
491 | } | 506 | } |
492 | 507 | ||
508 | static int inotify_fasync(int fd, struct file *file, int on) | ||
509 | { | ||
510 | struct inotify_device *dev = file->private_data; | ||
511 | |||
512 | return fasync_helper(fd, file, on, &dev->fa) >= 0 ? 0 : -EIO; | ||
513 | } | ||
514 | |||
493 | static int inotify_release(struct inode *ignored, struct file *file) | 515 | static int inotify_release(struct inode *ignored, struct file *file) |
494 | { | 516 | { |
495 | struct inotify_device *dev = file->private_data; | 517 | struct inotify_device *dev = file->private_data; |
@@ -502,6 +524,9 @@ static int inotify_release(struct inode *ignored, struct file *file) | |||
502 | inotify_dev_event_dequeue(dev); | 524 | inotify_dev_event_dequeue(dev); |
503 | mutex_unlock(&dev->ev_mutex); | 525 | mutex_unlock(&dev->ev_mutex); |
504 | 526 | ||
527 | if (file->f_flags & FASYNC) | ||
528 | inotify_fasync(-1, file, 0); | ||
529 | |||
505 | /* free this device: the put matching the get in inotify_init() */ | 530 | /* free this device: the put matching the get in inotify_init() */ |
506 | put_inotify_dev(dev); | 531 | put_inotify_dev(dev); |
507 | 532 | ||
@@ -530,6 +555,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd, | |||
530 | static const struct file_operations inotify_fops = { | 555 | static const struct file_operations inotify_fops = { |
531 | .poll = inotify_poll, | 556 | .poll = inotify_poll, |
532 | .read = inotify_read, | 557 | .read = inotify_read, |
558 | .fasync = inotify_fasync, | ||
533 | .release = inotify_release, | 559 | .release = inotify_release, |
534 | .unlocked_ioctl = inotify_ioctl, | 560 | .unlocked_ioctl = inotify_ioctl, |
535 | .compat_ioctl = inotify_ioctl, | 561 | .compat_ioctl = inotify_ioctl, |
@@ -577,6 +603,7 @@ asmlinkage long sys_inotify_init(void) | |||
577 | goto out_free_dev; | 603 | goto out_free_dev; |
578 | } | 604 | } |
579 | dev->ih = ih; | 605 | dev->ih = ih; |
606 | dev->fa = NULL; | ||
580 | 607 | ||
581 | filp->f_op = &inotify_fops; | 608 | filp->f_op = &inotify_fops; |
582 | filp->f_path.mnt = mntget(inotify_mnt); | 609 | filp->f_path.mnt = mntget(inotify_mnt); |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 5d14243499d4..3943a8905eb2 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -1457,7 +1457,7 @@ static const char *journal_dev_name(journal_t *journal, char *buffer) | |||
1457 | * Aborts hard --- we mark the abort as occurred, but do _nothing_ else, | 1457 | * Aborts hard --- we mark the abort as occurred, but do _nothing_ else, |
1458 | * and don't attempt to make any other journal updates. | 1458 | * and don't attempt to make any other journal updates. |
1459 | */ | 1459 | */ |
1460 | void __journal_abort_hard(journal_t *journal) | 1460 | static void __journal_abort_hard(journal_t *journal) |
1461 | { | 1461 | { |
1462 | transaction_t *transaction; | 1462 | transaction_t *transaction; |
1463 | char b[BDEVNAME_SIZE]; | 1463 | char b[BDEVNAME_SIZE]; |
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index c5d9694b6a2f..2b8edf4d6eaa 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
@@ -354,7 +354,7 @@ static int do_one_pass(journal_t *journal, | |||
354 | struct buffer_head * obh; | 354 | struct buffer_head * obh; |
355 | struct buffer_head * nbh; | 355 | struct buffer_head * nbh; |
356 | 356 | ||
357 | cond_resched(); /* We're under lock_kernel() */ | 357 | cond_resched(); |
358 | 358 | ||
359 | /* If we already know where to stop the log traversal, | 359 | /* If we already know where to stop the log traversal, |
360 | * check right now that we haven't gone past the end of | 360 | * check right now that we haven't gone past the end of |
diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 921680663fa2..d36356f7d222 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c | |||
@@ -397,7 +397,7 @@ static int do_one_pass(journal_t *journal, | |||
397 | struct buffer_head * obh; | 397 | struct buffer_head * obh; |
398 | struct buffer_head * nbh; | 398 | struct buffer_head * nbh; |
399 | 399 | ||
400 | cond_resched(); /* We're under lock_kernel() */ | 400 | cond_resched(); |
401 | 401 | ||
402 | /* If we already know where to stop the log traversal, | 402 | /* If we already know where to stop the log traversal, |
403 | * check right now that we haven't gone past the end of | 403 | * check right now that we haven't gone past the end of |
diff --git a/fs/namei.c b/fs/namei.c index 73e2e665817a..241cff423653 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2188,6 +2188,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2188 | 2188 | ||
2189 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 2189 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
2190 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 2190 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
2191 | fsnotify_link_count(dentry->d_inode); | ||
2191 | d_delete(dentry); | 2192 | d_delete(dentry); |
2192 | } | 2193 | } |
2193 | 2194 | ||
@@ -2360,7 +2361,7 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2360 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2361 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2361 | mutex_unlock(&old_dentry->d_inode->i_mutex); | 2362 | mutex_unlock(&old_dentry->d_inode->i_mutex); |
2362 | if (!error) | 2363 | if (!error) |
2363 | fsnotify_create(dir, new_dentry); | 2364 | fsnotify_link(dir, old_dentry->d_inode, new_dentry); |
2364 | return error; | 2365 | return error; |
2365 | } | 2366 | } |
2366 | 2367 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 61bf376e29e8..e9c10cd01e13 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -25,18 +25,21 @@ | |||
25 | #include <linux/security.h> | 25 | #include <linux/security.h> |
26 | #include <linux/mount.h> | 26 | #include <linux/mount.h> |
27 | #include <linux/ramfs.h> | 27 | #include <linux/ramfs.h> |
28 | #include <linux/log2.h> | ||
28 | #include <asm/uaccess.h> | 29 | #include <asm/uaccess.h> |
29 | #include <asm/unistd.h> | 30 | #include <asm/unistd.h> |
30 | #include "pnode.h" | 31 | #include "pnode.h" |
31 | #include "internal.h" | 32 | #include "internal.h" |
32 | 33 | ||
34 | #define HASH_SHIFT ilog2(PAGE_SIZE / sizeof(struct list_head)) | ||
35 | #define HASH_SIZE (1UL << HASH_SHIFT) | ||
36 | |||
33 | /* spinlock for vfsmount related operations, inplace of dcache_lock */ | 37 | /* spinlock for vfsmount related operations, inplace of dcache_lock */ |
34 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); | 38 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock); |
35 | 39 | ||
36 | static int event; | 40 | static int event; |
37 | 41 | ||
38 | static struct list_head *mount_hashtable __read_mostly; | 42 | static struct list_head *mount_hashtable __read_mostly; |
39 | static int hash_mask __read_mostly, hash_bits __read_mostly; | ||
40 | static struct kmem_cache *mnt_cache __read_mostly; | 43 | static struct kmem_cache *mnt_cache __read_mostly; |
41 | static struct rw_semaphore namespace_sem; | 44 | static struct rw_semaphore namespace_sem; |
42 | 45 | ||
@@ -48,8 +51,8 @@ static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry) | |||
48 | { | 51 | { |
49 | unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES); | 52 | unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES); |
50 | tmp += ((unsigned long)dentry / L1_CACHE_BYTES); | 53 | tmp += ((unsigned long)dentry / L1_CACHE_BYTES); |
51 | tmp = tmp + (tmp >> hash_bits); | 54 | tmp = tmp + (tmp >> HASH_SHIFT); |
52 | return tmp & hash_mask; | 55 | return tmp & (HASH_SIZE - 1); |
53 | } | 56 | } |
54 | 57 | ||
55 | struct vfsmount *alloc_vfsmnt(const char *name) | 58 | struct vfsmount *alloc_vfsmnt(const char *name) |
@@ -1813,9 +1816,7 @@ static void __init init_mount_tree(void) | |||
1813 | 1816 | ||
1814 | void __init mnt_init(void) | 1817 | void __init mnt_init(void) |
1815 | { | 1818 | { |
1816 | struct list_head *d; | 1819 | unsigned u; |
1817 | unsigned int nr_hash; | ||
1818 | int i; | ||
1819 | int err; | 1820 | int err; |
1820 | 1821 | ||
1821 | init_rwsem(&namespace_sem); | 1822 | init_rwsem(&namespace_sem); |
@@ -1828,35 +1829,11 @@ void __init mnt_init(void) | |||
1828 | if (!mount_hashtable) | 1829 | if (!mount_hashtable) |
1829 | panic("Failed to allocate mount hash table\n"); | 1830 | panic("Failed to allocate mount hash table\n"); |
1830 | 1831 | ||
1831 | /* | 1832 | printk("Mount-cache hash table entries: %lu\n", HASH_SIZE); |
1832 | * Find the power-of-two list-heads that can fit into the allocation.. | 1833 | |
1833 | * We don't guarantee that "sizeof(struct list_head)" is necessarily | 1834 | for (u = 0; u < HASH_SIZE; u++) |
1834 | * a power-of-two. | 1835 | INIT_LIST_HEAD(&mount_hashtable[u]); |
1835 | */ | ||
1836 | nr_hash = PAGE_SIZE / sizeof(struct list_head); | ||
1837 | hash_bits = 0; | ||
1838 | do { | ||
1839 | hash_bits++; | ||
1840 | } while ((nr_hash >> hash_bits) != 0); | ||
1841 | hash_bits--; | ||
1842 | 1836 | ||
1843 | /* | ||
1844 | * Re-calculate the actual number of entries and the mask | ||
1845 | * from the number of bits we can fit. | ||
1846 | */ | ||
1847 | nr_hash = 1UL << hash_bits; | ||
1848 | hash_mask = nr_hash - 1; | ||
1849 | |||
1850 | printk("Mount-cache hash table entries: %d\n", nr_hash); | ||
1851 | |||
1852 | /* And initialize the newly allocated array */ | ||
1853 | d = mount_hashtable; | ||
1854 | i = nr_hash; | ||
1855 | do { | ||
1856 | INIT_LIST_HEAD(d); | ||
1857 | d++; | ||
1858 | i--; | ||
1859 | } while (i); | ||
1860 | err = sysfs_init(); | 1837 | err = sysfs_init(); |
1861 | if (err) | 1838 | if (err) |
1862 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", | 1839 | printk(KERN_WARNING "%s: sysfs_init error: %d\n", |
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c index e1cb70c643f8..eff1f18d034f 100644 --- a/fs/ncpfs/inode.c +++ b/fs/ncpfs/inode.c | |||
@@ -987,7 +987,7 @@ static struct file_system_type ncp_fs_type = { | |||
987 | static int __init init_ncp_fs(void) | 987 | static int __init init_ncp_fs(void) |
988 | { | 988 | { |
989 | int err; | 989 | int err; |
990 | DPRINTK("ncpfs: init_module called\n"); | 990 | DPRINTK("ncpfs: init_ncp_fs called\n"); |
991 | 991 | ||
992 | err = init_inodecache(); | 992 | err = init_inodecache(); |
993 | if (err) | 993 | if (err) |
@@ -1004,7 +1004,7 @@ out1: | |||
1004 | 1004 | ||
1005 | static void __exit exit_ncp_fs(void) | 1005 | static void __exit exit_ncp_fs(void) |
1006 | { | 1006 | { |
1007 | DPRINTK("ncpfs: cleanup_module called\n"); | 1007 | DPRINTK("ncpfs: exit_ncp_fs called\n"); |
1008 | unregister_filesystem(&ncp_fs_type); | 1008 | unregister_filesystem(&ncp_fs_type); |
1009 | destroy_inodecache(); | 1009 | destroy_inodecache(); |
1010 | } | 1010 | } |
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index a99acd8de353..cb5f0a3f1b03 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -198,7 +198,7 @@ config LDM_DEBUG | |||
198 | 198 | ||
199 | config SGI_PARTITION | 199 | config SGI_PARTITION |
200 | bool "SGI partition support" if PARTITION_ADVANCED | 200 | bool "SGI partition support" if PARTITION_ADVANCED |
201 | default y if (SGI_IP22 || SGI_IP27 || ((MACH_JAZZ || SNI_RM) && !CPU_LITTLE_ENDIAN)) | 201 | default y if DEFAULT_SGI_PARTITION |
202 | help | 202 | help |
203 | Say Y here if you would like to be able to read the hard disk | 203 | Say Y here if you would like to be able to read the hard disk |
204 | partition table format used by SGI machines. | 204 | partition table format used by SGI machines. |
diff --git a/fs/pnode.c b/fs/pnode.c index 89940f243fc2..05ba692bc540 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -83,6 +83,8 @@ void change_mnt_propagation(struct vfsmount *mnt, int type) | |||
83 | mnt->mnt_master = NULL; | 83 | mnt->mnt_master = NULL; |
84 | if (type == MS_UNBINDABLE) | 84 | if (type == MS_UNBINDABLE) |
85 | mnt->mnt_flags |= MNT_UNBINDABLE; | 85 | mnt->mnt_flags |= MNT_UNBINDABLE; |
86 | else | ||
87 | mnt->mnt_flags &= ~MNT_UNBINDABLE; | ||
86 | } | 88 | } |
87 | } | 89 | } |
88 | 90 | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index 51288db37a0c..2686592dbcb2 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/mmzone.h> | 30 | #include <linux/mmzone.h> |
31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
32 | #include <linux/interrupt.h> | ||
32 | #include <linux/swap.h> | 33 | #include <linux/swap.h> |
33 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
34 | #include <linux/smp.h> | 35 | #include <linux/smp.h> |
@@ -64,7 +65,6 @@ | |||
64 | */ | 65 | */ |
65 | extern int get_hardware_list(char *); | 66 | extern int get_hardware_list(char *); |
66 | extern int get_stram_list(char *); | 67 | extern int get_stram_list(char *); |
67 | extern int get_filesystem_list(char *); | ||
68 | extern int get_exec_domain_list(char *); | 68 | extern int get_exec_domain_list(char *); |
69 | extern int get_dma_list(char *); | 69 | extern int get_dma_list(char *); |
70 | 70 | ||
@@ -84,10 +84,15 @@ static int loadavg_read_proc(char *page, char **start, off_t off, | |||
84 | { | 84 | { |
85 | int a, b, c; | 85 | int a, b, c; |
86 | int len; | 86 | int len; |
87 | unsigned long seq; | ||
88 | |||
89 | do { | ||
90 | seq = read_seqbegin(&xtime_lock); | ||
91 | a = avenrun[0] + (FIXED_1/200); | ||
92 | b = avenrun[1] + (FIXED_1/200); | ||
93 | c = avenrun[2] + (FIXED_1/200); | ||
94 | } while (read_seqretry(&xtime_lock, seq)); | ||
87 | 95 | ||
88 | a = avenrun[0] + (FIXED_1/200); | ||
89 | b = avenrun[1] + (FIXED_1/200); | ||
90 | c = avenrun[2] + (FIXED_1/200); | ||
91 | len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", | 96 | len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d\n", |
92 | LOAD_INT(a), LOAD_FRAC(a), | 97 | LOAD_INT(a), LOAD_FRAC(a), |
93 | LOAD_INT(b), LOAD_FRAC(b), | 98 | LOAD_INT(b), LOAD_FRAC(b), |
@@ -599,7 +604,6 @@ static void int_seq_stop(struct seq_file *f, void *v) | |||
599 | } | 604 | } |
600 | 605 | ||
601 | 606 | ||
602 | extern int show_interrupts(struct seq_file *f, void *v); /* In arch code */ | ||
603 | static struct seq_operations int_seq_ops = { | 607 | static struct seq_operations int_seq_ops = { |
604 | .start = int_seq_start, | 608 | .start = int_seq_start, |
605 | .next = int_seq_next, | 609 | .next = int_seq_next, |
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index 5e7388b32d02..740bb8c0c1ae 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c | |||
@@ -575,6 +575,8 @@ void print_block(struct buffer_head *bh, ...) //int print_mode, int first, int l | |||
575 | printk | 575 | printk |
576 | ("Block %llu contains unformatted data\n", | 576 | ("Block %llu contains unformatted data\n", |
577 | (unsigned long long)bh->b_blocknr); | 577 | (unsigned long long)bh->b_blocknr); |
578 | |||
579 | va_end(args); | ||
578 | } | 580 | } |
579 | 581 | ||
580 | static char print_tb_buf[2048]; | 582 | static char print_tb_buf[2048]; |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index 1597f6b649e0..a5bd23ce0e46 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -1084,7 +1084,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |||
1084 | } | 1084 | } |
1085 | 1085 | ||
1086 | /* This is the implementation for the xattr plugin infrastructure */ | 1086 | /* This is the implementation for the xattr plugin infrastructure */ |
1087 | static struct list_head xattr_handlers = LIST_HEAD_INIT(xattr_handlers); | 1087 | static LIST_HEAD(xattr_handlers); |
1088 | static DEFINE_RWLOCK(handler_lock); | 1088 | static DEFINE_RWLOCK(handler_lock); |
1089 | 1089 | ||
1090 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char | 1090 | static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char |
diff --git a/fs/select.c b/fs/select.c index 47f47925aea2..5633fe980781 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -739,7 +739,7 @@ asmlinkage long sys_poll(struct pollfd __user *ufds, unsigned int nfds, | |||
739 | timeout_jiffies = -1; | 739 | timeout_jiffies = -1; |
740 | else | 740 | else |
741 | #endif | 741 | #endif |
742 | timeout_jiffies = msecs_to_jiffies(timeout_msecs); | 742 | timeout_jiffies = msecs_to_jiffies(timeout_msecs) + 1; |
743 | } else { | 743 | } else { |
744 | /* Infinite (< 0) or no (0) timeout */ | 744 | /* Infinite (< 0) or no (0) timeout */ |
745 | timeout_jiffies = timeout_msecs; | 745 | timeout_jiffies = timeout_msecs; |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 2d3e107da2d3..cb2b63ae0bf4 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/list.h> | 27 | #include <linux/list.h> |
28 | #include <linux/anon_inodes.h> | 28 | #include <linux/anon_inodes.h> |
29 | #include <linux/signalfd.h> | 29 | #include <linux/signalfd.h> |
30 | #include <linux/syscalls.h> | ||
30 | 31 | ||
31 | struct signalfd_ctx { | 32 | struct signalfd_ctx { |
32 | sigset_t sigmask; | 33 | sigset_t sigmask; |
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c index 9416ead0c7aa..4e5c22ca802e 100644 --- a/fs/smbfs/inode.c +++ b/fs/smbfs/inode.c | |||
@@ -500,6 +500,13 @@ static int smb_fill_super(struct super_block *sb, void *raw_data, int silent) | |||
500 | struct smb_fattr root; | 500 | struct smb_fattr root; |
501 | int ver; | 501 | int ver; |
502 | void *mem; | 502 | void *mem; |
503 | static int warn_count; | ||
504 | |||
505 | if (warn_count < 5) { | ||
506 | warn_count++; | ||
507 | printk(KERN_EMERG "smbfs is deprecated and will be removed" | ||
508 | "from the 2.6.27 kernel. Please migrate to cifs\n"); | ||
509 | } | ||
503 | 510 | ||
504 | if (!raw_data) | 511 | if (!raw_data) |
505 | goto out_no_data; | 512 | goto out_no_data; |
diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index e48bd8235a8e..e37fe4deebd0 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c | |||
@@ -329,9 +329,8 @@ smb_receive(struct smb_sb_info *server, struct smb_request *req) | |||
329 | msg.msg_control = NULL; | 329 | msg.msg_control = NULL; |
330 | 330 | ||
331 | /* Dont repeat bytes and count available bufferspace */ | 331 | /* Dont repeat bytes and count available bufferspace */ |
332 | rlen = smb_move_iov(&p, &num, iov, req->rq_bytes_recvd); | 332 | rlen = min_t(int, smb_move_iov(&p, &num, iov, req->rq_bytes_recvd), |
333 | if (req->rq_rlen < rlen) | 333 | (req->rq_rlen - req->rq_bytes_recvd)); |
334 | rlen = req->rq_rlen; | ||
335 | 334 | ||
336 | result = kernel_recvmsg(sock, &msg, p, num, rlen, flags); | 335 | result = kernel_recvmsg(sock, &msg, p, num, rlen, flags); |
337 | 336 | ||
diff --git a/fs/utimes.c b/fs/utimes.c index b9912ecbee24..e5588cd8530e 100644 --- a/fs/utimes.c +++ b/fs/utimes.c | |||
@@ -6,6 +6,7 @@ | |||
6 | #include <linux/sched.h> | 6 | #include <linux/sched.h> |
7 | #include <linux/stat.h> | 7 | #include <linux/stat.h> |
8 | #include <linux/utime.h> | 8 | #include <linux/utime.h> |
9 | #include <linux/syscalls.h> | ||
9 | #include <asm/uaccess.h> | 10 | #include <asm/uaccess.h> |
10 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
11 | 12 | ||
diff --git a/include/asm-arm/arch-s3c2410/regs-lcd.h b/include/asm-arm/arch-s3c2410/regs-lcd.h index 76fe5f693426..bd854845697f 100644 --- a/include/asm-arm/arch-s3c2410/regs-lcd.h +++ b/include/asm-arm/arch-s3c2410/regs-lcd.h | |||
@@ -147,7 +147,16 @@ | |||
147 | 147 | ||
148 | #define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) | 148 | #define S3C2412_FRCPAT(x) S3C2410_LCDREG(0xB4 + ((x)*4)) |
149 | 149 | ||
150 | #endif /* ___ASM_ARCH_REGS_LCD_H */ | 150 | /* general registers */ |
151 | |||
152 | /* base of the LCD registers, where INTPND, INTSRC and then INTMSK | ||
153 | * are available. */ | ||
151 | 154 | ||
155 | #define S3C2410_LCDINTBASE S3C2410_LCDREG(0x54) | ||
156 | #define S3C2412_LCDINTBASE S3C2410_LCDREG(0x24) | ||
152 | 157 | ||
158 | #define S3C24XX_LCDINTPND (0x00) | ||
159 | #define S3C24XX_LCDSRCPND (0x04) | ||
160 | #define S3C24XX_LCDINTMSK (0x08) | ||
153 | 161 | ||
162 | #endif /* ___ASM_ARCH_REGS_LCD_H */ | ||
diff --git a/include/asm-arm/arch-s3c2410/spi-gpio.h b/include/asm-arm/arch-s3c2410/spi-gpio.h index ba1dca88d480..73803731142a 100644 --- a/include/asm-arm/arch-s3c2410/spi-gpio.h +++ b/include/asm-arm/arch-s3c2410/spi-gpio.h | |||
@@ -13,9 +13,6 @@ | |||
13 | #ifndef __ASM_ARCH_SPIGPIO_H | 13 | #ifndef __ASM_ARCH_SPIGPIO_H |
14 | #define __ASM_ARCH_SPIGPIO_H __FILE__ | 14 | #define __ASM_ARCH_SPIGPIO_H __FILE__ |
15 | 15 | ||
16 | struct s3c2410_spigpio_info; | ||
17 | struct spi_board_info; | ||
18 | |||
19 | struct s3c2410_spigpio_info { | 16 | struct s3c2410_spigpio_info { |
20 | unsigned long pin_clk; | 17 | unsigned long pin_clk; |
21 | unsigned long pin_mosi; | 18 | unsigned long pin_mosi; |
@@ -23,9 +20,6 @@ struct s3c2410_spigpio_info { | |||
23 | 20 | ||
24 | int bus_num; | 21 | int bus_num; |
25 | 22 | ||
26 | unsigned long board_size; | ||
27 | struct spi_board_info *board_info; | ||
28 | |||
29 | void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs); | 23 | void (*chip_select)(struct s3c2410_spigpio_info *spi, int cs); |
30 | }; | 24 | }; |
31 | 25 | ||
diff --git a/include/asm-arm/arch-s3c2410/spi.h b/include/asm-arm/arch-s3c2410/spi.h index 4029a1a1ab40..7ca0ed97a6d0 100644 --- a/include/asm-arm/arch-s3c2410/spi.h +++ b/include/asm-arm/arch-s3c2410/spi.h | |||
@@ -13,15 +13,9 @@ | |||
13 | #ifndef __ASM_ARCH_SPI_H | 13 | #ifndef __ASM_ARCH_SPI_H |
14 | #define __ASM_ARCH_SPI_H __FILE__ | 14 | #define __ASM_ARCH_SPI_H __FILE__ |
15 | 15 | ||
16 | struct s3c2410_spi_info; | ||
17 | struct spi_board_info; | ||
18 | |||
19 | struct s3c2410_spi_info { | 16 | struct s3c2410_spi_info { |
20 | unsigned long pin_cs; /* simple gpio cs */ | 17 | unsigned long pin_cs; /* simple gpio cs */ |
21 | 18 | ||
22 | unsigned long board_size; | ||
23 | struct spi_board_info *board_info; | ||
24 | |||
25 | void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); | 19 | void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol); |
26 | }; | 20 | }; |
27 | 21 | ||
diff --git a/include/asm-avr32/delay.h b/include/asm-avr32/delay.h index cc3b2e3343b3..a0ed9a9839a5 100644 --- a/include/asm-avr32/delay.h +++ b/include/asm-avr32/delay.h | |||
@@ -12,7 +12,7 @@ extern void __bad_ndelay(void); | |||
12 | 12 | ||
13 | extern void __udelay(unsigned long usecs); | 13 | extern void __udelay(unsigned long usecs); |
14 | extern void __ndelay(unsigned long nsecs); | 14 | extern void __ndelay(unsigned long nsecs); |
15 | extern void __const_udelay(unsigned long usecs); | 15 | extern void __const_udelay(unsigned long xloops); |
16 | extern void __delay(unsigned long loops); | 16 | extern void __delay(unsigned long loops); |
17 | 17 | ||
18 | #define udelay(n) (__builtin_constant_p(n) ? \ | 18 | #define udelay(n) (__builtin_constant_p(n) ? \ |
diff --git a/include/asm-avr32/timex.h b/include/asm-avr32/timex.h index 5e44ecb3ce0c..187dcf38b210 100644 --- a/include/asm-avr32/timex.h +++ b/include/asm-avr32/timex.h | |||
@@ -34,7 +34,6 @@ static inline cycles_t get_cycles (void) | |||
34 | return 0; | 34 | return 0; |
35 | } | 35 | } |
36 | 36 | ||
37 | extern int read_current_timer(unsigned long *timer_value); | 37 | #define ARCH_HAS_READ_CURRENT_TIMER |
38 | #define ARCH_HAS_READ_CURRENT_TIMER 1 | ||
39 | 38 | ||
40 | #endif /* __ASM_AVR32_TIMEX_H */ | 39 | #endif /* __ASM_AVR32_TIMEX_H */ |
diff --git a/include/asm-avr32/unistd.h b/include/asm-avr32/unistd.h index de09009593f8..89861a27543e 100644 --- a/include/asm-avr32/unistd.h +++ b/include/asm-avr32/unistd.h | |||
@@ -297,7 +297,7 @@ | |||
297 | 297 | ||
298 | #define __NR_utimensat 278 | 298 | #define __NR_utimensat 278 |
299 | #define __NR_signalfd 279 | 299 | #define __NR_signalfd 279 |
300 | #define __NR_timerfd 280 | 300 | /* 280 was __NR_timerfd */ |
301 | #define __NR_eventfd 281 | 301 | #define __NR_eventfd 281 |
302 | 302 | ||
303 | #ifdef __KERNEL__ | 303 | #ifdef __KERNEL__ |
diff --git a/include/asm-blackfin/io.h b/include/asm-blackfin/io.h index 1601d62f39a5..574fe56989d1 100644 --- a/include/asm-blackfin/io.h +++ b/include/asm-blackfin/io.h | |||
@@ -188,8 +188,6 @@ extern void blkfin_inv_cache_all(void); | |||
188 | #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) | 188 | #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) |
189 | #define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) | 189 | #define page_to_bus(page) ((page - mem_map) << PAGE_SHIFT) |
190 | 190 | ||
191 | #define mm_ptov(vaddr) ((void *) (vaddr)) | ||
192 | #define mm_vtop(vaddr) ((unsigned long) (vaddr)) | ||
193 | #define phys_to_virt(vaddr) ((void *) (vaddr)) | 191 | #define phys_to_virt(vaddr) ((void *) (vaddr)) |
194 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) | 192 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) |
195 | 193 | ||
diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index cd84f1771e34..e8c986667532 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h | |||
@@ -328,7 +328,7 @@ | |||
328 | #define __NR_epoll_pwait 319 | 328 | #define __NR_epoll_pwait 319 |
329 | #define __NR_utimensat 320 | 329 | #define __NR_utimensat 320 |
330 | #define __NR_signalfd 321 | 330 | #define __NR_signalfd 321 |
331 | #define __NR_timerfd 322 | 331 | /* #define __NR_timerfd 322 removed */ |
332 | #define __NR_eventfd 323 | 332 | #define __NR_eventfd 323 |
333 | #define __NR_fallocate 324 | 333 | #define __NR_fallocate 324 |
334 | 334 | ||
diff --git a/include/asm-generic/cputime.h b/include/asm-generic/cputime.h index 09204e40d663..1c1fa422d18a 100644 --- a/include/asm-generic/cputime.h +++ b/include/asm-generic/cputime.h | |||
@@ -18,6 +18,7 @@ typedef unsigned long cputime_t; | |||
18 | #define cputime_lt(__a, __b) ((__a) < (__b)) | 18 | #define cputime_lt(__a, __b) ((__a) < (__b)) |
19 | #define cputime_le(__a, __b) ((__a) <= (__b)) | 19 | #define cputime_le(__a, __b) ((__a) <= (__b)) |
20 | #define cputime_to_jiffies(__ct) (__ct) | 20 | #define cputime_to_jiffies(__ct) (__ct) |
21 | #define cputime_to_scaled(__ct) (__ct) | ||
21 | #define jiffies_to_cputime(__hz) (__hz) | 22 | #define jiffies_to_cputime(__hz) (__hz) |
22 | 23 | ||
23 | typedef u64 cputime64_t; | 24 | typedef u64 cputime64_t; |
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 962cad7cfbbd..8feeae1f2369 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h | |||
@@ -8,8 +8,6 @@ extern char _data[], _sdata[], _edata[]; | |||
8 | extern char __bss_start[], __bss_stop[]; | 8 | extern char __bss_start[], __bss_stop[]; |
9 | extern char __init_begin[], __init_end[]; | 9 | extern char __init_begin[], __init_end[]; |
10 | extern char _sinittext[], _einittext[]; | 10 | extern char _sinittext[], _einittext[]; |
11 | extern char _sextratext[] __attribute__((weak)); | ||
12 | extern char _eextratext[] __attribute__((weak)); | ||
13 | extern char _end[]; | 11 | extern char _end[]; |
14 | extern char __per_cpu_start[], __per_cpu_end[]; | 12 | extern char __per_cpu_start[], __per_cpu_end[]; |
15 | extern char __kprobes_text_start[], __kprobes_text_end[]; | 13 | extern char __kprobes_text_start[], __kprobes_text_end[]; |
diff --git a/include/asm-h8300/io.h b/include/asm-h8300/io.h index 7543a57b4ea1..26dc6ccd9441 100644 --- a/include/asm-h8300/io.h +++ b/include/asm-h8300/io.h | |||
@@ -302,8 +302,6 @@ static __inline__ void ctrl_outl(unsigned long b, unsigned long addr) | |||
302 | /* | 302 | /* |
303 | * Macros used for converting between virtual and physical mappings. | 303 | * Macros used for converting between virtual and physical mappings. |
304 | */ | 304 | */ |
305 | #define mm_ptov(vaddr) ((void *) (vaddr)) | ||
306 | #define mm_vtop(vaddr) ((unsigned long) (vaddr)) | ||
307 | #define phys_to_virt(vaddr) ((void *) (vaddr)) | 305 | #define phys_to_virt(vaddr) ((void *) (vaddr)) |
308 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) | 306 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) |
309 | 307 | ||
diff --git a/include/asm-h8300/virtconvert.h b/include/asm-h8300/virtconvert.h index ee7d5ea10065..19cfd62b11c3 100644 --- a/include/asm-h8300/virtconvert.h +++ b/include/asm-h8300/virtconvert.h | |||
@@ -10,8 +10,6 @@ | |||
10 | #include <asm/setup.h> | 10 | #include <asm/setup.h> |
11 | #include <asm/page.h> | 11 | #include <asm/page.h> |
12 | 12 | ||
13 | #define mm_ptov(vaddr) ((void *) (vaddr)) | ||
14 | #define mm_vtop(vaddr) ((unsigned long) (vaddr)) | ||
15 | #define phys_to_virt(vaddr) ((void *) (vaddr)) | 13 | #define phys_to_virt(vaddr) ((void *) (vaddr)) |
16 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) | 14 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) |
17 | 15 | ||
diff --git a/include/asm-m32r/delay.h b/include/asm-m32r/delay.h index 164448d23850..9dd9e999ea69 100644 --- a/include/asm-m32r/delay.h +++ b/include/asm-m32r/delay.h | |||
@@ -12,7 +12,7 @@ extern void __bad_ndelay(void); | |||
12 | 12 | ||
13 | extern void __udelay(unsigned long usecs); | 13 | extern void __udelay(unsigned long usecs); |
14 | extern void __ndelay(unsigned long nsecs); | 14 | extern void __ndelay(unsigned long nsecs); |
15 | extern void __const_udelay(unsigned long usecs); | 15 | extern void __const_udelay(unsigned long xloops); |
16 | extern void __delay(unsigned long loops); | 16 | extern void __delay(unsigned long loops); |
17 | 17 | ||
18 | #define udelay(n) (__builtin_constant_p(n) ? \ | 18 | #define udelay(n) (__builtin_constant_p(n) ? \ |
diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h index f467eac9ba70..cf701c933249 100644 --- a/include/asm-m32r/unistd.h +++ b/include/asm-m32r/unistd.h | |||
@@ -327,7 +327,7 @@ | |||
327 | #define __NR_epoll_pwait 319 | 327 | #define __NR_epoll_pwait 319 |
328 | #define __NR_utimensat 320 | 328 | #define __NR_utimensat 320 |
329 | #define __NR_signalfd 321 | 329 | #define __NR_signalfd 321 |
330 | #define __NR_timerfd 322 | 330 | /* #define __NR_timerfd 322 removed */ |
331 | #define __NR_eventfd 323 | 331 | #define __NR_eventfd 323 |
332 | #define __NR_fallocate 324 | 332 | #define __NR_fallocate 324 |
333 | 333 | ||
diff --git a/include/asm-m68k/pgtable.h b/include/asm-m68k/pgtable.h index 778a4c538eb2..0b604f0f192d 100644 --- a/include/asm-m68k/pgtable.h +++ b/include/asm-m68k/pgtable.h | |||
@@ -107,8 +107,6 @@ extern void *empty_zero_page; | |||
107 | /* 64-bit machines, beware! SRB. */ | 107 | /* 64-bit machines, beware! SRB. */ |
108 | #define SIZEOF_PTR_LOG2 2 | 108 | #define SIZEOF_PTR_LOG2 2 |
109 | 109 | ||
110 | #define mm_end_of_chunk(addr, len) 0 | ||
111 | |||
112 | extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode); | 110 | extern void kernel_set_cachemode(void *addr, unsigned long size, int cmode); |
113 | 111 | ||
114 | /* | 112 | /* |
diff --git a/include/asm-m68knommu/io.h b/include/asm-m68knommu/io.h index 653d9b2d7ddf..6adef1ee2082 100644 --- a/include/asm-m68knommu/io.h +++ b/include/asm-m68knommu/io.h | |||
@@ -172,8 +172,6 @@ extern void iounmap(void *addr); | |||
172 | /* | 172 | /* |
173 | * Macros used for converting between virtual and physical mappings. | 173 | * Macros used for converting between virtual and physical mappings. |
174 | */ | 174 | */ |
175 | #define mm_ptov(vaddr) ((void *) (vaddr)) | ||
176 | #define mm_vtop(vaddr) ((unsigned long) (vaddr)) | ||
177 | #define phys_to_virt(vaddr) ((void *) (vaddr)) | 175 | #define phys_to_virt(vaddr) ((void *) (vaddr)) |
178 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) | 176 | #define virt_to_phys(vaddr) ((unsigned long) (vaddr)) |
179 | 177 | ||
diff --git a/include/asm-powerpc/cputime.h b/include/asm-powerpc/cputime.h index 310804485208..f42e623030ee 100644 --- a/include/asm-powerpc/cputime.h +++ b/include/asm-powerpc/cputime.h | |||
@@ -52,12 +52,26 @@ typedef u64 cputime64_t; | |||
52 | * Convert cputime <-> jiffies | 52 | * Convert cputime <-> jiffies |
53 | */ | 53 | */ |
54 | extern u64 __cputime_jiffies_factor; | 54 | extern u64 __cputime_jiffies_factor; |
55 | DECLARE_PER_CPU(unsigned long, cputime_last_delta); | ||
56 | DECLARE_PER_CPU(unsigned long, cputime_scaled_last_delta); | ||
55 | 57 | ||
56 | static inline unsigned long cputime_to_jiffies(const cputime_t ct) | 58 | static inline unsigned long cputime_to_jiffies(const cputime_t ct) |
57 | { | 59 | { |
58 | return mulhdu(ct, __cputime_jiffies_factor); | 60 | return mulhdu(ct, __cputime_jiffies_factor); |
59 | } | 61 | } |
60 | 62 | ||
63 | /* Estimate the scaled cputime by scaling the real cputime based on | ||
64 | * the last scaled to real ratio */ | ||
65 | static inline cputime_t cputime_to_scaled(const cputime_t ct) | ||
66 | { | ||
67 | if (cpu_has_feature(CPU_FTR_SPURR) && | ||
68 | per_cpu(cputime_last_delta, smp_processor_id())) | ||
69 | return ct * | ||
70 | per_cpu(cputime_scaled_last_delta, smp_processor_id())/ | ||
71 | per_cpu(cputime_last_delta, smp_processor_id()); | ||
72 | return ct; | ||
73 | } | ||
74 | |||
61 | static inline cputime_t jiffies_to_cputime(const unsigned long jif) | 75 | static inline cputime_t jiffies_to_cputime(const unsigned long jif) |
62 | { | 76 | { |
63 | cputime_t ct; | 77 | cputime_t ct; |
diff --git a/include/asm-powerpc/dma.h b/include/asm-powerpc/dma.h index 7a4374bdbef4..a7e06e25c708 100644 --- a/include/asm-powerpc/dma.h +++ b/include/asm-powerpc/dma.h | |||
@@ -93,16 +93,6 @@ | |||
93 | * | 93 | * |
94 | */ | 94 | */ |
95 | 95 | ||
96 | /* see prep_setup_arch() for detailed informations */ | ||
97 | #if defined(CONFIG_SOUND_CS4232) && defined(CONFIG_PPC_PREP) | ||
98 | extern long ppc_cs4232_dma, ppc_cs4232_dma2; | ||
99 | #define SND_DMA1 ppc_cs4232_dma | ||
100 | #define SND_DMA2 ppc_cs4232_dma2 | ||
101 | #else | ||
102 | #define SND_DMA1 -1 | ||
103 | #define SND_DMA2 -1 | ||
104 | #endif | ||
105 | |||
106 | /* 8237 DMA controllers */ | 96 | /* 8237 DMA controllers */ |
107 | #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ | 97 | #define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ |
108 | #define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ | 98 | #define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ |
@@ -269,24 +259,15 @@ static __inline__ void set_dma_page(unsigned int dmanr, int pagenr) | |||
269 | dma_outb(pagenr >> 8, DMA_HI_PAGE_3); | 259 | dma_outb(pagenr >> 8, DMA_HI_PAGE_3); |
270 | break; | 260 | break; |
271 | case 5: | 261 | case 5: |
272 | if (SND_DMA1 == 5 || SND_DMA2 == 5) | 262 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5); |
273 | dma_outb(pagenr, DMA_LO_PAGE_5); | ||
274 | else | ||
275 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_5); | ||
276 | dma_outb(pagenr >> 8, DMA_HI_PAGE_5); | 263 | dma_outb(pagenr >> 8, DMA_HI_PAGE_5); |
277 | break; | 264 | break; |
278 | case 6: | 265 | case 6: |
279 | if (SND_DMA1 == 6 || SND_DMA2 == 6) | 266 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6); |
280 | dma_outb(pagenr, DMA_LO_PAGE_6); | ||
281 | else | ||
282 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_6); | ||
283 | dma_outb(pagenr >> 8, DMA_HI_PAGE_6); | 267 | dma_outb(pagenr >> 8, DMA_HI_PAGE_6); |
284 | break; | 268 | break; |
285 | case 7: | 269 | case 7: |
286 | if (SND_DMA1 == 7 || SND_DMA2 == 7) | 270 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7); |
287 | dma_outb(pagenr, DMA_LO_PAGE_7); | ||
288 | else | ||
289 | dma_outb(pagenr & 0xfe, DMA_LO_PAGE_7); | ||
290 | dma_outb(pagenr >> 8, DMA_HI_PAGE_7); | 271 | dma_outb(pagenr >> 8, DMA_HI_PAGE_7); |
291 | break; | 272 | break; |
292 | } | 273 | } |
@@ -302,12 +283,6 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int phys) | |||
302 | ((dmanr & 3) << 1) + IO_DMA1_BASE); | 283 | ((dmanr & 3) << 1) + IO_DMA1_BASE); |
303 | dma_outb((phys >> 8) & 0xff, | 284 | dma_outb((phys >> 8) & 0xff, |
304 | ((dmanr & 3) << 1) + IO_DMA1_BASE); | 285 | ((dmanr & 3) << 1) + IO_DMA1_BASE); |
305 | } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { | ||
306 | dma_outb(phys & 0xff, | ||
307 | ((dmanr & 3) << 2) + IO_DMA2_BASE); | ||
308 | dma_outb((phys >> 8) & 0xff, | ||
309 | ((dmanr & 3) << 2) + IO_DMA2_BASE); | ||
310 | dma_outb((dmanr & 3), DMA2_EXT_REG); | ||
311 | } else { | 286 | } else { |
312 | dma_outb((phys >> 1) & 0xff, | 287 | dma_outb((phys >> 1) & 0xff, |
313 | ((dmanr & 3) << 2) + IO_DMA2_BASE); | 288 | ((dmanr & 3) << 2) + IO_DMA2_BASE); |
@@ -334,11 +309,6 @@ static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) | |||
334 | ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); | 309 | ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); |
335 | dma_outb((count >> 8) & 0xff, | 310 | dma_outb((count >> 8) & 0xff, |
336 | ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); | 311 | ((dmanr & 3) << 1) + 1 + IO_DMA1_BASE); |
337 | } else if (dmanr == SND_DMA1 || dmanr == SND_DMA2) { | ||
338 | dma_outb(count & 0xff, | ||
339 | ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); | ||
340 | dma_outb((count >> 8) & 0xff, | ||
341 | ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); | ||
342 | } else { | 312 | } else { |
343 | dma_outb((count >> 1) & 0xff, | 313 | dma_outb((count >> 1) & 0xff, |
344 | ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); | 314 | ((dmanr & 3) << 2) + 2 + IO_DMA2_BASE); |
@@ -368,8 +338,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr) | |||
368 | count = 1 + dma_inb(io_port); | 338 | count = 1 + dma_inb(io_port); |
369 | count += dma_inb(io_port) << 8; | 339 | count += dma_inb(io_port) << 8; |
370 | 340 | ||
371 | return (dmanr <= 3 || dmanr == SND_DMA1 || dmanr == SND_DMA2) | 341 | return (dmanr <= 3) ? count : (count << 1); |
372 | ? count : (count << 1); | ||
373 | } | 342 | } |
374 | 343 | ||
375 | /* These are in kernel/dma.c: */ | 344 | /* These are in kernel/dma.c: */ |
diff --git a/include/asm-powerpc/mediabay.h b/include/asm-powerpc/mediabay.h index 9daa3252d7b6..de83fe196309 100644 --- a/include/asm-powerpc/mediabay.h +++ b/include/asm-powerpc/mediabay.h | |||
@@ -18,14 +18,14 @@ | |||
18 | #define MB_NO 7 /* media bay contains nothing */ | 18 | #define MB_NO 7 /* media bay contains nothing */ |
19 | 19 | ||
20 | int check_media_bay(struct device_node *which_bay, int what); | 20 | int check_media_bay(struct device_node *which_bay, int what); |
21 | int check_media_bay_by_base(unsigned long base, int what); | ||
22 | 21 | ||
23 | /* Number of bays in the machine or 0 */ | 22 | /* Number of bays in the machine or 0 */ |
24 | extern int media_bay_count; | 23 | extern int media_bay_count; |
25 | 24 | ||
26 | /* called by pmac-ide.c to register IDE controller for media bay */ | 25 | int check_media_bay_by_base(unsigned long base, int what); |
27 | extern int media_bay_set_ide_infos(struct device_node* which_bay, | 26 | /* called by IDE PMAC host driver to register IDE controller for media bay */ |
28 | unsigned long base, int irq, int index); | 27 | int media_bay_set_ide_infos(struct device_node *which_bay, unsigned long base, |
28 | int irq, int index); | ||
29 | 29 | ||
30 | #endif /* __KERNEL__ */ | 30 | #endif /* __KERNEL__ */ |
31 | #endif /* _PPC_MEDIABAY_H */ | 31 | #endif /* _PPC_MEDIABAY_H */ |
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h index f6dfce025adf..748b35ab37b5 100644 --- a/include/asm-powerpc/paca.h +++ b/include/asm-powerpc/paca.h | |||
@@ -115,8 +115,6 @@ struct paca_struct { | |||
115 | u64 system_time; /* accumulated system TB ticks */ | 115 | u64 system_time; /* accumulated system TB ticks */ |
116 | u64 startpurr; /* PURR/TB value snapshot */ | 116 | u64 startpurr; /* PURR/TB value snapshot */ |
117 | u64 startspurr; /* SPURR value snapshot */ | 117 | u64 startspurr; /* SPURR value snapshot */ |
118 | u64 purrdelta; /* FIXME: document */ | ||
119 | u64 spurrdelta; /* FIXME: document */ | ||
120 | }; | 118 | }; |
121 | 119 | ||
122 | extern struct paca_struct paca[]; | 120 | extern struct paca_struct paca[]; |
diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h index 967930b82ed3..fda98715cd35 100644 --- a/include/asm-powerpc/ps3av.h +++ b/include/asm-powerpc/ps3av.h | |||
@@ -310,19 +310,25 @@ | |||
310 | #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ | 310 | #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ |
311 | #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ | 311 | #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ |
312 | 312 | ||
313 | #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 2 /* 480p */ | ||
314 | #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 1 /* 480i */ | ||
315 | #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 7 /* 576p */ | ||
316 | #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 6 /* 576i */ | ||
317 | |||
318 | #define PS3AV_REGION_60 0x01 | ||
319 | #define PS3AV_REGION_50 0x02 | ||
320 | #define PS3AV_REGION_RGB 0x10 | ||
321 | |||
322 | #define get_status(buf) (((__u32 *)buf)[2]) | ||
323 | #define PS3AV_HDR_SIZE 4 /* version + size */ | ||
324 | 313 | ||
325 | /* for video mode */ | 314 | /* for video mode */ |
315 | enum ps3av_mode_num { | ||
316 | PS3AV_MODE_AUTO = 0, | ||
317 | PS3AV_MODE_480I = 1, | ||
318 | PS3AV_MODE_480P = 2, | ||
319 | PS3AV_MODE_720P60 = 3, | ||
320 | PS3AV_MODE_1080I60 = 4, | ||
321 | PS3AV_MODE_1080P60 = 5, | ||
322 | PS3AV_MODE_576I = 6, | ||
323 | PS3AV_MODE_576P = 7, | ||
324 | PS3AV_MODE_720P50 = 8, | ||
325 | PS3AV_MODE_1080I50 = 9, | ||
326 | PS3AV_MODE_1080P50 = 10, | ||
327 | PS3AV_MODE_WXGA = 11, | ||
328 | PS3AV_MODE_SXGA = 12, | ||
329 | PS3AV_MODE_WUXGA = 13, | ||
330 | }; | ||
331 | |||
326 | #define PS3AV_MODE_MASK 0x000F | 332 | #define PS3AV_MODE_MASK 0x000F |
327 | #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */ | 333 | #define PS3AV_MODE_HDCP_OFF 0x1000 /* Retail PS3 product doesn't support this */ |
328 | #define PS3AV_MODE_DITHER 0x0800 | 334 | #define PS3AV_MODE_DITHER 0x0800 |
@@ -333,6 +339,19 @@ | |||
333 | #define PS3AV_MODE_RGB 0x0020 | 339 | #define PS3AV_MODE_RGB 0x0020 |
334 | 340 | ||
335 | 341 | ||
342 | #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 PS3AV_MODE_480P | ||
343 | #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 PS3AV_MODE_480I | ||
344 | #define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 PS3AV_MODE_576P | ||
345 | #define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 PS3AV_MODE_576I | ||
346 | |||
347 | #define PS3AV_REGION_60 0x01 | ||
348 | #define PS3AV_REGION_50 0x02 | ||
349 | #define PS3AV_REGION_RGB 0x10 | ||
350 | |||
351 | #define get_status(buf) (((__u32 *)buf)[2]) | ||
352 | #define PS3AV_HDR_SIZE 4 /* version + size */ | ||
353 | |||
354 | |||
336 | /** command packet structure **/ | 355 | /** command packet structure **/ |
337 | struct ps3av_send_hdr { | 356 | struct ps3av_send_hdr { |
338 | u16 version; | 357 | u16 version; |
@@ -713,8 +732,6 @@ extern int ps3av_set_video_mode(u32); | |||
713 | extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); | 732 | extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); |
714 | extern int ps3av_get_auto_mode(void); | 733 | extern int ps3av_get_auto_mode(void); |
715 | extern int ps3av_get_mode(void); | 734 | extern int ps3av_get_mode(void); |
716 | extern int ps3av_get_scanmode(int); | ||
717 | extern int ps3av_get_refresh_rate(int); | ||
718 | extern int ps3av_video_mode2res(u32, u32 *, u32 *); | 735 | extern int ps3av_video_mode2res(u32, u32 *, u32 *); |
719 | extern int ps3av_video_mute(int); | 736 | extern int ps3av_video_mute(int); |
720 | extern int ps3av_audio_mute(int); | 737 | extern int ps3av_audio_mute(int); |
diff --git a/include/asm-s390/cputime.h b/include/asm-s390/cputime.h index 4b3ef7cad115..133ce054fc89 100644 --- a/include/asm-s390/cputime.h +++ b/include/asm-s390/cputime.h | |||
@@ -54,6 +54,7 @@ __div(unsigned long long n, unsigned int base) | |||
54 | #define cputime_lt(__a, __b) ((__a) < (__b)) | 54 | #define cputime_lt(__a, __b) ((__a) < (__b)) |
55 | #define cputime_le(__a, __b) ((__a) <= (__b)) | 55 | #define cputime_le(__a, __b) ((__a) <= (__b)) |
56 | #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) | 56 | #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) |
57 | #define cputime_to_scaled(__ct) (__ct) | ||
57 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) | 58 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) |
58 | 59 | ||
59 | #define cputime64_zero (0ULL) | 60 | #define cputime64_zero (0ULL) |
diff --git a/include/asm-sh/delay.h b/include/asm-sh/delay.h index 031db84f2aa1..d5d464041003 100644 --- a/include/asm-sh/delay.h +++ b/include/asm-sh/delay.h | |||
@@ -12,7 +12,7 @@ extern void __bad_ndelay(void); | |||
12 | 12 | ||
13 | extern void __udelay(unsigned long usecs); | 13 | extern void __udelay(unsigned long usecs); |
14 | extern void __ndelay(unsigned long nsecs); | 14 | extern void __ndelay(unsigned long nsecs); |
15 | extern void __const_udelay(unsigned long usecs); | 15 | extern void __const_udelay(unsigned long xloops); |
16 | extern void __delay(unsigned long loops); | 16 | extern void __delay(unsigned long loops); |
17 | 17 | ||
18 | #ifdef CONFIG_SUPERH32 | 18 | #ifdef CONFIG_SUPERH32 |
diff --git a/include/asm-sh/unistd_32.h b/include/asm-sh/unistd_32.h index b182b1cb05fd..433fd1b48fa2 100644 --- a/include/asm-sh/unistd_32.h +++ b/include/asm-sh/unistd_32.h | |||
@@ -330,7 +330,7 @@ | |||
330 | #define __NR_epoll_pwait 319 | 330 | #define __NR_epoll_pwait 319 |
331 | #define __NR_utimensat 320 | 331 | #define __NR_utimensat 320 |
332 | #define __NR_signalfd 321 | 332 | #define __NR_signalfd 321 |
333 | #define __NR_timerfd 322 | 333 | /* #define __NR_timerfd 322 removed */ |
334 | #define __NR_eventfd 323 | 334 | #define __NR_eventfd 323 |
335 | #define __NR_fallocate 324 | 335 | #define __NR_fallocate 324 |
336 | 336 | ||
diff --git a/include/asm-sh/unistd_64.h b/include/asm-sh/unistd_64.h index 944511882cac..108d2ba897fe 100644 --- a/include/asm-sh/unistd_64.h +++ b/include/asm-sh/unistd_64.h | |||
@@ -370,7 +370,7 @@ | |||
370 | #define __NR_epoll_pwait 347 | 370 | #define __NR_epoll_pwait 347 |
371 | #define __NR_utimensat 348 | 371 | #define __NR_utimensat 348 |
372 | #define __NR_signalfd 349 | 372 | #define __NR_signalfd 349 |
373 | #define __NR_timerfd 350 | 373 | /* #define __NR_timerfd 350 removed */ |
374 | #define __NR_eventfd 351 | 374 | #define __NR_eventfd 351 |
375 | #define __NR_fallocate 352 | 375 | #define __NR_fallocate 352 |
376 | 376 | ||
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 0decdf763716..2338a0276377 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
@@ -327,11 +327,13 @@ | |||
327 | #define __NR_epoll_pwait 309 | 327 | #define __NR_epoll_pwait 309 |
328 | #define __NR_utimensat 310 | 328 | #define __NR_utimensat 310 |
329 | #define __NR_signalfd 311 | 329 | #define __NR_signalfd 311 |
330 | #define __NR_timerfd 312 | 330 | #define __NR_timerfd_create 312 |
331 | #define __NR_eventfd 313 | 331 | #define __NR_eventfd 313 |
332 | #define __NR_fallocate 314 | 332 | #define __NR_fallocate 314 |
333 | #define __NR_timerfd_settime 315 | ||
334 | #define __NR_timerfd_gettime 316 | ||
333 | 335 | ||
334 | #define NR_SYSCALLS 315 | 336 | #define NR_SYSCALLS 317 |
335 | 337 | ||
336 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, | 338 | /* Sparc 32-bit only has the "setresuid32", "getresuid32" variants, |
337 | * it never had the plain ones and there is no value to adding those | 339 | * it never had the plain ones and there is no value to adding those |
diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h index c299b853b5ba..b6ece223562d 100644 --- a/include/asm-sparc64/io.h +++ b/include/asm-sparc64/io.h | |||
@@ -16,7 +16,7 @@ | |||
16 | /* BIO layer definitions. */ | 16 | /* BIO layer definitions. */ |
17 | extern unsigned long kern_base, kern_size; | 17 | extern unsigned long kern_base, kern_size; |
18 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) | 18 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) |
19 | #define BIO_VMERGE_BOUNDARY 8192 | 19 | #define BIO_VMERGE_BOUNDARY 0 |
20 | 20 | ||
21 | static inline u8 _inb(unsigned long addr) | 21 | static inline u8 _inb(unsigned long addr) |
22 | { | 22 | { |
diff --git a/include/asm-sparc64/timex.h b/include/asm-sparc64/timex.h index 2a5e4ebaad80..c622535c4560 100644 --- a/include/asm-sparc64/timex.h +++ b/include/asm-sparc64/timex.h | |||
@@ -14,10 +14,6 @@ | |||
14 | typedef unsigned long cycles_t; | 14 | typedef unsigned long cycles_t; |
15 | #define get_cycles() tick_ops->get_tick() | 15 | #define get_cycles() tick_ops->get_tick() |
16 | 16 | ||
17 | #define ARCH_HAS_READ_CURRENT_TIMER 1 | 17 | #define ARCH_HAS_READ_CURRENT_TIMER |
18 | #define read_current_timer(timer_val_p) \ | ||
19 | ({ *timer_val_p = tick_ops->get_tick(); \ | ||
20 | 0; \ | ||
21 | }) | ||
22 | 18 | ||
23 | #endif | 19 | #endif |
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index cb751b4d0f56..77559da0ea3f 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
@@ -329,11 +329,13 @@ | |||
329 | #define __NR_epoll_pwait 309 | 329 | #define __NR_epoll_pwait 309 |
330 | #define __NR_utimensat 310 | 330 | #define __NR_utimensat 310 |
331 | #define __NR_signalfd 311 | 331 | #define __NR_signalfd 311 |
332 | #define __NR_timerfd 312 | 332 | #define __NR_timerfd_create 312 |
333 | #define __NR_eventfd 313 | 333 | #define __NR_eventfd 313 |
334 | #define __NR_fallocate 314 | 334 | #define __NR_fallocate 314 |
335 | #define __NR_timerfd_settime 315 | ||
336 | #define __NR_timerfd_gettime 316 | ||
335 | 337 | ||
336 | #define NR_SYSCALLS 315 | 338 | #define NR_SYSCALLS 317 |
337 | 339 | ||
338 | #ifdef __KERNEL__ | 340 | #ifdef __KERNEL__ |
339 | /* sysconf options, for SunOS compatibility */ | 341 | /* sysconf options, for SunOS compatibility */ |
diff --git a/include/asm-v850/io.h b/include/asm-v850/io.h index cc364fcbec10..cdad251fba9f 100644 --- a/include/asm-v850/io.h +++ b/include/asm-v850/io.h | |||
@@ -122,8 +122,6 @@ outsl (unsigned long port, const void *src, unsigned long count) | |||
122 | #endif | 122 | #endif |
123 | 123 | ||
124 | /* Conversion between virtual and physical mappings. */ | 124 | /* Conversion between virtual and physical mappings. */ |
125 | #define mm_ptov(addr) ((void *)__phys_to_virt (addr)) | ||
126 | #define mm_vtop(addr) ((unsigned long)__virt_to_phys (addr)) | ||
127 | #define phys_to_virt(addr) ((void *)__phys_to_virt (addr)) | 125 | #define phys_to_virt(addr) ((void *)__phys_to_virt (addr)) |
128 | #define virt_to_phys(addr) ((unsigned long)__virt_to_phys (addr)) | 126 | #define virt_to_phys(addr) ((unsigned long)__virt_to_phys (addr)) |
129 | 127 | ||
diff --git a/include/asm-x86/delay.h b/include/asm-x86/delay.h index d11d47fc1a0e..409a649204aa 100644 --- a/include/asm-x86/delay.h +++ b/include/asm-x86/delay.h | |||
@@ -13,7 +13,7 @@ extern void __bad_ndelay(void); | |||
13 | 13 | ||
14 | extern void __udelay(unsigned long usecs); | 14 | extern void __udelay(unsigned long usecs); |
15 | extern void __ndelay(unsigned long nsecs); | 15 | extern void __ndelay(unsigned long nsecs); |
16 | extern void __const_udelay(unsigned long usecs); | 16 | extern void __const_udelay(unsigned long xloops); |
17 | extern void __delay(unsigned long loops); | 17 | extern void __delay(unsigned long loops); |
18 | 18 | ||
19 | /* 0x10c7 is 2**32 / 1000000 (rounded up) */ | 19 | /* 0x10c7 is 2**32 / 1000000 (rounded up) */ |
diff --git a/include/asm-x86/timex.h b/include/asm-x86/timex.h index 27cfd6c599ba..43e5a78500c5 100644 --- a/include/asm-x86/timex.h +++ b/include/asm-x86/timex.h | |||
@@ -14,7 +14,6 @@ | |||
14 | #endif | 14 | #endif |
15 | #define CLOCK_TICK_RATE PIT_TICK_RATE | 15 | #define CLOCK_TICK_RATE PIT_TICK_RATE |
16 | 16 | ||
17 | extern int read_current_timer(unsigned long *timer_value); | 17 | #define ARCH_HAS_READ_CURRENT_TIMER |
18 | #define ARCH_HAS_READ_CURRENT_TIMER 1 | ||
19 | 18 | ||
20 | #endif | 19 | #endif |
diff --git a/include/linux/ac97_codec.h b/include/linux/ac97_codec.h index 22eb9367235a..0260c3e79fdd 100644 --- a/include/linux/ac97_codec.h +++ b/include/linux/ac97_codec.h | |||
@@ -326,11 +326,7 @@ struct ac97_ops | |||
326 | #define AC97_DEFAULT_POWER_OFF 4 /* Needs warm reset to power up */ | 326 | #define AC97_DEFAULT_POWER_OFF 4 /* Needs warm reset to power up */ |
327 | }; | 327 | }; |
328 | 328 | ||
329 | extern int ac97_read_proc (char *page_out, char **start, off_t off, | ||
330 | int count, int *eof, void *data); | ||
331 | extern int ac97_probe_codec(struct ac97_codec *); | 329 | extern int ac97_probe_codec(struct ac97_codec *); |
332 | extern unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate); | ||
333 | extern unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate); | ||
334 | 330 | ||
335 | extern struct ac97_codec *ac97_alloc_codec(void); | 331 | extern struct ac97_codec *ac97_alloc_codec(void); |
336 | extern void ac97_release_codec(struct ac97_codec *codec); | 332 | extern void ac97_release_codec(struct ac97_codec *codec); |
@@ -363,7 +359,4 @@ struct ac97_quirk { | |||
363 | int type; /* quirk type above */ | 359 | int type; /* quirk type above */ |
364 | }; | 360 | }; |
365 | 361 | ||
366 | struct pci_dev; | ||
367 | extern int ac97_tune_hardware(struct pci_dev *pdev, struct ac97_quirk *quirk, int override); | ||
368 | |||
369 | #endif /* _AC97_CODEC_H_ */ | 362 | #endif /* _AC97_CODEC_H_ */ |
diff --git a/include/linux/acct.h b/include/linux/acct.h index 302eb727ecb8..e8cae54e8d88 100644 --- a/include/linux/acct.h +++ b/include/linux/acct.h | |||
@@ -173,7 +173,11 @@ typedef struct acct acct_t; | |||
173 | static inline u32 jiffies_to_AHZ(unsigned long x) | 173 | static inline u32 jiffies_to_AHZ(unsigned long x) |
174 | { | 174 | { |
175 | #if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0 | 175 | #if (TICK_NSEC % (NSEC_PER_SEC / AHZ)) == 0 |
176 | # if HZ < AHZ | ||
177 | return x * (AHZ / HZ); | ||
178 | # else | ||
176 | return x / (HZ / AHZ); | 179 | return x / (HZ / AHZ); |
180 | # endif | ||
177 | #else | 181 | #else |
178 | u64 tmp = (u64)x * TICK_NSEC; | 182 | u64 tmp = (u64)x * TICK_NSEC; |
179 | do_div(tmp, (NSEC_PER_SEC / AHZ)); | 183 | do_div(tmp, (NSEC_PER_SEC / AHZ)); |
diff --git a/include/linux/compat.h b/include/linux/compat.h index ae0a483bef9b..a671dbff7a1f 100644 --- a/include/linux/compat.h +++ b/include/linux/compat.h | |||
@@ -257,16 +257,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | |||
257 | /* | 257 | /* |
258 | * epoll (fs/eventpoll.c) compat bits follow ... | 258 | * epoll (fs/eventpoll.c) compat bits follow ... |
259 | */ | 259 | */ |
260 | #ifndef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
261 | struct epoll_event; | 260 | struct epoll_event; |
262 | #define compat_epoll_event epoll_event | 261 | #define compat_epoll_event epoll_event |
263 | #else | ||
264 | asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd, | ||
265 | struct compat_epoll_event __user *event); | ||
266 | asmlinkage long compat_sys_epoll_wait(int epfd, | ||
267 | struct compat_epoll_event __user *events, | ||
268 | int maxevents, int timeout); | ||
269 | #endif | ||
270 | asmlinkage long compat_sys_epoll_pwait(int epfd, | 262 | asmlinkage long compat_sys_epoll_pwait(int epfd, |
271 | struct compat_epoll_event __user *events, | 263 | struct compat_epoll_event __user *events, |
272 | int maxevents, int timeout, | 264 | int maxevents, int timeout, |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 56bd421c1208..109734bf6377 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | /* Fixed constants first: */ | 22 | /* Fixed constants first: */ |
23 | #undef NR_OPEN | 23 | #undef NR_OPEN |
24 | #define NR_OPEN (1024*1024) /* Absolute upper limit on fd num */ | 24 | extern int sysctl_nr_open; |
25 | #define INR_OPEN 1024 /* Initial setting for nfile rlimits */ | 25 | #define INR_OPEN 1024 /* Initial setting for nfile rlimits */ |
26 | 26 | ||
27 | #define BLOCK_SIZE_BITS 10 | 27 | #define BLOCK_SIZE_BITS 10 |
@@ -977,7 +977,6 @@ extern int send_sigurg(struct fown_struct *fown); | |||
977 | extern struct list_head super_blocks; | 977 | extern struct list_head super_blocks; |
978 | extern spinlock_t sb_lock; | 978 | extern spinlock_t sb_lock; |
979 | 979 | ||
980 | #define sb_entry(list) list_entry((list), struct super_block, s_list) | ||
981 | #define S_BIAS (1<<30) | 980 | #define S_BIAS (1<<30) |
982 | struct super_block { | 981 | struct super_block { |
983 | struct list_head s_list; /* Keep this first */ | 982 | struct list_head s_list; /* Keep this first */ |
@@ -1279,8 +1278,10 @@ struct super_operations { | |||
1279 | * | 1278 | * |
1280 | * Two bits are used for locking and completion notification, I_LOCK and I_SYNC. | 1279 | * Two bits are used for locking and completion notification, I_LOCK and I_SYNC. |
1281 | * | 1280 | * |
1282 | * I_DIRTY_SYNC Inode itself is dirty. | 1281 | * I_DIRTY_SYNC Inode is dirty, but doesn't have to be written on |
1283 | * I_DIRTY_DATASYNC Data-related inode changes pending | 1282 | * fdatasync(). i_atime is the usual cause. |
1283 | * I_DIRTY_DATASYNC Inode is dirty and must be written on fdatasync(), f.e. | ||
1284 | * because i_size changed. | ||
1284 | * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. | 1285 | * I_DIRTY_PAGES Inode has dirty pages. Inode itself may be clean. |
1285 | * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both | 1286 | * I_NEW get_new_inode() sets i_state to I_LOCK|I_NEW. Both |
1286 | * are cleared by unlock_new_inode(), called from iget(). | 1287 | * are cleared by unlock_new_inode(), called from iget(). |
@@ -1312,8 +1313,6 @@ struct super_operations { | |||
1312 | * purpose reduces latency and prevents some filesystem- | 1313 | * purpose reduces latency and prevents some filesystem- |
1313 | * specific deadlocks. | 1314 | * specific deadlocks. |
1314 | * | 1315 | * |
1315 | * Q: Why does I_DIRTY_DATASYNC exist? It appears as if it could be replaced | ||
1316 | * by (I_DIRTY_SYNC|I_DIRTY_PAGES). | ||
1317 | * Q: What is the difference between I_WILL_FREE and I_FREEING? | 1316 | * Q: What is the difference between I_WILL_FREE and I_FREEING? |
1318 | * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on | 1317 | * Q: igrab() only checks on (I_FREEING|I_WILL_FREE). Should it also check on |
1319 | * I_CLEAR? If not, why? | 1318 | * I_CLEAR? If not, why? |
@@ -2113,6 +2112,7 @@ struct ctl_table; | |||
2113 | int proc_nr_files(struct ctl_table *table, int write, struct file *filp, | 2112 | int proc_nr_files(struct ctl_table *table, int write, struct file *filp, |
2114 | void __user *buffer, size_t *lenp, loff_t *ppos); | 2113 | void __user *buffer, size_t *lenp, loff_t *ppos); |
2115 | 2114 | ||
2115 | int get_filesystem_list(char * buf); | ||
2116 | 2116 | ||
2117 | #endif /* __KERNEL__ */ | 2117 | #endif /* __KERNEL__ */ |
2118 | #endif /* _LINUX_FS_H */ | 2118 | #endif /* _LINUX_FS_H */ |
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h index 2bd31fa623b6..d4b7c4ac72e6 100644 --- a/include/linux/fsnotify.h +++ b/include/linux/fsnotify.h | |||
@@ -92,6 +92,14 @@ static inline void fsnotify_inoderemove(struct inode *inode) | |||
92 | } | 92 | } |
93 | 93 | ||
94 | /* | 94 | /* |
95 | * fsnotify_link_count - inode's link count changed | ||
96 | */ | ||
97 | static inline void fsnotify_link_count(struct inode *inode) | ||
98 | { | ||
99 | inotify_inode_queue_event(inode, IN_ATTRIB, 0, NULL, NULL); | ||
100 | } | ||
101 | |||
102 | /* | ||
95 | * fsnotify_create - 'name' was linked in | 103 | * fsnotify_create - 'name' was linked in |
96 | */ | 104 | */ |
97 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | 105 | static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) |
@@ -103,6 +111,20 @@ static inline void fsnotify_create(struct inode *inode, struct dentry *dentry) | |||
103 | } | 111 | } |
104 | 112 | ||
105 | /* | 113 | /* |
114 | * fsnotify_link - new hardlink in 'inode' directory | ||
115 | * Note: We have to pass also the linked inode ptr as some filesystems leave | ||
116 | * new_dentry->d_inode NULL and instantiate inode pointer later | ||
117 | */ | ||
118 | static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry) | ||
119 | { | ||
120 | inode_dir_notify(dir, DN_CREATE); | ||
121 | inotify_inode_queue_event(dir, IN_CREATE, 0, new_dentry->d_name.name, | ||
122 | inode); | ||
123 | fsnotify_link_count(inode); | ||
124 | audit_inode_child(new_dentry->d_name.name, new_dentry, dir); | ||
125 | } | ||
126 | |||
127 | /* | ||
106 | * fsnotify_mkdir - directory 'name' was created | 128 | * fsnotify_mkdir - directory 'name' was created |
107 | */ | 129 | */ |
108 | static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) | 130 | static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry) |
diff --git a/include/linux/hash.h b/include/linux/hash.h index acf17bb8e7f9..06d25c189cc5 100644 --- a/include/linux/hash.h +++ b/include/linux/hash.h | |||
@@ -1,6 +1,6 @@ | |||
1 | #ifndef _LINUX_HASH_H | 1 | #ifndef _LINUX_HASH_H |
2 | #define _LINUX_HASH_H | 2 | #define _LINUX_HASH_H |
3 | /* Fast hashing routine for a long. | 3 | /* Fast hashing routine for ints, longs and pointers. |
4 | (C) 2002 William Lee Irwin III, IBM */ | 4 | (C) 2002 William Lee Irwin III, IBM */ |
5 | 5 | ||
6 | /* | 6 | /* |
@@ -13,23 +13,30 @@ | |||
13 | * them can use shifts and additions instead of multiplications for | 13 | * them can use shifts and additions instead of multiplications for |
14 | * machines where multiplications are slow. | 14 | * machines where multiplications are slow. |
15 | */ | 15 | */ |
16 | #if BITS_PER_LONG == 32 | 16 | |
17 | #include <asm/types.h> | ||
18 | |||
17 | /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ | 19 | /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ |
18 | #define GOLDEN_RATIO_PRIME 0x9e370001UL | 20 | #define GOLDEN_RATIO_PRIME_32 0x9e370001UL |
19 | #elif BITS_PER_LONG == 64 | ||
20 | /* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ | 21 | /* 2^63 + 2^61 - 2^57 + 2^54 - 2^51 - 2^18 + 1 */ |
21 | #define GOLDEN_RATIO_PRIME 0x9e37fffffffc0001UL | 22 | #define GOLDEN_RATIO_PRIME_64 0x9e37fffffffc0001UL |
23 | |||
24 | #if BITS_PER_LONG == 32 | ||
25 | #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_32 | ||
26 | #define hash_long(val, bits) hash_32(val, bits) | ||
27 | #elif BITS_PER_LONG == 64 | ||
28 | #define hash_long(val, bits) hash_64(val, bits) | ||
29 | #define GOLDEN_RATIO_PRIME GOLDEN_RATIO_PRIME_64 | ||
22 | #else | 30 | #else |
23 | #error Define GOLDEN_RATIO_PRIME for your wordsize. | 31 | #error Wordsize not 32 or 64 |
24 | #endif | 32 | #endif |
25 | 33 | ||
26 | static inline unsigned long hash_long(unsigned long val, unsigned int bits) | 34 | static inline u64 hash_64(u64 val, unsigned int bits) |
27 | { | 35 | { |
28 | unsigned long hash = val; | 36 | u64 hash = val; |
29 | 37 | ||
30 | #if BITS_PER_LONG == 64 | ||
31 | /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ | 38 | /* Sigh, gcc can't optimise this alone like it does for 32 bits. */ |
32 | unsigned long n = hash; | 39 | u64 n = hash; |
33 | n <<= 18; | 40 | n <<= 18; |
34 | hash -= n; | 41 | hash -= n; |
35 | n <<= 33; | 42 | n <<= 33; |
@@ -42,15 +49,20 @@ static inline unsigned long hash_long(unsigned long val, unsigned int bits) | |||
42 | hash += n; | 49 | hash += n; |
43 | n <<= 2; | 50 | n <<= 2; |
44 | hash += n; | 51 | hash += n; |
45 | #else | 52 | |
53 | /* High bits are more random, so use them. */ | ||
54 | return hash >> (64 - bits); | ||
55 | } | ||
56 | |||
57 | static inline u32 hash_32(u32 val, unsigned int bits) | ||
58 | { | ||
46 | /* On some cpus multiply is faster, on others gcc will do shifts */ | 59 | /* On some cpus multiply is faster, on others gcc will do shifts */ |
47 | hash *= GOLDEN_RATIO_PRIME; | 60 | u32 hash = val * GOLDEN_RATIO_PRIME_32; |
48 | #endif | ||
49 | 61 | ||
50 | /* High bits are more random, so use them. */ | 62 | /* High bits are more random, so use them. */ |
51 | return hash >> (BITS_PER_LONG - bits); | 63 | return hash >> (32 - bits); |
52 | } | 64 | } |
53 | 65 | ||
54 | static inline unsigned long hash_ptr(void *ptr, unsigned int bits) | 66 | static inline unsigned long hash_ptr(void *ptr, unsigned int bits) |
55 | { | 67 | { |
56 | return hash_long((unsigned long)ptr, bits); | 68 | return hash_long((unsigned long)ptr, bits); |
diff --git a/include/linux/i2c/pca9539.h b/include/linux/i2c/pca953x.h index 611d84ab7a30..3c7361217df8 100644 --- a/include/linux/i2c/pca9539.h +++ b/include/linux/i2c/pca953x.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* platform data for the PCA9539 16-bit I/O expander driver */ | 1 | /* platform data for the PCA9539 16-bit I/O expander driver */ |
2 | 2 | ||
3 | struct pca9539_platform_data { | 3 | struct pca953x_platform_data { |
4 | /* number of the first GPIO */ | 4 | /* number of the first GPIO */ |
5 | unsigned gpio_base; | 5 | unsigned gpio_base; |
6 | 6 | ||
diff --git a/include/linux/ide.h b/include/linux/ide.h index 367c17084a28..acec99da832d 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -115,10 +115,6 @@ typedef unsigned char byte; /* used everywhere */ | |||
115 | #define SATA_ERROR_OFFSET (1) | 115 | #define SATA_ERROR_OFFSET (1) |
116 | #define SATA_CONTROL_OFFSET (2) | 116 | #define SATA_CONTROL_OFFSET (2) |
117 | 117 | ||
118 | #define SATA_MISC_OFFSET (0) | ||
119 | #define SATA_PHY_OFFSET (1) | ||
120 | #define SATA_IEN_OFFSET (2) | ||
121 | |||
122 | /* | 118 | /* |
123 | * Our Physical Region Descriptor (PRD) table should be large enough | 119 | * Our Physical Region Descriptor (PRD) table should be large enough |
124 | * to handle the biggest I/O request we are likely to see. Since requests | 120 | * to handle the biggest I/O request we are likely to see. Since requests |
@@ -173,7 +169,7 @@ enum { ide_unknown, ide_generic, ide_pci, | |||
173 | ide_rz1000, ide_trm290, | 169 | ide_rz1000, ide_trm290, |
174 | ide_cmd646, ide_cy82c693, ide_4drives, | 170 | ide_cmd646, ide_cy82c693, ide_4drives, |
175 | ide_pmac, ide_etrax100, ide_acorn, | 171 | ide_pmac, ide_etrax100, ide_acorn, |
176 | ide_au1xxx, ide_forced | 172 | ide_au1xxx, ide_palm3710, ide_forced |
177 | }; | 173 | }; |
178 | 174 | ||
179 | typedef u8 hwif_chipset_t; | 175 | typedef u8 hwif_chipset_t; |
@@ -198,17 +194,6 @@ struct ide_drive_s; | |||
198 | int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *), | 194 | int ide_register_hw(hw_regs_t *, void (*)(struct ide_drive_s *), |
199 | struct hwif_s **); | 195 | struct hwif_s **); |
200 | 196 | ||
201 | void ide_setup_ports( hw_regs_t *hw, | ||
202 | unsigned long base, | ||
203 | int *offsets, | ||
204 | unsigned long ctrl, | ||
205 | unsigned long intr, | ||
206 | ide_ack_intr_t *ack_intr, | ||
207 | #if 0 | ||
208 | ide_io_ops_t *iops, | ||
209 | #endif | ||
210 | int irq); | ||
211 | |||
212 | static inline void ide_std_init_ports(hw_regs_t *hw, | 197 | static inline void ide_std_init_ports(hw_regs_t *hw, |
213 | unsigned long io_addr, | 198 | unsigned long io_addr, |
214 | unsigned long ctl_addr) | 199 | unsigned long ctl_addr) |
@@ -473,7 +458,6 @@ typedef struct hwif_s { | |||
473 | /* task file registers for pata and sata */ | 458 | /* task file registers for pata and sata */ |
474 | unsigned long io_ports[IDE_NR_PORTS]; | 459 | unsigned long io_ports[IDE_NR_PORTS]; |
475 | unsigned long sata_scr[SATA_NR_PORTS]; | 460 | unsigned long sata_scr[SATA_NR_PORTS]; |
476 | unsigned long sata_misc[SATA_NR_PORTS]; | ||
477 | 461 | ||
478 | ide_drive_t drives[MAX_DRIVES]; /* drive info */ | 462 | ide_drive_t drives[MAX_DRIVES]; /* drive info */ |
479 | 463 | ||
@@ -1014,7 +998,8 @@ extern int __ide_pci_register_driver(struct pci_driver *driver, struct module *o | |||
1014 | void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *); | 998 | void ide_pci_setup_ports(struct pci_dev *, const struct ide_port_info *, int, u8 *); |
1015 | void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); | 999 | void ide_setup_pci_noise(struct pci_dev *, const struct ide_port_info *); |
1016 | 1000 | ||
1017 | #ifdef CONFIG_BLK_DEV_IDEDMA_PCI | 1001 | /* FIXME: palm_bk3710 uses BLK_DEV_IDEDMA_PCI without BLK_DEV_IDEPCI! */ |
1002 | #if defined(CONFIG_BLK_DEV_IDEPCI) && defined(CONFIG_BLK_DEV_IDEDMA_PCI) | ||
1018 | void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); | 1003 | void ide_hwif_setup_dma(ide_hwif_t *, const struct ide_port_info *); |
1019 | #else | 1004 | #else |
1020 | static inline void ide_hwif_setup_dma(ide_hwif_t *hwif, | 1005 | static inline void ide_hwif_setup_dma(ide_hwif_t *hwif, |
@@ -1324,4 +1309,25 @@ static inline void ide_set_irq(ide_drive_t *drive, int on) | |||
1324 | drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG); | 1309 | drive->hwif->OUTB(drive->ctl | (on ? 0 : 2), IDE_CONTROL_REG); |
1325 | } | 1310 | } |
1326 | 1311 | ||
1312 | static inline u8 ide_read_status(ide_drive_t *drive) | ||
1313 | { | ||
1314 | ide_hwif_t *hwif = drive->hwif; | ||
1315 | |||
1316 | return hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); | ||
1317 | } | ||
1318 | |||
1319 | static inline u8 ide_read_altstatus(ide_drive_t *drive) | ||
1320 | { | ||
1321 | ide_hwif_t *hwif = drive->hwif; | ||
1322 | |||
1323 | return hwif->INB(hwif->io_ports[IDE_CONTROL_OFFSET]); | ||
1324 | } | ||
1325 | |||
1326 | static inline u8 ide_read_error(ide_drive_t *drive) | ||
1327 | { | ||
1328 | ide_hwif_t *hwif = drive->hwif; | ||
1329 | |||
1330 | return hwif->INB(hwif->io_ports[IDE_ERROR_OFFSET]); | ||
1331 | } | ||
1332 | |||
1327 | #endif /* _IDE_H */ | 1333 | #endif /* _IDE_H */ |
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index c3db4a00f1fa..dea7598aeff4 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h | |||
@@ -444,4 +444,6 @@ static inline void init_irq_proc(void) | |||
444 | } | 444 | } |
445 | #endif | 445 | #endif |
446 | 446 | ||
447 | int show_interrupts(struct seq_file *p, void *v); | ||
448 | |||
447 | #endif | 449 | #endif |
diff --git a/include/linux/isdn.h b/include/linux/isdn.h index d0ecc8eebfbf..9cb2855bb170 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h | |||
@@ -507,7 +507,6 @@ typedef struct modem_info { | |||
507 | struct ktermios normal_termios; /* For saving termios structs */ | 507 | struct ktermios normal_termios; /* For saving termios structs */ |
508 | struct ktermios callout_termios; | 508 | struct ktermios callout_termios; |
509 | wait_queue_head_t open_wait, close_wait; | 509 | wait_queue_head_t open_wait, close_wait; |
510 | struct semaphore write_sem; | ||
511 | spinlock_t readlock; | 510 | spinlock_t readlock; |
512 | } modem_info; | 511 | } modem_info; |
513 | 512 | ||
diff --git a/include/linux/jbd.h b/include/linux/jbd.h index d9ecd13393b0..b18fd3b9b835 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/lockdep.h> | 33 | #include <linux/lockdep.h> |
34 | 34 | ||
35 | #include <asm/semaphore.h> | 35 | #include <asm/semaphore.h> |
36 | #endif | ||
37 | 36 | ||
38 | #define journal_oom_retry 1 | 37 | #define journal_oom_retry 1 |
39 | 38 | ||
@@ -84,7 +83,6 @@ static inline void jbd_free(void *ptr, size_t size) | |||
84 | 83 | ||
85 | #define JFS_MIN_JOURNAL_BLOCKS 1024 | 84 | #define JFS_MIN_JOURNAL_BLOCKS 1024 |
86 | 85 | ||
87 | #ifdef __KERNEL__ | ||
88 | 86 | ||
89 | /** | 87 | /** |
90 | * typedef handle_t - The handle_t type represents a single atomic update being performed by some process. | 88 | * typedef handle_t - The handle_t type represents a single atomic update being performed by some process. |
@@ -924,7 +922,6 @@ extern int journal_recover (journal_t *journal); | |||
924 | extern int journal_wipe (journal_t *, int); | 922 | extern int journal_wipe (journal_t *, int); |
925 | extern int journal_skip_recovery (journal_t *); | 923 | extern int journal_skip_recovery (journal_t *); |
926 | extern void journal_update_superblock (journal_t *, int); | 924 | extern void journal_update_superblock (journal_t *, int); |
927 | extern void __journal_abort_hard (journal_t *); | ||
928 | extern void journal_abort (journal_t *, int); | 925 | extern void journal_abort (journal_t *, int); |
929 | extern int journal_errno (journal_t *); | 926 | extern int journal_errno (journal_t *); |
930 | extern void journal_ack_err (journal_t *); | 927 | extern void journal_ack_err (journal_t *); |
diff --git a/include/linux/kernel.h b/include/linux/kernel.h index ff356b2ee478..18222f267bc4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h | |||
@@ -35,7 +35,7 @@ extern const char linux_proc_banner[]; | |||
35 | #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) | 35 | #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) |
36 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) | 36 | #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) |
37 | #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) | 37 | #define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) |
38 | #define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0) | 38 | #define IS_ALIGNED(x, a) (((x) & ((typeof(x))(a) - 1)) == 0) |
39 | 39 | ||
40 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) | 40 | #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) |
41 | 41 | ||
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 6168c0a44172..4a6ce82ba039 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
@@ -152,8 +152,10 @@ static inline int arch_trampoline_kprobe(struct kprobe *p) | |||
152 | struct kretprobe { | 152 | struct kretprobe { |
153 | struct kprobe kp; | 153 | struct kprobe kp; |
154 | kretprobe_handler_t handler; | 154 | kretprobe_handler_t handler; |
155 | kretprobe_handler_t entry_handler; | ||
155 | int maxactive; | 156 | int maxactive; |
156 | int nmissed; | 157 | int nmissed; |
158 | size_t data_size; | ||
157 | struct hlist_head free_instances; | 159 | struct hlist_head free_instances; |
158 | struct hlist_head used_instances; | 160 | struct hlist_head used_instances; |
159 | }; | 161 | }; |
@@ -164,6 +166,7 @@ struct kretprobe_instance { | |||
164 | struct kretprobe *rp; | 166 | struct kretprobe *rp; |
165 | kprobe_opcode_t *ret_addr; | 167 | kprobe_opcode_t *ret_addr; |
166 | struct task_struct *task; | 168 | struct task_struct *task; |
169 | char data[0]; | ||
167 | }; | 170 | }; |
168 | 171 | ||
169 | struct kretprobe_blackpoint { | 172 | struct kretprobe_blackpoint { |
diff --git a/include/linux/log2.h b/include/linux/log2.h index c8cf5e8ef171..25b808631cd9 100644 --- a/include/linux/log2.h +++ b/include/linux/log2.h | |||
@@ -190,4 +190,20 @@ unsigned long __rounddown_pow_of_two(unsigned long n) | |||
190 | __rounddown_pow_of_two(n) \ | 190 | __rounddown_pow_of_two(n) \ |
191 | ) | 191 | ) |
192 | 192 | ||
193 | /** | ||
194 | * order_base_2 - calculate the (rounded up) base 2 order of the argument | ||
195 | * @n: parameter | ||
196 | * | ||
197 | * The first few values calculated by this routine: | ||
198 | * ob2(0) = 0 | ||
199 | * ob2(1) = 0 | ||
200 | * ob2(2) = 1 | ||
201 | * ob2(3) = 2 | ||
202 | * ob2(4) = 2 | ||
203 | * ob2(5) = 3 | ||
204 | * ... and so on. | ||
205 | */ | ||
206 | |||
207 | #define order_base_2(n) ilog2(roundup_pow_of_two(n)) | ||
208 | |||
193 | #endif /* _LINUX_LOG2_H */ | 209 | #endif /* _LINUX_LOG2_H */ |
diff --git a/include/linux/loop.h b/include/linux/loop.h index 26a0a103898f..46169a7b559b 100644 --- a/include/linux/loop.h +++ b/include/linux/loop.h | |||
@@ -76,6 +76,7 @@ struct loop_device { | |||
76 | enum { | 76 | enum { |
77 | LO_FLAGS_READ_ONLY = 1, | 77 | LO_FLAGS_READ_ONLY = 1, |
78 | LO_FLAGS_USE_AOPS = 2, | 78 | LO_FLAGS_USE_AOPS = 2, |
79 | LO_FLAGS_AUTOCLEAR = 4, | ||
79 | }; | 80 | }; |
80 | 81 | ||
81 | #include <asm/posix_types.h> /* for __kernel_old_dev_t */ | 82 | #include <asm/posix_types.h> /* for __kernel_old_dev_t */ |
diff --git a/include/linux/lp.h b/include/linux/lp.h index 7059b6b9878a..0df024bfd6f0 100644 --- a/include/linux/lp.h +++ b/include/linux/lp.h | |||
@@ -99,7 +99,7 @@ | |||
99 | #ifdef __KERNEL__ | 99 | #ifdef __KERNEL__ |
100 | 100 | ||
101 | #include <linux/wait.h> | 101 | #include <linux/wait.h> |
102 | #include <asm/semaphore.h> | 102 | #include <linux/mutex.h> |
103 | 103 | ||
104 | /* Magic numbers for defining port-device mappings */ | 104 | /* Magic numbers for defining port-device mappings */ |
105 | #define LP_PARPORT_UNSPEC -4 | 105 | #define LP_PARPORT_UNSPEC -4 |
@@ -145,7 +145,7 @@ struct lp_struct { | |||
145 | #endif | 145 | #endif |
146 | wait_queue_head_t waitq; | 146 | wait_queue_head_t waitq; |
147 | unsigned int last_error; | 147 | unsigned int last_error; |
148 | struct semaphore port_mutex; | 148 | struct mutex port_mutex; |
149 | wait_queue_head_t dataq; | 149 | wait_queue_head_t dataq; |
150 | long timeout; | 150 | long timeout; |
151 | unsigned int best_mode; | 151 | unsigned int best_mode; |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 39d32837265b..df6dd79a0d3b 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -1765,6 +1765,7 @@ | |||
1765 | #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 | 1765 | #define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 |
1766 | #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 | 1766 | #define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 |
1767 | #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 | 1767 | #define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 |
1768 | #define PCI_DEVICE_ID_QUATECH_SPPXP_100 0x0278 | ||
1768 | 1769 | ||
1769 | #define PCI_VENDOR_ID_SEALEVEL 0x135e | 1770 | #define PCI_VENDOR_ID_SEALEVEL 0x135e |
1770 | #define PCI_DEVICE_ID_SEALEVEL_U530 0x7101 | 1771 | #define PCI_DEVICE_ID_SEALEVEL_U530 0x7101 |
diff --git a/include/linux/percpu.h b/include/linux/percpu.h index 50faa0ea28e4..1ac969724bb2 100644 --- a/include/linux/percpu.h +++ b/include/linux/percpu.h | |||
@@ -54,7 +54,7 @@ | |||
54 | #ifdef CONFIG_SMP | 54 | #ifdef CONFIG_SMP |
55 | 55 | ||
56 | struct percpu_data { | 56 | struct percpu_data { |
57 | void *ptrs[NR_CPUS]; | 57 | void *ptrs[1]; |
58 | }; | 58 | }; |
59 | 59 | ||
60 | #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) | 60 | #define __percpu_disguise(pdata) (struct percpu_data *)~(unsigned long)(pdata) |
diff --git a/include/linux/pnp.h b/include/linux/pnp.h index b9339d8b95bc..cd6332b88829 100644 --- a/include/linux/pnp.h +++ b/include/linux/pnp.h | |||
@@ -258,6 +258,7 @@ extern struct pnp_protocol isapnp_protocol; | |||
258 | #else | 258 | #else |
259 | #define pnp_device_is_isapnp(dev) 0 | 259 | #define pnp_device_is_isapnp(dev) 0 |
260 | #endif | 260 | #endif |
261 | extern struct mutex pnp_res_mutex; | ||
261 | 262 | ||
262 | #ifdef CONFIG_PNPBIOS | 263 | #ifdef CONFIG_PNPBIOS |
263 | extern struct pnp_protocol pnpbios_protocol; | 264 | extern struct pnp_protocol pnpbios_protocol; |
diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 515bff053de8..6ab80714a916 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h | |||
@@ -204,6 +204,41 @@ static inline void user_enable_block_step(struct task_struct *task) | |||
204 | } | 204 | } |
205 | #endif /* arch_has_block_step */ | 205 | #endif /* arch_has_block_step */ |
206 | 206 | ||
207 | #ifndef arch_ptrace_stop_needed | ||
208 | /** | ||
209 | * arch_ptrace_stop_needed - Decide whether arch_ptrace_stop() should be called | ||
210 | * @code: current->exit_code value ptrace will stop with | ||
211 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with | ||
212 | * | ||
213 | * This is called with the siglock held, to decide whether or not it's | ||
214 | * necessary to release the siglock and call arch_ptrace_stop() with the | ||
215 | * same @code and @info arguments. It can be defined to a constant if | ||
216 | * arch_ptrace_stop() is never required, or always is. On machines where | ||
217 | * this makes sense, it should be defined to a quick test to optimize out | ||
218 | * calling arch_ptrace_stop() when it would be superfluous. For example, | ||
219 | * if the thread has not been back to user mode since the last stop, the | ||
220 | * thread state might indicate that nothing needs to be done. | ||
221 | */ | ||
222 | #define arch_ptrace_stop_needed(code, info) (0) | ||
223 | #endif | ||
224 | |||
225 | #ifndef arch_ptrace_stop | ||
226 | /** | ||
227 | * arch_ptrace_stop - Do machine-specific work before stopping for ptrace | ||
228 | * @code: current->exit_code value ptrace will stop with | ||
229 | * @info: siginfo_t pointer (or %NULL) for signal ptrace will stop with | ||
230 | * | ||
231 | * This is called with no locks held when arch_ptrace_stop_needed() has | ||
232 | * just returned nonzero. It is allowed to block, e.g. for user memory | ||
233 | * access. The arch can have machine-specific work to be done before | ||
234 | * ptrace stops. On ia64, register backing store gets written back to user | ||
235 | * memory here. Since this can be costly (requires dropping the siglock), | ||
236 | * we only do it when the arch requires it for this particular stop, as | ||
237 | * indicated by arch_ptrace_stop_needed(). | ||
238 | */ | ||
239 | #define arch_ptrace_stop(code, info) do { } while (0) | ||
240 | #endif | ||
241 | |||
207 | #endif | 242 | #endif |
208 | 243 | ||
209 | #endif | 244 | #endif |
diff --git a/include/linux/raid/bitmap.h b/include/linux/raid/bitmap.h index 306a1d1a5af0..e51b531cd0b2 100644 --- a/include/linux/raid/bitmap.h +++ b/include/linux/raid/bitmap.h | |||
@@ -244,6 +244,8 @@ struct bitmap { | |||
244 | */ | 244 | */ |
245 | unsigned long daemon_lastrun; /* jiffies of last run */ | 245 | unsigned long daemon_lastrun; /* jiffies of last run */ |
246 | unsigned long daemon_sleep; /* how many seconds between updates? */ | 246 | unsigned long daemon_sleep; /* how many seconds between updates? */ |
247 | unsigned long last_end_sync; /* when we lasted called end_sync to | ||
248 | * update bitmap with resync progress */ | ||
247 | 249 | ||
248 | atomic_t pending_writes; /* pending writes to the bitmap file */ | 250 | atomic_t pending_writes; /* pending writes to the bitmap file */ |
249 | wait_queue_head_t write_wait; | 251 | wait_queue_head_t write_wait; |
@@ -275,6 +277,7 @@ void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, | |||
275 | int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded); | 277 | int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded); |
276 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); | 278 | void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted); |
277 | void bitmap_close_sync(struct bitmap *bitmap); | 279 | void bitmap_close_sync(struct bitmap *bitmap); |
280 | void bitmap_cond_end_sync(struct bitmap *bitmap, sector_t sector); | ||
278 | 281 | ||
279 | void bitmap_unplug(struct bitmap *bitmap); | 282 | void bitmap_unplug(struct bitmap *bitmap); |
280 | void bitmap_daemon_work(struct bitmap *bitmap); | 283 | void bitmap_daemon_work(struct bitmap *bitmap); |
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h index dcb729244f47..85a068bab625 100644 --- a/include/linux/raid/md_k.h +++ b/include/linux/raid/md_k.h | |||
@@ -81,6 +81,8 @@ struct mdk_rdev_s | |||
81 | #define In_sync 2 /* device is in_sync with rest of array */ | 81 | #define In_sync 2 /* device is in_sync with rest of array */ |
82 | #define WriteMostly 4 /* Avoid reading if at all possible */ | 82 | #define WriteMostly 4 /* Avoid reading if at all possible */ |
83 | #define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */ | 83 | #define BarriersNotsupp 5 /* BIO_RW_BARRIER is not supported */ |
84 | #define AllReserved 6 /* If whole device is reserved for | ||
85 | * one array */ | ||
84 | 86 | ||
85 | int desc_nr; /* descriptor index in the superblock */ | 87 | int desc_nr; /* descriptor index in the superblock */ |
86 | int raid_disk; /* role of device in array */ | 88 | int raid_disk; /* role of device in array */ |
@@ -130,6 +132,9 @@ struct mddev_s | |||
130 | minor_version, | 132 | minor_version, |
131 | patch_version; | 133 | patch_version; |
132 | int persistent; | 134 | int persistent; |
135 | int external; /* metadata is | ||
136 | * managed externally */ | ||
137 | char metadata_type[17]; /* externally set*/ | ||
133 | int chunk_size; | 138 | int chunk_size; |
134 | time_t ctime, utime; | 139 | time_t ctime, utime; |
135 | int level, layout; | 140 | int level, layout; |
@@ -216,6 +221,8 @@ struct mddev_s | |||
216 | atomic_t recovery_active; /* blocks scheduled, but not written */ | 221 | atomic_t recovery_active; /* blocks scheduled, but not written */ |
217 | wait_queue_head_t recovery_wait; | 222 | wait_queue_head_t recovery_wait; |
218 | sector_t recovery_cp; | 223 | sector_t recovery_cp; |
224 | sector_t resync_max; /* resync should pause | ||
225 | * when it gets here */ | ||
219 | 226 | ||
220 | spinlock_t write_lock; | 227 | spinlock_t write_lock; |
221 | wait_queue_head_t sb_wait; /* for waiting on superblock updates */ | 228 | wait_queue_head_t sb_wait; /* for waiting on superblock updates */ |
@@ -306,23 +313,17 @@ static inline char * mdname (mddev_t * mddev) | |||
306 | * iterates through some rdev ringlist. It's safe to remove the | 313 | * iterates through some rdev ringlist. It's safe to remove the |
307 | * current 'rdev'. Dont touch 'tmp' though. | 314 | * current 'rdev'. Dont touch 'tmp' though. |
308 | */ | 315 | */ |
309 | #define ITERATE_RDEV_GENERIC(head,rdev,tmp) \ | 316 | #define rdev_for_each_list(rdev, tmp, list) \ |
310 | \ | 317 | \ |
311 | for ((tmp) = (head).next; \ | 318 | for ((tmp) = (list).next; \ |
312 | (rdev) = (list_entry((tmp), mdk_rdev_t, same_set)), \ | 319 | (rdev) = (list_entry((tmp), mdk_rdev_t, same_set)), \ |
313 | (tmp) = (tmp)->next, (tmp)->prev != &(head) \ | 320 | (tmp) = (tmp)->next, (tmp)->prev != &(list) \ |
314 | ; ) | 321 | ; ) |
315 | /* | 322 | /* |
316 | * iterates through the 'same array disks' ringlist | 323 | * iterates through the 'same array disks' ringlist |
317 | */ | 324 | */ |
318 | #define ITERATE_RDEV(mddev,rdev,tmp) \ | 325 | #define rdev_for_each(rdev, tmp, mddev) \ |
319 | ITERATE_RDEV_GENERIC((mddev)->disks,rdev,tmp) | 326 | rdev_for_each_list(rdev, tmp, (mddev)->disks) |
320 | |||
321 | /* | ||
322 | * Iterates through 'pending RAID disks' | ||
323 | */ | ||
324 | #define ITERATE_RDEV_PENDING(rdev,tmp) \ | ||
325 | ITERATE_RDEV_GENERIC(pending_raid_disks,rdev,tmp) | ||
326 | 327 | ||
327 | typedef struct mdk_thread_s { | 328 | typedef struct mdk_thread_s { |
328 | void (*run) (mddev_t *mddev); | 329 | void (*run) (mddev_t *mddev); |
diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index d32c14de270e..37a642c54871 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h | |||
@@ -174,10 +174,13 @@ struct rcu_head { | |||
174 | * code. | 174 | * code. |
175 | */ | 175 | */ |
176 | 176 | ||
177 | #define rcu_assign_pointer(p, v) ({ \ | 177 | #define rcu_assign_pointer(p, v) \ |
178 | smp_wmb(); \ | 178 | ({ \ |
179 | (p) = (v); \ | 179 | if (!__builtin_constant_p(v) || \ |
180 | }) | 180 | ((v) != NULL)) \ |
181 | smp_wmb(); \ | ||
182 | (p) = (v); \ | ||
183 | }) | ||
181 | 184 | ||
182 | /** | 185 | /** |
183 | * synchronize_sched - block until all CPUs have exited any non-preemptive | 186 | * synchronize_sched - block until all CPUs have exited any non-preemptive |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 9c13be3a21e8..7c8ca05c3cae 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -810,7 +810,7 @@ static inline int above_background_load(void) | |||
810 | 810 | ||
811 | struct io_context; /* See blkdev.h */ | 811 | struct io_context; /* See blkdev.h */ |
812 | #define NGROUPS_SMALL 32 | 812 | #define NGROUPS_SMALL 32 |
813 | #define NGROUPS_PER_BLOCK ((int)(PAGE_SIZE / sizeof(gid_t))) | 813 | #define NGROUPS_PER_BLOCK ((unsigned int)(PAGE_SIZE / sizeof(gid_t))) |
814 | struct group_info { | 814 | struct group_info { |
815 | int ngroups; | 815 | int ngroups; |
816 | atomic_t usage; | 816 | atomic_t usage; |
diff --git a/include/linux/signal.h b/include/linux/signal.h index 0ae338866240..7e095147656c 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h | |||
@@ -371,6 +371,8 @@ int unhandled_signal(struct task_struct *tsk, int sig); | |||
371 | (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ | 371 | (!siginmask(signr, SIG_KERNEL_IGNORE_MASK|SIG_KERNEL_STOP_MASK) && \ |
372 | (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) | 372 | (t)->sighand->action[(signr)-1].sa.sa_handler == SIG_DFL) |
373 | 373 | ||
374 | void signals_init(void); | ||
375 | |||
374 | #endif /* __KERNEL__ */ | 376 | #endif /* __KERNEL__ */ |
375 | 377 | ||
376 | #endif /* _LINUX_SIGNAL_H */ | 378 | #endif /* _LINUX_SIGNAL_H */ |
diff --git a/include/linux/sm501.h b/include/linux/sm501.h index 9e3aaad6fe4d..932a9efee8a5 100644 --- a/include/linux/sm501.h +++ b/include/linux/sm501.h | |||
@@ -70,6 +70,8 @@ extern unsigned long sm501_gpio_get(struct device *dev, | |||
70 | #define SM501FB_FLAG_DISABLE_AT_EXIT (1<<1) | 70 | #define SM501FB_FLAG_DISABLE_AT_EXIT (1<<1) |
71 | #define SM501FB_FLAG_USE_HWCURSOR (1<<2) | 71 | #define SM501FB_FLAG_USE_HWCURSOR (1<<2) |
72 | #define SM501FB_FLAG_USE_HWACCEL (1<<3) | 72 | #define SM501FB_FLAG_USE_HWACCEL (1<<3) |
73 | #define SM501FB_FLAG_PANEL_USE_FPEN (1<<4) | ||
74 | #define SM501FB_FLAG_PANEL_USE_VBIASEN (1<<5) | ||
73 | 75 | ||
74 | struct sm501_platdata_fbsub { | 76 | struct sm501_platdata_fbsub { |
75 | struct fb_videomode *def_mode; | 77 | struct fb_videomode *def_mode; |
diff --git a/include/linux/timex.h b/include/linux/timex.h index 24c6a2b59511..8ea3e71ba7fa 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -244,6 +244,8 @@ extern int do_adjtimex(struct timex *); | |||
244 | /* Don't use! Compatibility define for existing users. */ | 244 | /* Don't use! Compatibility define for existing users. */ |
245 | #define tickadj (500/HZ ? : 1) | 245 | #define tickadj (500/HZ ? : 1) |
246 | 246 | ||
247 | int read_current_timer(unsigned long *timer_val); | ||
248 | |||
247 | #endif /* KERNEL */ | 249 | #endif /* KERNEL */ |
248 | 250 | ||
249 | #endif /* LINUX_TIMEX_H */ | 251 | #endif /* LINUX_TIMEX_H */ |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 402de892b3ed..5824a9777ad7 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -74,7 +74,6 @@ struct tty_buffer { | |||
74 | 74 | ||
75 | struct tty_bufhead { | 75 | struct tty_bufhead { |
76 | struct delayed_work work; | 76 | struct delayed_work work; |
77 | struct semaphore pty_sem; | ||
78 | spinlock_t lock; | 77 | spinlock_t lock; |
79 | struct tty_buffer *head; /* Queue head */ | 78 | struct tty_buffer *head; /* Queue head */ |
80 | struct tty_buffer *tail; /* Active buffer */ | 79 | struct tty_buffer *tail; /* Active buffer */ |
diff --git a/include/linux/vt_kern.h b/include/linux/vt_kern.h index feb5e99a1079..9448ffbdcbf6 100644 --- a/include/linux/vt_kern.h +++ b/include/linux/vt_kern.h | |||
@@ -77,6 +77,7 @@ void change_console(struct vc_data *new_vc); | |||
77 | void reset_vc(struct vc_data *vc); | 77 | void reset_vc(struct vc_data *vc); |
78 | extern int unbind_con_driver(const struct consw *csw, int first, int last, | 78 | extern int unbind_con_driver(const struct consw *csw, int first, int last, |
79 | int deflt); | 79 | int deflt); |
80 | int vty_init(void); | ||
80 | 81 | ||
81 | /* | 82 | /* |
82 | * vc_screen.c shares this temporary buffer with the console write code so that | 83 | * vc_screen.c shares this temporary buffer with the console write code so that |
diff --git a/include/linux/w1-gpio.h b/include/linux/w1-gpio.h new file mode 100644 index 000000000000..9797fec7748a --- /dev/null +++ b/include/linux/w1-gpio.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * w1-gpio interface to platform code | ||
3 | * | ||
4 | * Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 | ||
8 | * as published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef _LINUX_W1_GPIO_H | ||
11 | #define _LINUX_W1_GPIO_H | ||
12 | |||
13 | /** | ||
14 | * struct w1_gpio_platform_data - Platform-dependent data for w1-gpio | ||
15 | * @pin: GPIO pin to use | ||
16 | * @is_open_drain: GPIO pin is configured as open drain | ||
17 | */ | ||
18 | struct w1_gpio_platform_data { | ||
19 | unsigned int pin; | ||
20 | unsigned int is_open_drain:1; | ||
21 | }; | ||
22 | |||
23 | #endif /* _LINUX_W1_GPIO_H */ | ||
diff --git a/include/video/atmel_lcdc.h b/include/video/atmel_lcdc.h index 4eea63761a3f..336c20db87f8 100644 --- a/include/video/atmel_lcdc.h +++ b/include/video/atmel_lcdc.h | |||
@@ -22,7 +22,7 @@ | |||
22 | #ifndef __ATMEL_LCDC_H__ | 22 | #ifndef __ATMEL_LCDC_H__ |
23 | #define __ATMEL_LCDC_H__ | 23 | #define __ATMEL_LCDC_H__ |
24 | 24 | ||
25 | /* LCD Controller info data structure */ | 25 | /* LCD Controller info data structure, stored in device platform_data */ |
26 | struct atmel_lcdfb_info { | 26 | struct atmel_lcdfb_info { |
27 | spinlock_t lock; | 27 | spinlock_t lock; |
28 | struct fb_info *info; | 28 | struct fb_info *info; |
@@ -33,7 +33,14 @@ struct atmel_lcdfb_info { | |||
33 | struct platform_device *pdev; | 33 | struct platform_device *pdev; |
34 | struct clk *bus_clk; | 34 | struct clk *bus_clk; |
35 | struct clk *lcdc_clk; | 35 | struct clk *lcdc_clk; |
36 | unsigned int default_bpp; | 36 | |
37 | #ifdef CONFIG_BACKLIGHT_ATMEL_LCDC | ||
38 | struct backlight_device *backlight; | ||
39 | u8 bl_power; | ||
40 | #endif | ||
41 | bool lcdcon_is_backlight; | ||
42 | |||
43 | u8 default_bpp; | ||
37 | unsigned int default_lcdcon2; | 44 | unsigned int default_lcdcon2; |
38 | unsigned int default_dmacon; | 45 | unsigned int default_dmacon; |
39 | void (*atmel_lcdfb_power_control)(int on); | 46 | void (*atmel_lcdfb_power_control)(int on); |
@@ -115,20 +122,20 @@ struct atmel_lcdfb_info { | |||
115 | #define ATMEL_LCDC_MEMOR_LITTLE (1 << 31) | 122 | #define ATMEL_LCDC_MEMOR_LITTLE (1 << 31) |
116 | 123 | ||
117 | #define ATMEL_LCDC_TIM1 0x0808 | 124 | #define ATMEL_LCDC_TIM1 0x0808 |
118 | #define ATMEL_LCDC_VFP (0xff << 0) | 125 | #define ATMEL_LCDC_VFP (0xffU << 0) |
119 | #define ATMEL_LCDC_VBP_OFFSET 8 | 126 | #define ATMEL_LCDC_VBP_OFFSET 8 |
120 | #define ATMEL_LCDC_VBP (0xff << ATMEL_LCDC_VBP_OFFSET) | 127 | #define ATMEL_LCDC_VBP (0xffU << ATMEL_LCDC_VBP_OFFSET) |
121 | #define ATMEL_LCDC_VPW_OFFSET 16 | 128 | #define ATMEL_LCDC_VPW_OFFSET 16 |
122 | #define ATMEL_LCDC_VPW (0x3f << ATMEL_LCDC_VPW_OFFSET) | 129 | #define ATMEL_LCDC_VPW (0x3fU << ATMEL_LCDC_VPW_OFFSET) |
123 | #define ATMEL_LCDC_VHDLY_OFFSET 24 | 130 | #define ATMEL_LCDC_VHDLY_OFFSET 24 |
124 | #define ATMEL_LCDC_VHDLY (0xf << ATMEL_LCDC_VHDLY_OFFSET) | 131 | #define ATMEL_LCDC_VHDLY (0xfU << ATMEL_LCDC_VHDLY_OFFSET) |
125 | 132 | ||
126 | #define ATMEL_LCDC_TIM2 0x080c | 133 | #define ATMEL_LCDC_TIM2 0x080c |
127 | #define ATMEL_LCDC_HBP (0xff << 0) | 134 | #define ATMEL_LCDC_HBP (0xffU << 0) |
128 | #define ATMEL_LCDC_HPW_OFFSET 8 | 135 | #define ATMEL_LCDC_HPW_OFFSET 8 |
129 | #define ATMEL_LCDC_HPW (0x3f << ATMEL_LCDC_HPW_OFFSET) | 136 | #define ATMEL_LCDC_HPW (0x3fU << ATMEL_LCDC_HPW_OFFSET) |
130 | #define ATMEL_LCDC_HFP_OFFSET 21 | 137 | #define ATMEL_LCDC_HFP_OFFSET 21 |
131 | #define ATMEL_LCDC_HFP (0x7ff << ATMEL_LCDC_HFP_OFFSET) | 138 | #define ATMEL_LCDC_HFP (0x7ffU << ATMEL_LCDC_HFP_OFFSET) |
132 | 139 | ||
133 | #define ATMEL_LCDC_LCDFRMCFG 0x0810 | 140 | #define ATMEL_LCDC_LCDFRMCFG 0x0810 |
134 | #define ATMEL_LCDC_LINEVAL (0x7ff << 0) | 141 | #define ATMEL_LCDC_LINEVAL (0x7ff << 0) |
diff --git a/init/calibrate.c b/init/calibrate.c index 2d3d73bd4ce1..ecb3822d4f70 100644 --- a/init/calibrate.c +++ b/init/calibrate.c | |||
@@ -7,8 +7,7 @@ | |||
7 | #include <linux/jiffies.h> | 7 | #include <linux/jiffies.h> |
8 | #include <linux/delay.h> | 8 | #include <linux/delay.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | 10 | #include <linux/timex.h> | |
11 | #include <asm/timex.h> | ||
12 | 11 | ||
13 | unsigned long preset_lpj; | 12 | unsigned long preset_lpj; |
14 | static int __init lpj_setup(char *str) | 13 | static int __init lpj_setup(char *str) |
@@ -29,7 +28,7 @@ __setup("lpj=", lpj_setup); | |||
29 | #define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100)) | 28 | #define DELAY_CALIBRATION_TICKS ((HZ < 100) ? 1 : (HZ/100)) |
30 | #define MAX_DIRECT_CALIBRATION_RETRIES 5 | 29 | #define MAX_DIRECT_CALIBRATION_RETRIES 5 |
31 | 30 | ||
32 | static unsigned long __devinit calibrate_delay_direct(void) | 31 | static unsigned long __cpuinit calibrate_delay_direct(void) |
33 | { | 32 | { |
34 | unsigned long pre_start, start, post_start; | 33 | unsigned long pre_start, start, post_start; |
35 | unsigned long pre_end, end, post_end; | 34 | unsigned long pre_end, end, post_end; |
@@ -102,7 +101,7 @@ static unsigned long __devinit calibrate_delay_direct(void) | |||
102 | return 0; | 101 | return 0; |
103 | } | 102 | } |
104 | #else | 103 | #else |
105 | static unsigned long __devinit calibrate_delay_direct(void) {return 0;} | 104 | static unsigned long __cpuinit calibrate_delay_direct(void) {return 0;} |
106 | #endif | 105 | #endif |
107 | 106 | ||
108 | /* | 107 | /* |
@@ -112,7 +111,7 @@ static unsigned long __devinit calibrate_delay_direct(void) {return 0;} | |||
112 | */ | 111 | */ |
113 | #define LPS_PREC 8 | 112 | #define LPS_PREC 8 |
114 | 113 | ||
115 | void __devinit calibrate_delay(void) | 114 | void __cpuinit calibrate_delay(void) |
116 | { | 115 | { |
117 | unsigned long ticks, loopbit; | 116 | unsigned long ticks, loopbit; |
118 | int lps_precision = LPS_PREC; | 117 | int lps_precision = LPS_PREC; |
diff --git a/init/do_mounts.c b/init/do_mounts.c index 1161dfd7b0d3..f86573126f83 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/mount.h> | 11 | #include <linux/mount.h> |
12 | #include <linux/device.h> | 12 | #include <linux/device.h> |
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/fs.h> | ||
14 | 15 | ||
15 | #include <linux/nfs_fs.h> | 16 | #include <linux/nfs_fs.h> |
16 | #include <linux/nfs_fs_sb.h> | 17 | #include <linux/nfs_fs_sb.h> |
@@ -18,8 +19,6 @@ | |||
18 | 19 | ||
19 | #include "do_mounts.h" | 20 | #include "do_mounts.h" |
20 | 21 | ||
21 | extern int get_filesystem_list(char * buf); | ||
22 | |||
23 | int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ | 22 | int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ |
24 | 23 | ||
25 | int root_mountflags = MS_RDONLY | MS_SILENT; | 24 | int root_mountflags = MS_RDONLY | MS_SILENT; |
diff --git a/init/initramfs.c b/init/initramfs.c index 1db02a0025db..d53fee8d8604 100644 --- a/init/initramfs.c +++ b/init/initramfs.c | |||
@@ -503,7 +503,6 @@ static int __init retain_initrd_param(char *str) | |||
503 | __setup("retain_initrd", retain_initrd_param); | 503 | __setup("retain_initrd", retain_initrd_param); |
504 | 504 | ||
505 | extern char __initramfs_start[], __initramfs_end[]; | 505 | extern char __initramfs_start[], __initramfs_end[]; |
506 | #ifdef CONFIG_BLK_DEV_INITRD | ||
507 | #include <linux/initrd.h> | 506 | #include <linux/initrd.h> |
508 | #include <linux/kexec.h> | 507 | #include <linux/kexec.h> |
509 | 508 | ||
@@ -539,15 +538,12 @@ skip: | |||
539 | initrd_end = 0; | 538 | initrd_end = 0; |
540 | } | 539 | } |
541 | 540 | ||
542 | #endif | ||
543 | |||
544 | static int __init populate_rootfs(void) | 541 | static int __init populate_rootfs(void) |
545 | { | 542 | { |
546 | char *err = unpack_to_rootfs(__initramfs_start, | 543 | char *err = unpack_to_rootfs(__initramfs_start, |
547 | __initramfs_end - __initramfs_start, 0); | 544 | __initramfs_end - __initramfs_start, 0); |
548 | if (err) | 545 | if (err) |
549 | panic(err); | 546 | panic(err); |
550 | #ifdef CONFIG_BLK_DEV_INITRD | ||
551 | if (initrd_start) { | 547 | if (initrd_start) { |
552 | #ifdef CONFIG_BLK_DEV_RAM | 548 | #ifdef CONFIG_BLK_DEV_RAM |
553 | int fd; | 549 | int fd; |
@@ -579,7 +575,6 @@ static int __init populate_rootfs(void) | |||
579 | free_initrd(); | 575 | free_initrd(); |
580 | #endif | 576 | #endif |
581 | } | 577 | } |
582 | #endif | ||
583 | return 0; | 578 | return 0; |
584 | } | 579 | } |
585 | rootfs_initcall(populate_rootfs); | 580 | rootfs_initcall(populate_rootfs); |
diff --git a/init/main.c b/init/main.c index cb81ed116f62..c691f5f7fc27 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/device.h> | 57 | #include <linux/device.h> |
58 | #include <linux/kthread.h> | 58 | #include <linux/kthread.h> |
59 | #include <linux/sched.h> | 59 | #include <linux/sched.h> |
60 | #include <linux/signal.h> | ||
60 | 61 | ||
61 | #include <asm/io.h> | 62 | #include <asm/io.h> |
62 | #include <asm/bugs.h> | 63 | #include <asm/bugs.h> |
@@ -83,7 +84,6 @@ extern void init_IRQ(void); | |||
83 | extern void fork_init(unsigned long); | 84 | extern void fork_init(unsigned long); |
84 | extern void mca_init(void); | 85 | extern void mca_init(void); |
85 | extern void sbus_init(void); | 86 | extern void sbus_init(void); |
86 | extern void signals_init(void); | ||
87 | extern void pidhash_init(void); | 87 | extern void pidhash_init(void); |
88 | extern void pidmap_init(void); | 88 | extern void pidmap_init(void); |
89 | extern void prio_tree_init(void); | 89 | extern void prio_tree_init(void); |
@@ -105,6 +105,7 @@ int msg_init_ns(struct ipc_namespace *ns) | |||
105 | void msg_exit_ns(struct ipc_namespace *ns) | 105 | void msg_exit_ns(struct ipc_namespace *ns) |
106 | { | 106 | { |
107 | struct msg_queue *msq; | 107 | struct msg_queue *msq; |
108 | struct kern_ipc_perm *perm; | ||
108 | int next_id; | 109 | int next_id; |
109 | int total, in_use; | 110 | int total, in_use; |
110 | 111 | ||
@@ -113,10 +114,11 @@ void msg_exit_ns(struct ipc_namespace *ns) | |||
113 | in_use = msg_ids(ns).in_use; | 114 | in_use = msg_ids(ns).in_use; |
114 | 115 | ||
115 | for (total = 0, next_id = 0; total < in_use; next_id++) { | 116 | for (total = 0, next_id = 0; total < in_use; next_id++) { |
116 | msq = idr_find(&msg_ids(ns).ipcs_idr, next_id); | 117 | perm = idr_find(&msg_ids(ns).ipcs_idr, next_id); |
117 | if (msq == NULL) | 118 | if (perm == NULL) |
118 | continue; | 119 | continue; |
119 | ipc_lock_by_ptr(&msq->q_perm); | 120 | ipc_lock_by_ptr(perm); |
121 | msq = container_of(perm, struct msg_queue, q_perm); | ||
120 | freeque(ns, msq); | 122 | freeque(ns, msq); |
121 | total++; | 123 | total++; |
122 | } | 124 | } |
@@ -144,6 +146,9 @@ static inline struct msg_queue *msg_lock_check_down(struct ipc_namespace *ns, | |||
144 | { | 146 | { |
145 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id); | 147 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&msg_ids(ns), id); |
146 | 148 | ||
149 | if (IS_ERR(ipcp)) | ||
150 | return (struct msg_queue *)ipcp; | ||
151 | |||
147 | return container_of(ipcp, struct msg_queue, q_perm); | 152 | return container_of(ipcp, struct msg_queue, q_perm); |
148 | } | 153 | } |
149 | 154 | ||
@@ -155,6 +160,9 @@ static inline struct msg_queue *msg_lock(struct ipc_namespace *ns, int id) | |||
155 | { | 160 | { |
156 | struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id); | 161 | struct kern_ipc_perm *ipcp = ipc_lock(&msg_ids(ns), id); |
157 | 162 | ||
163 | if (IS_ERR(ipcp)) | ||
164 | return (struct msg_queue *)ipcp; | ||
165 | |||
158 | return container_of(ipcp, struct msg_queue, q_perm); | 166 | return container_of(ipcp, struct msg_queue, q_perm); |
159 | } | 167 | } |
160 | 168 | ||
@@ -163,6 +171,9 @@ static inline struct msg_queue *msg_lock_check(struct ipc_namespace *ns, | |||
163 | { | 171 | { |
164 | struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id); | 172 | struct kern_ipc_perm *ipcp = ipc_lock_check(&msg_ids(ns), id); |
165 | 173 | ||
174 | if (IS_ERR(ipcp)) | ||
175 | return (struct msg_queue *)ipcp; | ||
176 | |||
166 | return container_of(ipcp, struct msg_queue, q_perm); | 177 | return container_of(ipcp, struct msg_queue, q_perm); |
167 | } | 178 | } |
168 | 179 | ||
@@ -143,6 +143,7 @@ int sem_init_ns(struct ipc_namespace *ns) | |||
143 | void sem_exit_ns(struct ipc_namespace *ns) | 143 | void sem_exit_ns(struct ipc_namespace *ns) |
144 | { | 144 | { |
145 | struct sem_array *sma; | 145 | struct sem_array *sma; |
146 | struct kern_ipc_perm *perm; | ||
146 | int next_id; | 147 | int next_id; |
147 | int total, in_use; | 148 | int total, in_use; |
148 | 149 | ||
@@ -151,10 +152,11 @@ void sem_exit_ns(struct ipc_namespace *ns) | |||
151 | in_use = sem_ids(ns).in_use; | 152 | in_use = sem_ids(ns).in_use; |
152 | 153 | ||
153 | for (total = 0, next_id = 0; total < in_use; next_id++) { | 154 | for (total = 0, next_id = 0; total < in_use; next_id++) { |
154 | sma = idr_find(&sem_ids(ns).ipcs_idr, next_id); | 155 | perm = idr_find(&sem_ids(ns).ipcs_idr, next_id); |
155 | if (sma == NULL) | 156 | if (perm == NULL) |
156 | continue; | 157 | continue; |
157 | ipc_lock_by_ptr(&sma->sem_perm); | 158 | ipc_lock_by_ptr(perm); |
159 | sma = container_of(perm, struct sem_array, sem_perm); | ||
158 | freeary(ns, sma); | 160 | freeary(ns, sma); |
159 | total++; | 161 | total++; |
160 | } | 162 | } |
@@ -181,6 +183,9 @@ static inline struct sem_array *sem_lock_check_down(struct ipc_namespace *ns, | |||
181 | { | 183 | { |
182 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id); | 184 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&sem_ids(ns), id); |
183 | 185 | ||
186 | if (IS_ERR(ipcp)) | ||
187 | return (struct sem_array *)ipcp; | ||
188 | |||
184 | return container_of(ipcp, struct sem_array, sem_perm); | 189 | return container_of(ipcp, struct sem_array, sem_perm); |
185 | } | 190 | } |
186 | 191 | ||
@@ -192,6 +197,9 @@ static inline struct sem_array *sem_lock(struct ipc_namespace *ns, int id) | |||
192 | { | 197 | { |
193 | struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id); | 198 | struct kern_ipc_perm *ipcp = ipc_lock(&sem_ids(ns), id); |
194 | 199 | ||
200 | if (IS_ERR(ipcp)) | ||
201 | return (struct sem_array *)ipcp; | ||
202 | |||
195 | return container_of(ipcp, struct sem_array, sem_perm); | 203 | return container_of(ipcp, struct sem_array, sem_perm); |
196 | } | 204 | } |
197 | 205 | ||
@@ -200,6 +208,9 @@ static inline struct sem_array *sem_lock_check(struct ipc_namespace *ns, | |||
200 | { | 208 | { |
201 | struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id); | 209 | struct kern_ipc_perm *ipcp = ipc_lock_check(&sem_ids(ns), id); |
202 | 210 | ||
211 | if (IS_ERR(ipcp)) | ||
212 | return (struct sem_array *)ipcp; | ||
213 | |||
203 | return container_of(ipcp, struct sem_array, sem_perm); | 214 | return container_of(ipcp, struct sem_array, sem_perm); |
204 | } | 215 | } |
205 | 216 | ||
@@ -111,6 +111,7 @@ int shm_init_ns(struct ipc_namespace *ns) | |||
111 | void shm_exit_ns(struct ipc_namespace *ns) | 111 | void shm_exit_ns(struct ipc_namespace *ns) |
112 | { | 112 | { |
113 | struct shmid_kernel *shp; | 113 | struct shmid_kernel *shp; |
114 | struct kern_ipc_perm *perm; | ||
114 | int next_id; | 115 | int next_id; |
115 | int total, in_use; | 116 | int total, in_use; |
116 | 117 | ||
@@ -119,10 +120,11 @@ void shm_exit_ns(struct ipc_namespace *ns) | |||
119 | in_use = shm_ids(ns).in_use; | 120 | in_use = shm_ids(ns).in_use; |
120 | 121 | ||
121 | for (total = 0, next_id = 0; total < in_use; next_id++) { | 122 | for (total = 0, next_id = 0; total < in_use; next_id++) { |
122 | shp = idr_find(&shm_ids(ns).ipcs_idr, next_id); | 123 | perm = idr_find(&shm_ids(ns).ipcs_idr, next_id); |
123 | if (shp == NULL) | 124 | if (perm == NULL) |
124 | continue; | 125 | continue; |
125 | ipc_lock_by_ptr(&shp->shm_perm); | 126 | ipc_lock_by_ptr(perm); |
127 | shp = container_of(perm, struct shmid_kernel, shm_perm); | ||
126 | do_shm_rmid(ns, shp); | 128 | do_shm_rmid(ns, shp); |
127 | total++; | 129 | total++; |
128 | } | 130 | } |
@@ -149,6 +151,9 @@ static inline struct shmid_kernel *shm_lock_down(struct ipc_namespace *ns, | |||
149 | { | 151 | { |
150 | struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id); | 152 | struct kern_ipc_perm *ipcp = ipc_lock_down(&shm_ids(ns), id); |
151 | 153 | ||
154 | if (IS_ERR(ipcp)) | ||
155 | return (struct shmid_kernel *)ipcp; | ||
156 | |||
152 | return container_of(ipcp, struct shmid_kernel, shm_perm); | 157 | return container_of(ipcp, struct shmid_kernel, shm_perm); |
153 | } | 158 | } |
154 | 159 | ||
@@ -158,6 +163,9 @@ static inline struct shmid_kernel *shm_lock_check_down( | |||
158 | { | 163 | { |
159 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id); | 164 | struct kern_ipc_perm *ipcp = ipc_lock_check_down(&shm_ids(ns), id); |
160 | 165 | ||
166 | if (IS_ERR(ipcp)) | ||
167 | return (struct shmid_kernel *)ipcp; | ||
168 | |||
161 | return container_of(ipcp, struct shmid_kernel, shm_perm); | 169 | return container_of(ipcp, struct shmid_kernel, shm_perm); |
162 | } | 170 | } |
163 | 171 | ||
@@ -169,6 +177,9 @@ static inline struct shmid_kernel *shm_lock(struct ipc_namespace *ns, int id) | |||
169 | { | 177 | { |
170 | struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id); | 178 | struct kern_ipc_perm *ipcp = ipc_lock(&shm_ids(ns), id); |
171 | 179 | ||
180 | if (IS_ERR(ipcp)) | ||
181 | return (struct shmid_kernel *)ipcp; | ||
182 | |||
172 | return container_of(ipcp, struct shmid_kernel, shm_perm); | 183 | return container_of(ipcp, struct shmid_kernel, shm_perm); |
173 | } | 184 | } |
174 | 185 | ||
@@ -177,6 +188,9 @@ static inline struct shmid_kernel *shm_lock_check(struct ipc_namespace *ns, | |||
177 | { | 188 | { |
178 | struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id); | 189 | struct kern_ipc_perm *ipcp = ipc_lock_check(&shm_ids(ns), id); |
179 | 190 | ||
191 | if (IS_ERR(ipcp)) | ||
192 | return (struct shmid_kernel *)ipcp; | ||
193 | |||
180 | return container_of(ipcp, struct shmid_kernel, shm_perm); | 194 | return container_of(ipcp, struct shmid_kernel, shm_perm); |
181 | } | 195 | } |
182 | 196 | ||
diff --git a/ipc/util.c b/ipc/util.c index 1aa0ebf71bac..76c1f3461e22 100644 --- a/ipc/util.c +++ b/ipc/util.c | |||
@@ -802,8 +802,8 @@ struct ipc_proc_iter { | |||
802 | /* | 802 | /* |
803 | * This routine locks the ipc structure found at least at position pos. | 803 | * This routine locks the ipc structure found at least at position pos. |
804 | */ | 804 | */ |
805 | struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, | 805 | static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, |
806 | loff_t *new_pos) | 806 | loff_t *new_pos) |
807 | { | 807 | { |
808 | struct kern_ipc_perm *ipc; | 808 | struct kern_ipc_perm *ipc; |
809 | int total, id; | 809 | int total, id; |
diff --git a/kernel/exit.c b/kernel/exit.c index 9d3d0f0b27d9..eb9934a82fc1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -1590,8 +1590,6 @@ repeat: | |||
1590 | goto repeat; | 1590 | goto repeat; |
1591 | if (retval != 0) /* He released the lock. */ | 1591 | if (retval != 0) /* He released the lock. */ |
1592 | goto end; | 1592 | goto end; |
1593 | } else if (p->exit_state == EXIT_DEAD) { | ||
1594 | continue; | ||
1595 | } else if (p->exit_state == EXIT_ZOMBIE) { | 1593 | } else if (p->exit_state == EXIT_ZOMBIE) { |
1596 | /* | 1594 | /* |
1597 | * Eligible but we cannot release it yet: | 1595 | * Eligible but we cannot release it yet: |
@@ -1606,7 +1604,7 @@ repeat: | |||
1606 | /* He released the lock. */ | 1604 | /* He released the lock. */ |
1607 | if (retval != 0) | 1605 | if (retval != 0) |
1608 | goto end; | 1606 | goto end; |
1609 | } else { | 1607 | } else if (p->exit_state != EXIT_DEAD) { |
1610 | check_continued: | 1608 | check_continued: |
1611 | /* | 1609 | /* |
1612 | * It's running now, so it might later | 1610 | * It's running now, so it might later |
diff --git a/kernel/fork.c b/kernel/fork.c index 2b55b74cd999..3995297567a9 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1399,7 +1399,7 @@ fork_out: | |||
1399 | return ERR_PTR(retval); | 1399 | return ERR_PTR(retval); |
1400 | } | 1400 | } |
1401 | 1401 | ||
1402 | noinline struct pt_regs * __devinit __attribute__((weak)) idle_regs(struct pt_regs *regs) | 1402 | noinline struct pt_regs * __cpuinit __attribute__((weak)) idle_regs(struct pt_regs *regs) |
1403 | { | 1403 | { |
1404 | memset(regs, 0, sizeof(struct pt_regs)); | 1404 | memset(regs, 0, sizeof(struct pt_regs)); |
1405 | return regs; | 1405 | return regs; |
@@ -1510,7 +1510,7 @@ long do_fork(unsigned long clone_flags, | |||
1510 | if (!(clone_flags & CLONE_STOPPED)) | 1510 | if (!(clone_flags & CLONE_STOPPED)) |
1511 | wake_up_new_task(p, clone_flags); | 1511 | wake_up_new_task(p, clone_flags); |
1512 | else | 1512 | else |
1513 | p->state = TASK_STOPPED; | 1513 | __set_task_state(p, TASK_STOPPED); |
1514 | 1514 | ||
1515 | if (unlikely (trace)) { | 1515 | if (unlikely (trace)) { |
1516 | current->ptrace_message = nr; | 1516 | current->ptrace_message = nr; |
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 7dadc71ce516..f091d13def00 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -53,14 +53,6 @@ static inline int is_kernel_inittext(unsigned long addr) | |||
53 | return 0; | 53 | return 0; |
54 | } | 54 | } |
55 | 55 | ||
56 | static inline int is_kernel_extratext(unsigned long addr) | ||
57 | { | ||
58 | if (addr >= (unsigned long)_sextratext | ||
59 | && addr <= (unsigned long)_eextratext) | ||
60 | return 1; | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static inline int is_kernel_text(unsigned long addr) | 56 | static inline int is_kernel_text(unsigned long addr) |
65 | { | 57 | { |
66 | if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) | 58 | if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) |
@@ -80,8 +72,7 @@ static int is_ksym_addr(unsigned long addr) | |||
80 | if (all_var) | 72 | if (all_var) |
81 | return is_kernel(addr); | 73 | return is_kernel(addr); |
82 | 74 | ||
83 | return is_kernel_text(addr) || is_kernel_inittext(addr) || | 75 | return is_kernel_text(addr) || is_kernel_inittext(addr); |
84 | is_kernel_extratext(addr); | ||
85 | } | 76 | } |
86 | 77 | ||
87 | /* expand a compressed symbol data into the resulting uncompressed string, | 78 | /* expand a compressed symbol data into the resulting uncompressed string, |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index d0493eafea3e..7a86e6432338 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -699,6 +699,12 @@ static int __kprobes pre_handler_kretprobe(struct kprobe *p, | |||
699 | struct kretprobe_instance, uflist); | 699 | struct kretprobe_instance, uflist); |
700 | ri->rp = rp; | 700 | ri->rp = rp; |
701 | ri->task = current; | 701 | ri->task = current; |
702 | |||
703 | if (rp->entry_handler && rp->entry_handler(ri, regs)) { | ||
704 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
705 | return 0; | ||
706 | } | ||
707 | |||
702 | arch_prepare_kretprobe(ri, regs); | 708 | arch_prepare_kretprobe(ri, regs); |
703 | 709 | ||
704 | /* XXX(hch): why is there no hlist_move_head? */ | 710 | /* XXX(hch): why is there no hlist_move_head? */ |
@@ -745,7 +751,8 @@ int __kprobes register_kretprobe(struct kretprobe *rp) | |||
745 | INIT_HLIST_HEAD(&rp->used_instances); | 751 | INIT_HLIST_HEAD(&rp->used_instances); |
746 | INIT_HLIST_HEAD(&rp->free_instances); | 752 | INIT_HLIST_HEAD(&rp->free_instances); |
747 | for (i = 0; i < rp->maxactive; i++) { | 753 | for (i = 0; i < rp->maxactive; i++) { |
748 | inst = kmalloc(sizeof(struct kretprobe_instance), GFP_KERNEL); | 754 | inst = kmalloc(sizeof(struct kretprobe_instance) + |
755 | rp->data_size, GFP_KERNEL); | ||
749 | if (inst == NULL) { | 756 | if (inst == NULL) { |
750 | free_rp_inst(rp); | 757 | free_rp_inst(rp); |
751 | return -ENOMEM; | 758 | return -ENOMEM; |
diff --git a/kernel/notifier.c b/kernel/notifier.c index 4253f472f060..643360d1bb14 100644 --- a/kernel/notifier.c +++ b/kernel/notifier.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/notifier.h> | 4 | #include <linux/notifier.h> |
5 | #include <linux/rcupdate.h> | 5 | #include <linux/rcupdate.h> |
6 | #include <linux/vmalloc.h> | 6 | #include <linux/vmalloc.h> |
7 | #include <linux/reboot.h> | ||
7 | 8 | ||
8 | /* | 9 | /* |
9 | * Notifier list for kernel code which wants to be called | 10 | * Notifier list for kernel code which wants to be called |
diff --git a/kernel/params.c b/kernel/params.c index 42fe5e6126c0..e28c70628bb7 100644 --- a/kernel/params.c +++ b/kernel/params.c | |||
@@ -272,7 +272,7 @@ static int param_array(const char *name, | |||
272 | unsigned int min, unsigned int max, | 272 | unsigned int min, unsigned int max, |
273 | void *elem, int elemsize, | 273 | void *elem, int elemsize, |
274 | int (*set)(const char *, struct kernel_param *kp), | 274 | int (*set)(const char *, struct kernel_param *kp), |
275 | int *num) | 275 | unsigned int *num) |
276 | { | 276 | { |
277 | int ret; | 277 | int ret; |
278 | struct kernel_param kp; | 278 | struct kernel_param kp; |
diff --git a/kernel/printk.c b/kernel/printk.c index 29ae1e99cde0..4a090621f379 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -93,16 +93,16 @@ static int console_locked, console_suspended; | |||
93 | */ | 93 | */ |
94 | static DEFINE_SPINLOCK(logbuf_lock); | 94 | static DEFINE_SPINLOCK(logbuf_lock); |
95 | 95 | ||
96 | #define LOG_BUF_MASK (log_buf_len-1) | 96 | #define LOG_BUF_MASK (log_buf_len-1) |
97 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) | 97 | #define LOG_BUF(idx) (log_buf[(idx) & LOG_BUF_MASK]) |
98 | 98 | ||
99 | /* | 99 | /* |
100 | * The indices into log_buf are not constrained to log_buf_len - they | 100 | * The indices into log_buf are not constrained to log_buf_len - they |
101 | * must be masked before subscripting | 101 | * must be masked before subscripting |
102 | */ | 102 | */ |
103 | static unsigned long log_start; /* Index into log_buf: next char to be read by syslog() */ | 103 | static unsigned log_start; /* Index into log_buf: next char to be read by syslog() */ |
104 | static unsigned long con_start; /* Index into log_buf: next char to be sent to consoles */ | 104 | static unsigned con_start; /* Index into log_buf: next char to be sent to consoles */ |
105 | static unsigned long log_end; /* Index into log_buf: most-recently-written-char + 1 */ | 105 | static unsigned log_end; /* Index into log_buf: most-recently-written-char + 1 */ |
106 | 106 | ||
107 | /* | 107 | /* |
108 | * Array of consoles built from command line options (console=) | 108 | * Array of consoles built from command line options (console=) |
@@ -128,17 +128,17 @@ static int console_may_schedule; | |||
128 | static char __log_buf[__LOG_BUF_LEN]; | 128 | static char __log_buf[__LOG_BUF_LEN]; |
129 | static char *log_buf = __log_buf; | 129 | static char *log_buf = __log_buf; |
130 | static int log_buf_len = __LOG_BUF_LEN; | 130 | static int log_buf_len = __LOG_BUF_LEN; |
131 | static unsigned long logged_chars; /* Number of chars produced since last read+clear operation */ | 131 | static unsigned logged_chars; /* Number of chars produced since last read+clear operation */ |
132 | 132 | ||
133 | static int __init log_buf_len_setup(char *str) | 133 | static int __init log_buf_len_setup(char *str) |
134 | { | 134 | { |
135 | unsigned long size = memparse(str, &str); | 135 | unsigned size = memparse(str, &str); |
136 | unsigned long flags; | 136 | unsigned long flags; |
137 | 137 | ||
138 | if (size) | 138 | if (size) |
139 | size = roundup_pow_of_two(size); | 139 | size = roundup_pow_of_two(size); |
140 | if (size > log_buf_len) { | 140 | if (size > log_buf_len) { |
141 | unsigned long start, dest_idx, offset; | 141 | unsigned start, dest_idx, offset; |
142 | char *new_log_buf; | 142 | char *new_log_buf; |
143 | 143 | ||
144 | new_log_buf = alloc_bootmem(size); | 144 | new_log_buf = alloc_bootmem(size); |
@@ -295,7 +295,7 @@ int log_buf_read(int idx) | |||
295 | */ | 295 | */ |
296 | int do_syslog(int type, char __user *buf, int len) | 296 | int do_syslog(int type, char __user *buf, int len) |
297 | { | 297 | { |
298 | unsigned long i, j, limit, count; | 298 | unsigned i, j, limit, count; |
299 | int do_clear = 0; | 299 | int do_clear = 0; |
300 | char c; | 300 | char c; |
301 | int error = 0; | 301 | int error = 0; |
@@ -436,7 +436,7 @@ asmlinkage long sys_syslog(int type, char __user *buf, int len) | |||
436 | /* | 436 | /* |
437 | * Call the console drivers on a range of log_buf | 437 | * Call the console drivers on a range of log_buf |
438 | */ | 438 | */ |
439 | static void __call_console_drivers(unsigned long start, unsigned long end) | 439 | static void __call_console_drivers(unsigned start, unsigned end) |
440 | { | 440 | { |
441 | struct console *con; | 441 | struct console *con; |
442 | 442 | ||
@@ -463,8 +463,8 @@ early_param("ignore_loglevel", ignore_loglevel_setup); | |||
463 | /* | 463 | /* |
464 | * Write out chars from start to end - 1 inclusive | 464 | * Write out chars from start to end - 1 inclusive |
465 | */ | 465 | */ |
466 | static void _call_console_drivers(unsigned long start, | 466 | static void _call_console_drivers(unsigned start, |
467 | unsigned long end, int msg_log_level) | 467 | unsigned end, int msg_log_level) |
468 | { | 468 | { |
469 | if ((msg_log_level < console_loglevel || ignore_loglevel) && | 469 | if ((msg_log_level < console_loglevel || ignore_loglevel) && |
470 | console_drivers && start != end) { | 470 | console_drivers && start != end) { |
@@ -484,12 +484,12 @@ static void _call_console_drivers(unsigned long start, | |||
484 | * log_buf[start] to log_buf[end - 1]. | 484 | * log_buf[start] to log_buf[end - 1]. |
485 | * The console_sem must be held. | 485 | * The console_sem must be held. |
486 | */ | 486 | */ |
487 | static void call_console_drivers(unsigned long start, unsigned long end) | 487 | static void call_console_drivers(unsigned start, unsigned end) |
488 | { | 488 | { |
489 | unsigned long cur_index, start_print; | 489 | unsigned cur_index, start_print; |
490 | static int msg_level = -1; | 490 | static int msg_level = -1; |
491 | 491 | ||
492 | BUG_ON(((long)(start - end)) > 0); | 492 | BUG_ON(((int)(start - end)) > 0); |
493 | 493 | ||
494 | cur_index = start; | 494 | cur_index = start; |
495 | start_print = start; | 495 | start_print = start; |
@@ -790,7 +790,7 @@ asmlinkage long sys_syslog(int type, char __user *buf, int len) | |||
790 | return -ENOSYS; | 790 | return -ENOSYS; |
791 | } | 791 | } |
792 | 792 | ||
793 | static void call_console_drivers(unsigned long start, unsigned long end) | 793 | static void call_console_drivers(unsigned start, unsigned end) |
794 | { | 794 | { |
795 | } | 795 | } |
796 | 796 | ||
@@ -983,8 +983,8 @@ void wake_up_klogd(void) | |||
983 | void release_console_sem(void) | 983 | void release_console_sem(void) |
984 | { | 984 | { |
985 | unsigned long flags; | 985 | unsigned long flags; |
986 | unsigned long _con_start, _log_end; | 986 | unsigned _con_start, _log_end; |
987 | unsigned long wake_klogd = 0; | 987 | unsigned wake_klogd = 0; |
988 | 988 | ||
989 | if (console_suspended) { | 989 | if (console_suspended) { |
990 | up(&secondary_console_sem); | 990 | up(&secondary_console_sem); |
@@ -1275,7 +1275,7 @@ void tty_write_message(struct tty_struct *tty, char *msg) | |||
1275 | int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst) | 1275 | int __printk_ratelimit(int ratelimit_jiffies, int ratelimit_burst) |
1276 | { | 1276 | { |
1277 | static DEFINE_SPINLOCK(ratelimit_lock); | 1277 | static DEFINE_SPINLOCK(ratelimit_lock); |
1278 | static unsigned long toks = 10 * 5 * HZ; | 1278 | static unsigned toks = 10 * 5 * HZ; |
1279 | static unsigned long last_msg; | 1279 | static unsigned long last_msg; |
1280 | static int missed; | 1280 | static int missed; |
1281 | unsigned long flags; | 1281 | unsigned long flags; |
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index b0d4ab4dfd3d..628b03ab88a5 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/signal.h> | 20 | #include <linux/signal.h> |
21 | #include <linux/audit.h> | 21 | #include <linux/audit.h> |
22 | #include <linux/pid_namespace.h> | 22 | #include <linux/pid_namespace.h> |
23 | #include <linux/syscalls.h> | ||
23 | 24 | ||
24 | #include <asm/pgtable.h> | 25 | #include <asm/pgtable.h> |
25 | #include <asm/uaccess.h> | 26 | #include <asm/uaccess.h> |
@@ -53,7 +54,7 @@ void ptrace_untrace(struct task_struct *child) | |||
53 | spin_lock(&child->sighand->siglock); | 54 | spin_lock(&child->sighand->siglock); |
54 | if (task_is_traced(child)) { | 55 | if (task_is_traced(child)) { |
55 | if (child->signal->flags & SIGNAL_STOP_STOPPED) { | 56 | if (child->signal->flags & SIGNAL_STOP_STOPPED) { |
56 | child->state = TASK_STOPPED; | 57 | __set_task_state(child, TASK_STOPPED); |
57 | } else { | 58 | } else { |
58 | signal_wake_up(child, 1); | 59 | signal_wake_up(child, 1); |
59 | } | 60 | } |
@@ -103,18 +104,16 @@ int ptrace_check_attach(struct task_struct *child, int kill) | |||
103 | && child->signal != NULL) { | 104 | && child->signal != NULL) { |
104 | ret = 0; | 105 | ret = 0; |
105 | spin_lock_irq(&child->sighand->siglock); | 106 | spin_lock_irq(&child->sighand->siglock); |
106 | if (task_is_stopped(child)) { | 107 | if (task_is_stopped(child)) |
107 | child->state = TASK_TRACED; | 108 | child->state = TASK_TRACED; |
108 | } else if (!task_is_traced(child) && !kill) { | 109 | else if (!task_is_traced(child) && !kill) |
109 | ret = -ESRCH; | 110 | ret = -ESRCH; |
110 | } | ||
111 | spin_unlock_irq(&child->sighand->siglock); | 111 | spin_unlock_irq(&child->sighand->siglock); |
112 | } | 112 | } |
113 | read_unlock(&tasklist_lock); | 113 | read_unlock(&tasklist_lock); |
114 | 114 | ||
115 | if (!ret && !kill) { | 115 | if (!ret && !kill) |
116 | wait_task_inactive(child); | 116 | wait_task_inactive(child); |
117 | } | ||
118 | 117 | ||
119 | /* All systems go.. */ | 118 | /* All systems go.. */ |
120 | return ret; | 119 | return ret; |
diff --git a/kernel/relay.c b/kernel/relay.c index 7c0373322f18..d080b9d161a7 100644 --- a/kernel/relay.c +++ b/kernel/relay.c | |||
@@ -37,37 +37,31 @@ static void relay_file_mmap_close(struct vm_area_struct *vma) | |||
37 | } | 37 | } |
38 | 38 | ||
39 | /* | 39 | /* |
40 | * nopage() vm_op implementation for relay file mapping. | 40 | * fault() vm_op implementation for relay file mapping. |
41 | */ | 41 | */ |
42 | static struct page *relay_buf_nopage(struct vm_area_struct *vma, | 42 | static int relay_buf_fault(struct vm_area_struct *vma, struct vm_fault *vmf) |
43 | unsigned long address, | ||
44 | int *type) | ||
45 | { | 43 | { |
46 | struct page *page; | 44 | struct page *page; |
47 | struct rchan_buf *buf = vma->vm_private_data; | 45 | struct rchan_buf *buf = vma->vm_private_data; |
48 | unsigned long offset = address - vma->vm_start; | 46 | pgoff_t pgoff = vmf->pgoff; |
49 | 47 | ||
50 | if (address > vma->vm_end) | ||
51 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
52 | if (!buf) | 48 | if (!buf) |
53 | return NOPAGE_OOM; | 49 | return VM_FAULT_OOM; |
54 | 50 | ||
55 | page = vmalloc_to_page(buf->start + offset); | 51 | page = vmalloc_to_page(buf->start + (pgoff << PAGE_SHIFT)); |
56 | if (!page) | 52 | if (!page) |
57 | return NOPAGE_OOM; | 53 | return VM_FAULT_SIGBUS; |
58 | get_page(page); | 54 | get_page(page); |
55 | vmf->page = page; | ||
59 | 56 | ||
60 | if (type) | 57 | return 0; |
61 | *type = VM_FAULT_MINOR; | ||
62 | |||
63 | return page; | ||
64 | } | 58 | } |
65 | 59 | ||
66 | /* | 60 | /* |
67 | * vm_ops for relay file mappings. | 61 | * vm_ops for relay file mappings. |
68 | */ | 62 | */ |
69 | static struct vm_operations_struct relay_file_mmap_ops = { | 63 | static struct vm_operations_struct relay_file_mmap_ops = { |
70 | .nopage = relay_buf_nopage, | 64 | .fault = relay_buf_fault, |
71 | .close = relay_file_mmap_close, | 65 | .close = relay_file_mmap_close, |
72 | }; | 66 | }; |
73 | 67 | ||
diff --git a/kernel/signal.c b/kernel/signal.c index 6a5f97cd337a..5d30ff561847 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -1578,6 +1578,17 @@ static inline int may_ptrace_stop(void) | |||
1578 | } | 1578 | } |
1579 | 1579 | ||
1580 | /* | 1580 | /* |
1581 | * Return nonzero if there is a SIGKILL that should be waking us up. | ||
1582 | * Called with the siglock held. | ||
1583 | */ | ||
1584 | static int sigkill_pending(struct task_struct *tsk) | ||
1585 | { | ||
1586 | return ((sigismember(&tsk->pending.signal, SIGKILL) || | ||
1587 | sigismember(&tsk->signal->shared_pending.signal, SIGKILL)) && | ||
1588 | !unlikely(sigismember(&tsk->blocked, SIGKILL))); | ||
1589 | } | ||
1590 | |||
1591 | /* | ||
1581 | * This must be called with current->sighand->siglock held. | 1592 | * This must be called with current->sighand->siglock held. |
1582 | * | 1593 | * |
1583 | * This should be the path for all ptrace stops. | 1594 | * This should be the path for all ptrace stops. |
@@ -1590,6 +1601,26 @@ static inline int may_ptrace_stop(void) | |||
1590 | */ | 1601 | */ |
1591 | static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | 1602 | static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) |
1592 | { | 1603 | { |
1604 | int killed = 0; | ||
1605 | |||
1606 | if (arch_ptrace_stop_needed(exit_code, info)) { | ||
1607 | /* | ||
1608 | * The arch code has something special to do before a | ||
1609 | * ptrace stop. This is allowed to block, e.g. for faults | ||
1610 | * on user stack pages. We can't keep the siglock while | ||
1611 | * calling arch_ptrace_stop, so we must release it now. | ||
1612 | * To preserve proper semantics, we must do this before | ||
1613 | * any signal bookkeeping like checking group_stop_count. | ||
1614 | * Meanwhile, a SIGKILL could come in before we retake the | ||
1615 | * siglock. That must prevent us from sleeping in TASK_TRACED. | ||
1616 | * So after regaining the lock, we must check for SIGKILL. | ||
1617 | */ | ||
1618 | spin_unlock_irq(¤t->sighand->siglock); | ||
1619 | arch_ptrace_stop(exit_code, info); | ||
1620 | spin_lock_irq(¤t->sighand->siglock); | ||
1621 | killed = sigkill_pending(current); | ||
1622 | } | ||
1623 | |||
1593 | /* | 1624 | /* |
1594 | * If there is a group stop in progress, | 1625 | * If there is a group stop in progress, |
1595 | * we must participate in the bookkeeping. | 1626 | * we must participate in the bookkeeping. |
@@ -1601,11 +1632,11 @@ static void ptrace_stop(int exit_code, int nostop_code, siginfo_t *info) | |||
1601 | current->exit_code = exit_code; | 1632 | current->exit_code = exit_code; |
1602 | 1633 | ||
1603 | /* Let the debugger run. */ | 1634 | /* Let the debugger run. */ |
1604 | set_current_state(TASK_TRACED); | 1635 | __set_current_state(TASK_TRACED); |
1605 | spin_unlock_irq(¤t->sighand->siglock); | 1636 | spin_unlock_irq(¤t->sighand->siglock); |
1606 | try_to_freeze(); | 1637 | try_to_freeze(); |
1607 | read_lock(&tasklist_lock); | 1638 | read_lock(&tasklist_lock); |
1608 | if (may_ptrace_stop()) { | 1639 | if (!unlikely(killed) && may_ptrace_stop()) { |
1609 | do_notify_parent_cldstop(current, CLD_TRAPPED); | 1640 | do_notify_parent_cldstop(current, CLD_TRAPPED); |
1610 | read_unlock(&tasklist_lock); | 1641 | read_unlock(&tasklist_lock); |
1611 | schedule(); | 1642 | schedule(); |
diff --git a/kernel/srcu.c b/kernel/srcu.c index 3507cabe963b..b0aeeaf22ce4 100644 --- a/kernel/srcu.c +++ b/kernel/srcu.c | |||
@@ -74,7 +74,7 @@ static int srcu_readers_active_idx(struct srcu_struct *sp, int idx) | |||
74 | * severe errors when invoked on an active srcu_struct. That said, it | 74 | * severe errors when invoked on an active srcu_struct. That said, it |
75 | * can be useful as an error check at cleanup time. | 75 | * can be useful as an error check at cleanup time. |
76 | */ | 76 | */ |
77 | int srcu_readers_active(struct srcu_struct *sp) | 77 | static int srcu_readers_active(struct srcu_struct *sp) |
78 | { | 78 | { |
79 | return srcu_readers_active_idx(sp, 0) + srcu_readers_active_idx(sp, 1); | 79 | return srcu_readers_active_idx(sp, 0) + srcu_readers_active_idx(sp, 1); |
80 | } | 80 | } |
@@ -255,4 +255,3 @@ EXPORT_SYMBOL_GPL(srcu_read_lock); | |||
255 | EXPORT_SYMBOL_GPL(srcu_read_unlock); | 255 | EXPORT_SYMBOL_GPL(srcu_read_unlock); |
256 | EXPORT_SYMBOL_GPL(synchronize_srcu); | 256 | EXPORT_SYMBOL_GPL(synchronize_srcu); |
257 | EXPORT_SYMBOL_GPL(srcu_batches_completed); | 257 | EXPORT_SYMBOL_GPL(srcu_batches_completed); |
258 | EXPORT_SYMBOL_GPL(srcu_readers_active); | ||
diff --git a/kernel/stop_machine.c b/kernel/stop_machine.c index 51b5ee53571a..6f4e0e13f70c 100644 --- a/kernel/stop_machine.c +++ b/kernel/stop_machine.c | |||
@@ -29,7 +29,6 @@ enum stopmachine_state { | |||
29 | static enum stopmachine_state stopmachine_state; | 29 | static enum stopmachine_state stopmachine_state; |
30 | static unsigned int stopmachine_num_threads; | 30 | static unsigned int stopmachine_num_threads; |
31 | static atomic_t stopmachine_thread_ack; | 31 | static atomic_t stopmachine_thread_ack; |
32 | static DECLARE_MUTEX(stopmachine_mutex); | ||
33 | 32 | ||
34 | static int stopmachine(void *cpu) | 33 | static int stopmachine(void *cpu) |
35 | { | 34 | { |
@@ -170,6 +169,7 @@ static int do_stop(void *_smdata) | |||
170 | struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, | 169 | struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, |
171 | unsigned int cpu) | 170 | unsigned int cpu) |
172 | { | 171 | { |
172 | static DEFINE_MUTEX(stopmachine_mutex); | ||
173 | struct stop_machine_data smdata; | 173 | struct stop_machine_data smdata; |
174 | struct task_struct *p; | 174 | struct task_struct *p; |
175 | 175 | ||
@@ -177,7 +177,7 @@ struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, | |||
177 | smdata.data = data; | 177 | smdata.data = data; |
178 | init_completion(&smdata.done); | 178 | init_completion(&smdata.done); |
179 | 179 | ||
180 | down(&stopmachine_mutex); | 180 | mutex_lock(&stopmachine_mutex); |
181 | 181 | ||
182 | /* If they don't care which CPU fn runs on, bind to any online one. */ | 182 | /* If they don't care which CPU fn runs on, bind to any online one. */ |
183 | if (cpu == NR_CPUS) | 183 | if (cpu == NR_CPUS) |
@@ -193,7 +193,7 @@ struct task_struct *__stop_machine_run(int (*fn)(void *), void *data, | |||
193 | wake_up_process(p); | 193 | wake_up_process(p); |
194 | wait_for_completion(&smdata.done); | 194 | wait_for_completion(&smdata.done); |
195 | } | 195 | } |
196 | up(&stopmachine_mutex); | 196 | mutex_unlock(&stopmachine_mutex); |
197 | return p; | 197 | return p; |
198 | } | 198 | } |
199 | 199 | ||
diff --git a/kernel/sys.c b/kernel/sys.c index 53de35fc8245..e3c08d4324de 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1145,16 +1145,16 @@ static int groups_to_user(gid_t __user *grouplist, | |||
1145 | struct group_info *group_info) | 1145 | struct group_info *group_info) |
1146 | { | 1146 | { |
1147 | int i; | 1147 | int i; |
1148 | int count = group_info->ngroups; | 1148 | unsigned int count = group_info->ngroups; |
1149 | 1149 | ||
1150 | for (i = 0; i < group_info->nblocks; i++) { | 1150 | for (i = 0; i < group_info->nblocks; i++) { |
1151 | int cp_count = min(NGROUPS_PER_BLOCK, count); | 1151 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); |
1152 | int off = i * NGROUPS_PER_BLOCK; | 1152 | unsigned int len = cp_count * sizeof(*grouplist); |
1153 | int len = cp_count * sizeof(*grouplist); | ||
1154 | 1153 | ||
1155 | if (copy_to_user(grouplist+off, group_info->blocks[i], len)) | 1154 | if (copy_to_user(grouplist, group_info->blocks[i], len)) |
1156 | return -EFAULT; | 1155 | return -EFAULT; |
1157 | 1156 | ||
1157 | grouplist += NGROUPS_PER_BLOCK; | ||
1158 | count -= cp_count; | 1158 | count -= cp_count; |
1159 | } | 1159 | } |
1160 | return 0; | 1160 | return 0; |
@@ -1165,16 +1165,16 @@ static int groups_from_user(struct group_info *group_info, | |||
1165 | gid_t __user *grouplist) | 1165 | gid_t __user *grouplist) |
1166 | { | 1166 | { |
1167 | int i; | 1167 | int i; |
1168 | int count = group_info->ngroups; | 1168 | unsigned int count = group_info->ngroups; |
1169 | 1169 | ||
1170 | for (i = 0; i < group_info->nblocks; i++) { | 1170 | for (i = 0; i < group_info->nblocks; i++) { |
1171 | int cp_count = min(NGROUPS_PER_BLOCK, count); | 1171 | unsigned int cp_count = min(NGROUPS_PER_BLOCK, count); |
1172 | int off = i * NGROUPS_PER_BLOCK; | 1172 | unsigned int len = cp_count * sizeof(*grouplist); |
1173 | int len = cp_count * sizeof(*grouplist); | ||
1174 | 1173 | ||
1175 | if (copy_from_user(group_info->blocks[i], grouplist+off, len)) | 1174 | if (copy_from_user(group_info->blocks[i], grouplist, len)) |
1176 | return -EFAULT; | 1175 | return -EFAULT; |
1177 | 1176 | ||
1177 | grouplist += NGROUPS_PER_BLOCK; | ||
1178 | count -= cp_count; | 1178 | count -= cp_count; |
1179 | } | 1179 | } |
1180 | return 0; | 1180 | return 0; |
@@ -1472,7 +1472,7 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) | |||
1472 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && | 1472 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
1473 | !capable(CAP_SYS_RESOURCE)) | 1473 | !capable(CAP_SYS_RESOURCE)) |
1474 | return -EPERM; | 1474 | return -EPERM; |
1475 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN) | 1475 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) |
1476 | return -EPERM; | 1476 | return -EPERM; |
1477 | 1477 | ||
1478 | retval = security_task_setrlimit(resource, &new_rlim); | 1478 | retval = security_task_setrlimit(resource, &new_rlim); |
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 5e2ad5bf88e2..86daaa26d120 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1203,6 +1203,14 @@ static struct ctl_table fs_table[] = { | |||
1203 | .proc_handler = &proc_dointvec, | 1203 | .proc_handler = &proc_dointvec, |
1204 | }, | 1204 | }, |
1205 | { | 1205 | { |
1206 | .ctl_name = CTL_UNNUMBERED, | ||
1207 | .procname = "nr_open", | ||
1208 | .data = &sysctl_nr_open, | ||
1209 | .maxlen = sizeof(int), | ||
1210 | .mode = 0644, | ||
1211 | .proc_handler = &proc_dointvec, | ||
1212 | }, | ||
1213 | { | ||
1206 | .ctl_name = FS_DENTRY, | 1214 | .ctl_name = FS_DENTRY, |
1207 | .procname = "dentry-state", | 1215 | .procname = "dentry-state", |
1208 | .data = &dentry_stat, | 1216 | .data = &dentry_stat, |
diff --git a/kernel/test_kprobes.c b/kernel/test_kprobes.c index 88cdb109e13c..06b6395b45b2 100644 --- a/kernel/test_kprobes.c +++ b/kernel/test_kprobes.c | |||
@@ -135,6 +135,12 @@ static int test_jprobe(void) | |||
135 | #ifdef CONFIG_KRETPROBES | 135 | #ifdef CONFIG_KRETPROBES |
136 | static u32 krph_val; | 136 | static u32 krph_val; |
137 | 137 | ||
138 | static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | ||
139 | { | ||
140 | krph_val = (rand1 / div_factor); | ||
141 | return 0; | ||
142 | } | ||
143 | |||
138 | static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | 144 | static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) |
139 | { | 145 | { |
140 | unsigned long ret = regs_return_value(regs); | 146 | unsigned long ret = regs_return_value(regs); |
@@ -144,13 +150,19 @@ static int return_handler(struct kretprobe_instance *ri, struct pt_regs *regs) | |||
144 | printk(KERN_ERR "Kprobe smoke test failed: " | 150 | printk(KERN_ERR "Kprobe smoke test failed: " |
145 | "incorrect value in kretprobe handler\n"); | 151 | "incorrect value in kretprobe handler\n"); |
146 | } | 152 | } |
153 | if (krph_val == 0) { | ||
154 | handler_errors++; | ||
155 | printk(KERN_ERR "Kprobe smoke test failed: " | ||
156 | "call to kretprobe entry handler failed\n"); | ||
157 | } | ||
147 | 158 | ||
148 | krph_val = (rand1 / div_factor); | 159 | krph_val = rand1; |
149 | return 0; | 160 | return 0; |
150 | } | 161 | } |
151 | 162 | ||
152 | static struct kretprobe rp = { | 163 | static struct kretprobe rp = { |
153 | .handler = return_handler, | 164 | .handler = return_handler, |
165 | .entry_handler = entry_handler, | ||
154 | .kp.symbol_name = "kprobe_target" | 166 | .kp.symbol_name = "kprobe_target" |
155 | }; | 167 | }; |
156 | 168 | ||
@@ -167,7 +179,7 @@ static int test_kretprobe(void) | |||
167 | 179 | ||
168 | ret = kprobe_target(rand1); | 180 | ret = kprobe_target(rand1); |
169 | unregister_kretprobe(&rp); | 181 | unregister_kretprobe(&rp); |
170 | if (krph_val == 0) { | 182 | if (krph_val != rand1) { |
171 | printk(KERN_ERR "Kprobe smoke test failed: " | 183 | printk(KERN_ERR "Kprobe smoke test failed: " |
172 | "kretprobe handler not called\n"); | 184 | "kretprobe handler not called\n"); |
173 | handler_errors++; | 185 | handler_errors++; |
diff --git a/kernel/time.c b/kernel/time.c index 4064c0566e77..33af3e55570d 100644 --- a/kernel/time.c +++ b/kernel/time.c | |||
@@ -566,7 +566,11 @@ EXPORT_SYMBOL(jiffies_to_timeval); | |||
566 | clock_t jiffies_to_clock_t(long x) | 566 | clock_t jiffies_to_clock_t(long x) |
567 | { | 567 | { |
568 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 | 568 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 |
569 | # if HZ < USER_HZ | ||
570 | return x * (USER_HZ / HZ); | ||
571 | # else | ||
569 | return x / (HZ / USER_HZ); | 572 | return x / (HZ / USER_HZ); |
573 | # endif | ||
570 | #else | 574 | #else |
571 | u64 tmp = (u64)x * TICK_NSEC; | 575 | u64 tmp = (u64)x * TICK_NSEC; |
572 | do_div(tmp, (NSEC_PER_SEC / USER_HZ)); | 576 | do_div(tmp, (NSEC_PER_SEC / USER_HZ)); |
@@ -599,7 +603,14 @@ EXPORT_SYMBOL(clock_t_to_jiffies); | |||
599 | u64 jiffies_64_to_clock_t(u64 x) | 603 | u64 jiffies_64_to_clock_t(u64 x) |
600 | { | 604 | { |
601 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 | 605 | #if (TICK_NSEC % (NSEC_PER_SEC / USER_HZ)) == 0 |
606 | # if HZ < USER_HZ | ||
607 | x *= USER_HZ; | ||
608 | do_div(x, HZ); | ||
609 | # elif HZ > USER_HZ | ||
602 | do_div(x, HZ / USER_HZ); | 610 | do_div(x, HZ / USER_HZ); |
611 | # else | ||
612 | /* Nothing to do */ | ||
613 | # endif | ||
603 | #else | 614 | #else |
604 | /* | 615 | /* |
605 | * There are better ways that don't overflow early, | 616 | * There are better ways that don't overflow early, |
@@ -611,7 +622,6 @@ u64 jiffies_64_to_clock_t(u64 x) | |||
611 | #endif | 622 | #endif |
612 | return x; | 623 | return x; |
613 | } | 624 | } |
614 | |||
615 | EXPORT_SYMBOL(jiffies_64_to_clock_t); | 625 | EXPORT_SYMBOL(jiffies_64_to_clock_t); |
616 | 626 | ||
617 | u64 nsec_to_clock_t(u64 x) | 627 | u64 nsec_to_clock_t(u64 x) |
@@ -646,7 +656,6 @@ u64 get_jiffies_64(void) | |||
646 | } while (read_seqretry(&xtime_lock, seq)); | 656 | } while (read_seqretry(&xtime_lock, seq)); |
647 | return ret; | 657 | return ret; |
648 | } | 658 | } |
649 | |||
650 | EXPORT_SYMBOL(get_jiffies_64); | 659 | EXPORT_SYMBOL(get_jiffies_64); |
651 | #endif | 660 | #endif |
652 | 661 | ||
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index 6e9259a5d501..81afb3927ecc 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c | |||
@@ -363,15 +363,13 @@ void clocksource_unregister(struct clocksource *cs) | |||
363 | static ssize_t | 363 | static ssize_t |
364 | sysfs_show_current_clocksources(struct sys_device *dev, char *buf) | 364 | sysfs_show_current_clocksources(struct sys_device *dev, char *buf) |
365 | { | 365 | { |
366 | char *curr = buf; | 366 | ssize_t count = 0; |
367 | 367 | ||
368 | spin_lock_irq(&clocksource_lock); | 368 | spin_lock_irq(&clocksource_lock); |
369 | curr += sprintf(curr, "%s ", curr_clocksource->name); | 369 | count = snprintf(buf, PAGE_SIZE, "%s\n", curr_clocksource->name); |
370 | spin_unlock_irq(&clocksource_lock); | 370 | spin_unlock_irq(&clocksource_lock); |
371 | 371 | ||
372 | curr += sprintf(curr, "\n"); | 372 | return count; |
373 | |||
374 | return curr - buf; | ||
375 | } | 373 | } |
376 | 374 | ||
377 | /** | 375 | /** |
@@ -439,17 +437,20 @@ static ssize_t | |||
439 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) | 437 | sysfs_show_available_clocksources(struct sys_device *dev, char *buf) |
440 | { | 438 | { |
441 | struct clocksource *src; | 439 | struct clocksource *src; |
442 | char *curr = buf; | 440 | ssize_t count = 0; |
443 | 441 | ||
444 | spin_lock_irq(&clocksource_lock); | 442 | spin_lock_irq(&clocksource_lock); |
445 | list_for_each_entry(src, &clocksource_list, list) { | 443 | list_for_each_entry(src, &clocksource_list, list) { |
446 | curr += sprintf(curr, "%s ", src->name); | 444 | count += snprintf(buf + count, |
445 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), | ||
446 | "%s ", src->name); | ||
447 | } | 447 | } |
448 | spin_unlock_irq(&clocksource_lock); | 448 | spin_unlock_irq(&clocksource_lock); |
449 | 449 | ||
450 | curr += sprintf(curr, "\n"); | 450 | count += snprintf(buf + count, |
451 | max((ssize_t)PAGE_SIZE - count, (ssize_t)0), "\n"); | ||
451 | 452 | ||
452 | return curr - buf; | 453 | return count; |
453 | } | 454 | } |
454 | 455 | ||
455 | /* | 456 | /* |
diff --git a/kernel/timer.c b/kernel/timer.c index 9fbb472b8cf0..70b29b59343f 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -818,12 +818,14 @@ unsigned long next_timer_interrupt(void) | |||
818 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING | 818 | #ifndef CONFIG_VIRT_CPU_ACCOUNTING |
819 | void account_process_tick(struct task_struct *p, int user_tick) | 819 | void account_process_tick(struct task_struct *p, int user_tick) |
820 | { | 820 | { |
821 | cputime_t one_jiffy = jiffies_to_cputime(1); | ||
822 | |||
821 | if (user_tick) { | 823 | if (user_tick) { |
822 | account_user_time(p, jiffies_to_cputime(1)); | 824 | account_user_time(p, one_jiffy); |
823 | account_user_time_scaled(p, jiffies_to_cputime(1)); | 825 | account_user_time_scaled(p, cputime_to_scaled(one_jiffy)); |
824 | } else { | 826 | } else { |
825 | account_system_time(p, HARDIRQ_OFFSET, jiffies_to_cputime(1)); | 827 | account_system_time(p, HARDIRQ_OFFSET, one_jiffy); |
826 | account_system_time_scaled(p, jiffies_to_cputime(1)); | 828 | account_system_time_scaled(p, cputime_to_scaled(one_jiffy)); |
827 | } | 829 | } |
828 | } | 830 | } |
829 | #endif | 831 | #endif |
diff --git a/lib/extable.c b/lib/extable.c index 463f4560f16d..179c08745595 100644 --- a/lib/extable.c +++ b/lib/extable.c | |||
@@ -57,10 +57,10 @@ search_extable(const struct exception_table_entry *first, | |||
57 | while (first <= last) { | 57 | while (first <= last) { |
58 | const struct exception_table_entry *mid; | 58 | const struct exception_table_entry *mid; |
59 | 59 | ||
60 | mid = (last - first) / 2 + first; | 60 | mid = ((last - first) >> 1) + first; |
61 | /* | 61 | /* |
62 | * careful, the distance between entries can be | 62 | * careful, the distance between value and insn |
63 | * larger than 2GB: | 63 | * can be larger than MAX_LONG: |
64 | */ | 64 | */ |
65 | if (mid->insn < value) | 65 | if (mid->insn < value) |
66 | first = mid + 1; | 66 | first = mid + 1; |
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c index eddc9b3d3876..6c90fb90e19c 100644 --- a/lib/smp_processor_id.c +++ b/lib/smp_processor_id.c | |||
@@ -42,7 +42,9 @@ unsigned int debug_smp_processor_id(void) | |||
42 | if (!printk_ratelimit()) | 42 | if (!printk_ratelimit()) |
43 | goto out_enable; | 43 | goto out_enable; |
44 | 44 | ||
45 | printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] code: %s/%d\n", preempt_count(), current->comm, current->pid); | 45 | printk(KERN_ERR "BUG: using smp_processor_id() in preemptible [%08x] " |
46 | "code: %s/%d\n", | ||
47 | preempt_count() - 1, current->comm, current->pid); | ||
46 | print_symbol("caller is %s\n", (long)__builtin_return_address(0)); | 48 | print_symbol("caller is %s\n", (long)__builtin_return_address(0)); |
47 | dump_stack(); | 49 | dump_stack(); |
48 | 50 | ||
diff --git a/mm/Makefile b/mm/Makefile index 44e2528af70c..4af5dff37277 100644 --- a/mm/Makefile +++ b/mm/Makefile | |||
@@ -16,6 +16,7 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \ | |||
16 | obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o | 16 | obj-$(CONFIG_PROC_PAGE_MONITOR) += pagewalk.o |
17 | obj-$(CONFIG_BOUNCE) += bounce.o | 17 | obj-$(CONFIG_BOUNCE) += bounce.o |
18 | obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o | 18 | obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o |
19 | obj-$(CONFIG_HAS_DMA) += dmapool.o | ||
19 | obj-$(CONFIG_HUGETLBFS) += hugetlb.o | 20 | obj-$(CONFIG_HUGETLBFS) += hugetlb.o |
20 | obj-$(CONFIG_NUMA) += mempolicy.o | 21 | obj-$(CONFIG_NUMA) += mempolicy.o |
21 | obj-$(CONFIG_SPARSEMEM) += sparse.o | 22 | obj-$(CONFIG_SPARSEMEM) += sparse.o |
diff --git a/mm/allocpercpu.c b/mm/allocpercpu.c index 00b02623f008..7e58322b7134 100644 --- a/mm/allocpercpu.c +++ b/mm/allocpercpu.c | |||
@@ -98,7 +98,7 @@ EXPORT_SYMBOL_GPL(__percpu_populate_mask); | |||
98 | */ | 98 | */ |
99 | void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) | 99 | void *__percpu_alloc_mask(size_t size, gfp_t gfp, cpumask_t *mask) |
100 | { | 100 | { |
101 | void *pdata = kzalloc(sizeof(struct percpu_data), gfp); | 101 | void *pdata = kzalloc(nr_cpu_ids * sizeof(void *), gfp); |
102 | void *__pdata = __percpu_disguise(pdata); | 102 | void *__pdata = __percpu_disguise(pdata); |
103 | 103 | ||
104 | if (unlikely(!pdata)) | 104 | if (unlikely(!pdata)) |
diff --git a/mm/dmapool.c b/mm/dmapool.c new file mode 100644 index 000000000000..34aaac451a96 --- /dev/null +++ b/mm/dmapool.c | |||
@@ -0,0 +1,500 @@ | |||
1 | /* | ||
2 | * DMA Pool allocator | ||
3 | * | ||
4 | * Copyright 2001 David Brownell | ||
5 | * Copyright 2007 Intel Corporation | ||
6 | * Author: Matthew Wilcox <willy@linux.intel.com> | ||
7 | * | ||
8 | * This software may be redistributed and/or modified under the terms of | ||
9 | * the GNU General Public License ("GPL") version 2 as published by the | ||
10 | * Free Software Foundation. | ||
11 | * | ||
12 | * This allocator returns small blocks of a given size which are DMA-able by | ||
13 | * the given device. It uses the dma_alloc_coherent page allocator to get | ||
14 | * new pages, then splits them up into blocks of the required size. | ||
15 | * Many older drivers still have their own code to do this. | ||
16 | * | ||
17 | * The current design of this allocator is fairly simple. The pool is | ||
18 | * represented by the 'struct dma_pool' which keeps a doubly-linked list of | ||
19 | * allocated pages. Each page in the page_list is split into blocks of at | ||
20 | * least 'size' bytes. Free blocks are tracked in an unsorted singly-linked | ||
21 | * list of free blocks within the page. Used blocks aren't tracked, but we | ||
22 | * keep a count of how many are currently allocated from each page. | ||
23 | */ | ||
24 | |||
25 | #include <linux/device.h> | ||
26 | #include <linux/dma-mapping.h> | ||
27 | #include <linux/dmapool.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/module.h> | ||
31 | #include <linux/mutex.h> | ||
32 | #include <linux/poison.h> | ||
33 | #include <linux/sched.h> | ||
34 | #include <linux/slab.h> | ||
35 | #include <linux/spinlock.h> | ||
36 | #include <linux/string.h> | ||
37 | #include <linux/types.h> | ||
38 | #include <linux/wait.h> | ||
39 | |||
40 | struct dma_pool { /* the pool */ | ||
41 | struct list_head page_list; | ||
42 | spinlock_t lock; | ||
43 | size_t size; | ||
44 | struct device *dev; | ||
45 | size_t allocation; | ||
46 | size_t boundary; | ||
47 | char name[32]; | ||
48 | wait_queue_head_t waitq; | ||
49 | struct list_head pools; | ||
50 | }; | ||
51 | |||
52 | struct dma_page { /* cacheable header for 'allocation' bytes */ | ||
53 | struct list_head page_list; | ||
54 | void *vaddr; | ||
55 | dma_addr_t dma; | ||
56 | unsigned int in_use; | ||
57 | unsigned int offset; | ||
58 | }; | ||
59 | |||
60 | #define POOL_TIMEOUT_JIFFIES ((100 /* msec */ * HZ) / 1000) | ||
61 | |||
62 | static DEFINE_MUTEX(pools_lock); | ||
63 | |||
64 | static ssize_t | ||
65 | show_pools(struct device *dev, struct device_attribute *attr, char *buf) | ||
66 | { | ||
67 | unsigned temp; | ||
68 | unsigned size; | ||
69 | char *next; | ||
70 | struct dma_page *page; | ||
71 | struct dma_pool *pool; | ||
72 | |||
73 | next = buf; | ||
74 | size = PAGE_SIZE; | ||
75 | |||
76 | temp = scnprintf(next, size, "poolinfo - 0.1\n"); | ||
77 | size -= temp; | ||
78 | next += temp; | ||
79 | |||
80 | mutex_lock(&pools_lock); | ||
81 | list_for_each_entry(pool, &dev->dma_pools, pools) { | ||
82 | unsigned pages = 0; | ||
83 | unsigned blocks = 0; | ||
84 | |||
85 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
86 | pages++; | ||
87 | blocks += page->in_use; | ||
88 | } | ||
89 | |||
90 | /* per-pool info, no real statistics yet */ | ||
91 | temp = scnprintf(next, size, "%-16s %4u %4Zu %4Zu %2u\n", | ||
92 | pool->name, blocks, | ||
93 | pages * (pool->allocation / pool->size), | ||
94 | pool->size, pages); | ||
95 | size -= temp; | ||
96 | next += temp; | ||
97 | } | ||
98 | mutex_unlock(&pools_lock); | ||
99 | |||
100 | return PAGE_SIZE - size; | ||
101 | } | ||
102 | |||
103 | static DEVICE_ATTR(pools, S_IRUGO, show_pools, NULL); | ||
104 | |||
105 | /** | ||
106 | * dma_pool_create - Creates a pool of consistent memory blocks, for dma. | ||
107 | * @name: name of pool, for diagnostics | ||
108 | * @dev: device that will be doing the DMA | ||
109 | * @size: size of the blocks in this pool. | ||
110 | * @align: alignment requirement for blocks; must be a power of two | ||
111 | * @boundary: returned blocks won't cross this power of two boundary | ||
112 | * Context: !in_interrupt() | ||
113 | * | ||
114 | * Returns a dma allocation pool with the requested characteristics, or | ||
115 | * null if one can't be created. Given one of these pools, dma_pool_alloc() | ||
116 | * may be used to allocate memory. Such memory will all have "consistent" | ||
117 | * DMA mappings, accessible by the device and its driver without using | ||
118 | * cache flushing primitives. The actual size of blocks allocated may be | ||
119 | * larger than requested because of alignment. | ||
120 | * | ||
121 | * If @boundary is nonzero, objects returned from dma_pool_alloc() won't | ||
122 | * cross that size boundary. This is useful for devices which have | ||
123 | * addressing restrictions on individual DMA transfers, such as not crossing | ||
124 | * boundaries of 4KBytes. | ||
125 | */ | ||
126 | struct dma_pool *dma_pool_create(const char *name, struct device *dev, | ||
127 | size_t size, size_t align, size_t boundary) | ||
128 | { | ||
129 | struct dma_pool *retval; | ||
130 | size_t allocation; | ||
131 | |||
132 | if (align == 0) { | ||
133 | align = 1; | ||
134 | } else if (align & (align - 1)) { | ||
135 | return NULL; | ||
136 | } | ||
137 | |||
138 | if (size == 0) { | ||
139 | return NULL; | ||
140 | } else if (size < 4) { | ||
141 | size = 4; | ||
142 | } | ||
143 | |||
144 | if ((size % align) != 0) | ||
145 | size = ALIGN(size, align); | ||
146 | |||
147 | allocation = max_t(size_t, size, PAGE_SIZE); | ||
148 | |||
149 | if (!boundary) { | ||
150 | boundary = allocation; | ||
151 | } else if ((boundary < size) || (boundary & (boundary - 1))) { | ||
152 | return NULL; | ||
153 | } | ||
154 | |||
155 | retval = kmalloc_node(sizeof(*retval), GFP_KERNEL, dev_to_node(dev)); | ||
156 | if (!retval) | ||
157 | return retval; | ||
158 | |||
159 | strlcpy(retval->name, name, sizeof(retval->name)); | ||
160 | |||
161 | retval->dev = dev; | ||
162 | |||
163 | INIT_LIST_HEAD(&retval->page_list); | ||
164 | spin_lock_init(&retval->lock); | ||
165 | retval->size = size; | ||
166 | retval->boundary = boundary; | ||
167 | retval->allocation = allocation; | ||
168 | init_waitqueue_head(&retval->waitq); | ||
169 | |||
170 | if (dev) { | ||
171 | int ret; | ||
172 | |||
173 | mutex_lock(&pools_lock); | ||
174 | if (list_empty(&dev->dma_pools)) | ||
175 | ret = device_create_file(dev, &dev_attr_pools); | ||
176 | else | ||
177 | ret = 0; | ||
178 | /* note: not currently insisting "name" be unique */ | ||
179 | if (!ret) | ||
180 | list_add(&retval->pools, &dev->dma_pools); | ||
181 | else { | ||
182 | kfree(retval); | ||
183 | retval = NULL; | ||
184 | } | ||
185 | mutex_unlock(&pools_lock); | ||
186 | } else | ||
187 | INIT_LIST_HEAD(&retval->pools); | ||
188 | |||
189 | return retval; | ||
190 | } | ||
191 | EXPORT_SYMBOL(dma_pool_create); | ||
192 | |||
193 | static void pool_initialise_page(struct dma_pool *pool, struct dma_page *page) | ||
194 | { | ||
195 | unsigned int offset = 0; | ||
196 | unsigned int next_boundary = pool->boundary; | ||
197 | |||
198 | do { | ||
199 | unsigned int next = offset + pool->size; | ||
200 | if (unlikely((next + pool->size) >= next_boundary)) { | ||
201 | next = next_boundary; | ||
202 | next_boundary += pool->boundary; | ||
203 | } | ||
204 | *(int *)(page->vaddr + offset) = next; | ||
205 | offset = next; | ||
206 | } while (offset < pool->allocation); | ||
207 | } | ||
208 | |||
209 | static struct dma_page *pool_alloc_page(struct dma_pool *pool, gfp_t mem_flags) | ||
210 | { | ||
211 | struct dma_page *page; | ||
212 | |||
213 | page = kmalloc(sizeof(*page), mem_flags); | ||
214 | if (!page) | ||
215 | return NULL; | ||
216 | page->vaddr = dma_alloc_coherent(pool->dev, pool->allocation, | ||
217 | &page->dma, mem_flags); | ||
218 | if (page->vaddr) { | ||
219 | #ifdef CONFIG_DEBUG_SLAB | ||
220 | memset(page->vaddr, POOL_POISON_FREED, pool->allocation); | ||
221 | #endif | ||
222 | pool_initialise_page(pool, page); | ||
223 | list_add(&page->page_list, &pool->page_list); | ||
224 | page->in_use = 0; | ||
225 | page->offset = 0; | ||
226 | } else { | ||
227 | kfree(page); | ||
228 | page = NULL; | ||
229 | } | ||
230 | return page; | ||
231 | } | ||
232 | |||
233 | static inline int is_page_busy(struct dma_page *page) | ||
234 | { | ||
235 | return page->in_use != 0; | ||
236 | } | ||
237 | |||
238 | static void pool_free_page(struct dma_pool *pool, struct dma_page *page) | ||
239 | { | ||
240 | dma_addr_t dma = page->dma; | ||
241 | |||
242 | #ifdef CONFIG_DEBUG_SLAB | ||
243 | memset(page->vaddr, POOL_POISON_FREED, pool->allocation); | ||
244 | #endif | ||
245 | dma_free_coherent(pool->dev, pool->allocation, page->vaddr, dma); | ||
246 | list_del(&page->page_list); | ||
247 | kfree(page); | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * dma_pool_destroy - destroys a pool of dma memory blocks. | ||
252 | * @pool: dma pool that will be destroyed | ||
253 | * Context: !in_interrupt() | ||
254 | * | ||
255 | * Caller guarantees that no more memory from the pool is in use, | ||
256 | * and that nothing will try to use the pool after this call. | ||
257 | */ | ||
258 | void dma_pool_destroy(struct dma_pool *pool) | ||
259 | { | ||
260 | mutex_lock(&pools_lock); | ||
261 | list_del(&pool->pools); | ||
262 | if (pool->dev && list_empty(&pool->dev->dma_pools)) | ||
263 | device_remove_file(pool->dev, &dev_attr_pools); | ||
264 | mutex_unlock(&pools_lock); | ||
265 | |||
266 | while (!list_empty(&pool->page_list)) { | ||
267 | struct dma_page *page; | ||
268 | page = list_entry(pool->page_list.next, | ||
269 | struct dma_page, page_list); | ||
270 | if (is_page_busy(page)) { | ||
271 | if (pool->dev) | ||
272 | dev_err(pool->dev, | ||
273 | "dma_pool_destroy %s, %p busy\n", | ||
274 | pool->name, page->vaddr); | ||
275 | else | ||
276 | printk(KERN_ERR | ||
277 | "dma_pool_destroy %s, %p busy\n", | ||
278 | pool->name, page->vaddr); | ||
279 | /* leak the still-in-use consistent memory */ | ||
280 | list_del(&page->page_list); | ||
281 | kfree(page); | ||
282 | } else | ||
283 | pool_free_page(pool, page); | ||
284 | } | ||
285 | |||
286 | kfree(pool); | ||
287 | } | ||
288 | EXPORT_SYMBOL(dma_pool_destroy); | ||
289 | |||
290 | /** | ||
291 | * dma_pool_alloc - get a block of consistent memory | ||
292 | * @pool: dma pool that will produce the block | ||
293 | * @mem_flags: GFP_* bitmask | ||
294 | * @handle: pointer to dma address of block | ||
295 | * | ||
296 | * This returns the kernel virtual address of a currently unused block, | ||
297 | * and reports its dma address through the handle. | ||
298 | * If such a memory block can't be allocated, %NULL is returned. | ||
299 | */ | ||
300 | void *dma_pool_alloc(struct dma_pool *pool, gfp_t mem_flags, | ||
301 | dma_addr_t *handle) | ||
302 | { | ||
303 | unsigned long flags; | ||
304 | struct dma_page *page; | ||
305 | size_t offset; | ||
306 | void *retval; | ||
307 | |||
308 | spin_lock_irqsave(&pool->lock, flags); | ||
309 | restart: | ||
310 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
311 | if (page->offset < pool->allocation) | ||
312 | goto ready; | ||
313 | } | ||
314 | page = pool_alloc_page(pool, GFP_ATOMIC); | ||
315 | if (!page) { | ||
316 | if (mem_flags & __GFP_WAIT) { | ||
317 | DECLARE_WAITQUEUE(wait, current); | ||
318 | |||
319 | __set_current_state(TASK_INTERRUPTIBLE); | ||
320 | __add_wait_queue(&pool->waitq, &wait); | ||
321 | spin_unlock_irqrestore(&pool->lock, flags); | ||
322 | |||
323 | schedule_timeout(POOL_TIMEOUT_JIFFIES); | ||
324 | |||
325 | spin_lock_irqsave(&pool->lock, flags); | ||
326 | __remove_wait_queue(&pool->waitq, &wait); | ||
327 | goto restart; | ||
328 | } | ||
329 | retval = NULL; | ||
330 | goto done; | ||
331 | } | ||
332 | |||
333 | ready: | ||
334 | page->in_use++; | ||
335 | offset = page->offset; | ||
336 | page->offset = *(int *)(page->vaddr + offset); | ||
337 | retval = offset + page->vaddr; | ||
338 | *handle = offset + page->dma; | ||
339 | #ifdef CONFIG_DEBUG_SLAB | ||
340 | memset(retval, POOL_POISON_ALLOCATED, pool->size); | ||
341 | #endif | ||
342 | done: | ||
343 | spin_unlock_irqrestore(&pool->lock, flags); | ||
344 | return retval; | ||
345 | } | ||
346 | EXPORT_SYMBOL(dma_pool_alloc); | ||
347 | |||
348 | static struct dma_page *pool_find_page(struct dma_pool *pool, dma_addr_t dma) | ||
349 | { | ||
350 | unsigned long flags; | ||
351 | struct dma_page *page; | ||
352 | |||
353 | spin_lock_irqsave(&pool->lock, flags); | ||
354 | list_for_each_entry(page, &pool->page_list, page_list) { | ||
355 | if (dma < page->dma) | ||
356 | continue; | ||
357 | if (dma < (page->dma + pool->allocation)) | ||
358 | goto done; | ||
359 | } | ||
360 | page = NULL; | ||
361 | done: | ||
362 | spin_unlock_irqrestore(&pool->lock, flags); | ||
363 | return page; | ||
364 | } | ||
365 | |||
366 | /** | ||
367 | * dma_pool_free - put block back into dma pool | ||
368 | * @pool: the dma pool holding the block | ||
369 | * @vaddr: virtual address of block | ||
370 | * @dma: dma address of block | ||
371 | * | ||
372 | * Caller promises neither device nor driver will again touch this block | ||
373 | * unless it is first re-allocated. | ||
374 | */ | ||
375 | void dma_pool_free(struct dma_pool *pool, void *vaddr, dma_addr_t dma) | ||
376 | { | ||
377 | struct dma_page *page; | ||
378 | unsigned long flags; | ||
379 | unsigned int offset; | ||
380 | |||
381 | page = pool_find_page(pool, dma); | ||
382 | if (!page) { | ||
383 | if (pool->dev) | ||
384 | dev_err(pool->dev, | ||
385 | "dma_pool_free %s, %p/%lx (bad dma)\n", | ||
386 | pool->name, vaddr, (unsigned long)dma); | ||
387 | else | ||
388 | printk(KERN_ERR "dma_pool_free %s, %p/%lx (bad dma)\n", | ||
389 | pool->name, vaddr, (unsigned long)dma); | ||
390 | return; | ||
391 | } | ||
392 | |||
393 | offset = vaddr - page->vaddr; | ||
394 | #ifdef CONFIG_DEBUG_SLAB | ||
395 | if ((dma - page->dma) != offset) { | ||
396 | if (pool->dev) | ||
397 | dev_err(pool->dev, | ||
398 | "dma_pool_free %s, %p (bad vaddr)/%Lx\n", | ||
399 | pool->name, vaddr, (unsigned long long)dma); | ||
400 | else | ||
401 | printk(KERN_ERR | ||
402 | "dma_pool_free %s, %p (bad vaddr)/%Lx\n", | ||
403 | pool->name, vaddr, (unsigned long long)dma); | ||
404 | return; | ||
405 | } | ||
406 | { | ||
407 | unsigned int chain = page->offset; | ||
408 | while (chain < pool->allocation) { | ||
409 | if (chain != offset) { | ||
410 | chain = *(int *)(page->vaddr + chain); | ||
411 | continue; | ||
412 | } | ||
413 | if (pool->dev) | ||
414 | dev_err(pool->dev, "dma_pool_free %s, dma %Lx " | ||
415 | "already free\n", pool->name, | ||
416 | (unsigned long long)dma); | ||
417 | else | ||
418 | printk(KERN_ERR "dma_pool_free %s, dma %Lx " | ||
419 | "already free\n", pool->name, | ||
420 | (unsigned long long)dma); | ||
421 | return; | ||
422 | } | ||
423 | } | ||
424 | memset(vaddr, POOL_POISON_FREED, pool->size); | ||
425 | #endif | ||
426 | |||
427 | spin_lock_irqsave(&pool->lock, flags); | ||
428 | page->in_use--; | ||
429 | *(int *)vaddr = page->offset; | ||
430 | page->offset = offset; | ||
431 | if (waitqueue_active(&pool->waitq)) | ||
432 | wake_up_locked(&pool->waitq); | ||
433 | /* | ||
434 | * Resist a temptation to do | ||
435 | * if (!is_page_busy(page)) pool_free_page(pool, page); | ||
436 | * Better have a few empty pages hang around. | ||
437 | */ | ||
438 | spin_unlock_irqrestore(&pool->lock, flags); | ||
439 | } | ||
440 | EXPORT_SYMBOL(dma_pool_free); | ||
441 | |||
442 | /* | ||
443 | * Managed DMA pool | ||
444 | */ | ||
445 | static void dmam_pool_release(struct device *dev, void *res) | ||
446 | { | ||
447 | struct dma_pool *pool = *(struct dma_pool **)res; | ||
448 | |||
449 | dma_pool_destroy(pool); | ||
450 | } | ||
451 | |||
452 | static int dmam_pool_match(struct device *dev, void *res, void *match_data) | ||
453 | { | ||
454 | return *(struct dma_pool **)res == match_data; | ||
455 | } | ||
456 | |||
457 | /** | ||
458 | * dmam_pool_create - Managed dma_pool_create() | ||
459 | * @name: name of pool, for diagnostics | ||
460 | * @dev: device that will be doing the DMA | ||
461 | * @size: size of the blocks in this pool. | ||
462 | * @align: alignment requirement for blocks; must be a power of two | ||
463 | * @allocation: returned blocks won't cross this boundary (or zero) | ||
464 | * | ||
465 | * Managed dma_pool_create(). DMA pool created with this function is | ||
466 | * automatically destroyed on driver detach. | ||
467 | */ | ||
468 | struct dma_pool *dmam_pool_create(const char *name, struct device *dev, | ||
469 | size_t size, size_t align, size_t allocation) | ||
470 | { | ||
471 | struct dma_pool **ptr, *pool; | ||
472 | |||
473 | ptr = devres_alloc(dmam_pool_release, sizeof(*ptr), GFP_KERNEL); | ||
474 | if (!ptr) | ||
475 | return NULL; | ||
476 | |||
477 | pool = *ptr = dma_pool_create(name, dev, size, align, allocation); | ||
478 | if (pool) | ||
479 | devres_add(dev, ptr); | ||
480 | else | ||
481 | devres_free(ptr); | ||
482 | |||
483 | return pool; | ||
484 | } | ||
485 | EXPORT_SYMBOL(dmam_pool_create); | ||
486 | |||
487 | /** | ||
488 | * dmam_pool_destroy - Managed dma_pool_destroy() | ||
489 | * @pool: dma pool that will be destroyed | ||
490 | * | ||
491 | * Managed dma_pool_destroy(). | ||
492 | */ | ||
493 | void dmam_pool_destroy(struct dma_pool *pool) | ||
494 | { | ||
495 | struct device *dev = pool->dev; | ||
496 | |||
497 | dma_pool_destroy(pool); | ||
498 | WARN_ON(devres_destroy(dev, dmam_pool_release, dmam_pool_match, pool)); | ||
499 | } | ||
500 | EXPORT_SYMBOL(dmam_pool_destroy); | ||
diff --git a/scripts/checkstack.pl b/scripts/checkstack.pl index d716b76098bb..340ad6920511 100755 --- a/scripts/checkstack.pl +++ b/scripts/checkstack.pl | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | # Check the stack usage of functions | 3 | # Check the stack usage of functions |
4 | # | 4 | # |
5 | # Copyright Joern Engel <joern@wh.fh-wedel.de> | 5 | # Copyright Joern Engel <joern@lazybastard.org> |
6 | # Inspired by Linus Torvalds | 6 | # Inspired by Linus Torvalds |
7 | # Original idea maybe from Keith Owens | 7 | # Original idea maybe from Keith Owens |
8 | # s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de> | 8 | # s390 port and big speedup by Arnd Bergmann <arnd@bergmann-dalldorf.de> |
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 1f11d848532a..c912137f80e2 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
@@ -31,17 +31,16 @@ | |||
31 | 31 | ||
32 | #define KSYM_NAME_LEN 128 | 32 | #define KSYM_NAME_LEN 128 |
33 | 33 | ||
34 | |||
35 | struct sym_entry { | 34 | struct sym_entry { |
36 | unsigned long long addr; | 35 | unsigned long long addr; |
37 | unsigned int len; | 36 | unsigned int len; |
37 | unsigned int start_pos; | ||
38 | unsigned char *sym; | 38 | unsigned char *sym; |
39 | }; | 39 | }; |
40 | 40 | ||
41 | |||
42 | static struct sym_entry *table; | 41 | static struct sym_entry *table; |
43 | static unsigned int table_size, table_cnt; | 42 | static unsigned int table_size, table_cnt; |
44 | static unsigned long long _text, _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; | 43 | static unsigned long long _text, _stext, _etext, _sinittext, _einittext; |
45 | static int all_symbols = 0; | 44 | static int all_symbols = 0; |
46 | static char symbol_prefix_char = '\0'; | 45 | static char symbol_prefix_char = '\0'; |
47 | 46 | ||
@@ -99,10 +98,6 @@ static int read_symbol(FILE *in, struct sym_entry *s) | |||
99 | _sinittext = s->addr; | 98 | _sinittext = s->addr; |
100 | else if (strcmp(sym, "_einittext") == 0) | 99 | else if (strcmp(sym, "_einittext") == 0) |
101 | _einittext = s->addr; | 100 | _einittext = s->addr; |
102 | else if (strcmp(sym, "_sextratext") == 0) | ||
103 | _sextratext = s->addr; | ||
104 | else if (strcmp(sym, "_eextratext") == 0) | ||
105 | _eextratext = s->addr; | ||
106 | else if (toupper(stype) == 'A') | 101 | else if (toupper(stype) == 'A') |
107 | { | 102 | { |
108 | /* Keep these useful absolute symbols */ | 103 | /* Keep these useful absolute symbols */ |
@@ -165,18 +160,18 @@ static int symbol_valid(struct sym_entry *s) | |||
165 | * and inittext sections are discarded */ | 160 | * and inittext sections are discarded */ |
166 | if (!all_symbols) { | 161 | if (!all_symbols) { |
167 | if ((s->addr < _stext || s->addr > _etext) | 162 | if ((s->addr < _stext || s->addr > _etext) |
168 | && (s->addr < _sinittext || s->addr > _einittext) | 163 | && (s->addr < _sinittext || s->addr > _einittext)) |
169 | && (s->addr < _sextratext || s->addr > _eextratext)) | ||
170 | return 0; | 164 | return 0; |
171 | /* Corner case. Discard any symbols with the same value as | 165 | /* Corner case. Discard any symbols with the same value as |
172 | * _etext _einittext or _eextratext; they can move between pass | 166 | * _etext _einittext; they can move between pass 1 and 2 when |
173 | * 1 and 2 when the kallsyms data are added. If these symbols | 167 | * the kallsyms data are added. If these symbols move then |
174 | * move then they may get dropped in pass 2, which breaks the | 168 | * they may get dropped in pass 2, which breaks the kallsyms |
175 | * kallsyms rules. | 169 | * rules. |
176 | */ | 170 | */ |
177 | if ((s->addr == _etext && strcmp((char*)s->sym + offset, "_etext")) || | 171 | if ((s->addr == _etext && |
178 | (s->addr == _einittext && strcmp((char*)s->sym + offset, "_einittext")) || | 172 | strcmp((char *)s->sym + offset, "_etext")) || |
179 | (s->addr == _eextratext && strcmp((char*)s->sym + offset, "_eextratext"))) | 173 | (s->addr == _einittext && |
174 | strcmp((char *)s->sym + offset, "_einittext"))) | ||
180 | return 0; | 175 | return 0; |
181 | } | 176 | } |
182 | 177 | ||
@@ -202,8 +197,10 @@ static void read_map(FILE *in) | |||
202 | exit (1); | 197 | exit (1); |
203 | } | 198 | } |
204 | } | 199 | } |
205 | if (read_symbol(in, &table[table_cnt]) == 0) | 200 | if (read_symbol(in, &table[table_cnt]) == 0) { |
201 | table[table_cnt].start_pos = table_cnt; | ||
206 | table_cnt++; | 202 | table_cnt++; |
203 | } | ||
207 | } | 204 | } |
208 | } | 205 | } |
209 | 206 | ||
@@ -506,6 +503,35 @@ static void optimize_token_table(void) | |||
506 | optimize_result(); | 503 | optimize_result(); |
507 | } | 504 | } |
508 | 505 | ||
506 | static int compare_symbols(const void *a, const void *b) | ||
507 | { | ||
508 | const struct sym_entry *sa; | ||
509 | const struct sym_entry *sb; | ||
510 | int wa, wb; | ||
511 | |||
512 | sa = a; | ||
513 | sb = b; | ||
514 | |||
515 | /* sort by address first */ | ||
516 | if (sa->addr > sb->addr) | ||
517 | return 1; | ||
518 | if (sa->addr < sb->addr) | ||
519 | return -1; | ||
520 | |||
521 | /* sort by "weakness" type */ | ||
522 | wa = (sa->sym[0] == 'w') || (sa->sym[0] == 'W'); | ||
523 | wb = (sb->sym[0] == 'w') || (sb->sym[0] == 'W'); | ||
524 | if (wa != wb) | ||
525 | return wa - wb; | ||
526 | |||
527 | /* sort by initial order, so that other symbols are left undisturbed */ | ||
528 | return sa->start_pos - sb->start_pos; | ||
529 | } | ||
530 | |||
531 | static void sort_symbols(void) | ||
532 | { | ||
533 | qsort(table, table_cnt, sizeof(struct sym_entry), compare_symbols); | ||
534 | } | ||
509 | 535 | ||
510 | int main(int argc, char **argv) | 536 | int main(int argc, char **argv) |
511 | { | 537 | { |
@@ -527,6 +553,7 @@ int main(int argc, char **argv) | |||
527 | usage(); | 553 | usage(); |
528 | 554 | ||
529 | read_map(stdin); | 555 | read_map(stdin); |
556 | sort_symbols(); | ||
530 | optimize_token_table(); | 557 | optimize_token_table(); |
531 | write_src(); | 558 | write_src(); |
532 | 559 | ||
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index f883c4b676ab..1f86299fae40 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
@@ -6,7 +6,6 @@ | |||
6 | # Each configuration option enables a list of files. | 6 | # Each configuration option enables a list of files. |
7 | 7 | ||
8 | obj-$(CONFIG_SOUND_OSS) += sound.o | 8 | obj-$(CONFIG_SOUND_OSS) += sound.o |
9 | obj-$(CONFIG_SOUND_CS4232) += cs4232.o ad1848.o | ||
10 | 9 | ||
11 | # Please leave it as is, cause the link order is significant ! | 10 | # Please leave it as is, cause the link order is significant ! |
12 | 11 | ||
@@ -16,7 +15,6 @@ obj-$(CONFIG_SOUND_AEDSP16) += aedsp16.o | |||
16 | obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o | 15 | obj-$(CONFIG_SOUND_PSS) += pss.o ad1848.o mpu401.o |
17 | obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o | 16 | obj-$(CONFIG_SOUND_TRIX) += trix.o ad1848.o sb_lib.o uart401.o |
18 | obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o | 17 | obj-$(CONFIG_SOUND_SSCAPE) += sscape.o ad1848.o mpu401.o |
19 | obj-$(CONFIG_SOUND_CS4232) += cs4232.o uart401.o | ||
20 | obj-$(CONFIG_SOUND_MSS) += ad1848.o | 18 | obj-$(CONFIG_SOUND_MSS) += ad1848.o |
21 | obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o | 19 | obj-$(CONFIG_SOUND_PAS) += pas2.o sb.o sb_lib.o uart401.o |
22 | obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o | 20 | obj-$(CONFIG_SOUND_SB) += sb.o sb_lib.o uart401.o |
@@ -27,19 +25,12 @@ obj-$(CONFIG_SOUND_YM3812) += opl3.o | |||
27 | obj-$(CONFIG_SOUND_VMIDI) += v_midi.o | 25 | obj-$(CONFIG_SOUND_VMIDI) += v_midi.o |
28 | obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o | 26 | obj-$(CONFIG_SOUND_VIDC) += vidc_mod.o |
29 | obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o | 27 | obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o |
30 | |||
31 | obj-$(CONFIG_SOUND_VIA82CXXX) += via82cxxx_audio.o ac97_codec.o | ||
32 | ifeq ($(CONFIG_MIDI_VIA82CXXX),y) | ||
33 | obj-$(CONFIG_SOUND_VIA82CXXX) += sound.o uart401.o | ||
34 | endif | ||
35 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o | 28 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o |
36 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o | 29 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o |
37 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o | 30 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o |
38 | obj-$(CONFIG_SOUND_ICH) += i810_audio.o ac97_codec.o | ||
39 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o | 31 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o |
40 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o | 32 | obj-$(CONFIG_SOUND_TRIDENT) += trident.o ac97_codec.o |
41 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o | 33 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o |
42 | obj-$(CONFIG_SOUND_BT878) += btaudio.o | ||
43 | 34 | ||
44 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o | 35 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o |
45 | 36 | ||
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index fef56cac06c8..87a672680761 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c | |||
@@ -189,42 +189,6 @@ static const struct { | |||
189 | {0x57454301, "Winbond 83971D", &null_ops}, | 189 | {0x57454301, "Winbond 83971D", &null_ops}, |
190 | }; | 190 | }; |
191 | 191 | ||
192 | static const char *ac97_stereo_enhancements[] = | ||
193 | { | ||
194 | /* 0 */ "No 3D Stereo Enhancement", | ||
195 | /* 1 */ "Analog Devices Phat Stereo", | ||
196 | /* 2 */ "Creative Stereo Enhancement", | ||
197 | /* 3 */ "National Semi 3D Stereo Enhancement", | ||
198 | /* 4 */ "YAMAHA Ymersion", | ||
199 | /* 5 */ "BBE 3D Stereo Enhancement", | ||
200 | /* 6 */ "Crystal Semi 3D Stereo Enhancement", | ||
201 | /* 7 */ "Qsound QXpander", | ||
202 | /* 8 */ "Spatializer 3D Stereo Enhancement", | ||
203 | /* 9 */ "SRS 3D Stereo Enhancement", | ||
204 | /* 10 */ "Platform Tech 3D Stereo Enhancement", | ||
205 | /* 11 */ "AKM 3D Audio", | ||
206 | /* 12 */ "Aureal Stereo Enhancement", | ||
207 | /* 13 */ "Aztech 3D Enhancement", | ||
208 | /* 14 */ "Binaura 3D Audio Enhancement", | ||
209 | /* 15 */ "ESS Technology Stereo Enhancement", | ||
210 | /* 16 */ "Harman International VMAx", | ||
211 | /* 17 */ "Nvidea 3D Stereo Enhancement", | ||
212 | /* 18 */ "Philips Incredible Sound", | ||
213 | /* 19 */ "Texas Instruments 3D Stereo Enhancement", | ||
214 | /* 20 */ "VLSI Technology 3D Stereo Enhancement", | ||
215 | /* 21 */ "TriTech 3D Stereo Enhancement", | ||
216 | /* 22 */ "Realtek 3D Stereo Enhancement", | ||
217 | /* 23 */ "Samsung 3D Stereo Enhancement", | ||
218 | /* 24 */ "Wolfson Microelectronics 3D Enhancement", | ||
219 | /* 25 */ "Delta Integration 3D Enhancement", | ||
220 | /* 26 */ "SigmaTel 3D Enhancement", | ||
221 | /* 27 */ "Winbond 3D Stereo Enhancement", | ||
222 | /* 28 */ "Rockwell 3D Stereo Enhancement", | ||
223 | /* 29 */ "Reserved 29", | ||
224 | /* 30 */ "Reserved 30", | ||
225 | /* 31 */ "Reserved 31" | ||
226 | }; | ||
227 | |||
228 | /* this table has default mixer values for all OSS mixers. */ | 192 | /* this table has default mixer values for all OSS mixers. */ |
229 | static struct mixer_defaults { | 193 | static struct mixer_defaults { |
230 | int mixer; | 194 | int mixer; |
@@ -614,83 +578,6 @@ static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned | |||
614 | return -EINVAL; | 578 | return -EINVAL; |
615 | } | 579 | } |
616 | 580 | ||
617 | /* entry point for /proc/driver/controller_vendor/ac97/%d */ | ||
618 | int ac97_read_proc (char *page, char **start, off_t off, | ||
619 | int count, int *eof, void *data) | ||
620 | { | ||
621 | int len = 0, cap, extid, val, id1, id2; | ||
622 | struct ac97_codec *codec; | ||
623 | int is_ac97_20 = 0; | ||
624 | |||
625 | if ((codec = data) == NULL) | ||
626 | return -ENODEV; | ||
627 | |||
628 | id1 = codec->codec_read(codec, AC97_VENDOR_ID1); | ||
629 | id2 = codec->codec_read(codec, AC97_VENDOR_ID2); | ||
630 | len += sprintf (page+len, "Vendor name : %s\n", codec->name); | ||
631 | len += sprintf (page+len, "Vendor id : %04X %04X\n", id1, id2); | ||
632 | |||
633 | extid = codec->codec_read(codec, AC97_EXTENDED_ID); | ||
634 | extid &= ~((1<<2)|(1<<4)|(1<<5)|(1<<10)|(1<<11)|(1<<12)|(1<<13)); | ||
635 | len += sprintf (page+len, "AC97 Version : %s\n", | ||
636 | extid ? "2.0 or later" : "1.0"); | ||
637 | if (extid) is_ac97_20 = 1; | ||
638 | |||
639 | cap = codec->codec_read(codec, AC97_RESET); | ||
640 | len += sprintf (page+len, "Capabilities :%s%s%s%s%s%s\n", | ||
641 | cap & 0x0001 ? " -dedicated MIC PCM IN channel-" : "", | ||
642 | cap & 0x0002 ? " -reserved1-" : "", | ||
643 | cap & 0x0004 ? " -bass & treble-" : "", | ||
644 | cap & 0x0008 ? " -simulated stereo-" : "", | ||
645 | cap & 0x0010 ? " -headphone out-" : "", | ||
646 | cap & 0x0020 ? " -loudness-" : ""); | ||
647 | val = cap & 0x00c0; | ||
648 | len += sprintf (page+len, "DAC resolutions :%s%s%s\n", | ||
649 | " -16-bit-", | ||
650 | val & 0x0040 ? " -18-bit-" : "", | ||
651 | val & 0x0080 ? " -20-bit-" : ""); | ||
652 | val = cap & 0x0300; | ||
653 | len += sprintf (page+len, "ADC resolutions :%s%s%s\n", | ||
654 | " -16-bit-", | ||
655 | val & 0x0100 ? " -18-bit-" : "", | ||
656 | val & 0x0200 ? " -20-bit-" : ""); | ||
657 | len += sprintf (page+len, "3D enhancement : %s\n", | ||
658 | ac97_stereo_enhancements[(cap >> 10) & 0x1f]); | ||
659 | |||
660 | val = codec->codec_read(codec, AC97_GENERAL_PURPOSE); | ||
661 | len += sprintf (page+len, "POP path : %s 3D\n" | ||
662 | "Sim. stereo : %s\n" | ||
663 | "3D enhancement : %s\n" | ||
664 | "Loudness : %s\n" | ||
665 | "Mono output : %s\n" | ||
666 | "MIC select : %s\n" | ||
667 | "ADC/DAC loopback : %s\n", | ||
668 | val & 0x8000 ? "post" : "pre", | ||
669 | val & 0x4000 ? "on" : "off", | ||
670 | val & 0x2000 ? "on" : "off", | ||
671 | val & 0x1000 ? "on" : "off", | ||
672 | val & 0x0200 ? "MIC" : "MIX", | ||
673 | val & 0x0100 ? "MIC2" : "MIC1", | ||
674 | val & 0x0080 ? "on" : "off"); | ||
675 | |||
676 | extid = codec->codec_read(codec, AC97_EXTENDED_ID); | ||
677 | cap = extid; | ||
678 | len += sprintf (page+len, "Ext Capabilities :%s%s%s%s%s%s%s\n", | ||
679 | cap & 0x0001 ? " -var rate PCM audio-" : "", | ||
680 | cap & 0x0002 ? " -2x PCM audio out-" : "", | ||
681 | cap & 0x0008 ? " -var rate MIC in-" : "", | ||
682 | cap & 0x0040 ? " -PCM center DAC-" : "", | ||
683 | cap & 0x0080 ? " -PCM surround DAC-" : "", | ||
684 | cap & 0x0100 ? " -PCM LFE DAC-" : "", | ||
685 | cap & 0x0200 ? " -slot/DAC mappings-" : ""); | ||
686 | if (is_ac97_20) { | ||
687 | len += sprintf (page+len, "Front DAC rate : %d\n", | ||
688 | codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)); | ||
689 | } | ||
690 | |||
691 | return len; | ||
692 | } | ||
693 | |||
694 | /** | 581 | /** |
695 | * codec_id - Turn id1/id2 into a PnP string | 582 | * codec_id - Turn id1/id2 into a PnP string |
696 | * @id1: Vendor ID1 | 583 | * @id1: Vendor ID1 |
@@ -1313,176 +1200,5 @@ static int pt101_init(struct ac97_codec * codec) | |||
1313 | #endif | 1200 | #endif |
1314 | 1201 | ||
1315 | 1202 | ||
1316 | EXPORT_SYMBOL(ac97_read_proc); | ||
1317 | EXPORT_SYMBOL(ac97_probe_codec); | 1203 | EXPORT_SYMBOL(ac97_probe_codec); |
1318 | 1204 | ||
1319 | /* | ||
1320 | * AC97 library support routines | ||
1321 | */ | ||
1322 | |||
1323 | /** | ||
1324 | * ac97_set_dac_rate - set codec rate adaption | ||
1325 | * @codec: ac97 code | ||
1326 | * @rate: rate in hertz | ||
1327 | * | ||
1328 | * Set the DAC rate. Assumes the codec supports VRA. The caller is | ||
1329 | * expected to have checked this little detail. | ||
1330 | */ | ||
1331 | |||
1332 | unsigned int ac97_set_dac_rate(struct ac97_codec *codec, unsigned int rate) | ||
1333 | { | ||
1334 | unsigned int new_rate = rate; | ||
1335 | u32 dacp; | ||
1336 | u32 mast_vol, phone_vol, mono_vol, pcm_vol; | ||
1337 | u32 mute_vol = 0x8000; /* The mute volume? */ | ||
1338 | |||
1339 | if(rate != codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE)) | ||
1340 | { | ||
1341 | /* Mute several registers */ | ||
1342 | mast_vol = codec->codec_read(codec, AC97_MASTER_VOL_STEREO); | ||
1343 | mono_vol = codec->codec_read(codec, AC97_MASTER_VOL_MONO); | ||
1344 | phone_vol = codec->codec_read(codec, AC97_HEADPHONE_VOL); | ||
1345 | pcm_vol = codec->codec_read(codec, AC97_PCMOUT_VOL); | ||
1346 | codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mute_vol); | ||
1347 | codec->codec_write(codec, AC97_MASTER_VOL_MONO, mute_vol); | ||
1348 | codec->codec_write(codec, AC97_HEADPHONE_VOL, mute_vol); | ||
1349 | codec->codec_write(codec, AC97_PCMOUT_VOL, mute_vol); | ||
1350 | |||
1351 | /* Power down the DAC */ | ||
1352 | dacp=codec->codec_read(codec, AC97_POWER_CONTROL); | ||
1353 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0200); | ||
1354 | /* Load the rate and read the effective rate */ | ||
1355 | codec->codec_write(codec, AC97_PCM_FRONT_DAC_RATE, rate); | ||
1356 | new_rate=codec->codec_read(codec, AC97_PCM_FRONT_DAC_RATE); | ||
1357 | /* Power it back up */ | ||
1358 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp); | ||
1359 | |||
1360 | /* Restore volumes */ | ||
1361 | codec->codec_write(codec, AC97_MASTER_VOL_STEREO, mast_vol); | ||
1362 | codec->codec_write(codec, AC97_MASTER_VOL_MONO, mono_vol); | ||
1363 | codec->codec_write(codec, AC97_HEADPHONE_VOL, phone_vol); | ||
1364 | codec->codec_write(codec, AC97_PCMOUT_VOL, pcm_vol); | ||
1365 | } | ||
1366 | return new_rate; | ||
1367 | } | ||
1368 | |||
1369 | EXPORT_SYMBOL(ac97_set_dac_rate); | ||
1370 | |||
1371 | /** | ||
1372 | * ac97_set_adc_rate - set codec rate adaption | ||
1373 | * @codec: ac97 code | ||
1374 | * @rate: rate in hertz | ||
1375 | * | ||
1376 | * Set the ADC rate. Assumes the codec supports VRA. The caller is | ||
1377 | * expected to have checked this little detail. | ||
1378 | */ | ||
1379 | |||
1380 | unsigned int ac97_set_adc_rate(struct ac97_codec *codec, unsigned int rate) | ||
1381 | { | ||
1382 | unsigned int new_rate = rate; | ||
1383 | u32 dacp; | ||
1384 | |||
1385 | if(rate != codec->codec_read(codec, AC97_PCM_LR_ADC_RATE)) | ||
1386 | { | ||
1387 | /* Power down the ADC */ | ||
1388 | dacp=codec->codec_read(codec, AC97_POWER_CONTROL); | ||
1389 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp|0x0100); | ||
1390 | /* Load the rate and read the effective rate */ | ||
1391 | codec->codec_write(codec, AC97_PCM_LR_ADC_RATE, rate); | ||
1392 | new_rate=codec->codec_read(codec, AC97_PCM_LR_ADC_RATE); | ||
1393 | /* Power it back up */ | ||
1394 | codec->codec_write(codec, AC97_POWER_CONTROL, dacp); | ||
1395 | } | ||
1396 | return new_rate; | ||
1397 | } | ||
1398 | |||
1399 | EXPORT_SYMBOL(ac97_set_adc_rate); | ||
1400 | |||
1401 | static int swap_headphone(int remove_master) | ||
1402 | { | ||
1403 | struct list_head *l; | ||
1404 | struct ac97_codec *c; | ||
1405 | |||
1406 | if (remove_master) { | ||
1407 | mutex_lock(&codec_mutex); | ||
1408 | list_for_each(l, &codecs) | ||
1409 | { | ||
1410 | c = list_entry(l, struct ac97_codec, list); | ||
1411 | if (supported_mixer(c, SOUND_MIXER_PHONEOUT)) | ||
1412 | c->supported_mixers &= ~SOUND_MASK_PHONEOUT; | ||
1413 | } | ||
1414 | mutex_unlock(&codec_mutex); | ||
1415 | } else | ||
1416 | ac97_hw[SOUND_MIXER_PHONEOUT].offset = AC97_MASTER_VOL_STEREO; | ||
1417 | |||
1418 | /* Scale values already match */ | ||
1419 | ac97_hw[SOUND_MIXER_VOLUME].offset = AC97_MASTER_VOL_MONO; | ||
1420 | return 0; | ||
1421 | } | ||
1422 | |||
1423 | static int apply_quirk(int quirk) | ||
1424 | { | ||
1425 | switch (quirk) { | ||
1426 | case AC97_TUNE_NONE: | ||
1427 | return 0; | ||
1428 | case AC97_TUNE_HP_ONLY: | ||
1429 | return swap_headphone(1); | ||
1430 | case AC97_TUNE_SWAP_HP: | ||
1431 | return swap_headphone(0); | ||
1432 | case AC97_TUNE_SWAP_SURROUND: | ||
1433 | return -ENOSYS; /* not yet implemented */ | ||
1434 | case AC97_TUNE_AD_SHARING: | ||
1435 | return -ENOSYS; /* not yet implemented */ | ||
1436 | case AC97_TUNE_ALC_JACK: | ||
1437 | return -ENOSYS; /* not yet implemented */ | ||
1438 | } | ||
1439 | return -EINVAL; | ||
1440 | } | ||
1441 | |||
1442 | /** | ||
1443 | * ac97_tune_hardware - tune up the hardware | ||
1444 | * @pdev: pci_dev pointer | ||
1445 | * @quirk: quirk list | ||
1446 | * @override: explicit quirk value (overrides if not AC97_TUNE_DEFAULT) | ||
1447 | * | ||
1448 | * Do some workaround for each pci device, such as renaming of the | ||
1449 | * headphone (true line-out) control as "Master". | ||
1450 | * The quirk-list must be terminated with a zero-filled entry. | ||
1451 | * | ||
1452 | * Returns zero if successful, or a negative error code on failure. | ||
1453 | */ | ||
1454 | |||
1455 | int ac97_tune_hardware(struct pci_dev *pdev, struct ac97_quirk *quirk, int override) | ||
1456 | { | ||
1457 | int result; | ||
1458 | |||
1459 | if (!quirk) | ||
1460 | return -EINVAL; | ||
1461 | |||
1462 | if (override != AC97_TUNE_DEFAULT) { | ||
1463 | result = apply_quirk(override); | ||
1464 | if (result < 0) | ||
1465 | printk(KERN_ERR "applying quirk type %d failed (%d)\n", override, result); | ||
1466 | return result; | ||
1467 | } | ||
1468 | |||
1469 | for (; quirk->vendor; quirk++) { | ||
1470 | if (quirk->vendor != pdev->subsystem_vendor) | ||
1471 | continue; | ||
1472 | if ((! quirk->mask && quirk->device == pdev->subsystem_device) || | ||
1473 | quirk->device == (quirk->mask & pdev->subsystem_device)) { | ||
1474 | #ifdef DEBUG | ||
1475 | printk("ac97 quirk for %s (%04x:%04x)\n", quirk->name, ac97->subsystem_vendor, pdev->subsystem_device); | ||
1476 | #endif | ||
1477 | result = apply_quirk(quirk->type); | ||
1478 | if (result < 0) | ||
1479 | printk(KERN_ERR "applying quirk type %d for %s failed (%d)\n", quirk->type, quirk->name, result); | ||
1480 | return result; | ||
1481 | } | ||
1482 | } | ||
1483 | return 0; | ||
1484 | } | ||
1485 | |||
1486 | EXPORT_SYMBOL_GPL(ac97_tune_hardware); | ||
1487 | |||
1488 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/oss/btaudio.c b/sound/oss/btaudio.c deleted file mode 100644 index 4d5cf05b8922..000000000000 --- a/sound/oss/btaudio.c +++ /dev/null | |||
@@ -1,1139 +0,0 @@ | |||
1 | /* | ||
2 | btaudio - bt878 audio dma driver for linux 2.4.x | ||
3 | |||
4 | (c) 2000-2002 Gerd Knorr <kraxel@bytesex.org> | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
11 | This program is distributed in the hope that it will be useful, | ||
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | GNU General Public License for more details. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | |||
20 | */ | ||
21 | |||
22 | #include <linux/module.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/signal.h> | ||
27 | #include <linux/types.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/poll.h> | ||
31 | #include <linux/sound.h> | ||
32 | #include <linux/soundcard.h> | ||
33 | #include <linux/slab.h> | ||
34 | #include <linux/kdev_t.h> | ||
35 | #include <linux/mutex.h> | ||
36 | |||
37 | #include <asm/uaccess.h> | ||
38 | #include <asm/io.h> | ||
39 | |||
40 | |||
41 | /* mmio access */ | ||
42 | #define btwrite(dat,adr) writel((dat), (bta->mmio+(adr))) | ||
43 | #define btread(adr) readl(bta->mmio+(adr)) | ||
44 | |||
45 | #define btand(dat,adr) btwrite((dat) & btread(adr), adr) | ||
46 | #define btor(dat,adr) btwrite((dat) | btread(adr), adr) | ||
47 | #define btaor(dat,mask,adr) btwrite((dat) | ((mask) & btread(adr)), adr) | ||
48 | |||
49 | /* registers (shifted because bta->mmio is long) */ | ||
50 | #define REG_INT_STAT (0x100 >> 2) | ||
51 | #define REG_INT_MASK (0x104 >> 2) | ||
52 | #define REG_GPIO_DMA_CTL (0x10c >> 2) | ||
53 | #define REG_PACKET_LEN (0x110 >> 2) | ||
54 | #define REG_RISC_STRT_ADD (0x114 >> 2) | ||
55 | #define REG_RISC_COUNT (0x120 >> 2) | ||
56 | |||
57 | /* IRQ bits - REG_INT_(STAT|MASK) */ | ||
58 | #define IRQ_SCERR (1 << 19) | ||
59 | #define IRQ_OCERR (1 << 18) | ||
60 | #define IRQ_PABORT (1 << 17) | ||
61 | #define IRQ_RIPERR (1 << 16) | ||
62 | #define IRQ_PPERR (1 << 15) | ||
63 | #define IRQ_FDSR (1 << 14) | ||
64 | #define IRQ_FTRGT (1 << 13) | ||
65 | #define IRQ_FBUS (1 << 12) | ||
66 | #define IRQ_RISCI (1 << 11) | ||
67 | #define IRQ_OFLOW (1 << 3) | ||
68 | |||
69 | #define IRQ_BTAUDIO (IRQ_SCERR | IRQ_OCERR | IRQ_PABORT | IRQ_RIPERR |\ | ||
70 | IRQ_PPERR | IRQ_FDSR | IRQ_FTRGT | IRQ_FBUS |\ | ||
71 | IRQ_RISCI) | ||
72 | |||
73 | /* REG_GPIO_DMA_CTL bits */ | ||
74 | #define DMA_CTL_A_PWRDN (1 << 26) | ||
75 | #define DMA_CTL_DA_SBR (1 << 14) | ||
76 | #define DMA_CTL_DA_ES2 (1 << 13) | ||
77 | #define DMA_CTL_ACAP_EN (1 << 4) | ||
78 | #define DMA_CTL_RISC_EN (1 << 1) | ||
79 | #define DMA_CTL_FIFO_EN (1 << 0) | ||
80 | |||
81 | /* RISC instructions */ | ||
82 | #define RISC_WRITE (0x01 << 28) | ||
83 | #define RISC_JUMP (0x07 << 28) | ||
84 | #define RISC_SYNC (0x08 << 28) | ||
85 | |||
86 | /* RISC bits */ | ||
87 | #define RISC_WR_SOL (1 << 27) | ||
88 | #define RISC_WR_EOL (1 << 26) | ||
89 | #define RISC_IRQ (1 << 24) | ||
90 | #define RISC_SYNC_RESYNC (1 << 15) | ||
91 | #define RISC_SYNC_FM1 0x06 | ||
92 | #define RISC_SYNC_VRO 0x0c | ||
93 | |||
94 | #define HWBASE_AD (448000) | ||
95 | |||
96 | /* -------------------------------------------------------------- */ | ||
97 | |||
98 | struct btaudio { | ||
99 | /* linked list */ | ||
100 | struct btaudio *next; | ||
101 | |||
102 | /* device info */ | ||
103 | int dsp_digital; | ||
104 | int dsp_analog; | ||
105 | int mixer_dev; | ||
106 | struct pci_dev *pci; | ||
107 | unsigned int irq; | ||
108 | unsigned long mem; | ||
109 | unsigned long __iomem *mmio; | ||
110 | |||
111 | /* locking */ | ||
112 | int users; | ||
113 | struct mutex lock; | ||
114 | |||
115 | /* risc instructions */ | ||
116 | unsigned int risc_size; | ||
117 | unsigned long *risc_cpu; | ||
118 | dma_addr_t risc_dma; | ||
119 | |||
120 | /* audio data */ | ||
121 | unsigned int buf_size; | ||
122 | unsigned char *buf_cpu; | ||
123 | dma_addr_t buf_dma; | ||
124 | |||
125 | /* buffer setup */ | ||
126 | int line_bytes; | ||
127 | int line_count; | ||
128 | int block_bytes; | ||
129 | int block_count; | ||
130 | |||
131 | /* read fifo management */ | ||
132 | int recording; | ||
133 | int dma_block; | ||
134 | int read_offset; | ||
135 | int read_count; | ||
136 | wait_queue_head_t readq; | ||
137 | |||
138 | /* settings */ | ||
139 | int gain[3]; | ||
140 | int source; | ||
141 | int bits; | ||
142 | int decimation; | ||
143 | int mixcount; | ||
144 | int sampleshift; | ||
145 | int channels; | ||
146 | int analog; | ||
147 | int rate; | ||
148 | }; | ||
149 | |||
150 | struct cardinfo { | ||
151 | char *name; | ||
152 | int rate; | ||
153 | }; | ||
154 | |||
155 | static struct btaudio *btaudios; | ||
156 | static unsigned int debug; | ||
157 | static unsigned int irq_debug; | ||
158 | |||
159 | /* -------------------------------------------------------------- */ | ||
160 | |||
161 | #define BUF_DEFAULT 128*1024 | ||
162 | #define BUF_MIN 8192 | ||
163 | |||
164 | static int alloc_buffer(struct btaudio *bta) | ||
165 | { | ||
166 | if (NULL == bta->buf_cpu) { | ||
167 | for (bta->buf_size = BUF_DEFAULT; bta->buf_size >= BUF_MIN; | ||
168 | bta->buf_size = bta->buf_size >> 1) { | ||
169 | bta->buf_cpu = pci_alloc_consistent | ||
170 | (bta->pci, bta->buf_size, &bta->buf_dma); | ||
171 | if (NULL != bta->buf_cpu) | ||
172 | break; | ||
173 | } | ||
174 | if (NULL == bta->buf_cpu) | ||
175 | return -ENOMEM; | ||
176 | memset(bta->buf_cpu,0,bta->buf_size); | ||
177 | } | ||
178 | if (NULL == bta->risc_cpu) { | ||
179 | bta->risc_size = PAGE_SIZE; | ||
180 | bta->risc_cpu = pci_alloc_consistent | ||
181 | (bta->pci, bta->risc_size, &bta->risc_dma); | ||
182 | if (NULL == bta->risc_cpu) { | ||
183 | pci_free_consistent(bta->pci, bta->buf_size, bta->buf_cpu, bta->buf_dma); | ||
184 | bta->buf_cpu = NULL; | ||
185 | return -ENOMEM; | ||
186 | } | ||
187 | } | ||
188 | return 0; | ||
189 | } | ||
190 | |||
191 | static void free_buffer(struct btaudio *bta) | ||
192 | { | ||
193 | if (NULL != bta->buf_cpu) { | ||
194 | pci_free_consistent(bta->pci, bta->buf_size, | ||
195 | bta->buf_cpu, bta->buf_dma); | ||
196 | bta->buf_cpu = NULL; | ||
197 | } | ||
198 | if (NULL != bta->risc_cpu) { | ||
199 | pci_free_consistent(bta->pci, bta->risc_size, | ||
200 | bta->risc_cpu, bta->risc_dma); | ||
201 | bta->risc_cpu = NULL; | ||
202 | } | ||
203 | } | ||
204 | |||
205 | static int make_risc(struct btaudio *bta) | ||
206 | { | ||
207 | int rp, bp, line, block; | ||
208 | unsigned long risc; | ||
209 | |||
210 | bta->block_bytes = bta->buf_size >> 4; | ||
211 | bta->block_count = 1 << 4; | ||
212 | bta->line_bytes = bta->block_bytes; | ||
213 | bta->line_count = bta->block_count; | ||
214 | while (bta->line_bytes > 4095) { | ||
215 | bta->line_bytes >>= 1; | ||
216 | bta->line_count <<= 1; | ||
217 | } | ||
218 | if (bta->line_count > 255) | ||
219 | return -EINVAL; | ||
220 | if (debug) | ||
221 | printk(KERN_DEBUG | ||
222 | "btaudio: bufsize=%d - bs=%d bc=%d - ls=%d, lc=%d\n", | ||
223 | bta->buf_size,bta->block_bytes,bta->block_count, | ||
224 | bta->line_bytes,bta->line_count); | ||
225 | rp = 0; bp = 0; | ||
226 | block = 0; | ||
227 | bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_FM1); | ||
228 | bta->risc_cpu[rp++] = cpu_to_le32(0); | ||
229 | for (line = 0; line < bta->line_count; line++) { | ||
230 | risc = RISC_WRITE | RISC_WR_SOL | RISC_WR_EOL; | ||
231 | risc |= bta->line_bytes; | ||
232 | if (0 == (bp & (bta->block_bytes-1))) { | ||
233 | risc |= RISC_IRQ; | ||
234 | risc |= (block & 0x0f) << 16; | ||
235 | risc |= (~block & 0x0f) << 20; | ||
236 | block++; | ||
237 | } | ||
238 | bta->risc_cpu[rp++] = cpu_to_le32(risc); | ||
239 | bta->risc_cpu[rp++] = cpu_to_le32(bta->buf_dma + bp); | ||
240 | bp += bta->line_bytes; | ||
241 | } | ||
242 | bta->risc_cpu[rp++] = cpu_to_le32(RISC_SYNC|RISC_SYNC_VRO); | ||
243 | bta->risc_cpu[rp++] = cpu_to_le32(0); | ||
244 | bta->risc_cpu[rp++] = cpu_to_le32(RISC_JUMP); | ||
245 | bta->risc_cpu[rp++] = cpu_to_le32(bta->risc_dma); | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | static int start_recording(struct btaudio *bta) | ||
250 | { | ||
251 | int ret; | ||
252 | |||
253 | if (0 != (ret = alloc_buffer(bta))) | ||
254 | return ret; | ||
255 | if (0 != (ret = make_risc(bta))) | ||
256 | return ret; | ||
257 | |||
258 | btwrite(bta->risc_dma, REG_RISC_STRT_ADD); | ||
259 | btwrite((bta->line_count << 16) | bta->line_bytes, | ||
260 | REG_PACKET_LEN); | ||
261 | btwrite(IRQ_BTAUDIO, REG_INT_MASK); | ||
262 | if (bta->analog) { | ||
263 | btwrite(DMA_CTL_ACAP_EN | | ||
264 | DMA_CTL_RISC_EN | | ||
265 | DMA_CTL_FIFO_EN | | ||
266 | DMA_CTL_DA_ES2 | | ||
267 | ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) | | ||
268 | (bta->gain[bta->source] << 28) | | ||
269 | (bta->source << 24) | | ||
270 | (bta->decimation << 8), | ||
271 | REG_GPIO_DMA_CTL); | ||
272 | } else { | ||
273 | btwrite(DMA_CTL_ACAP_EN | | ||
274 | DMA_CTL_RISC_EN | | ||
275 | DMA_CTL_FIFO_EN | | ||
276 | DMA_CTL_DA_ES2 | | ||
277 | DMA_CTL_A_PWRDN | | ||
278 | (1 << 6) | | ||
279 | ((bta->bits == 8) ? DMA_CTL_DA_SBR : 0) | | ||
280 | (bta->gain[bta->source] << 28) | | ||
281 | (bta->source << 24) | | ||
282 | (bta->decimation << 8), | ||
283 | REG_GPIO_DMA_CTL); | ||
284 | } | ||
285 | bta->dma_block = 0; | ||
286 | bta->read_offset = 0; | ||
287 | bta->read_count = 0; | ||
288 | bta->recording = 1; | ||
289 | if (debug) | ||
290 | printk(KERN_DEBUG "btaudio: recording started\n"); | ||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static void stop_recording(struct btaudio *bta) | ||
295 | { | ||
296 | btand(~15, REG_GPIO_DMA_CTL); | ||
297 | bta->recording = 0; | ||
298 | if (debug) | ||
299 | printk(KERN_DEBUG "btaudio: recording stopped\n"); | ||
300 | } | ||
301 | |||
302 | |||
303 | /* -------------------------------------------------------------- */ | ||
304 | |||
305 | static int btaudio_mixer_open(struct inode *inode, struct file *file) | ||
306 | { | ||
307 | int minor = iminor(inode); | ||
308 | struct btaudio *bta; | ||
309 | |||
310 | for (bta = btaudios; bta != NULL; bta = bta->next) | ||
311 | if (bta->mixer_dev == minor) | ||
312 | break; | ||
313 | if (NULL == bta) | ||
314 | return -ENODEV; | ||
315 | |||
316 | if (debug) | ||
317 | printk("btaudio: open mixer [%d]\n",minor); | ||
318 | file->private_data = bta; | ||
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static int btaudio_mixer_release(struct inode *inode, struct file *file) | ||
323 | { | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static int btaudio_mixer_ioctl(struct inode *inode, struct file *file, | ||
328 | unsigned int cmd, unsigned long arg) | ||
329 | { | ||
330 | struct btaudio *bta = file->private_data; | ||
331 | int ret,val=0,i=0; | ||
332 | void __user *argp = (void __user *)arg; | ||
333 | |||
334 | if (cmd == SOUND_MIXER_INFO) { | ||
335 | mixer_info info; | ||
336 | memset(&info,0,sizeof(info)); | ||
337 | strlcpy(info.id,"bt878",sizeof(info.id)); | ||
338 | strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); | ||
339 | info.modify_counter = bta->mixcount; | ||
340 | if (copy_to_user(argp, &info, sizeof(info))) | ||
341 | return -EFAULT; | ||
342 | return 0; | ||
343 | } | ||
344 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
345 | _old_mixer_info info; | ||
346 | memset(&info,0,sizeof(info)); | ||
347 | strlcpy(info.id, "bt878", sizeof(info.id)); | ||
348 | strlcpy(info.name,"Brooktree Bt878 audio",sizeof(info.name)); | ||
349 | if (copy_to_user(argp, &info, sizeof(info))) | ||
350 | return -EFAULT; | ||
351 | return 0; | ||
352 | } | ||
353 | if (cmd == OSS_GETVERSION) | ||
354 | return put_user(SOUND_VERSION, (int __user *)argp); | ||
355 | |||
356 | /* read */ | ||
357 | if (_SIOC_DIR(cmd) & _SIOC_WRITE) | ||
358 | if (get_user(val, (int __user *)argp)) | ||
359 | return -EFAULT; | ||
360 | |||
361 | switch (cmd) { | ||
362 | case MIXER_READ(SOUND_MIXER_CAPS): | ||
363 | ret = SOUND_CAP_EXCL_INPUT; | ||
364 | break; | ||
365 | case MIXER_READ(SOUND_MIXER_STEREODEVS): | ||
366 | ret = 0; | ||
367 | break; | ||
368 | case MIXER_READ(SOUND_MIXER_RECMASK): | ||
369 | case MIXER_READ(SOUND_MIXER_DEVMASK): | ||
370 | ret = SOUND_MASK_LINE1|SOUND_MASK_LINE2|SOUND_MASK_LINE3; | ||
371 | break; | ||
372 | |||
373 | case MIXER_WRITE(SOUND_MIXER_RECSRC): | ||
374 | if (val & SOUND_MASK_LINE1 && bta->source != 0) | ||
375 | bta->source = 0; | ||
376 | else if (val & SOUND_MASK_LINE2 && bta->source != 1) | ||
377 | bta->source = 1; | ||
378 | else if (val & SOUND_MASK_LINE3 && bta->source != 2) | ||
379 | bta->source = 2; | ||
380 | btaor((bta->gain[bta->source] << 28) | | ||
381 | (bta->source << 24), | ||
382 | 0x0cffffff, REG_GPIO_DMA_CTL); | ||
383 | case MIXER_READ(SOUND_MIXER_RECSRC): | ||
384 | switch (bta->source) { | ||
385 | case 0: ret = SOUND_MASK_LINE1; break; | ||
386 | case 1: ret = SOUND_MASK_LINE2; break; | ||
387 | case 2: ret = SOUND_MASK_LINE3; break; | ||
388 | default: ret = 0; | ||
389 | } | ||
390 | break; | ||
391 | |||
392 | case MIXER_WRITE(SOUND_MIXER_LINE1): | ||
393 | case MIXER_WRITE(SOUND_MIXER_LINE2): | ||
394 | case MIXER_WRITE(SOUND_MIXER_LINE3): | ||
395 | if (MIXER_WRITE(SOUND_MIXER_LINE1) == cmd) | ||
396 | i = 0; | ||
397 | if (MIXER_WRITE(SOUND_MIXER_LINE2) == cmd) | ||
398 | i = 1; | ||
399 | if (MIXER_WRITE(SOUND_MIXER_LINE3) == cmd) | ||
400 | i = 2; | ||
401 | bta->gain[i] = (val & 0xff) * 15 / 100; | ||
402 | if (bta->gain[i] > 15) bta->gain[i] = 15; | ||
403 | if (bta->gain[i] < 0) bta->gain[i] = 0; | ||
404 | if (i == bta->source) | ||
405 | btaor((bta->gain[bta->source]<<28), | ||
406 | 0x0fffffff, REG_GPIO_DMA_CTL); | ||
407 | ret = bta->gain[i] * 100 / 15; | ||
408 | ret |= ret << 8; | ||
409 | break; | ||
410 | |||
411 | case MIXER_READ(SOUND_MIXER_LINE1): | ||
412 | case MIXER_READ(SOUND_MIXER_LINE2): | ||
413 | case MIXER_READ(SOUND_MIXER_LINE3): | ||
414 | if (MIXER_READ(SOUND_MIXER_LINE1) == cmd) | ||
415 | i = 0; | ||
416 | if (MIXER_READ(SOUND_MIXER_LINE2) == cmd) | ||
417 | i = 1; | ||
418 | if (MIXER_READ(SOUND_MIXER_LINE3) == cmd) | ||
419 | i = 2; | ||
420 | ret = bta->gain[i] * 100 / 15; | ||
421 | ret |= ret << 8; | ||
422 | break; | ||
423 | |||
424 | default: | ||
425 | return -EINVAL; | ||
426 | } | ||
427 | if (put_user(ret, (int __user *)argp)) | ||
428 | return -EFAULT; | ||
429 | return 0; | ||
430 | } | ||
431 | |||
432 | static const struct file_operations btaudio_mixer_fops = { | ||
433 | .owner = THIS_MODULE, | ||
434 | .llseek = no_llseek, | ||
435 | .open = btaudio_mixer_open, | ||
436 | .release = btaudio_mixer_release, | ||
437 | .ioctl = btaudio_mixer_ioctl, | ||
438 | }; | ||
439 | |||
440 | /* -------------------------------------------------------------- */ | ||
441 | |||
442 | static int btaudio_dsp_open(struct inode *inode, struct file *file, | ||
443 | struct btaudio *bta, int analog) | ||
444 | { | ||
445 | mutex_lock(&bta->lock); | ||
446 | if (bta->users) | ||
447 | goto busy; | ||
448 | bta->users++; | ||
449 | file->private_data = bta; | ||
450 | |||
451 | bta->analog = analog; | ||
452 | bta->dma_block = 0; | ||
453 | bta->read_offset = 0; | ||
454 | bta->read_count = 0; | ||
455 | bta->sampleshift = 0; | ||
456 | |||
457 | mutex_unlock(&bta->lock); | ||
458 | return 0; | ||
459 | |||
460 | busy: | ||
461 | mutex_unlock(&bta->lock); | ||
462 | return -EBUSY; | ||
463 | } | ||
464 | |||
465 | static int btaudio_dsp_open_digital(struct inode *inode, struct file *file) | ||
466 | { | ||
467 | int minor = iminor(inode); | ||
468 | struct btaudio *bta; | ||
469 | |||
470 | for (bta = btaudios; bta != NULL; bta = bta->next) | ||
471 | if (bta->dsp_digital == minor) | ||
472 | break; | ||
473 | if (NULL == bta) | ||
474 | return -ENODEV; | ||
475 | |||
476 | if (debug) | ||
477 | printk("btaudio: open digital dsp [%d]\n",minor); | ||
478 | return btaudio_dsp_open(inode,file,bta,0); | ||
479 | } | ||
480 | |||
481 | static int btaudio_dsp_open_analog(struct inode *inode, struct file *file) | ||
482 | { | ||
483 | int minor = iminor(inode); | ||
484 | struct btaudio *bta; | ||
485 | |||
486 | for (bta = btaudios; bta != NULL; bta = bta->next) | ||
487 | if (bta->dsp_analog == minor) | ||
488 | break; | ||
489 | if (NULL == bta) | ||
490 | return -ENODEV; | ||
491 | |||
492 | if (debug) | ||
493 | printk("btaudio: open analog dsp [%d]\n",minor); | ||
494 | return btaudio_dsp_open(inode,file,bta,1); | ||
495 | } | ||
496 | |||
497 | static int btaudio_dsp_release(struct inode *inode, struct file *file) | ||
498 | { | ||
499 | struct btaudio *bta = file->private_data; | ||
500 | |||
501 | mutex_lock(&bta->lock); | ||
502 | if (bta->recording) | ||
503 | stop_recording(bta); | ||
504 | bta->users--; | ||
505 | mutex_unlock(&bta->lock); | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | static ssize_t btaudio_dsp_read(struct file *file, char __user *buffer, | ||
510 | size_t swcount, loff_t *ppos) | ||
511 | { | ||
512 | struct btaudio *bta = file->private_data; | ||
513 | int hwcount = swcount << bta->sampleshift; | ||
514 | int nsrc, ndst, err, ret = 0; | ||
515 | DECLARE_WAITQUEUE(wait, current); | ||
516 | |||
517 | add_wait_queue(&bta->readq, &wait); | ||
518 | mutex_lock(&bta->lock); | ||
519 | while (swcount > 0) { | ||
520 | if (0 == bta->read_count) { | ||
521 | if (!bta->recording) { | ||
522 | if (0 != (err = start_recording(bta))) { | ||
523 | if (0 == ret) | ||
524 | ret = err; | ||
525 | break; | ||
526 | } | ||
527 | } | ||
528 | if (file->f_flags & O_NONBLOCK) { | ||
529 | if (0 == ret) | ||
530 | ret = -EAGAIN; | ||
531 | break; | ||
532 | } | ||
533 | mutex_unlock(&bta->lock); | ||
534 | current->state = TASK_INTERRUPTIBLE; | ||
535 | schedule(); | ||
536 | mutex_lock(&bta->lock); | ||
537 | if(signal_pending(current)) { | ||
538 | if (0 == ret) | ||
539 | ret = -EINTR; | ||
540 | break; | ||
541 | } | ||
542 | } | ||
543 | nsrc = (bta->read_count < hwcount) ? bta->read_count : hwcount; | ||
544 | if (nsrc > bta->buf_size - bta->read_offset) | ||
545 | nsrc = bta->buf_size - bta->read_offset; | ||
546 | ndst = nsrc >> bta->sampleshift; | ||
547 | |||
548 | if ((bta->analog && 0 == bta->sampleshift) || | ||
549 | (!bta->analog && 2 == bta->channels)) { | ||
550 | /* just copy */ | ||
551 | if (copy_to_user(buffer + ret, bta->buf_cpu + bta->read_offset, nsrc)) { | ||
552 | if (0 == ret) | ||
553 | ret = -EFAULT; | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | } else if (!bta->analog) { | ||
558 | /* stereo => mono (digital audio) */ | ||
559 | __s16 *src = (__s16*)(bta->buf_cpu + bta->read_offset); | ||
560 | __s16 __user *dst = (__s16 __user *)(buffer + ret); | ||
561 | __s16 avg; | ||
562 | int n = ndst>>1; | ||
563 | if (!access_ok(VERIFY_WRITE, dst, ndst)) { | ||
564 | if (0 == ret) | ||
565 | ret = -EFAULT; | ||
566 | break; | ||
567 | } | ||
568 | for (; n; n--, dst++) { | ||
569 | avg = (__s16)le16_to_cpu(*src) / 2; src++; | ||
570 | avg += (__s16)le16_to_cpu(*src) / 2; src++; | ||
571 | __put_user(cpu_to_le16(avg),dst); | ||
572 | } | ||
573 | |||
574 | } else if (8 == bta->bits) { | ||
575 | /* copy + byte downsampling (audio A/D) */ | ||
576 | __u8 *src = bta->buf_cpu + bta->read_offset; | ||
577 | __u8 __user *dst = buffer + ret; | ||
578 | int n = ndst; | ||
579 | if (!access_ok(VERIFY_WRITE, dst, ndst)) { | ||
580 | if (0 == ret) | ||
581 | ret = -EFAULT; | ||
582 | break; | ||
583 | } | ||
584 | for (; n; n--, src += (1 << bta->sampleshift), dst++) | ||
585 | __put_user(*src, dst); | ||
586 | |||
587 | } else { | ||
588 | /* copy + word downsampling (audio A/D) */ | ||
589 | __u16 *src = (__u16*)(bta->buf_cpu + bta->read_offset); | ||
590 | __u16 __user *dst = (__u16 __user *)(buffer + ret); | ||
591 | int n = ndst>>1; | ||
592 | if (!access_ok(VERIFY_WRITE,dst,ndst)) { | ||
593 | if (0 == ret) | ||
594 | ret = -EFAULT; | ||
595 | break; | ||
596 | } | ||
597 | for (; n; n--, src += (1 << bta->sampleshift), dst++) | ||
598 | __put_user(*src, dst); | ||
599 | } | ||
600 | |||
601 | ret += ndst; | ||
602 | swcount -= ndst; | ||
603 | hwcount -= nsrc; | ||
604 | bta->read_count -= nsrc; | ||
605 | bta->read_offset += nsrc; | ||
606 | if (bta->read_offset == bta->buf_size) | ||
607 | bta->read_offset = 0; | ||
608 | } | ||
609 | mutex_unlock(&bta->lock); | ||
610 | remove_wait_queue(&bta->readq, &wait); | ||
611 | current->state = TASK_RUNNING; | ||
612 | return ret; | ||
613 | } | ||
614 | |||
615 | static ssize_t btaudio_dsp_write(struct file *file, const char __user *buffer, | ||
616 | size_t count, loff_t *ppos) | ||
617 | { | ||
618 | return -EINVAL; | ||
619 | } | ||
620 | |||
621 | static int btaudio_dsp_ioctl(struct inode *inode, struct file *file, | ||
622 | unsigned int cmd, unsigned long arg) | ||
623 | { | ||
624 | struct btaudio *bta = file->private_data; | ||
625 | int s, i, ret, val = 0; | ||
626 | void __user *argp = (void __user *)arg; | ||
627 | int __user *p = argp; | ||
628 | |||
629 | switch (cmd) { | ||
630 | case OSS_GETVERSION: | ||
631 | return put_user(SOUND_VERSION, p); | ||
632 | case SNDCTL_DSP_GETCAPS: | ||
633 | return 0; | ||
634 | |||
635 | case SNDCTL_DSP_SPEED: | ||
636 | if (get_user(val, p)) | ||
637 | return -EFAULT; | ||
638 | if (bta->analog) { | ||
639 | for (s = 0; s < 16; s++) | ||
640 | if (val << s >= HWBASE_AD*4/15) | ||
641 | break; | ||
642 | for (i = 15; i >= 5; i--) | ||
643 | if (val << s <= HWBASE_AD*4/i) | ||
644 | break; | ||
645 | bta->sampleshift = s; | ||
646 | bta->decimation = i; | ||
647 | if (debug) | ||
648 | printk(KERN_DEBUG "btaudio: rate: req=%d " | ||
649 | "dec=%d shift=%d hwrate=%d swrate=%d\n", | ||
650 | val,i,s,(HWBASE_AD*4/i),(HWBASE_AD*4/i)>>s); | ||
651 | } else { | ||
652 | bta->sampleshift = (bta->channels == 2) ? 0 : 1; | ||
653 | bta->decimation = 0; | ||
654 | } | ||
655 | if (bta->recording) { | ||
656 | mutex_lock(&bta->lock); | ||
657 | stop_recording(bta); | ||
658 | start_recording(bta); | ||
659 | mutex_unlock(&bta->lock); | ||
660 | } | ||
661 | /* fall through */ | ||
662 | case SOUND_PCM_READ_RATE: | ||
663 | if (bta->analog) { | ||
664 | return put_user(HWBASE_AD*4/bta->decimation>>bta->sampleshift, p); | ||
665 | } else { | ||
666 | return put_user(bta->rate, p); | ||
667 | } | ||
668 | |||
669 | case SNDCTL_DSP_STEREO: | ||
670 | if (!bta->analog) { | ||
671 | if (get_user(val, p)) | ||
672 | return -EFAULT; | ||
673 | bta->channels = (val > 0) ? 2 : 1; | ||
674 | bta->sampleshift = (bta->channels == 2) ? 0 : 1; | ||
675 | if (debug) | ||
676 | printk(KERN_INFO | ||
677 | "btaudio: stereo=%d channels=%d\n", | ||
678 | val,bta->channels); | ||
679 | } else { | ||
680 | if (val == 1) | ||
681 | return -EFAULT; | ||
682 | else { | ||
683 | bta->channels = 1; | ||
684 | if (debug) | ||
685 | printk(KERN_INFO | ||
686 | "btaudio: stereo=0 channels=1\n"); | ||
687 | } | ||
688 | } | ||
689 | return put_user((bta->channels)-1, p); | ||
690 | |||
691 | case SNDCTL_DSP_CHANNELS: | ||
692 | if (!bta->analog) { | ||
693 | if (get_user(val, p)) | ||
694 | return -EFAULT; | ||
695 | bta->channels = (val > 1) ? 2 : 1; | ||
696 | bta->sampleshift = (bta->channels == 2) ? 0 : 1; | ||
697 | if (debug) | ||
698 | printk(KERN_DEBUG | ||
699 | "btaudio: val=%d channels=%d\n", | ||
700 | val,bta->channels); | ||
701 | } | ||
702 | /* fall through */ | ||
703 | case SOUND_PCM_READ_CHANNELS: | ||
704 | return put_user(bta->channels, p); | ||
705 | |||
706 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
707 | if (bta->analog) | ||
708 | return put_user(AFMT_S16_LE|AFMT_S8, p); | ||
709 | else | ||
710 | return put_user(AFMT_S16_LE, p); | ||
711 | |||
712 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt*/ | ||
713 | if (get_user(val, p)) | ||
714 | return -EFAULT; | ||
715 | if (val != AFMT_QUERY) { | ||
716 | if (bta->analog) | ||
717 | bta->bits = (val == AFMT_S8) ? 8 : 16; | ||
718 | else | ||
719 | bta->bits = 16; | ||
720 | if (bta->recording) { | ||
721 | mutex_lock(&bta->lock); | ||
722 | stop_recording(bta); | ||
723 | start_recording(bta); | ||
724 | mutex_unlock(&bta->lock); | ||
725 | } | ||
726 | } | ||
727 | if (debug) | ||
728 | printk(KERN_DEBUG "btaudio: fmt: bits=%d\n",bta->bits); | ||
729 | return put_user((bta->bits==16) ? AFMT_S16_LE : AFMT_S8, | ||
730 | p); | ||
731 | break; | ||
732 | case SOUND_PCM_READ_BITS: | ||
733 | return put_user(bta->bits, p); | ||
734 | |||
735 | case SNDCTL_DSP_NONBLOCK: | ||
736 | file->f_flags |= O_NONBLOCK; | ||
737 | return 0; | ||
738 | |||
739 | case SNDCTL_DSP_RESET: | ||
740 | if (bta->recording) { | ||
741 | mutex_lock(&bta->lock); | ||
742 | stop_recording(bta); | ||
743 | mutex_unlock(&bta->lock); | ||
744 | } | ||
745 | return 0; | ||
746 | case SNDCTL_DSP_GETBLKSIZE: | ||
747 | if (!bta->recording) { | ||
748 | if (0 != (ret = alloc_buffer(bta))) | ||
749 | return ret; | ||
750 | if (0 != (ret = make_risc(bta))) | ||
751 | return ret; | ||
752 | } | ||
753 | return put_user(bta->block_bytes>>bta->sampleshift,p); | ||
754 | |||
755 | case SNDCTL_DSP_SYNC: | ||
756 | /* NOP */ | ||
757 | return 0; | ||
758 | case SNDCTL_DSP_GETISPACE: | ||
759 | { | ||
760 | audio_buf_info info; | ||
761 | if (!bta->recording) | ||
762 | return -EINVAL; | ||
763 | info.fragsize = bta->block_bytes>>bta->sampleshift; | ||
764 | info.fragstotal = bta->block_count; | ||
765 | info.bytes = bta->read_count; | ||
766 | info.fragments = info.bytes / info.fragsize; | ||
767 | if (debug) | ||
768 | printk(KERN_DEBUG "btaudio: SNDCTL_DSP_GETISPACE " | ||
769 | "returns %d/%d/%d/%d\n", | ||
770 | info.fragsize, info.fragstotal, | ||
771 | info.bytes, info.fragments); | ||
772 | if (copy_to_user(argp, &info, sizeof(info))) | ||
773 | return -EFAULT; | ||
774 | return 0; | ||
775 | } | ||
776 | #if 0 /* TODO */ | ||
777 | case SNDCTL_DSP_GETTRIGGER: | ||
778 | case SNDCTL_DSP_SETTRIGGER: | ||
779 | case SNDCTL_DSP_SETFRAGMENT: | ||
780 | #endif | ||
781 | default: | ||
782 | return -EINVAL; | ||
783 | } | ||
784 | } | ||
785 | |||
786 | static unsigned int btaudio_dsp_poll(struct file *file, struct poll_table_struct *wait) | ||
787 | { | ||
788 | struct btaudio *bta = file->private_data; | ||
789 | unsigned int mask = 0; | ||
790 | |||
791 | poll_wait(file, &bta->readq, wait); | ||
792 | |||
793 | if (0 != bta->read_count) | ||
794 | mask |= (POLLIN | POLLRDNORM); | ||
795 | |||
796 | return mask; | ||
797 | } | ||
798 | |||
799 | static const struct file_operations btaudio_digital_dsp_fops = { | ||
800 | .owner = THIS_MODULE, | ||
801 | .llseek = no_llseek, | ||
802 | .open = btaudio_dsp_open_digital, | ||
803 | .release = btaudio_dsp_release, | ||
804 | .read = btaudio_dsp_read, | ||
805 | .write = btaudio_dsp_write, | ||
806 | .ioctl = btaudio_dsp_ioctl, | ||
807 | .poll = btaudio_dsp_poll, | ||
808 | }; | ||
809 | |||
810 | static const struct file_operations btaudio_analog_dsp_fops = { | ||
811 | .owner = THIS_MODULE, | ||
812 | .llseek = no_llseek, | ||
813 | .open = btaudio_dsp_open_analog, | ||
814 | .release = btaudio_dsp_release, | ||
815 | .read = btaudio_dsp_read, | ||
816 | .write = btaudio_dsp_write, | ||
817 | .ioctl = btaudio_dsp_ioctl, | ||
818 | .poll = btaudio_dsp_poll, | ||
819 | }; | ||
820 | |||
821 | /* -------------------------------------------------------------- */ | ||
822 | |||
823 | static char *irq_name[] = { "", "", "", "OFLOW", "", "", "", "", "", "", "", | ||
824 | "RISCI", "FBUS", "FTRGT", "FDSR", "PPERR", | ||
825 | "RIPERR", "PABORT", "OCERR", "SCERR" }; | ||
826 | |||
827 | static irqreturn_t btaudio_irq(int irq, void *dev_id) | ||
828 | { | ||
829 | int count = 0; | ||
830 | u32 stat,astat; | ||
831 | struct btaudio *bta = dev_id; | ||
832 | int handled = 0; | ||
833 | |||
834 | for (;;) { | ||
835 | count++; | ||
836 | stat = btread(REG_INT_STAT); | ||
837 | astat = stat & btread(REG_INT_MASK); | ||
838 | if (!astat) | ||
839 | return IRQ_RETVAL(handled); | ||
840 | handled = 1; | ||
841 | btwrite(astat,REG_INT_STAT); | ||
842 | |||
843 | if (irq_debug) { | ||
844 | int i; | ||
845 | printk(KERN_DEBUG "btaudio: irq loop=%d risc=%x, bits:", | ||
846 | count, stat>>28); | ||
847 | for (i = 0; i < (sizeof(irq_name)/sizeof(char*)); i++) { | ||
848 | if (stat & (1 << i)) | ||
849 | printk(" %s",irq_name[i]); | ||
850 | if (astat & (1 << i)) | ||
851 | printk("*"); | ||
852 | } | ||
853 | printk("\n"); | ||
854 | } | ||
855 | if (stat & IRQ_RISCI) { | ||
856 | int blocks; | ||
857 | blocks = (stat >> 28) - bta->dma_block; | ||
858 | if (blocks < 0) | ||
859 | blocks += bta->block_count; | ||
860 | bta->dma_block = stat >> 28; | ||
861 | if (bta->read_count + 2*bta->block_bytes > bta->buf_size) { | ||
862 | stop_recording(bta); | ||
863 | printk(KERN_INFO "btaudio: buffer overrun\n"); | ||
864 | } | ||
865 | if (blocks > 0) { | ||
866 | bta->read_count += blocks * bta->block_bytes; | ||
867 | wake_up_interruptible(&bta->readq); | ||
868 | } | ||
869 | } | ||
870 | if (count > 10) { | ||
871 | printk(KERN_WARNING | ||
872 | "btaudio: Oops - irq mask cleared\n"); | ||
873 | btwrite(0, REG_INT_MASK); | ||
874 | } | ||
875 | } | ||
876 | return IRQ_NONE; | ||
877 | } | ||
878 | |||
879 | /* -------------------------------------------------------------- */ | ||
880 | |||
881 | static unsigned int dsp1 = -1; | ||
882 | static unsigned int dsp2 = -1; | ||
883 | static unsigned int mixer = -1; | ||
884 | static int latency = -1; | ||
885 | static int digital = 1; | ||
886 | static int analog = 1; | ||
887 | static int rate; | ||
888 | |||
889 | #define BTA_OSPREY200 1 | ||
890 | |||
891 | static struct cardinfo cards[] = { | ||
892 | [0] = { | ||
893 | .name = "default", | ||
894 | .rate = 32000, | ||
895 | }, | ||
896 | [BTA_OSPREY200] = { | ||
897 | .name = "Osprey 200", | ||
898 | .rate = 44100, | ||
899 | }, | ||
900 | }; | ||
901 | |||
902 | static int __devinit btaudio_probe(struct pci_dev *pci_dev, | ||
903 | const struct pci_device_id *pci_id) | ||
904 | { | ||
905 | struct btaudio *bta; | ||
906 | struct cardinfo *card = &cards[pci_id->driver_data]; | ||
907 | unsigned char revision,lat; | ||
908 | int rc = -EBUSY; | ||
909 | |||
910 | if (pci_enable_device(pci_dev)) | ||
911 | return -EIO; | ||
912 | if (!request_mem_region(pci_resource_start(pci_dev,0), | ||
913 | pci_resource_len(pci_dev,0), | ||
914 | "btaudio")) { | ||
915 | return -EBUSY; | ||
916 | } | ||
917 | |||
918 | bta = kzalloc(sizeof(*bta),GFP_ATOMIC); | ||
919 | if (!bta) { | ||
920 | rc = -ENOMEM; | ||
921 | goto fail0; | ||
922 | } | ||
923 | |||
924 | bta->pci = pci_dev; | ||
925 | bta->irq = pci_dev->irq; | ||
926 | bta->mem = pci_resource_start(pci_dev,0); | ||
927 | bta->mmio = ioremap(pci_resource_start(pci_dev,0), | ||
928 | pci_resource_len(pci_dev,0)); | ||
929 | |||
930 | bta->source = 1; | ||
931 | bta->bits = 8; | ||
932 | bta->channels = 1; | ||
933 | if (bta->analog) { | ||
934 | bta->decimation = 15; | ||
935 | } else { | ||
936 | bta->decimation = 0; | ||
937 | bta->sampleshift = 1; | ||
938 | } | ||
939 | |||
940 | /* sample rate */ | ||
941 | bta->rate = card->rate; | ||
942 | if (rate) | ||
943 | bta->rate = rate; | ||
944 | |||
945 | mutex_init(&bta->lock); | ||
946 | init_waitqueue_head(&bta->readq); | ||
947 | |||
948 | if (-1 != latency) { | ||
949 | printk(KERN_INFO "btaudio: setting pci latency timer to %d\n", | ||
950 | latency); | ||
951 | pci_write_config_byte(pci_dev, PCI_LATENCY_TIMER, latency); | ||
952 | } | ||
953 | pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &revision); | ||
954 | pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &lat); | ||
955 | printk(KERN_INFO "btaudio: Bt%x (rev %d) at %02x:%02x.%x, ", | ||
956 | pci_dev->device,revision,pci_dev->bus->number, | ||
957 | PCI_SLOT(pci_dev->devfn),PCI_FUNC(pci_dev->devfn)); | ||
958 | printk("irq: %d, latency: %d, mmio: 0x%lx\n", | ||
959 | bta->irq, lat, bta->mem); | ||
960 | printk("btaudio: using card config \"%s\"\n", card->name); | ||
961 | |||
962 | /* init hw */ | ||
963 | btwrite(0, REG_GPIO_DMA_CTL); | ||
964 | btwrite(0, REG_INT_MASK); | ||
965 | btwrite(~0U, REG_INT_STAT); | ||
966 | pci_set_master(pci_dev); | ||
967 | |||
968 | if ((rc = request_irq(bta->irq, btaudio_irq, IRQF_SHARED|IRQF_DISABLED, | ||
969 | "btaudio",(void *)bta)) < 0) { | ||
970 | printk(KERN_WARNING | ||
971 | "btaudio: can't request irq (rc=%d)\n",rc); | ||
972 | goto fail1; | ||
973 | } | ||
974 | |||
975 | /* register devices */ | ||
976 | if (digital) { | ||
977 | rc = bta->dsp_digital = | ||
978 | register_sound_dsp(&btaudio_digital_dsp_fops,dsp1); | ||
979 | if (rc < 0) { | ||
980 | printk(KERN_WARNING | ||
981 | "btaudio: can't register digital dsp (rc=%d)\n",rc); | ||
982 | goto fail2; | ||
983 | } | ||
984 | printk(KERN_INFO "btaudio: registered device dsp%d [digital]\n", | ||
985 | bta->dsp_digital >> 4); | ||
986 | } | ||
987 | if (analog) { | ||
988 | rc = bta->dsp_analog = | ||
989 | register_sound_dsp(&btaudio_analog_dsp_fops,dsp2); | ||
990 | if (rc < 0) { | ||
991 | printk(KERN_WARNING | ||
992 | "btaudio: can't register analog dsp (rc=%d)\n",rc); | ||
993 | goto fail3; | ||
994 | } | ||
995 | printk(KERN_INFO "btaudio: registered device dsp%d [analog]\n", | ||
996 | bta->dsp_analog >> 4); | ||
997 | rc = bta->mixer_dev = register_sound_mixer(&btaudio_mixer_fops,mixer); | ||
998 | if (rc < 0) { | ||
999 | printk(KERN_WARNING | ||
1000 | "btaudio: can't register mixer (rc=%d)\n",rc); | ||
1001 | goto fail4; | ||
1002 | } | ||
1003 | printk(KERN_INFO "btaudio: registered device mixer%d\n", | ||
1004 | bta->mixer_dev >> 4); | ||
1005 | } | ||
1006 | |||
1007 | /* hook into linked list */ | ||
1008 | bta->next = btaudios; | ||
1009 | btaudios = bta; | ||
1010 | |||
1011 | pci_set_drvdata(pci_dev,bta); | ||
1012 | return 0; | ||
1013 | |||
1014 | fail4: | ||
1015 | unregister_sound_dsp(bta->dsp_analog); | ||
1016 | fail3: | ||
1017 | if (digital) | ||
1018 | unregister_sound_dsp(bta->dsp_digital); | ||
1019 | fail2: | ||
1020 | free_irq(bta->irq,bta); | ||
1021 | fail1: | ||
1022 | iounmap(bta->mmio); | ||
1023 | kfree(bta); | ||
1024 | fail0: | ||
1025 | release_mem_region(pci_resource_start(pci_dev,0), | ||
1026 | pci_resource_len(pci_dev,0)); | ||
1027 | return rc; | ||
1028 | } | ||
1029 | |||
1030 | static void __devexit btaudio_remove(struct pci_dev *pci_dev) | ||
1031 | { | ||
1032 | struct btaudio *bta = pci_get_drvdata(pci_dev); | ||
1033 | struct btaudio *walk; | ||
1034 | |||
1035 | /* turn off all DMA / IRQs */ | ||
1036 | btand(~15, REG_GPIO_DMA_CTL); | ||
1037 | btwrite(0, REG_INT_MASK); | ||
1038 | btwrite(~0U, REG_INT_STAT); | ||
1039 | |||
1040 | /* unregister devices */ | ||
1041 | if (digital) { | ||
1042 | unregister_sound_dsp(bta->dsp_digital); | ||
1043 | } | ||
1044 | if (analog) { | ||
1045 | unregister_sound_dsp(bta->dsp_analog); | ||
1046 | unregister_sound_mixer(bta->mixer_dev); | ||
1047 | } | ||
1048 | |||
1049 | /* free resources */ | ||
1050 | free_buffer(bta); | ||
1051 | free_irq(bta->irq,bta); | ||
1052 | release_mem_region(pci_resource_start(pci_dev,0), | ||
1053 | pci_resource_len(pci_dev,0)); | ||
1054 | iounmap(bta->mmio); | ||
1055 | |||
1056 | /* remove from linked list */ | ||
1057 | if (bta == btaudios) { | ||
1058 | btaudios = NULL; | ||
1059 | } else { | ||
1060 | for (walk = btaudios; walk->next != bta; walk = walk->next) | ||
1061 | ; /* if (NULL == walk->next) BUG(); */ | ||
1062 | walk->next = bta->next; | ||
1063 | } | ||
1064 | |||
1065 | pci_set_drvdata(pci_dev, NULL); | ||
1066 | kfree(bta); | ||
1067 | return; | ||
1068 | } | ||
1069 | |||
1070 | /* -------------------------------------------------------------- */ | ||
1071 | |||
1072 | static struct pci_device_id btaudio_pci_tbl[] = { | ||
1073 | { | ||
1074 | .vendor = PCI_VENDOR_ID_BROOKTREE, | ||
1075 | .device = 0x0878, | ||
1076 | .subvendor = 0x0070, | ||
1077 | .subdevice = 0xff01, | ||
1078 | .driver_data = BTA_OSPREY200, | ||
1079 | },{ | ||
1080 | .vendor = PCI_VENDOR_ID_BROOKTREE, | ||
1081 | .device = 0x0878, | ||
1082 | .subvendor = PCI_ANY_ID, | ||
1083 | .subdevice = PCI_ANY_ID, | ||
1084 | },{ | ||
1085 | .vendor = PCI_VENDOR_ID_BROOKTREE, | ||
1086 | .device = 0x0878, | ||
1087 | .subvendor = PCI_ANY_ID, | ||
1088 | .subdevice = PCI_ANY_ID, | ||
1089 | },{ | ||
1090 | /* --- end of list --- */ | ||
1091 | } | ||
1092 | }; | ||
1093 | |||
1094 | static struct pci_driver btaudio_pci_driver = { | ||
1095 | .name = "btaudio", | ||
1096 | .id_table = btaudio_pci_tbl, | ||
1097 | .probe = btaudio_probe, | ||
1098 | .remove = __devexit_p(btaudio_remove), | ||
1099 | }; | ||
1100 | |||
1101 | static int btaudio_init_module(void) | ||
1102 | { | ||
1103 | printk(KERN_INFO "btaudio: driver version 0.7 loaded [%s%s%s]\n", | ||
1104 | digital ? "digital" : "", | ||
1105 | analog && digital ? "+" : "", | ||
1106 | analog ? "analog" : ""); | ||
1107 | return pci_register_driver(&btaudio_pci_driver); | ||
1108 | } | ||
1109 | |||
1110 | static void btaudio_cleanup_module(void) | ||
1111 | { | ||
1112 | pci_unregister_driver(&btaudio_pci_driver); | ||
1113 | return; | ||
1114 | } | ||
1115 | |||
1116 | module_init(btaudio_init_module); | ||
1117 | module_exit(btaudio_cleanup_module); | ||
1118 | |||
1119 | module_param(dsp1, int, S_IRUGO); | ||
1120 | module_param(dsp2, int, S_IRUGO); | ||
1121 | module_param(mixer, int, S_IRUGO); | ||
1122 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
1123 | module_param(irq_debug, int, S_IRUGO | S_IWUSR); | ||
1124 | module_param(digital, int, S_IRUGO); | ||
1125 | module_param(analog, int, S_IRUGO); | ||
1126 | module_param(rate, int, S_IRUGO); | ||
1127 | module_param(latency, int, S_IRUGO); | ||
1128 | MODULE_PARM_DESC(latency,"pci latency timer"); | ||
1129 | |||
1130 | MODULE_DEVICE_TABLE(pci, btaudio_pci_tbl); | ||
1131 | MODULE_DESCRIPTION("bt878 audio dma driver"); | ||
1132 | MODULE_AUTHOR("Gerd Knorr"); | ||
1133 | MODULE_LICENSE("GPL"); | ||
1134 | |||
1135 | /* | ||
1136 | * Local variables: | ||
1137 | * c-basic-offset: 8 | ||
1138 | * End: | ||
1139 | */ | ||
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c deleted file mode 100644 index de40e21bf279..000000000000 --- a/sound/oss/cs4232.c +++ /dev/null | |||
@@ -1,526 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) by Hannu Savolainen 1993-1997 | ||
3 | * | ||
4 | * cs4232.c | ||
5 | * | ||
6 | * The low level driver for Crystal CS4232 based cards. The CS4232 is | ||
7 | * a PnP compatible chip which contains a CS4231A codec, SB emulation, | ||
8 | * a MPU401 compatible MIDI port, joystick and synthesizer and IDE CD-ROM | ||
9 | * interfaces. This is just a temporary driver until full PnP support | ||
10 | * gets implemented. Just the WSS codec, FM synth and the MIDI ports are | ||
11 | * supported. Other interfaces are left uninitialized. | ||
12 | * | ||
13 | * ifdef ...WAVEFRONT... | ||
14 | * | ||
15 | * Support is provided for initializing the WaveFront synth | ||
16 | * interface as well, which is logical device #4. Note that if | ||
17 | * you have a Tropez+ card, you probably don't need to setup | ||
18 | * the CS4232-supported MIDI interface, since it corresponds to | ||
19 | * the internal 26-pin header that's hard to access. Using this | ||
20 | * requires an additional IRQ, a resource none too plentiful in | ||
21 | * this environment. Just don't set module parameters mpuio and | ||
22 | * mpuirq, and the MIDI port will be left uninitialized. You can | ||
23 | * still use the ICS2115 hosted MIDI interface which corresponds | ||
24 | * to the 9-pin D connector on the back of the card. | ||
25 | * | ||
26 | * endif ...WAVEFRONT... | ||
27 | * | ||
28 | * Supported chips are: | ||
29 | * CS4232 | ||
30 | * CS4236 | ||
31 | * CS4236B | ||
32 | * | ||
33 | * Note: You will need a PnP config setup to initialise some CS4232 boards | ||
34 | * anyway. | ||
35 | * | ||
36 | * Changes | ||
37 | * John Rood Added Bose Sound System Support. | ||
38 | * Toshio Spoor | ||
39 | * Alan Cox Modularisation, Basic cleanups. | ||
40 | * Paul Barton-Davis Separated MPU configuration, added | ||
41 | * Tropez+ (WaveFront) support | ||
42 | * Christoph Hellwig Adapted to module_init/module_exit, | ||
43 | * simple cleanups | ||
44 | * Arnaldo C. de Melo got rid of attach_uart401 | ||
45 | * Bartlomiej Zolnierkiewicz | ||
46 | * Added some __init/__initdata/__exit | ||
47 | * Marcus Meissner Added ISA PnP support. | ||
48 | */ | ||
49 | |||
50 | #include <linux/pnp.h> | ||
51 | #include <linux/module.h> | ||
52 | #include <linux/init.h> | ||
53 | |||
54 | #include "sound_config.h" | ||
55 | |||
56 | #include "ad1848.h" | ||
57 | #include "mpu401.h" | ||
58 | |||
59 | #define KEY_PORT 0x279 /* Same as LPT1 status port */ | ||
60 | #define CSN_NUM 0x99 /* Just a random number */ | ||
61 | #define INDEX_ADDRESS 0x00 /* (R0) Index Address Register */ | ||
62 | #define INDEX_DATA 0x01 /* (R1) Indexed Data Register */ | ||
63 | #define PIN_CONTROL 0x0a /* (I10) Pin Control */ | ||
64 | #define ENABLE_PINS 0xc0 /* XCTRL0/XCTRL1 enable */ | ||
65 | |||
66 | static void CS_OUT(unsigned char a) | ||
67 | { | ||
68 | outb(a, KEY_PORT); | ||
69 | } | ||
70 | |||
71 | #define CS_OUT2(a, b) {CS_OUT(a);CS_OUT(b);} | ||
72 | #define CS_OUT3(a, b, c) {CS_OUT(a);CS_OUT(b);CS_OUT(c);} | ||
73 | |||
74 | static int __initdata bss = 0; | ||
75 | static int mpu_base, mpu_irq; | ||
76 | static int synth_base, synth_irq; | ||
77 | static int mpu_detected; | ||
78 | |||
79 | static int probe_cs4232_mpu(struct address_info *hw_config) | ||
80 | { | ||
81 | /* | ||
82 | * Just write down the config values. | ||
83 | */ | ||
84 | |||
85 | mpu_base = hw_config->io_base; | ||
86 | mpu_irq = hw_config->irq; | ||
87 | |||
88 | return 1; | ||
89 | } | ||
90 | |||
91 | static unsigned char crystal_key[] = /* A 32 byte magic key sequence */ | ||
92 | { | ||
93 | 0x96, 0x35, 0x9a, 0xcd, 0xe6, 0xf3, 0x79, 0xbc, | ||
94 | 0x5e, 0xaf, 0x57, 0x2b, 0x15, 0x8a, 0xc5, 0xe2, | ||
95 | 0xf1, 0xf8, 0x7c, 0x3e, 0x9f, 0x4f, 0x27, 0x13, | ||
96 | 0x09, 0x84, 0x42, 0xa1, 0xd0, 0x68, 0x34, 0x1a | ||
97 | }; | ||
98 | |||
99 | static void sleep(unsigned howlong) | ||
100 | { | ||
101 | current->state = TASK_INTERRUPTIBLE; | ||
102 | schedule_timeout(howlong); | ||
103 | } | ||
104 | |||
105 | static void enable_xctrl(int baseio) | ||
106 | { | ||
107 | unsigned char regd; | ||
108 | |||
109 | /* | ||
110 | * Some IBM Aptiva's have the Bose Sound System. By default | ||
111 | * the Bose Amplifier is disabled. The amplifier will be | ||
112 | * activated, by setting the XCTRL0 and XCTRL1 bits. | ||
113 | * Volume of the monitor bose speakers/woofer, can then | ||
114 | * be set by changing the PCM volume. | ||
115 | * | ||
116 | */ | ||
117 | |||
118 | printk("cs4232: enabling Bose Sound System Amplifier.\n"); | ||
119 | |||
120 | /* Switch to Pin Control Address */ | ||
121 | regd = inb(baseio + INDEX_ADDRESS) & 0xe0; | ||
122 | outb(((unsigned char) (PIN_CONTROL | regd)), baseio + INDEX_ADDRESS ); | ||
123 | |||
124 | /* Activate the XCTRL0 and XCTRL1 Pins */ | ||
125 | regd = inb(baseio + INDEX_DATA); | ||
126 | outb(((unsigned char) (ENABLE_PINS | regd)), baseio + INDEX_DATA ); | ||
127 | } | ||
128 | |||
129 | static int __init probe_cs4232(struct address_info *hw_config, int isapnp_configured) | ||
130 | { | ||
131 | int i, n; | ||
132 | int base = hw_config->io_base, irq = hw_config->irq; | ||
133 | int dma1 = hw_config->dma, dma2 = hw_config->dma2; | ||
134 | struct resource *ports; | ||
135 | |||
136 | if (base == -1 || irq == -1 || dma1 == -1) { | ||
137 | printk(KERN_ERR "cs4232: dma, irq and io must be set.\n"); | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * Verify that the I/O port range is free. | ||
143 | */ | ||
144 | |||
145 | ports = request_region(base, 4, "ad1848"); | ||
146 | if (!ports) { | ||
147 | printk(KERN_ERR "cs4232.c: I/O port 0x%03x not free\n", base); | ||
148 | return 0; | ||
149 | } | ||
150 | if (ad1848_detect(ports, NULL, hw_config->osp)) { | ||
151 | goto got_it; /* The card is already active */ | ||
152 | } | ||
153 | if (isapnp_configured) { | ||
154 | printk(KERN_ERR "cs4232.c: ISA PnP configured, but not detected?\n"); | ||
155 | goto fail; | ||
156 | } | ||
157 | |||
158 | /* | ||
159 | * This version of the driver doesn't use the PnP method when configuring | ||
160 | * the card but a simplified method defined by Crystal. This means that | ||
161 | * just one CS4232 compatible device can exist on the system. Also this | ||
162 | * method conflicts with possible PnP support in the OS. For this reason | ||
163 | * driver is just a temporary kludge. | ||
164 | * | ||
165 | * Also the Cirrus/Crystal method doesn't always work. Try ISA PnP first ;) | ||
166 | */ | ||
167 | |||
168 | /* | ||
169 | * Repeat initialization few times since it doesn't always succeed in | ||
170 | * first time. | ||
171 | */ | ||
172 | |||
173 | for (n = 0; n < 4; n++) | ||
174 | { | ||
175 | /* | ||
176 | * Wake up the card by sending a 32 byte Crystal key to the key port. | ||
177 | */ | ||
178 | |||
179 | for (i = 0; i < 32; i++) | ||
180 | CS_OUT(crystal_key[i]); | ||
181 | |||
182 | sleep(HZ / 10); | ||
183 | |||
184 | /* | ||
185 | * Now set the CSN (Card Select Number). | ||
186 | */ | ||
187 | |||
188 | CS_OUT2(0x06, CSN_NUM); | ||
189 | |||
190 | /* | ||
191 | * Then set some config bytes. First logical device 0 | ||
192 | */ | ||
193 | |||
194 | CS_OUT2(0x15, 0x00); /* Select logical device 0 (WSS/SB/FM) */ | ||
195 | CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff); /* WSS base */ | ||
196 | |||
197 | if (!request_region(0x388, 4, "FM")) /* Not free */ | ||
198 | CS_OUT3(0x48, 0x00, 0x00) /* FM base off */ | ||
199 | else { | ||
200 | release_region(0x388, 4); | ||
201 | CS_OUT3(0x48, 0x03, 0x88); /* FM base 0x388 */ | ||
202 | } | ||
203 | |||
204 | CS_OUT3(0x42, 0x00, 0x00); /* SB base off */ | ||
205 | CS_OUT2(0x22, irq); /* SB+WSS IRQ */ | ||
206 | CS_OUT2(0x2a, dma1); /* SB+WSS DMA */ | ||
207 | |||
208 | if (dma2 != -1) | ||
209 | CS_OUT2(0x25, dma2) /* WSS DMA2 */ | ||
210 | else | ||
211 | CS_OUT2(0x25, 4); /* No WSS DMA2 */ | ||
212 | |||
213 | CS_OUT2(0x33, 0x01); /* Activate logical dev 0 */ | ||
214 | |||
215 | sleep(HZ / 10); | ||
216 | |||
217 | /* | ||
218 | * Initialize logical device 3 (MPU) | ||
219 | */ | ||
220 | |||
221 | if (mpu_base != 0 && mpu_irq != 0) | ||
222 | { | ||
223 | CS_OUT2(0x15, 0x03); /* Select logical device 3 (MPU) */ | ||
224 | CS_OUT3(0x47, (mpu_base >> 8) & 0xff, mpu_base & 0xff); /* MPU base */ | ||
225 | CS_OUT2(0x22, mpu_irq); /* MPU IRQ */ | ||
226 | CS_OUT2(0x33, 0x01); /* Activate logical dev 3 */ | ||
227 | } | ||
228 | |||
229 | if(synth_base != 0) | ||
230 | { | ||
231 | CS_OUT2 (0x15, 0x04); /* logical device 4 (WaveFront) */ | ||
232 | CS_OUT3 (0x47, (synth_base >> 8) & 0xff, | ||
233 | synth_base & 0xff); /* base */ | ||
234 | CS_OUT2 (0x22, synth_irq); /* IRQ */ | ||
235 | CS_OUT2 (0x33, 0x01); /* Activate logical dev 4 */ | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * Finally activate the chip | ||
240 | */ | ||
241 | |||
242 | CS_OUT(0x79); | ||
243 | |||
244 | sleep(HZ / 5); | ||
245 | |||
246 | /* | ||
247 | * Then try to detect the codec part of the chip | ||
248 | */ | ||
249 | |||
250 | if (ad1848_detect(ports, NULL, hw_config->osp)) | ||
251 | goto got_it; | ||
252 | |||
253 | sleep(HZ); | ||
254 | } | ||
255 | fail: | ||
256 | release_region(base, 4); | ||
257 | return 0; | ||
258 | |||
259 | got_it: | ||
260 | if (dma2 == -1) | ||
261 | dma2 = dma1; | ||
262 | |||
263 | hw_config->slots[0] = ad1848_init("Crystal audio controller", ports, | ||
264 | irq, | ||
265 | dma1, /* Playback DMA */ | ||
266 | dma2, /* Capture DMA */ | ||
267 | 0, | ||
268 | hw_config->osp, | ||
269 | THIS_MODULE); | ||
270 | |||
271 | if (hw_config->slots[0] != -1 && | ||
272 | audio_devs[hw_config->slots[0]]->mixer_dev!=-1) | ||
273 | { | ||
274 | /* Assume the mixer map is as suggested in the CS4232 databook */ | ||
275 | AD1848_REROUTE(SOUND_MIXER_LINE1, SOUND_MIXER_LINE); | ||
276 | AD1848_REROUTE(SOUND_MIXER_LINE2, SOUND_MIXER_CD); | ||
277 | AD1848_REROUTE(SOUND_MIXER_LINE3, SOUND_MIXER_SYNTH); /* FM synth */ | ||
278 | } | ||
279 | if (mpu_base != 0 && mpu_irq != 0) | ||
280 | { | ||
281 | static struct address_info hw_config2 = { | ||
282 | 0 | ||
283 | }; /* Ensure it's initialized */ | ||
284 | |||
285 | hw_config2.io_base = mpu_base; | ||
286 | hw_config2.irq = mpu_irq; | ||
287 | hw_config2.dma = -1; | ||
288 | hw_config2.dma2 = -1; | ||
289 | hw_config2.always_detect = 0; | ||
290 | hw_config2.name = NULL; | ||
291 | hw_config2.driver_use_1 = 0; | ||
292 | hw_config2.driver_use_2 = 0; | ||
293 | hw_config2.card_subtype = 0; | ||
294 | |||
295 | if (probe_uart401(&hw_config2, THIS_MODULE)) | ||
296 | { | ||
297 | mpu_detected = 1; | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | mpu_base = mpu_irq = 0; | ||
302 | } | ||
303 | hw_config->slots[1] = hw_config2.slots[1]; | ||
304 | } | ||
305 | |||
306 | if (bss) | ||
307 | enable_xctrl(base); | ||
308 | |||
309 | return 1; | ||
310 | } | ||
311 | |||
312 | static void __devexit unload_cs4232(struct address_info *hw_config) | ||
313 | { | ||
314 | int base = hw_config->io_base, irq = hw_config->irq; | ||
315 | int dma1 = hw_config->dma, dma2 = hw_config->dma2; | ||
316 | |||
317 | if (dma2 == -1) | ||
318 | dma2 = dma1; | ||
319 | |||
320 | ad1848_unload(base, | ||
321 | irq, | ||
322 | dma1, /* Playback DMA */ | ||
323 | dma2, /* Capture DMA */ | ||
324 | 0); | ||
325 | |||
326 | sound_unload_audiodev(hw_config->slots[0]); | ||
327 | if (mpu_base != 0 && mpu_irq != 0 && mpu_detected) | ||
328 | { | ||
329 | static struct address_info hw_config2 = | ||
330 | { | ||
331 | 0 | ||
332 | }; /* Ensure it's initialized */ | ||
333 | |||
334 | hw_config2.io_base = mpu_base; | ||
335 | hw_config2.irq = mpu_irq; | ||
336 | hw_config2.dma = -1; | ||
337 | hw_config2.dma2 = -1; | ||
338 | hw_config2.always_detect = 0; | ||
339 | hw_config2.name = NULL; | ||
340 | hw_config2.driver_use_1 = 0; | ||
341 | hw_config2.driver_use_2 = 0; | ||
342 | hw_config2.card_subtype = 0; | ||
343 | hw_config2.slots[1] = hw_config->slots[1]; | ||
344 | |||
345 | unload_uart401(&hw_config2); | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static struct address_info cfg; | ||
350 | static struct address_info cfg_mpu; | ||
351 | |||
352 | static int __initdata io = -1; | ||
353 | static int __initdata irq = -1; | ||
354 | static int __initdata dma = -1; | ||
355 | static int __initdata dma2 = -1; | ||
356 | static int __initdata mpuio = -1; | ||
357 | static int __initdata mpuirq = -1; | ||
358 | static int __initdata synthio = -1; | ||
359 | static int __initdata synthirq = -1; | ||
360 | static int __initdata isapnp = 1; | ||
361 | |||
362 | static unsigned int cs4232_devices; | ||
363 | |||
364 | MODULE_DESCRIPTION("CS4232 based soundcard driver"); | ||
365 | MODULE_AUTHOR("Hannu Savolainen, Paul Barton-Davis"); | ||
366 | MODULE_LICENSE("GPL"); | ||
367 | |||
368 | module_param(io, int, 0); | ||
369 | MODULE_PARM_DESC(io,"base I/O port for AD1848"); | ||
370 | module_param(irq, int, 0); | ||
371 | MODULE_PARM_DESC(irq,"IRQ for AD1848 chip"); | ||
372 | module_param(dma, int, 0); | ||
373 | MODULE_PARM_DESC(dma,"8 bit DMA for AD1848 chip"); | ||
374 | module_param(dma2, int, 0); | ||
375 | MODULE_PARM_DESC(dma2,"16 bit DMA for AD1848 chip"); | ||
376 | module_param(mpuio, int, 0); | ||
377 | MODULE_PARM_DESC(mpuio,"MPU 401 base address"); | ||
378 | module_param(mpuirq, int, 0); | ||
379 | MODULE_PARM_DESC(mpuirq,"MPU 401 IRQ"); | ||
380 | module_param(synthio, int, 0); | ||
381 | MODULE_PARM_DESC(synthio,"Maui WaveTable base I/O port"); | ||
382 | module_param(synthirq, int, 0); | ||
383 | MODULE_PARM_DESC(synthirq,"Maui WaveTable IRQ"); | ||
384 | module_param(isapnp, bool, 0); | ||
385 | MODULE_PARM_DESC(isapnp,"Enable ISAPnP probing (default 1)"); | ||
386 | module_param(bss, bool, 0); | ||
387 | MODULE_PARM_DESC(bss,"Enable Bose Sound System Support (default 0)"); | ||
388 | |||
389 | /* | ||
390 | * Install a CS4232 based card. Need to have ad1848 and mpu401 | ||
391 | * loaded ready. | ||
392 | */ | ||
393 | |||
394 | /* All cs4232 based cards have the main ad1848 card either as CSC0000 or | ||
395 | * CSC0100. */ | ||
396 | static const struct pnp_device_id cs4232_pnp_table[] = { | ||
397 | { .id = "CSC0100", .driver_data = 0 }, | ||
398 | { .id = "CSC0000", .driver_data = 0 }, | ||
399 | /* Guillemot Turtlebeach something appears to be cs4232 compatible | ||
400 | * (untested) */ | ||
401 | { .id = "GIM0100", .driver_data = 0 }, | ||
402 | { .id = ""} | ||
403 | }; | ||
404 | |||
405 | MODULE_DEVICE_TABLE(pnp, cs4232_pnp_table); | ||
406 | |||
407 | static int __init cs4232_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) | ||
408 | { | ||
409 | struct address_info *isapnpcfg; | ||
410 | |||
411 | isapnpcfg = kmalloc(sizeof(*isapnpcfg),GFP_KERNEL); | ||
412 | if (!isapnpcfg) | ||
413 | return -ENOMEM; | ||
414 | |||
415 | isapnpcfg->irq = pnp_irq(dev, 0); | ||
416 | isapnpcfg->dma = pnp_dma(dev, 0); | ||
417 | isapnpcfg->dma2 = pnp_dma(dev, 1); | ||
418 | isapnpcfg->io_base = pnp_port_start(dev, 0); | ||
419 | if (probe_cs4232(isapnpcfg,TRUE) == 0) { | ||
420 | printk(KERN_ERR "cs4232: ISA PnP card found, but not detected?\n"); | ||
421 | kfree(isapnpcfg); | ||
422 | return -ENODEV; | ||
423 | } | ||
424 | pnp_set_drvdata(dev,isapnpcfg); | ||
425 | cs4232_devices++; | ||
426 | return 0; | ||
427 | } | ||
428 | |||
429 | static void __devexit cs4232_pnp_remove(struct pnp_dev *dev) | ||
430 | { | ||
431 | struct address_info *cfg = pnp_get_drvdata(dev); | ||
432 | if (cfg) { | ||
433 | unload_cs4232(cfg); | ||
434 | kfree(cfg); | ||
435 | } | ||
436 | } | ||
437 | |||
438 | static struct pnp_driver cs4232_driver = { | ||
439 | .name = "cs4232", | ||
440 | .id_table = cs4232_pnp_table, | ||
441 | .probe = cs4232_pnp_probe, | ||
442 | .remove = __devexit_p(cs4232_pnp_remove), | ||
443 | }; | ||
444 | |||
445 | static int __init init_cs4232(void) | ||
446 | { | ||
447 | #ifdef CONFIG_SOUND_WAVEFRONT_MODULE | ||
448 | if(synthio == -1) | ||
449 | printk(KERN_INFO "cs4232: set synthio and synthirq to use the wavefront facilities.\n"); | ||
450 | else { | ||
451 | synth_base = synthio; | ||
452 | synth_irq = synthirq; | ||
453 | } | ||
454 | #else | ||
455 | if(synthio != -1) | ||
456 | printk(KERN_WARNING "cs4232: wavefront support not enabled in this driver.\n"); | ||
457 | #endif | ||
458 | cfg.irq = -1; | ||
459 | |||
460 | if (isapnp) { | ||
461 | pnp_register_driver(&cs4232_driver); | ||
462 | if (cs4232_devices) | ||
463 | return 0; | ||
464 | } | ||
465 | |||
466 | if(io==-1||irq==-1||dma==-1) | ||
467 | { | ||
468 | printk(KERN_ERR "cs4232: Must set io, irq and dma.\n"); | ||
469 | return -ENODEV; | ||
470 | } | ||
471 | |||
472 | cfg.io_base = io; | ||
473 | cfg.irq = irq; | ||
474 | cfg.dma = dma; | ||
475 | cfg.dma2 = dma2; | ||
476 | |||
477 | cfg_mpu.io_base = -1; | ||
478 | cfg_mpu.irq = -1; | ||
479 | |||
480 | if (mpuio != -1 && mpuirq != -1) { | ||
481 | cfg_mpu.io_base = mpuio; | ||
482 | cfg_mpu.irq = mpuirq; | ||
483 | probe_cs4232_mpu(&cfg_mpu); /* Bug always returns 0 not OK -- AC */ | ||
484 | } | ||
485 | |||
486 | if (probe_cs4232(&cfg,FALSE) == 0) | ||
487 | return -ENODEV; | ||
488 | |||
489 | return 0; | ||
490 | } | ||
491 | |||
492 | static void __exit cleanup_cs4232(void) | ||
493 | { | ||
494 | pnp_unregister_driver(&cs4232_driver); | ||
495 | if (cfg.irq != -1) | ||
496 | unload_cs4232(&cfg); /* Unloads global MPU as well, if needed */ | ||
497 | } | ||
498 | |||
499 | module_init(init_cs4232); | ||
500 | module_exit(cleanup_cs4232); | ||
501 | |||
502 | #ifndef MODULE | ||
503 | static int __init setup_cs4232(char *str) | ||
504 | { | ||
505 | /* io, irq, dma, dma2 mpuio, mpuirq*/ | ||
506 | int ints[7]; | ||
507 | |||
508 | /* If we have isapnp cards, no need for options */ | ||
509 | pnp_register_driver(&cs4232_driver); | ||
510 | if (cs4232_devices) | ||
511 | return 1; | ||
512 | |||
513 | str = get_options(str, ARRAY_SIZE(ints), ints); | ||
514 | |||
515 | io = ints[1]; | ||
516 | irq = ints[2]; | ||
517 | dma = ints[3]; | ||
518 | dma2 = ints[4]; | ||
519 | mpuio = ints[5]; | ||
520 | mpuirq = ints[6]; | ||
521 | |||
522 | return 1; | ||
523 | } | ||
524 | |||
525 | __setup("cs4232=", setup_cs4232); | ||
526 | #endif | ||
diff --git a/sound/oss/dmasound/Kconfig b/sound/oss/dmasound/Kconfig index 71b313479f83..3eb782720e58 100644 --- a/sound/oss/dmasound/Kconfig +++ b/sound/oss/dmasound/Kconfig | |||
@@ -14,7 +14,7 @@ config DMASOUND_ATARI | |||
14 | 14 | ||
15 | config DMASOUND_PAULA | 15 | config DMASOUND_PAULA |
16 | tristate "Amiga DMA sound support" | 16 | tristate "Amiga DMA sound support" |
17 | depends on (AMIGA || APUS) && SOUND | 17 | depends on AMIGA && SOUND |
18 | select DMASOUND | 18 | select DMASOUND |
19 | help | 19 | help |
20 | If you want to use the internal audio of your Amiga in Linux, answer | 20 | If you want to use the internal audio of your Amiga in Linux, answer |
diff --git a/sound/oss/dmasound/dmasound_paula.c b/sound/oss/dmasound/dmasound_paula.c index 90fc058e1159..202e8103dc4d 100644 --- a/sound/oss/dmasound/dmasound_paula.c +++ b/sound/oss/dmasound/dmasound_paula.c | |||
@@ -91,10 +91,6 @@ static irqreturn_t AmiInterrupt(int irq, void *dummy); | |||
91 | * power LED are controlled by the same line. | 91 | * power LED are controlled by the same line. |
92 | */ | 92 | */ |
93 | 93 | ||
94 | #ifdef CONFIG_APUS | ||
95 | #define mach_heartbeat ppc_md.heartbeat | ||
96 | #endif | ||
97 | |||
98 | static void (*saved_heartbeat)(int) = NULL; | 94 | static void (*saved_heartbeat)(int) = NULL; |
99 | 95 | ||
100 | static inline void disable_heartbeat(void) | 96 | static inline void disable_heartbeat(void) |
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c deleted file mode 100644 index f5e31f11973d..000000000000 --- a/sound/oss/i810_audio.c +++ /dev/null | |||
@@ -1,3656 +0,0 @@ | |||
1 | /* | ||
2 | * Intel i810 and friends ICH driver for Linux | ||
3 | * Alan Cox <alan@redhat.com> | ||
4 | * | ||
5 | * Built from: | ||
6 | * Low level code: Zach Brown (original nonworking i810 OSS driver) | ||
7 | * Jaroslav Kysela <perex@suse.cz> (working ALSA driver) | ||
8 | * | ||
9 | * Framework: Thomas Sailer <sailer@ife.ee.ethz.ch> | ||
10 | * Extended by: Zach Brown <zab@redhat.com> | ||
11 | * and others.. | ||
12 | * | ||
13 | * Hardware Provided By: | ||
14 | * Analog Devices (A major AC97 codec maker) | ||
15 | * Intel Corp (you've probably heard of them already) | ||
16 | * | ||
17 | * AC97 clues and assistance provided by | ||
18 | * Analog Devices | ||
19 | * Zach 'Fufu' Brown | ||
20 | * Jeff Garzik | ||
21 | * | ||
22 | * This program is free software; you can redistribute it and/or modify | ||
23 | * it under the terms of the GNU General Public License as published by | ||
24 | * the Free Software Foundation; either version 2 of the License, or | ||
25 | * (at your option) any later version. | ||
26 | * | ||
27 | * This program is distributed in the hope that it will be useful, | ||
28 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
29 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
30 | * GNU General Public License for more details. | ||
31 | * | ||
32 | * You should have received a copy of the GNU General Public License | ||
33 | * along with this program; if not, write to the Free Software | ||
34 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
35 | * | ||
36 | * | ||
37 | * Intel 810 theory of operation | ||
38 | * | ||
39 | * The chipset provides three DMA channels that talk to an AC97 | ||
40 | * CODEC (AC97 is a digital/analog mixer standard). At its simplest | ||
41 | * you get 48Khz audio with basic volume and mixer controls. At the | ||
42 | * best you get rate adaption in the codec. We set the card up so | ||
43 | * that we never take completion interrupts but instead keep the card | ||
44 | * chasing its tail around a ring buffer. This is needed for mmap | ||
45 | * mode audio and happens to work rather well for non-mmap modes too. | ||
46 | * | ||
47 | * The board has one output channel for PCM audio (supported) and | ||
48 | * a stereo line in and mono microphone input. Again these are normally | ||
49 | * locked to 48Khz only. Right now recording is not finished. | ||
50 | * | ||
51 | * There is no midi support, no synth support. Use timidity. To get | ||
52 | * esd working you need to use esd -r 48000 as it won't probe 48KHz | ||
53 | * by default. mpg123 can't handle 48Khz only audio so use xmms. | ||
54 | * | ||
55 | * Fix The Sound On Dell | ||
56 | * | ||
57 | * Not everyone uses 48KHz. We know of no way to detect this reliably | ||
58 | * and certainly not to get the right data. If your i810 audio sounds | ||
59 | * stupid you may need to investigate other speeds. According to Analog | ||
60 | * they tend to use a 14.318MHz clock which gives you a base rate of | ||
61 | * 41194Hz. | ||
62 | * | ||
63 | * This is available via the 'ftsodell=1' option. | ||
64 | * | ||
65 | * If you need to force a specific rate set the clocking= option | ||
66 | * | ||
67 | * This driver is cursed. (Ben LaHaise) | ||
68 | * | ||
69 | * ICH 3 caveats | ||
70 | * Intel errata #7 for ICH3 IO. We need to disable SMI stuff | ||
71 | * when codec probing. [Not Yet Done] | ||
72 | * | ||
73 | * ICH 4 caveats | ||
74 | * | ||
75 | * The ICH4 has the feature, that the codec ID doesn't have to be | ||
76 | * congruent with the IO connection. | ||
77 | * | ||
78 | * Therefore, from driver version 0.23 on, there is a "codec ID" <-> | ||
79 | * "IO register base offset" mapping (card->ac97_id_map) field. | ||
80 | * | ||
81 | * Juergen "George" Sawinski (jsaw) | ||
82 | */ | ||
83 | |||
84 | #include <linux/module.h> | ||
85 | #include <linux/string.h> | ||
86 | #include <linux/ctype.h> | ||
87 | #include <linux/ioport.h> | ||
88 | #include <linux/sched.h> | ||
89 | #include <linux/delay.h> | ||
90 | #include <linux/sound.h> | ||
91 | #include <linux/slab.h> | ||
92 | #include <linux/soundcard.h> | ||
93 | #include <linux/pci.h> | ||
94 | #include <linux/interrupt.h> | ||
95 | #include <asm/io.h> | ||
96 | #include <asm/dma.h> | ||
97 | #include <linux/init.h> | ||
98 | #include <linux/poll.h> | ||
99 | #include <linux/spinlock.h> | ||
100 | #include <linux/smp_lock.h> | ||
101 | #include <linux/ac97_codec.h> | ||
102 | #include <linux/bitops.h> | ||
103 | #include <linux/mutex.h> | ||
104 | #include <linux/mm.h> | ||
105 | |||
106 | #include <asm/uaccess.h> | ||
107 | |||
108 | #define DRIVER_VERSION "1.01" | ||
109 | |||
110 | #define MODULOP2(a, b) ((a) & ((b) - 1)) | ||
111 | #define MASKP2(a, b) ((a) & ~((b) - 1)) | ||
112 | |||
113 | static int ftsodell; | ||
114 | static int strict_clocking; | ||
115 | static unsigned int clocking; | ||
116 | static int spdif_locked; | ||
117 | static int ac97_quirk = AC97_TUNE_DEFAULT; | ||
118 | |||
119 | //#define DEBUG | ||
120 | //#define DEBUG2 | ||
121 | //#define DEBUG_INTERRUPTS | ||
122 | //#define DEBUG_MMAP | ||
123 | //#define DEBUG_MMIO | ||
124 | |||
125 | #define ADC_RUNNING 1 | ||
126 | #define DAC_RUNNING 2 | ||
127 | |||
128 | #define I810_FMT_16BIT 1 | ||
129 | #define I810_FMT_STEREO 2 | ||
130 | #define I810_FMT_MASK 3 | ||
131 | |||
132 | #define SPDIF_ON 0x0004 | ||
133 | #define SURR_ON 0x0010 | ||
134 | #define CENTER_LFE_ON 0x0020 | ||
135 | #define VOL_MUTED 0x8000 | ||
136 | |||
137 | /* the 810's array of pointers to data buffers */ | ||
138 | |||
139 | struct sg_item { | ||
140 | #define BUSADDR_MASK 0xFFFFFFFE | ||
141 | u32 busaddr; | ||
142 | #define CON_IOC 0x80000000 /* interrupt on completion */ | ||
143 | #define CON_BUFPAD 0x40000000 /* pad underrun with last sample, else 0 */ | ||
144 | #define CON_BUFLEN_MASK 0x0000ffff /* buffer length in samples */ | ||
145 | u32 control; | ||
146 | }; | ||
147 | |||
148 | /* an instance of the i810 channel */ | ||
149 | #define SG_LEN 32 | ||
150 | struct i810_channel | ||
151 | { | ||
152 | /* these sg guys should probably be allocated | ||
153 | separately as nocache. Must be 8 byte aligned */ | ||
154 | struct sg_item sg[SG_LEN]; /* 32*8 */ | ||
155 | u32 offset; /* 4 */ | ||
156 | u32 port; /* 4 */ | ||
157 | u32 used; | ||
158 | u32 num; | ||
159 | }; | ||
160 | |||
161 | /* | ||
162 | * we have 3 separate dma engines. pcm in, pcm out, and mic. | ||
163 | * each dma engine has controlling registers. These goofy | ||
164 | * names are from the datasheet, but make it easy to write | ||
165 | * code while leafing through it. | ||
166 | * | ||
167 | * ICH4 has 6 dma engines, pcm in, pcm out, mic, pcm in 2, | ||
168 | * mic in 2, s/pdif. Of special interest is the fact that | ||
169 | * the upper 3 DMA engines on the ICH4 *must* be accessed | ||
170 | * via mmio access instead of pio access. | ||
171 | */ | ||
172 | |||
173 | #define ENUM_ENGINE(PRE,DIG) \ | ||
174 | enum { \ | ||
175 | PRE##_BASE = 0x##DIG##0, /* Base Address */ \ | ||
176 | PRE##_BDBAR = 0x##DIG##0, /* Buffer Descriptor list Base Address */ \ | ||
177 | PRE##_CIV = 0x##DIG##4, /* Current Index Value */ \ | ||
178 | PRE##_LVI = 0x##DIG##5, /* Last Valid Index */ \ | ||
179 | PRE##_SR = 0x##DIG##6, /* Status Register */ \ | ||
180 | PRE##_PICB = 0x##DIG##8, /* Position In Current Buffer */ \ | ||
181 | PRE##_PIV = 0x##DIG##a, /* Prefetched Index Value */ \ | ||
182 | PRE##_CR = 0x##DIG##b /* Control Register */ \ | ||
183 | } | ||
184 | |||
185 | ENUM_ENGINE(OFF,0); /* Offsets */ | ||
186 | ENUM_ENGINE(PI,0); /* PCM In */ | ||
187 | ENUM_ENGINE(PO,1); /* PCM Out */ | ||
188 | ENUM_ENGINE(MC,2); /* Mic In */ | ||
189 | |||
190 | enum { | ||
191 | GLOB_CNT = 0x2c, /* Global Control */ | ||
192 | GLOB_STA = 0x30, /* Global Status */ | ||
193 | CAS = 0x34 /* Codec Write Semaphore Register */ | ||
194 | }; | ||
195 | |||
196 | ENUM_ENGINE(MC2,4); /* Mic In 2 */ | ||
197 | ENUM_ENGINE(PI2,5); /* PCM In 2 */ | ||
198 | ENUM_ENGINE(SP,6); /* S/PDIF */ | ||
199 | |||
200 | enum { | ||
201 | SDM = 0x80 /* SDATA_IN Map Register */ | ||
202 | }; | ||
203 | |||
204 | /* interrupts for a dma engine */ | ||
205 | #define DMA_INT_FIFO (1<<4) /* fifo under/over flow */ | ||
206 | #define DMA_INT_COMPLETE (1<<3) /* buffer read/write complete and ioc set */ | ||
207 | #define DMA_INT_LVI (1<<2) /* last valid done */ | ||
208 | #define DMA_INT_CELV (1<<1) /* last valid is current */ | ||
209 | #define DMA_INT_DCH (1) /* DMA Controller Halted (happens on LVI interrupts) */ | ||
210 | #define DMA_INT_MASK (DMA_INT_FIFO|DMA_INT_COMPLETE|DMA_INT_LVI) | ||
211 | |||
212 | /* interrupts for the whole chip */ | ||
213 | #define INT_SEC (1<<11) | ||
214 | #define INT_PRI (1<<10) | ||
215 | #define INT_MC (1<<7) | ||
216 | #define INT_PO (1<<6) | ||
217 | #define INT_PI (1<<5) | ||
218 | #define INT_MO (1<<2) | ||
219 | #define INT_NI (1<<1) | ||
220 | #define INT_GPI (1<<0) | ||
221 | #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI) | ||
222 | |||
223 | /* magic numbers to protect our data structures */ | ||
224 | #define I810_CARD_MAGIC 0x5072696E /* "Prin" */ | ||
225 | #define I810_STATE_MAGIC 0x63657373 /* "cess" */ | ||
226 | #define I810_DMA_MASK 0xffffffff /* DMA buffer mask for pci_alloc_consist */ | ||
227 | #define NR_HW_CH 3 | ||
228 | |||
229 | /* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */ | ||
230 | #define NR_AC97 4 | ||
231 | |||
232 | /* Please note that an 8bit mono stream is not valid on this card, you must have a 16bit */ | ||
233 | /* stream at a minimum for this card to be happy */ | ||
234 | static const unsigned sample_size[] = { 1, 2, 2, 4 }; | ||
235 | /* Samples are 16bit values, so we are shifting to a word, not to a byte, hence shift */ | ||
236 | /* values are one less than might be expected */ | ||
237 | static const unsigned sample_shift[] = { -1, 0, 0, 1 }; | ||
238 | |||
239 | enum { | ||
240 | ICH82801AA = 0, | ||
241 | ICH82901AB, | ||
242 | INTEL440MX, | ||
243 | INTELICH2, | ||
244 | INTELICH3, | ||
245 | INTELICH4, | ||
246 | INTELICH5, | ||
247 | SI7012, | ||
248 | NVIDIA_NFORCE, | ||
249 | AMD768, | ||
250 | AMD8111 | ||
251 | }; | ||
252 | |||
253 | static char * card_names[] = { | ||
254 | "Intel ICH 82801AA", | ||
255 | "Intel ICH 82901AB", | ||
256 | "Intel 440MX", | ||
257 | "Intel ICH2", | ||
258 | "Intel ICH3", | ||
259 | "Intel ICH4", | ||
260 | "Intel ICH5", | ||
261 | "SiS 7012", | ||
262 | "NVIDIA nForce Audio", | ||
263 | "AMD 768", | ||
264 | "AMD-8111 IOHub" | ||
265 | }; | ||
266 | |||
267 | /* These are capabilities (and bugs) the chipsets _can_ have */ | ||
268 | static struct { | ||
269 | int16_t nr_ac97; | ||
270 | #define CAP_MMIO 0x0001 | ||
271 | #define CAP_20BIT_AUDIO_SUPPORT 0x0002 | ||
272 | u_int16_t flags; | ||
273 | } card_cap[] = { | ||
274 | { 1, 0x0000 }, /* ICH82801AA */ | ||
275 | { 1, 0x0000 }, /* ICH82901AB */ | ||
276 | { 1, 0x0000 }, /* INTEL440MX */ | ||
277 | { 1, 0x0000 }, /* INTELICH2 */ | ||
278 | { 2, 0x0000 }, /* INTELICH3 */ | ||
279 | { 3, 0x0003 }, /* INTELICH4 */ | ||
280 | { 3, 0x0003 }, /* INTELICH5 */ | ||
281 | /*@FIXME to be verified*/ { 2, 0x0000 }, /* SI7012 */ | ||
282 | /*@FIXME to be verified*/ { 2, 0x0000 }, /* NVIDIA_NFORCE */ | ||
283 | /*@FIXME to be verified*/ { 2, 0x0000 }, /* AMD768 */ | ||
284 | /*@FIXME to be verified*/ { 3, 0x0001 }, /* AMD8111 */ | ||
285 | }; | ||
286 | |||
287 | static struct pci_device_id i810_pci_tbl [] = { | ||
288 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AA_5, | ||
289 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82801AA}, | ||
290 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801AB_5, | ||
291 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82901AB}, | ||
292 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX, | ||
293 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTEL440MX}, | ||
294 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_4, | ||
295 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2}, | ||
296 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_5, | ||
297 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH3}, | ||
298 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_5, | ||
299 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, | ||
300 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_5, | ||
301 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH5}, | ||
302 | {PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_7012, | ||
303 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, SI7012}, | ||
304 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO, | ||
305 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, | ||
306 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, | ||
307 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, | ||
308 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO, | ||
309 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, | ||
310 | {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_OPUS_7445, | ||
311 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD768}, | ||
312 | {PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8111_AUDIO, | ||
313 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, AMD8111}, | ||
314 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_5, | ||
315 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, | ||
316 | {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_18, | ||
317 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH4}, | ||
318 | {PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_AUDIO, | ||
319 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, NVIDIA_NFORCE}, | ||
320 | {0,} | ||
321 | }; | ||
322 | |||
323 | MODULE_DEVICE_TABLE (pci, i810_pci_tbl); | ||
324 | |||
325 | #ifdef CONFIG_PM | ||
326 | #define PM_SUSPENDED(card) (card->pm_suspended) | ||
327 | #else | ||
328 | #define PM_SUSPENDED(card) (0) | ||
329 | #endif | ||
330 | |||
331 | /* "software" or virtual channel, an instance of opened /dev/dsp */ | ||
332 | struct i810_state { | ||
333 | unsigned int magic; | ||
334 | struct i810_card *card; /* Card info */ | ||
335 | |||
336 | /* single open lock mechanism, only used for recording */ | ||
337 | struct mutex open_mutex; | ||
338 | wait_queue_head_t open_wait; | ||
339 | |||
340 | /* file mode */ | ||
341 | mode_t open_mode; | ||
342 | |||
343 | /* virtual channel number */ | ||
344 | int virt; | ||
345 | |||
346 | #ifdef CONFIG_PM | ||
347 | unsigned int pm_saved_dac_rate,pm_saved_adc_rate; | ||
348 | #endif | ||
349 | struct dmabuf { | ||
350 | /* wave sample stuff */ | ||
351 | unsigned int rate; | ||
352 | unsigned char fmt, enable, trigger; | ||
353 | |||
354 | /* hardware channel */ | ||
355 | struct i810_channel *read_channel; | ||
356 | struct i810_channel *write_channel; | ||
357 | |||
358 | /* OSS buffer management stuff */ | ||
359 | void *rawbuf; | ||
360 | dma_addr_t dma_handle; | ||
361 | unsigned buforder; | ||
362 | unsigned numfrag; | ||
363 | unsigned fragshift; | ||
364 | |||
365 | /* our buffer acts like a circular ring */ | ||
366 | unsigned hwptr; /* where dma last started, updated by update_ptr */ | ||
367 | unsigned swptr; /* where driver last clear/filled, updated by read/write */ | ||
368 | int count; /* bytes to be consumed or been generated by dma machine */ | ||
369 | unsigned total_bytes; /* total bytes dmaed by hardware */ | ||
370 | |||
371 | unsigned error; /* number of over/underruns */ | ||
372 | wait_queue_head_t wait; /* put process on wait queue when no more space in buffer */ | ||
373 | |||
374 | /* redundant, but makes calculations easier */ | ||
375 | /* what the hardware uses */ | ||
376 | unsigned dmasize; | ||
377 | unsigned fragsize; | ||
378 | unsigned fragsamples; | ||
379 | |||
380 | /* what we tell the user to expect */ | ||
381 | unsigned userfrags; | ||
382 | unsigned userfragsize; | ||
383 | |||
384 | /* OSS stuff */ | ||
385 | unsigned mapped:1; | ||
386 | unsigned ready:1; | ||
387 | unsigned update_flag; | ||
388 | unsigned ossfragsize; | ||
389 | unsigned ossmaxfrags; | ||
390 | unsigned subdivision; | ||
391 | } dmabuf; | ||
392 | }; | ||
393 | |||
394 | |||
395 | struct i810_card { | ||
396 | unsigned int magic; | ||
397 | |||
398 | /* We keep i810 cards in a linked list */ | ||
399 | struct i810_card *next; | ||
400 | |||
401 | /* The i810 has a certain amount of cross channel interaction | ||
402 | so we use a single per card lock */ | ||
403 | spinlock_t lock; | ||
404 | |||
405 | /* Control AC97 access serialization */ | ||
406 | spinlock_t ac97_lock; | ||
407 | |||
408 | /* PCI device stuff */ | ||
409 | struct pci_dev * pci_dev; | ||
410 | u16 pci_id; | ||
411 | u16 pci_id_internal; /* used to access card_cap[] */ | ||
412 | #ifdef CONFIG_PM | ||
413 | u16 pm_suspended; | ||
414 | int pm_saved_mixer_settings[SOUND_MIXER_NRDEVICES][NR_AC97]; | ||
415 | #endif | ||
416 | /* soundcore stuff */ | ||
417 | int dev_audio; | ||
418 | |||
419 | /* structures for abstraction of hardware facilities, codecs, banks and channels*/ | ||
420 | u16 ac97_id_map[NR_AC97]; | ||
421 | struct ac97_codec *ac97_codec[NR_AC97]; | ||
422 | struct i810_state *states[NR_HW_CH]; | ||
423 | struct i810_channel *channel; /* 1:1 to states[] but diff. lifetime */ | ||
424 | dma_addr_t chandma; | ||
425 | |||
426 | u16 ac97_features; | ||
427 | u16 ac97_status; | ||
428 | u16 channels; | ||
429 | |||
430 | /* hardware resources */ | ||
431 | unsigned long ac97base; | ||
432 | unsigned long iobase; | ||
433 | u32 irq; | ||
434 | |||
435 | unsigned long ac97base_mmio_phys; | ||
436 | unsigned long iobase_mmio_phys; | ||
437 | u_int8_t __iomem *ac97base_mmio; | ||
438 | u_int8_t __iomem *iobase_mmio; | ||
439 | |||
440 | int use_mmio; | ||
441 | |||
442 | /* Function support */ | ||
443 | struct i810_channel *(*alloc_pcm_channel)(struct i810_card *); | ||
444 | struct i810_channel *(*alloc_rec_pcm_channel)(struct i810_card *); | ||
445 | struct i810_channel *(*alloc_rec_mic_channel)(struct i810_card *); | ||
446 | void (*free_pcm_channel)(struct i810_card *, int chan); | ||
447 | |||
448 | /* We have a *very* long init time possibly, so use this to block */ | ||
449 | /* attempts to open our devices before we are ready (stops oops'es) */ | ||
450 | int initializing; | ||
451 | }; | ||
452 | |||
453 | /* extract register offset from codec struct */ | ||
454 | #define IO_REG_OFF(codec) (((struct i810_card *) codec->private_data)->ac97_id_map[codec->id]) | ||
455 | |||
456 | #define I810_IOREAD(size, type, card, off) \ | ||
457 | ({ \ | ||
458 | type val; \ | ||
459 | if (card->use_mmio) \ | ||
460 | val=read##size(card->iobase_mmio+off); \ | ||
461 | else \ | ||
462 | val=in##size(card->iobase+off); \ | ||
463 | val; \ | ||
464 | }) | ||
465 | |||
466 | #define I810_IOREADL(card, off) I810_IOREAD(l, u32, card, off) | ||
467 | #define I810_IOREADW(card, off) I810_IOREAD(w, u16, card, off) | ||
468 | #define I810_IOREADB(card, off) I810_IOREAD(b, u8, card, off) | ||
469 | |||
470 | #define I810_IOWRITE(size, val, card, off) \ | ||
471 | ({ \ | ||
472 | if (card->use_mmio) \ | ||
473 | write##size(val, card->iobase_mmio+off); \ | ||
474 | else \ | ||
475 | out##size(val, card->iobase+off); \ | ||
476 | }) | ||
477 | |||
478 | #define I810_IOWRITEL(val, card, off) I810_IOWRITE(l, val, card, off) | ||
479 | #define I810_IOWRITEW(val, card, off) I810_IOWRITE(w, val, card, off) | ||
480 | #define I810_IOWRITEB(val, card, off) I810_IOWRITE(b, val, card, off) | ||
481 | |||
482 | #define GET_CIV(card, port) MODULOP2(I810_IOREADB((card), (port) + OFF_CIV), SG_LEN) | ||
483 | #define GET_LVI(card, port) MODULOP2(I810_IOREADB((card), (port) + OFF_LVI), SG_LEN) | ||
484 | |||
485 | /* set LVI from CIV */ | ||
486 | #define CIV_TO_LVI(card, port, off) \ | ||
487 | I810_IOWRITEB(MODULOP2(GET_CIV((card), (port)) + (off), SG_LEN), (card), (port) + OFF_LVI) | ||
488 | |||
489 | static struct ac97_quirk ac97_quirks[] __devinitdata = { | ||
490 | { | ||
491 | .vendor = 0x0e11, | ||
492 | .device = 0x00b8, | ||
493 | .name = "Compaq Evo D510C", | ||
494 | .type = AC97_TUNE_HP_ONLY | ||
495 | }, | ||
496 | { | ||
497 | .vendor = 0x1028, | ||
498 | .device = 0x00d8, | ||
499 | .name = "Dell Precision 530", /* AD1885 */ | ||
500 | .type = AC97_TUNE_HP_ONLY | ||
501 | }, | ||
502 | { | ||
503 | .vendor = 0x1028, | ||
504 | .device = 0x0126, | ||
505 | .name = "Dell Optiplex GX260", /* AD1981A */ | ||
506 | .type = AC97_TUNE_HP_ONLY | ||
507 | }, | ||
508 | { | ||
509 | .vendor = 0x1028, | ||
510 | .device = 0x012d, | ||
511 | .name = "Dell Precision 450", /* AD1981B*/ | ||
512 | .type = AC97_TUNE_HP_ONLY | ||
513 | }, | ||
514 | { /* FIXME: which codec? */ | ||
515 | .vendor = 0x103c, | ||
516 | .device = 0x00c3, | ||
517 | .name = "Hewlett-Packard onboard", | ||
518 | .type = AC97_TUNE_HP_ONLY | ||
519 | }, | ||
520 | { | ||
521 | .vendor = 0x103c, | ||
522 | .device = 0x12f1, | ||
523 | .name = "HP xw8200", /* AD1981B*/ | ||
524 | .type = AC97_TUNE_HP_ONLY | ||
525 | }, | ||
526 | { | ||
527 | .vendor = 0x103c, | ||
528 | .device = 0x3008, | ||
529 | .name = "HP xw4200", /* AD1981B*/ | ||
530 | .type = AC97_TUNE_HP_ONLY | ||
531 | }, | ||
532 | { | ||
533 | .vendor = 0x10f1, | ||
534 | .device = 0x2665, | ||
535 | .name = "Fujitsu-Siemens Celsius", /* AD1981? */ | ||
536 | .type = AC97_TUNE_HP_ONLY | ||
537 | }, | ||
538 | { | ||
539 | .vendor = 0x10f1, | ||
540 | .device = 0x2885, | ||
541 | .name = "AMD64 Mobo", /* ALC650 */ | ||
542 | .type = AC97_TUNE_HP_ONLY | ||
543 | }, | ||
544 | { | ||
545 | .vendor = 0x110a, | ||
546 | .device = 0x0056, | ||
547 | .name = "Fujitsu-Siemens Scenic", /* AD1981? */ | ||
548 | .type = AC97_TUNE_HP_ONLY | ||
549 | }, | ||
550 | { | ||
551 | .vendor = 0x11d4, | ||
552 | .device = 0x5375, | ||
553 | .name = "ADI AD1985 (discrete)", | ||
554 | .type = AC97_TUNE_HP_ONLY | ||
555 | }, | ||
556 | { | ||
557 | .vendor = 0x1462, | ||
558 | .device = 0x5470, | ||
559 | .name = "MSI P4 ATX 645 Ultra", | ||
560 | .type = AC97_TUNE_HP_ONLY | ||
561 | }, | ||
562 | { | ||
563 | .vendor = 0x1734, | ||
564 | .device = 0x0088, | ||
565 | .name = "Fujitsu-Siemens D1522", /* AD1981 */ | ||
566 | .type = AC97_TUNE_HP_ONLY | ||
567 | }, | ||
568 | { | ||
569 | .vendor = 0x8086, | ||
570 | .device = 0x4856, | ||
571 | .name = "Intel D845WN (82801BA)", | ||
572 | .type = AC97_TUNE_SWAP_HP | ||
573 | }, | ||
574 | { | ||
575 | .vendor = 0x8086, | ||
576 | .device = 0x4d44, | ||
577 | .name = "Intel D850EMV2", /* AD1885 */ | ||
578 | .type = AC97_TUNE_HP_ONLY | ||
579 | }, | ||
580 | { | ||
581 | .vendor = 0x8086, | ||
582 | .device = 0x4d56, | ||
583 | .name = "Intel ICH/AD1885", | ||
584 | .type = AC97_TUNE_HP_ONLY | ||
585 | }, | ||
586 | { | ||
587 | .vendor = 0x1028, | ||
588 | .device = 0x012d, | ||
589 | .name = "Dell Precision 450", /* AD1981B*/ | ||
590 | .type = AC97_TUNE_HP_ONLY | ||
591 | }, | ||
592 | { | ||
593 | .vendor = 0x103c, | ||
594 | .device = 0x3008, | ||
595 | .name = "HP xw4200", /* AD1981B*/ | ||
596 | .type = AC97_TUNE_HP_ONLY | ||
597 | }, | ||
598 | { | ||
599 | .vendor = 0x103c, | ||
600 | .device = 0x12f1, | ||
601 | .name = "HP xw8200", /* AD1981B*/ | ||
602 | .type = AC97_TUNE_HP_ONLY | ||
603 | }, | ||
604 | { } /* terminator */ | ||
605 | }; | ||
606 | |||
607 | static struct i810_card *devs = NULL; | ||
608 | |||
609 | static int i810_open_mixdev(struct inode *inode, struct file *file); | ||
610 | static int i810_ioctl_mixdev(struct inode *inode, struct file *file, | ||
611 | unsigned int cmd, unsigned long arg); | ||
612 | static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg); | ||
613 | static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data); | ||
614 | static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg); | ||
615 | static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data); | ||
616 | static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg); | ||
617 | static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data); | ||
618 | |||
619 | static struct i810_channel *i810_alloc_pcm_channel(struct i810_card *card) | ||
620 | { | ||
621 | if(card->channel[1].used==1) | ||
622 | return NULL; | ||
623 | card->channel[1].used=1; | ||
624 | return &card->channel[1]; | ||
625 | } | ||
626 | |||
627 | static struct i810_channel *i810_alloc_rec_pcm_channel(struct i810_card *card) | ||
628 | { | ||
629 | if(card->channel[0].used==1) | ||
630 | return NULL; | ||
631 | card->channel[0].used=1; | ||
632 | return &card->channel[0]; | ||
633 | } | ||
634 | |||
635 | static struct i810_channel *i810_alloc_rec_mic_channel(struct i810_card *card) | ||
636 | { | ||
637 | if(card->channel[2].used==1) | ||
638 | return NULL; | ||
639 | card->channel[2].used=1; | ||
640 | return &card->channel[2]; | ||
641 | } | ||
642 | |||
643 | static void i810_free_pcm_channel(struct i810_card *card, int channel) | ||
644 | { | ||
645 | card->channel[channel].used=0; | ||
646 | } | ||
647 | |||
648 | static int i810_valid_spdif_rate ( struct ac97_codec *codec, int rate ) | ||
649 | { | ||
650 | unsigned long id = 0L; | ||
651 | |||
652 | id = (i810_ac97_get(codec, AC97_VENDOR_ID1) << 16); | ||
653 | id |= i810_ac97_get(codec, AC97_VENDOR_ID2) & 0xffff; | ||
654 | #ifdef DEBUG | ||
655 | printk ( "i810_audio: codec = %s, codec_id = 0x%08lx\n", codec->name, id); | ||
656 | #endif | ||
657 | switch ( id ) { | ||
658 | case 0x41445361: /* AD1886 */ | ||
659 | if (rate == 48000) { | ||
660 | return 1; | ||
661 | } | ||
662 | break; | ||
663 | default: /* all other codecs, until we know otherwiae */ | ||
664 | if (rate == 48000 || rate == 44100 || rate == 32000) { | ||
665 | return 1; | ||
666 | } | ||
667 | break; | ||
668 | } | ||
669 | return (0); | ||
670 | } | ||
671 | |||
672 | /* i810_set_spdif_output | ||
673 | * | ||
674 | * Configure the S/PDIF output transmitter. When we turn on | ||
675 | * S/PDIF, we turn off the analog output. This may not be | ||
676 | * the right thing to do. | ||
677 | * | ||
678 | * Assumptions: | ||
679 | * The DSP sample rate must already be set to a supported | ||
680 | * S/PDIF rate (32kHz, 44.1kHz, or 48kHz) or we abort. | ||
681 | */ | ||
682 | static int i810_set_spdif_output(struct i810_state *state, int slots, int rate) | ||
683 | { | ||
684 | int vol; | ||
685 | int aud_reg; | ||
686 | int r = 0; | ||
687 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
688 | |||
689 | if(!codec->codec_ops->digital) { | ||
690 | state->card->ac97_status &= ~SPDIF_ON; | ||
691 | } else { | ||
692 | if ( slots == -1 ) { /* Turn off S/PDIF */ | ||
693 | codec->codec_ops->digital(codec, 0, 0, 0); | ||
694 | /* If the volume wasn't muted before we turned on S/PDIF, unmute it */ | ||
695 | if ( !(state->card->ac97_status & VOL_MUTED) ) { | ||
696 | aud_reg = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO); | ||
697 | i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (aud_reg & ~VOL_MUTED)); | ||
698 | } | ||
699 | state->card->ac97_status &= ~(VOL_MUTED | SPDIF_ON); | ||
700 | return 0; | ||
701 | } | ||
702 | |||
703 | vol = i810_ac97_get(codec, AC97_MASTER_VOL_STEREO); | ||
704 | state->card->ac97_status = vol & VOL_MUTED; | ||
705 | |||
706 | r = codec->codec_ops->digital(codec, slots, rate, 0); | ||
707 | |||
708 | if(r) | ||
709 | state->card->ac97_status |= SPDIF_ON; | ||
710 | else | ||
711 | state->card->ac97_status &= ~SPDIF_ON; | ||
712 | |||
713 | /* Mute the analog output */ | ||
714 | /* Should this only mute the PCM volume??? */ | ||
715 | i810_ac97_set(codec, AC97_MASTER_VOL_STEREO, (vol | VOL_MUTED)); | ||
716 | } | ||
717 | return r; | ||
718 | } | ||
719 | |||
720 | /* i810_set_dac_channels | ||
721 | * | ||
722 | * Configure the codec's multi-channel DACs | ||
723 | * | ||
724 | * The logic is backwards. Setting the bit to 1 turns off the DAC. | ||
725 | * | ||
726 | * What about the ICH? We currently configure it using the | ||
727 | * SNDCTL_DSP_CHANNELS ioctl. If we're turnning on the DAC, | ||
728 | * does that imply that we want the ICH set to support | ||
729 | * these channels? | ||
730 | * | ||
731 | * TODO: | ||
732 | * vailidate that the codec really supports these DACs | ||
733 | * before turning them on. | ||
734 | */ | ||
735 | static void i810_set_dac_channels(struct i810_state *state, int channel) | ||
736 | { | ||
737 | int aud_reg; | ||
738 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
739 | |||
740 | /* No codec, no setup */ | ||
741 | |||
742 | if(codec == NULL) | ||
743 | return; | ||
744 | |||
745 | aud_reg = i810_ac97_get(codec, AC97_EXTENDED_STATUS); | ||
746 | aud_reg |= AC97_EA_PRI | AC97_EA_PRJ | AC97_EA_PRK; | ||
747 | state->card->ac97_status &= ~(SURR_ON | CENTER_LFE_ON); | ||
748 | |||
749 | switch ( channel ) { | ||
750 | case 2: /* always enabled */ | ||
751 | break; | ||
752 | case 4: | ||
753 | aud_reg &= ~AC97_EA_PRJ; | ||
754 | state->card->ac97_status |= SURR_ON; | ||
755 | break; | ||
756 | case 6: | ||
757 | aud_reg &= ~(AC97_EA_PRJ | AC97_EA_PRI | AC97_EA_PRK); | ||
758 | state->card->ac97_status |= SURR_ON | CENTER_LFE_ON; | ||
759 | break; | ||
760 | default: | ||
761 | break; | ||
762 | } | ||
763 | i810_ac97_set(codec, AC97_EXTENDED_STATUS, aud_reg); | ||
764 | |||
765 | } | ||
766 | |||
767 | |||
768 | /* set playback sample rate */ | ||
769 | static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int rate) | ||
770 | { | ||
771 | struct dmabuf *dmabuf = &state->dmabuf; | ||
772 | u32 new_rate; | ||
773 | struct ac97_codec *codec=state->card->ac97_codec[0]; | ||
774 | |||
775 | if(!(state->card->ac97_features&0x0001)) | ||
776 | { | ||
777 | dmabuf->rate = clocking; | ||
778 | #ifdef DEBUG | ||
779 | printk("Asked for %d Hz, but ac97_features says we only do %dHz. Sorry!\n", | ||
780 | rate,clocking); | ||
781 | #endif | ||
782 | return clocking; | ||
783 | } | ||
784 | |||
785 | if (rate > 48000) | ||
786 | rate = 48000; | ||
787 | if (rate < 8000) | ||
788 | rate = 8000; | ||
789 | dmabuf->rate = rate; | ||
790 | |||
791 | /* | ||
792 | * Adjust for misclocked crap | ||
793 | */ | ||
794 | rate = ( rate * clocking)/48000; | ||
795 | if(strict_clocking && rate < 8000) { | ||
796 | rate = 8000; | ||
797 | dmabuf->rate = (rate * 48000)/clocking; | ||
798 | } | ||
799 | |||
800 | new_rate=ac97_set_dac_rate(codec, rate); | ||
801 | if(new_rate != rate) { | ||
802 | dmabuf->rate = (new_rate * 48000)/clocking; | ||
803 | } | ||
804 | #ifdef DEBUG | ||
805 | printk("i810_audio: called i810_set_dac_rate : asked for %d, got %d\n", rate, dmabuf->rate); | ||
806 | #endif | ||
807 | rate = new_rate; | ||
808 | return dmabuf->rate; | ||
809 | } | ||
810 | |||
811 | /* set recording sample rate */ | ||
812 | static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int rate) | ||
813 | { | ||
814 | struct dmabuf *dmabuf = &state->dmabuf; | ||
815 | u32 new_rate; | ||
816 | struct ac97_codec *codec=state->card->ac97_codec[0]; | ||
817 | |||
818 | if(!(state->card->ac97_features&0x0001)) | ||
819 | { | ||
820 | dmabuf->rate = clocking; | ||
821 | return clocking; | ||
822 | } | ||
823 | |||
824 | if (rate > 48000) | ||
825 | rate = 48000; | ||
826 | if (rate < 8000) | ||
827 | rate = 8000; | ||
828 | dmabuf->rate = rate; | ||
829 | |||
830 | /* | ||
831 | * Adjust for misclocked crap | ||
832 | */ | ||
833 | |||
834 | rate = ( rate * clocking)/48000; | ||
835 | if(strict_clocking && rate < 8000) { | ||
836 | rate = 8000; | ||
837 | dmabuf->rate = (rate * 48000)/clocking; | ||
838 | } | ||
839 | |||
840 | new_rate = ac97_set_adc_rate(codec, rate); | ||
841 | |||
842 | if(new_rate != rate) { | ||
843 | dmabuf->rate = (new_rate * 48000)/clocking; | ||
844 | rate = new_rate; | ||
845 | } | ||
846 | #ifdef DEBUG | ||
847 | printk("i810_audio: called i810_set_adc_rate : rate = %d/%d\n", dmabuf->rate, rate); | ||
848 | #endif | ||
849 | return dmabuf->rate; | ||
850 | } | ||
851 | |||
852 | /* get current playback/recording dma buffer pointer (byte offset from LBA), | ||
853 | called with spinlock held! */ | ||
854 | |||
855 | static inline unsigned i810_get_dma_addr(struct i810_state *state, int rec) | ||
856 | { | ||
857 | struct dmabuf *dmabuf = &state->dmabuf; | ||
858 | unsigned int civ, offset, port, port_picb, bytes = 2; | ||
859 | |||
860 | if (!dmabuf->enable) | ||
861 | return 0; | ||
862 | |||
863 | if (rec) | ||
864 | port = dmabuf->read_channel->port; | ||
865 | else | ||
866 | port = dmabuf->write_channel->port; | ||
867 | |||
868 | if(state->card->pci_id == PCI_DEVICE_ID_SI_7012) { | ||
869 | port_picb = port + OFF_SR; | ||
870 | bytes = 1; | ||
871 | } else | ||
872 | port_picb = port + OFF_PICB; | ||
873 | |||
874 | do { | ||
875 | civ = GET_CIV(state->card, port); | ||
876 | offset = I810_IOREADW(state->card, port_picb); | ||
877 | /* Must have a delay here! */ | ||
878 | if(offset == 0) | ||
879 | udelay(1); | ||
880 | /* Reread both registers and make sure that that total | ||
881 | * offset from the first reading to the second is 0. | ||
882 | * There is an issue with SiS hardware where it will count | ||
883 | * picb down to 0, then update civ to the next value, | ||
884 | * then set the new picb to fragsize bytes. We can catch | ||
885 | * it between the civ update and the picb update, making | ||
886 | * it look as though we are 1 fragsize ahead of where we | ||
887 | * are. The next to we get the address though, it will | ||
888 | * be back in the right place, and we will suddenly think | ||
889 | * we just went forward dmasize - fragsize bytes, causing | ||
890 | * totally stupid *huge* dma overrun messages. We are | ||
891 | * assuming that the 1us delay is more than long enough | ||
892 | * that we won't have to worry about the chip still being | ||
893 | * out of sync with reality ;-) | ||
894 | */ | ||
895 | } while (civ != GET_CIV(state->card, port) || offset != I810_IOREADW(state->card, port_picb)); | ||
896 | |||
897 | return (((civ + 1) * dmabuf->fragsize - (bytes * offset)) | ||
898 | % dmabuf->dmasize); | ||
899 | } | ||
900 | |||
901 | /* Stop recording (lock held) */ | ||
902 | static inline void __stop_adc(struct i810_state *state) | ||
903 | { | ||
904 | struct dmabuf *dmabuf = &state->dmabuf; | ||
905 | struct i810_card *card = state->card; | ||
906 | |||
907 | dmabuf->enable &= ~ADC_RUNNING; | ||
908 | I810_IOWRITEB(0, card, PI_CR); | ||
909 | // wait for the card to acknowledge shutdown | ||
910 | while( I810_IOREADB(card, PI_CR) != 0 ) ; | ||
911 | // now clear any latent interrupt bits (like the halt bit) | ||
912 | if(card->pci_id == PCI_DEVICE_ID_SI_7012) | ||
913 | I810_IOWRITEB( I810_IOREADB(card, PI_PICB), card, PI_PICB ); | ||
914 | else | ||
915 | I810_IOWRITEB( I810_IOREADB(card, PI_SR), card, PI_SR ); | ||
916 | I810_IOWRITEL( I810_IOREADL(card, GLOB_STA) & INT_PI, card, GLOB_STA); | ||
917 | } | ||
918 | |||
919 | static void stop_adc(struct i810_state *state) | ||
920 | { | ||
921 | struct i810_card *card = state->card; | ||
922 | unsigned long flags; | ||
923 | |||
924 | spin_lock_irqsave(&card->lock, flags); | ||
925 | __stop_adc(state); | ||
926 | spin_unlock_irqrestore(&card->lock, flags); | ||
927 | } | ||
928 | |||
929 | static inline void __start_adc(struct i810_state *state) | ||
930 | { | ||
931 | struct dmabuf *dmabuf = &state->dmabuf; | ||
932 | |||
933 | if (dmabuf->count < dmabuf->dmasize && dmabuf->ready && !dmabuf->enable && | ||
934 | (dmabuf->trigger & PCM_ENABLE_INPUT)) { | ||
935 | dmabuf->enable |= ADC_RUNNING; | ||
936 | // Interrupt enable, LVI enable, DMA enable | ||
937 | I810_IOWRITEB(0x10 | 0x04 | 0x01, state->card, PI_CR); | ||
938 | } | ||
939 | } | ||
940 | |||
941 | static void start_adc(struct i810_state *state) | ||
942 | { | ||
943 | struct i810_card *card = state->card; | ||
944 | unsigned long flags; | ||
945 | |||
946 | spin_lock_irqsave(&card->lock, flags); | ||
947 | __start_adc(state); | ||
948 | spin_unlock_irqrestore(&card->lock, flags); | ||
949 | } | ||
950 | |||
951 | /* stop playback (lock held) */ | ||
952 | static inline void __stop_dac(struct i810_state *state) | ||
953 | { | ||
954 | struct dmabuf *dmabuf = &state->dmabuf; | ||
955 | struct i810_card *card = state->card; | ||
956 | |||
957 | dmabuf->enable &= ~DAC_RUNNING; | ||
958 | I810_IOWRITEB(0, card, PO_CR); | ||
959 | // wait for the card to acknowledge shutdown | ||
960 | while( I810_IOREADB(card, PO_CR) != 0 ) ; | ||
961 | // now clear any latent interrupt bits (like the halt bit) | ||
962 | if(card->pci_id == PCI_DEVICE_ID_SI_7012) | ||
963 | I810_IOWRITEB( I810_IOREADB(card, PO_PICB), card, PO_PICB ); | ||
964 | else | ||
965 | I810_IOWRITEB( I810_IOREADB(card, PO_SR), card, PO_SR ); | ||
966 | I810_IOWRITEL( I810_IOREADL(card, GLOB_STA) & INT_PO, card, GLOB_STA); | ||
967 | } | ||
968 | |||
969 | static void stop_dac(struct i810_state *state) | ||
970 | { | ||
971 | struct i810_card *card = state->card; | ||
972 | unsigned long flags; | ||
973 | |||
974 | spin_lock_irqsave(&card->lock, flags); | ||
975 | __stop_dac(state); | ||
976 | spin_unlock_irqrestore(&card->lock, flags); | ||
977 | } | ||
978 | |||
979 | static inline void __start_dac(struct i810_state *state) | ||
980 | { | ||
981 | struct dmabuf *dmabuf = &state->dmabuf; | ||
982 | |||
983 | if (dmabuf->count > 0 && dmabuf->ready && !dmabuf->enable && | ||
984 | (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { | ||
985 | dmabuf->enable |= DAC_RUNNING; | ||
986 | // Interrupt enable, LVI enable, DMA enable | ||
987 | I810_IOWRITEB(0x10 | 0x04 | 0x01, state->card, PO_CR); | ||
988 | } | ||
989 | } | ||
990 | static void start_dac(struct i810_state *state) | ||
991 | { | ||
992 | struct i810_card *card = state->card; | ||
993 | unsigned long flags; | ||
994 | |||
995 | spin_lock_irqsave(&card->lock, flags); | ||
996 | __start_dac(state); | ||
997 | spin_unlock_irqrestore(&card->lock, flags); | ||
998 | } | ||
999 | |||
1000 | #define DMABUF_DEFAULTORDER (16-PAGE_SHIFT) | ||
1001 | #define DMABUF_MINORDER 1 | ||
1002 | |||
1003 | /* allocate DMA buffer, playback and recording buffer should be allocated separately */ | ||
1004 | static int alloc_dmabuf(struct i810_state *state) | ||
1005 | { | ||
1006 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1007 | void *rawbuf= NULL; | ||
1008 | int order, size; | ||
1009 | struct page *page, *pend; | ||
1010 | |||
1011 | /* If we don't have any oss frag params, then use our default ones */ | ||
1012 | if(dmabuf->ossmaxfrags == 0) | ||
1013 | dmabuf->ossmaxfrags = 4; | ||
1014 | if(dmabuf->ossfragsize == 0) | ||
1015 | dmabuf->ossfragsize = (PAGE_SIZE<<DMABUF_DEFAULTORDER)/dmabuf->ossmaxfrags; | ||
1016 | size = dmabuf->ossfragsize * dmabuf->ossmaxfrags; | ||
1017 | |||
1018 | if(dmabuf->rawbuf && (PAGE_SIZE << dmabuf->buforder) == size) | ||
1019 | return 0; | ||
1020 | /* alloc enough to satisfy the oss params */ | ||
1021 | for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--) { | ||
1022 | if ( (PAGE_SIZE<<order) > size ) | ||
1023 | continue; | ||
1024 | if ((rawbuf = pci_alloc_consistent(state->card->pci_dev, | ||
1025 | PAGE_SIZE << order, | ||
1026 | &dmabuf->dma_handle))) | ||
1027 | break; | ||
1028 | } | ||
1029 | if (!rawbuf) | ||
1030 | return -ENOMEM; | ||
1031 | |||
1032 | |||
1033 | #ifdef DEBUG | ||
1034 | printk("i810_audio: allocated %ld (order = %d) bytes at %p\n", | ||
1035 | PAGE_SIZE << order, order, rawbuf); | ||
1036 | #endif | ||
1037 | |||
1038 | dmabuf->ready = dmabuf->mapped = 0; | ||
1039 | dmabuf->rawbuf = rawbuf; | ||
1040 | dmabuf->buforder = order; | ||
1041 | |||
1042 | /* now mark the pages as reserved; otherwise remap_pfn_range doesn't do what we want */ | ||
1043 | pend = virt_to_page(rawbuf + (PAGE_SIZE << order) - 1); | ||
1044 | for (page = virt_to_page(rawbuf); page <= pend; page++) | ||
1045 | SetPageReserved(page); | ||
1046 | |||
1047 | return 0; | ||
1048 | } | ||
1049 | |||
1050 | /* free DMA buffer */ | ||
1051 | static void dealloc_dmabuf(struct i810_state *state) | ||
1052 | { | ||
1053 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1054 | struct page *page, *pend; | ||
1055 | |||
1056 | if (dmabuf->rawbuf) { | ||
1057 | /* undo marking the pages as reserved */ | ||
1058 | pend = virt_to_page(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1); | ||
1059 | for (page = virt_to_page(dmabuf->rawbuf); page <= pend; page++) | ||
1060 | ClearPageReserved(page); | ||
1061 | pci_free_consistent(state->card->pci_dev, PAGE_SIZE << dmabuf->buforder, | ||
1062 | dmabuf->rawbuf, dmabuf->dma_handle); | ||
1063 | } | ||
1064 | dmabuf->rawbuf = NULL; | ||
1065 | dmabuf->mapped = dmabuf->ready = 0; | ||
1066 | } | ||
1067 | |||
1068 | static int prog_dmabuf(struct i810_state *state, unsigned rec) | ||
1069 | { | ||
1070 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1071 | struct i810_channel *c; | ||
1072 | struct sg_item *sg; | ||
1073 | unsigned long flags; | ||
1074 | int ret; | ||
1075 | unsigned fragint; | ||
1076 | int i; | ||
1077 | |||
1078 | spin_lock_irqsave(&state->card->lock, flags); | ||
1079 | if(dmabuf->enable & DAC_RUNNING) | ||
1080 | __stop_dac(state); | ||
1081 | if(dmabuf->enable & ADC_RUNNING) | ||
1082 | __stop_adc(state); | ||
1083 | dmabuf->total_bytes = 0; | ||
1084 | dmabuf->count = dmabuf->error = 0; | ||
1085 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
1086 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1087 | |||
1088 | /* allocate DMA buffer, let alloc_dmabuf determine if we are already | ||
1089 | * allocated well enough or if we should replace the current buffer | ||
1090 | * (assuming one is already allocated, if it isn't, then allocate it). | ||
1091 | */ | ||
1092 | if ((ret = alloc_dmabuf(state))) | ||
1093 | return ret; | ||
1094 | |||
1095 | /* FIXME: figure out all this OSS fragment stuff */ | ||
1096 | /* I did, it now does what it should according to the OSS API. DL */ | ||
1097 | /* We may not have realloced our dmabuf, but the fragment size to | ||
1098 | * fragment number ratio may have changed, so go ahead and reprogram | ||
1099 | * things | ||
1100 | */ | ||
1101 | dmabuf->dmasize = PAGE_SIZE << dmabuf->buforder; | ||
1102 | dmabuf->numfrag = SG_LEN; | ||
1103 | dmabuf->fragsize = dmabuf->dmasize/dmabuf->numfrag; | ||
1104 | dmabuf->fragsamples = dmabuf->fragsize >> 1; | ||
1105 | dmabuf->fragshift = ffs(dmabuf->fragsize) - 1; | ||
1106 | dmabuf->userfragsize = dmabuf->ossfragsize; | ||
1107 | dmabuf->userfrags = dmabuf->dmasize/dmabuf->ossfragsize; | ||
1108 | |||
1109 | memset(dmabuf->rawbuf, 0, dmabuf->dmasize); | ||
1110 | |||
1111 | if(dmabuf->ossmaxfrags == 4) { | ||
1112 | fragint = 8; | ||
1113 | } else if (dmabuf->ossmaxfrags == 8) { | ||
1114 | fragint = 4; | ||
1115 | } else if (dmabuf->ossmaxfrags == 16) { | ||
1116 | fragint = 2; | ||
1117 | } else { | ||
1118 | fragint = 1; | ||
1119 | } | ||
1120 | /* | ||
1121 | * Now set up the ring | ||
1122 | */ | ||
1123 | if(dmabuf->read_channel) | ||
1124 | c = dmabuf->read_channel; | ||
1125 | else | ||
1126 | c = dmabuf->write_channel; | ||
1127 | while(c != NULL) { | ||
1128 | sg=&c->sg[0]; | ||
1129 | /* | ||
1130 | * Load up 32 sg entries and take an interrupt at half | ||
1131 | * way (we might want more interrupts later..) | ||
1132 | */ | ||
1133 | |||
1134 | for(i=0;i<dmabuf->numfrag;i++) | ||
1135 | { | ||
1136 | sg->busaddr=(u32)dmabuf->dma_handle+dmabuf->fragsize*i; | ||
1137 | // the card will always be doing 16bit stereo | ||
1138 | sg->control=dmabuf->fragsamples; | ||
1139 | if(state->card->pci_id == PCI_DEVICE_ID_SI_7012) | ||
1140 | sg->control <<= 1; | ||
1141 | sg->control|=CON_BUFPAD; | ||
1142 | // set us up to get IOC interrupts as often as needed to | ||
1143 | // satisfy numfrag requirements, no more | ||
1144 | if( ((i+1) % fragint) == 0) { | ||
1145 | sg->control|=CON_IOC; | ||
1146 | } | ||
1147 | sg++; | ||
1148 | } | ||
1149 | spin_lock_irqsave(&state->card->lock, flags); | ||
1150 | I810_IOWRITEB(2, state->card, c->port+OFF_CR); /* reset DMA machine */ | ||
1151 | while( I810_IOREADB(state->card, c->port+OFF_CR) & 0x02 ) ; | ||
1152 | I810_IOWRITEL((u32)state->card->chandma + | ||
1153 | c->num*sizeof(struct i810_channel), | ||
1154 | state->card, c->port+OFF_BDBAR); | ||
1155 | CIV_TO_LVI(state->card, c->port, 0); | ||
1156 | |||
1157 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1158 | |||
1159 | if(c != dmabuf->write_channel) | ||
1160 | c = dmabuf->write_channel; | ||
1161 | else | ||
1162 | c = NULL; | ||
1163 | } | ||
1164 | |||
1165 | /* set the ready flag for the dma buffer */ | ||
1166 | dmabuf->ready = 1; | ||
1167 | |||
1168 | #ifdef DEBUG | ||
1169 | printk("i810_audio: prog_dmabuf, sample rate = %d, format = %d,\n\tnumfrag = %d, " | ||
1170 | "fragsize = %d dmasize = %d\n", | ||
1171 | dmabuf->rate, dmabuf->fmt, dmabuf->numfrag, | ||
1172 | dmabuf->fragsize, dmabuf->dmasize); | ||
1173 | #endif | ||
1174 | |||
1175 | return 0; | ||
1176 | } | ||
1177 | |||
1178 | static void __i810_update_lvi(struct i810_state *state, int rec) | ||
1179 | { | ||
1180 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1181 | int x, port; | ||
1182 | int trigger; | ||
1183 | int count, fragsize; | ||
1184 | void (*start)(struct i810_state *); | ||
1185 | |||
1186 | count = dmabuf->count; | ||
1187 | if (rec) { | ||
1188 | port = dmabuf->read_channel->port; | ||
1189 | trigger = PCM_ENABLE_INPUT; | ||
1190 | start = __start_adc; | ||
1191 | count = dmabuf->dmasize - count; | ||
1192 | } else { | ||
1193 | port = dmabuf->write_channel->port; | ||
1194 | trigger = PCM_ENABLE_OUTPUT; | ||
1195 | start = __start_dac; | ||
1196 | } | ||
1197 | |||
1198 | /* Do not process partial fragments. */ | ||
1199 | fragsize = dmabuf->fragsize; | ||
1200 | if (count < fragsize) | ||
1201 | return; | ||
1202 | |||
1203 | /* if we are currently stopped, then our CIV is actually set to our | ||
1204 | * *last* sg segment and we are ready to wrap to the next. However, | ||
1205 | * if we set our LVI to the last sg segment, then it won't wrap to | ||
1206 | * the next sg segment, it won't even get a start. So, instead, when | ||
1207 | * we are stopped, we set both the LVI value and also we increment | ||
1208 | * the CIV value to the next sg segment to be played so that when | ||
1209 | * we call start, things will operate properly. Since the CIV can't | ||
1210 | * be written to directly for this purpose, we set the LVI to CIV + 1 | ||
1211 | * temporarily. Once the engine has started we set the LVI to its | ||
1212 | * final value. | ||
1213 | */ | ||
1214 | if (!dmabuf->enable && dmabuf->ready) { | ||
1215 | if (!(dmabuf->trigger & trigger)) | ||
1216 | return; | ||
1217 | |||
1218 | CIV_TO_LVI(state->card, port, 1); | ||
1219 | |||
1220 | start(state); | ||
1221 | while (!(I810_IOREADB(state->card, port + OFF_CR) & ((1<<4) | (1<<2)))) | ||
1222 | ; | ||
1223 | } | ||
1224 | |||
1225 | /* MASKP2(swptr, fragsize) - 1 is the tail of our transfer */ | ||
1226 | x = MODULOP2(MASKP2(dmabuf->swptr, fragsize) - 1, dmabuf->dmasize); | ||
1227 | x >>= dmabuf->fragshift; | ||
1228 | I810_IOWRITEB(x, state->card, port + OFF_LVI); | ||
1229 | } | ||
1230 | |||
1231 | static void i810_update_lvi(struct i810_state *state, int rec) | ||
1232 | { | ||
1233 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1234 | unsigned long flags; | ||
1235 | |||
1236 | if(!dmabuf->ready) | ||
1237 | return; | ||
1238 | spin_lock_irqsave(&state->card->lock, flags); | ||
1239 | __i810_update_lvi(state, rec); | ||
1240 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1241 | } | ||
1242 | |||
1243 | /* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */ | ||
1244 | static void i810_update_ptr(struct i810_state *state) | ||
1245 | { | ||
1246 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1247 | unsigned hwptr; | ||
1248 | unsigned fragmask, dmamask; | ||
1249 | int diff; | ||
1250 | |||
1251 | fragmask = MASKP2(~0, dmabuf->fragsize); | ||
1252 | dmamask = MODULOP2(~0, dmabuf->dmasize); | ||
1253 | |||
1254 | /* error handling and process wake up for ADC */ | ||
1255 | if (dmabuf->enable == ADC_RUNNING) { | ||
1256 | /* update hardware pointer */ | ||
1257 | hwptr = i810_get_dma_addr(state, 1) & fragmask; | ||
1258 | diff = (hwptr - dmabuf->hwptr) & dmamask; | ||
1259 | #if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP) | ||
1260 | printk("ADC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff); | ||
1261 | #endif | ||
1262 | dmabuf->hwptr = hwptr; | ||
1263 | dmabuf->total_bytes += diff; | ||
1264 | dmabuf->count += diff; | ||
1265 | if (dmabuf->count > dmabuf->dmasize) { | ||
1266 | /* buffer underrun or buffer overrun */ | ||
1267 | /* this is normal for the end of a read */ | ||
1268 | /* only give an error if we went past the */ | ||
1269 | /* last valid sg entry */ | ||
1270 | if (GET_CIV(state->card, PI_BASE) != | ||
1271 | GET_LVI(state->card, PI_BASE)) { | ||
1272 | printk(KERN_WARNING "i810_audio: DMA overrun on read\n"); | ||
1273 | dmabuf->error++; | ||
1274 | } | ||
1275 | } | ||
1276 | if (diff) | ||
1277 | wake_up(&dmabuf->wait); | ||
1278 | } | ||
1279 | /* error handling and process wake up for DAC */ | ||
1280 | if (dmabuf->enable == DAC_RUNNING) { | ||
1281 | /* update hardware pointer */ | ||
1282 | hwptr = i810_get_dma_addr(state, 0) & fragmask; | ||
1283 | diff = (hwptr - dmabuf->hwptr) & dmamask; | ||
1284 | #if defined(DEBUG_INTERRUPTS) || defined(DEBUG_MMAP) | ||
1285 | printk("DAC HWP %d,%d,%d\n", hwptr, dmabuf->hwptr, diff); | ||
1286 | #endif | ||
1287 | dmabuf->hwptr = hwptr; | ||
1288 | dmabuf->total_bytes += diff; | ||
1289 | dmabuf->count -= diff; | ||
1290 | if (dmabuf->count < 0) { | ||
1291 | /* buffer underrun or buffer overrun */ | ||
1292 | /* this is normal for the end of a write */ | ||
1293 | /* only give an error if we went past the */ | ||
1294 | /* last valid sg entry */ | ||
1295 | if (GET_CIV(state->card, PO_BASE) != | ||
1296 | GET_LVI(state->card, PO_BASE)) { | ||
1297 | printk(KERN_WARNING "i810_audio: DMA overrun on write\n"); | ||
1298 | printk("i810_audio: CIV %d, LVI %d, hwptr %x, " | ||
1299 | "count %d\n", | ||
1300 | GET_CIV(state->card, PO_BASE), | ||
1301 | GET_LVI(state->card, PO_BASE), | ||
1302 | dmabuf->hwptr, dmabuf->count); | ||
1303 | dmabuf->error++; | ||
1304 | } | ||
1305 | } | ||
1306 | if (diff) | ||
1307 | wake_up(&dmabuf->wait); | ||
1308 | } | ||
1309 | } | ||
1310 | |||
1311 | static inline int i810_get_free_write_space(struct i810_state *state) | ||
1312 | { | ||
1313 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1314 | int free; | ||
1315 | |||
1316 | i810_update_ptr(state); | ||
1317 | // catch underruns during playback | ||
1318 | if (dmabuf->count < 0) { | ||
1319 | dmabuf->count = 0; | ||
1320 | dmabuf->swptr = dmabuf->hwptr; | ||
1321 | } | ||
1322 | free = dmabuf->dmasize - dmabuf->count; | ||
1323 | if(free < 0) | ||
1324 | return(0); | ||
1325 | return(free); | ||
1326 | } | ||
1327 | |||
1328 | static inline int i810_get_available_read_data(struct i810_state *state) | ||
1329 | { | ||
1330 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1331 | int avail; | ||
1332 | |||
1333 | i810_update_ptr(state); | ||
1334 | // catch overruns during record | ||
1335 | if (dmabuf->count > dmabuf->dmasize) { | ||
1336 | dmabuf->count = dmabuf->dmasize; | ||
1337 | dmabuf->swptr = dmabuf->hwptr; | ||
1338 | } | ||
1339 | avail = dmabuf->count; | ||
1340 | if(avail < 0) | ||
1341 | return(0); | ||
1342 | return(avail); | ||
1343 | } | ||
1344 | |||
1345 | static inline void fill_partial_frag(struct dmabuf *dmabuf) | ||
1346 | { | ||
1347 | unsigned fragsize; | ||
1348 | unsigned swptr, len; | ||
1349 | |||
1350 | fragsize = dmabuf->fragsize; | ||
1351 | swptr = dmabuf->swptr; | ||
1352 | len = fragsize - MODULOP2(dmabuf->swptr, fragsize); | ||
1353 | if (len == fragsize) | ||
1354 | return; | ||
1355 | |||
1356 | memset(dmabuf->rawbuf + swptr, '\0', len); | ||
1357 | dmabuf->swptr = MODULOP2(swptr + len, dmabuf->dmasize); | ||
1358 | dmabuf->count += len; | ||
1359 | } | ||
1360 | |||
1361 | static int drain_dac(struct i810_state *state, int signals_allowed) | ||
1362 | { | ||
1363 | DECLARE_WAITQUEUE(wait, current); | ||
1364 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1365 | unsigned long flags; | ||
1366 | unsigned long tmo; | ||
1367 | int count; | ||
1368 | |||
1369 | if (!dmabuf->ready) | ||
1370 | return 0; | ||
1371 | if(dmabuf->mapped) { | ||
1372 | stop_dac(state); | ||
1373 | return 0; | ||
1374 | } | ||
1375 | |||
1376 | spin_lock_irqsave(&state->card->lock, flags); | ||
1377 | |||
1378 | fill_partial_frag(dmabuf); | ||
1379 | |||
1380 | /* | ||
1381 | * This will make sure that our LVI is correct, that our | ||
1382 | * pointer is updated, and that the DAC is running. We | ||
1383 | * have to force the setting of dmabuf->trigger to avoid | ||
1384 | * any possible deadlocks. | ||
1385 | */ | ||
1386 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
1387 | __i810_update_lvi(state, 0); | ||
1388 | |||
1389 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1390 | |||
1391 | add_wait_queue(&dmabuf->wait, &wait); | ||
1392 | for (;;) { | ||
1393 | |||
1394 | spin_lock_irqsave(&state->card->lock, flags); | ||
1395 | i810_update_ptr(state); | ||
1396 | count = dmabuf->count; | ||
1397 | |||
1398 | /* It seems that we have to set the current state to | ||
1399 | * TASK_INTERRUPTIBLE every time to make the process | ||
1400 | * really go to sleep. This also has to be *after* the | ||
1401 | * update_ptr() call because update_ptr is likely to | ||
1402 | * do a wake_up() which will unset this before we ever | ||
1403 | * try to sleep, resuling in a tight loop in this code | ||
1404 | * instead of actually sleeping and waiting for an | ||
1405 | * interrupt to wake us up! | ||
1406 | */ | ||
1407 | __set_current_state(signals_allowed ? | ||
1408 | TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
1409 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1410 | |||
1411 | if (count <= 0) | ||
1412 | break; | ||
1413 | |||
1414 | if (signal_pending(current) && signals_allowed) { | ||
1415 | break; | ||
1416 | } | ||
1417 | |||
1418 | /* | ||
1419 | * set the timeout to significantly longer than it *should* | ||
1420 | * take for the DAC to drain the DMA buffer | ||
1421 | */ | ||
1422 | tmo = (count * HZ) / (dmabuf->rate); | ||
1423 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)){ | ||
1424 | printk(KERN_ERR "i810_audio: drain_dac, dma timeout?\n"); | ||
1425 | count = 0; | ||
1426 | break; | ||
1427 | } | ||
1428 | } | ||
1429 | set_current_state(TASK_RUNNING); | ||
1430 | remove_wait_queue(&dmabuf->wait, &wait); | ||
1431 | if(count > 0 && signal_pending(current) && signals_allowed) | ||
1432 | return -ERESTARTSYS; | ||
1433 | stop_dac(state); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | static void i810_channel_interrupt(struct i810_card *card) | ||
1438 | { | ||
1439 | int i, count; | ||
1440 | |||
1441 | #ifdef DEBUG_INTERRUPTS | ||
1442 | printk("CHANNEL "); | ||
1443 | #endif | ||
1444 | for(i=0;i<NR_HW_CH;i++) | ||
1445 | { | ||
1446 | struct i810_state *state = card->states[i]; | ||
1447 | struct i810_channel *c; | ||
1448 | struct dmabuf *dmabuf; | ||
1449 | unsigned long port; | ||
1450 | u16 status; | ||
1451 | |||
1452 | if(!state) | ||
1453 | continue; | ||
1454 | if(!state->dmabuf.ready) | ||
1455 | continue; | ||
1456 | dmabuf = &state->dmabuf; | ||
1457 | if(dmabuf->enable & DAC_RUNNING) { | ||
1458 | c=dmabuf->write_channel; | ||
1459 | } else if(dmabuf->enable & ADC_RUNNING) { | ||
1460 | c=dmabuf->read_channel; | ||
1461 | } else /* This can occur going from R/W to close */ | ||
1462 | continue; | ||
1463 | |||
1464 | port = c->port; | ||
1465 | |||
1466 | if(card->pci_id == PCI_DEVICE_ID_SI_7012) | ||
1467 | status = I810_IOREADW(card, port + OFF_PICB); | ||
1468 | else | ||
1469 | status = I810_IOREADW(card, port + OFF_SR); | ||
1470 | |||
1471 | #ifdef DEBUG_INTERRUPTS | ||
1472 | printk("NUM %d PORT %X IRQ ( ST%d ", c->num, c->port, status); | ||
1473 | #endif | ||
1474 | if(status & DMA_INT_COMPLETE) | ||
1475 | { | ||
1476 | /* only wake_up() waiters if this interrupt signals | ||
1477 | * us being beyond a userfragsize of data open or | ||
1478 | * available, and i810_update_ptr() does that for | ||
1479 | * us | ||
1480 | */ | ||
1481 | i810_update_ptr(state); | ||
1482 | #ifdef DEBUG_INTERRUPTS | ||
1483 | printk("COMP %d ", dmabuf->hwptr / | ||
1484 | dmabuf->fragsize); | ||
1485 | #endif | ||
1486 | } | ||
1487 | if(status & (DMA_INT_LVI | DMA_INT_DCH)) | ||
1488 | { | ||
1489 | /* wake_up() unconditionally on LVI and DCH */ | ||
1490 | i810_update_ptr(state); | ||
1491 | wake_up(&dmabuf->wait); | ||
1492 | #ifdef DEBUG_INTERRUPTS | ||
1493 | if(status & DMA_INT_LVI) | ||
1494 | printk("LVI "); | ||
1495 | if(status & DMA_INT_DCH) | ||
1496 | printk("DCH -"); | ||
1497 | #endif | ||
1498 | count = dmabuf->count; | ||
1499 | if(dmabuf->enable & ADC_RUNNING) | ||
1500 | count = dmabuf->dmasize - count; | ||
1501 | if (count >= (int)dmabuf->fragsize) { | ||
1502 | I810_IOWRITEB(I810_IOREADB(card, port+OFF_CR) | 1, card, port+OFF_CR); | ||
1503 | #ifdef DEBUG_INTERRUPTS | ||
1504 | printk(" CONTINUE "); | ||
1505 | #endif | ||
1506 | } else { | ||
1507 | if (dmabuf->enable & DAC_RUNNING) | ||
1508 | __stop_dac(state); | ||
1509 | if (dmabuf->enable & ADC_RUNNING) | ||
1510 | __stop_adc(state); | ||
1511 | dmabuf->enable = 0; | ||
1512 | #ifdef DEBUG_INTERRUPTS | ||
1513 | printk(" STOP "); | ||
1514 | #endif | ||
1515 | } | ||
1516 | } | ||
1517 | if(card->pci_id == PCI_DEVICE_ID_SI_7012) | ||
1518 | I810_IOWRITEW(status & DMA_INT_MASK, card, port + OFF_PICB); | ||
1519 | else | ||
1520 | I810_IOWRITEW(status & DMA_INT_MASK, card, port + OFF_SR); | ||
1521 | } | ||
1522 | #ifdef DEBUG_INTERRUPTS | ||
1523 | printk(")\n"); | ||
1524 | #endif | ||
1525 | } | ||
1526 | |||
1527 | static irqreturn_t i810_interrupt(int irq, void *dev_id) | ||
1528 | { | ||
1529 | struct i810_card *card = dev_id; | ||
1530 | u32 status; | ||
1531 | |||
1532 | spin_lock(&card->lock); | ||
1533 | |||
1534 | status = I810_IOREADL(card, GLOB_STA); | ||
1535 | |||
1536 | if(!(status & INT_MASK)) | ||
1537 | { | ||
1538 | spin_unlock(&card->lock); | ||
1539 | return IRQ_NONE; /* not for us */ | ||
1540 | } | ||
1541 | |||
1542 | if(status & (INT_PO|INT_PI|INT_MC)) | ||
1543 | i810_channel_interrupt(card); | ||
1544 | |||
1545 | /* clear 'em */ | ||
1546 | I810_IOWRITEL(status & INT_MASK, card, GLOB_STA); | ||
1547 | spin_unlock(&card->lock); | ||
1548 | return IRQ_HANDLED; | ||
1549 | } | ||
1550 | |||
1551 | /* in this loop, dmabuf.count signifies the amount of data that is | ||
1552 | waiting to be copied to the user's buffer. It is filled by the dma | ||
1553 | machine and drained by this loop. */ | ||
1554 | |||
1555 | static ssize_t i810_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
1556 | { | ||
1557 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
1558 | struct i810_card *card=state ? state->card : NULL; | ||
1559 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1560 | ssize_t ret; | ||
1561 | unsigned long flags; | ||
1562 | unsigned int swptr; | ||
1563 | int cnt; | ||
1564 | int pending; | ||
1565 | DECLARE_WAITQUEUE(waita, current); | ||
1566 | |||
1567 | #ifdef DEBUG2 | ||
1568 | printk("i810_audio: i810_read called, count = %d\n", count); | ||
1569 | #endif | ||
1570 | |||
1571 | if (dmabuf->mapped) | ||
1572 | return -ENXIO; | ||
1573 | if (dmabuf->enable & DAC_RUNNING) | ||
1574 | return -ENODEV; | ||
1575 | if (!dmabuf->read_channel) { | ||
1576 | dmabuf->ready = 0; | ||
1577 | dmabuf->read_channel = card->alloc_rec_pcm_channel(card); | ||
1578 | if (!dmabuf->read_channel) { | ||
1579 | return -EBUSY; | ||
1580 | } | ||
1581 | } | ||
1582 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 1))) | ||
1583 | return ret; | ||
1584 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1585 | return -EFAULT; | ||
1586 | ret = 0; | ||
1587 | |||
1588 | pending = 0; | ||
1589 | |||
1590 | add_wait_queue(&dmabuf->wait, &waita); | ||
1591 | while (count > 0) { | ||
1592 | set_current_state(TASK_INTERRUPTIBLE); | ||
1593 | spin_lock_irqsave(&card->lock, flags); | ||
1594 | if (PM_SUSPENDED(card)) { | ||
1595 | spin_unlock_irqrestore(&card->lock, flags); | ||
1596 | schedule(); | ||
1597 | if (signal_pending(current)) { | ||
1598 | if (!ret) ret = -EAGAIN; | ||
1599 | break; | ||
1600 | } | ||
1601 | continue; | ||
1602 | } | ||
1603 | cnt = i810_get_available_read_data(state); | ||
1604 | swptr = dmabuf->swptr; | ||
1605 | // this is to make the copy_to_user simpler below | ||
1606 | if(cnt > (dmabuf->dmasize - swptr)) | ||
1607 | cnt = dmabuf->dmasize - swptr; | ||
1608 | spin_unlock_irqrestore(&card->lock, flags); | ||
1609 | |||
1610 | if (cnt > count) | ||
1611 | cnt = count; | ||
1612 | if (cnt <= 0) { | ||
1613 | unsigned long tmo; | ||
1614 | /* | ||
1615 | * Don't let us deadlock. The ADC won't start if | ||
1616 | * dmabuf->trigger isn't set. A call to SETTRIGGER | ||
1617 | * could have turned it off after we set it to on | ||
1618 | * previously. | ||
1619 | */ | ||
1620 | dmabuf->trigger = PCM_ENABLE_INPUT; | ||
1621 | /* | ||
1622 | * This does three things. Updates LVI to be correct, | ||
1623 | * makes sure the ADC is running, and updates the | ||
1624 | * hwptr. | ||
1625 | */ | ||
1626 | i810_update_lvi(state,1); | ||
1627 | if (file->f_flags & O_NONBLOCK) { | ||
1628 | if (!ret) ret = -EAGAIN; | ||
1629 | goto done; | ||
1630 | } | ||
1631 | /* Set the timeout to how long it would take to fill | ||
1632 | * two of our buffers. If we haven't been woke up | ||
1633 | * by then, then we know something is wrong. | ||
1634 | */ | ||
1635 | tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4); | ||
1636 | /* There are two situations when sleep_on_timeout returns, one is when | ||
1637 | the interrupt is serviced correctly and the process is waked up by | ||
1638 | ISR ON TIME. Another is when timeout is expired, which means that | ||
1639 | either interrupt is NOT serviced correctly (pending interrupt) or it | ||
1640 | is TOO LATE for the process to be scheduled to run (scheduler latency) | ||
1641 | which results in a (potential) buffer overrun. And worse, there is | ||
1642 | NOTHING we can do to prevent it. */ | ||
1643 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)) { | ||
1644 | #ifdef DEBUG | ||
1645 | printk(KERN_ERR "i810_audio: recording schedule timeout, " | ||
1646 | "dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1647 | dmabuf->dmasize, dmabuf->fragsize, dmabuf->count, | ||
1648 | dmabuf->hwptr, dmabuf->swptr); | ||
1649 | #endif | ||
1650 | /* a buffer overrun, we delay the recovery until next time the | ||
1651 | while loop begin and we REALLY have space to record */ | ||
1652 | } | ||
1653 | if (signal_pending(current)) { | ||
1654 | ret = ret ? ret : -ERESTARTSYS; | ||
1655 | goto done; | ||
1656 | } | ||
1657 | continue; | ||
1658 | } | ||
1659 | |||
1660 | if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) { | ||
1661 | if (!ret) ret = -EFAULT; | ||
1662 | goto done; | ||
1663 | } | ||
1664 | |||
1665 | swptr = MODULOP2(swptr + cnt, dmabuf->dmasize); | ||
1666 | |||
1667 | spin_lock_irqsave(&card->lock, flags); | ||
1668 | |||
1669 | if (PM_SUSPENDED(card)) { | ||
1670 | spin_unlock_irqrestore(&card->lock, flags); | ||
1671 | continue; | ||
1672 | } | ||
1673 | dmabuf->swptr = swptr; | ||
1674 | pending = dmabuf->count -= cnt; | ||
1675 | spin_unlock_irqrestore(&card->lock, flags); | ||
1676 | |||
1677 | count -= cnt; | ||
1678 | buffer += cnt; | ||
1679 | ret += cnt; | ||
1680 | } | ||
1681 | done: | ||
1682 | pending = dmabuf->dmasize - pending; | ||
1683 | if (dmabuf->enable || pending >= dmabuf->userfragsize) | ||
1684 | i810_update_lvi(state, 1); | ||
1685 | set_current_state(TASK_RUNNING); | ||
1686 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1687 | |||
1688 | return ret; | ||
1689 | } | ||
1690 | |||
1691 | /* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to | ||
1692 | the soundcard. it is drained by the dma machine and filled by this loop. */ | ||
1693 | static ssize_t i810_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
1694 | { | ||
1695 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
1696 | struct i810_card *card=state ? state->card : NULL; | ||
1697 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1698 | ssize_t ret; | ||
1699 | unsigned long flags; | ||
1700 | unsigned int swptr = 0; | ||
1701 | int pending; | ||
1702 | int cnt; | ||
1703 | DECLARE_WAITQUEUE(waita, current); | ||
1704 | |||
1705 | #ifdef DEBUG2 | ||
1706 | printk("i810_audio: i810_write called, count = %d\n", count); | ||
1707 | #endif | ||
1708 | |||
1709 | if (dmabuf->mapped) | ||
1710 | return -ENXIO; | ||
1711 | if (dmabuf->enable & ADC_RUNNING) | ||
1712 | return -ENODEV; | ||
1713 | if (!dmabuf->write_channel) { | ||
1714 | dmabuf->ready = 0; | ||
1715 | dmabuf->write_channel = card->alloc_pcm_channel(card); | ||
1716 | if(!dmabuf->write_channel) | ||
1717 | return -EBUSY; | ||
1718 | } | ||
1719 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 0))) | ||
1720 | return ret; | ||
1721 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1722 | return -EFAULT; | ||
1723 | ret = 0; | ||
1724 | |||
1725 | pending = 0; | ||
1726 | |||
1727 | add_wait_queue(&dmabuf->wait, &waita); | ||
1728 | while (count > 0) { | ||
1729 | set_current_state(TASK_INTERRUPTIBLE); | ||
1730 | spin_lock_irqsave(&state->card->lock, flags); | ||
1731 | if (PM_SUSPENDED(card)) { | ||
1732 | spin_unlock_irqrestore(&card->lock, flags); | ||
1733 | schedule(); | ||
1734 | if (signal_pending(current)) { | ||
1735 | if (!ret) ret = -EAGAIN; | ||
1736 | break; | ||
1737 | } | ||
1738 | continue; | ||
1739 | } | ||
1740 | |||
1741 | cnt = i810_get_free_write_space(state); | ||
1742 | swptr = dmabuf->swptr; | ||
1743 | /* Bound the maximum size to how much we can copy to the | ||
1744 | * dma buffer before we hit the end. If we have more to | ||
1745 | * copy then it will get done in a second pass of this | ||
1746 | * loop starting from the beginning of the buffer. | ||
1747 | */ | ||
1748 | if(cnt > (dmabuf->dmasize - swptr)) | ||
1749 | cnt = dmabuf->dmasize - swptr; | ||
1750 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1751 | |||
1752 | #ifdef DEBUG2 | ||
1753 | printk(KERN_INFO "i810_audio: i810_write: %d bytes available space\n", cnt); | ||
1754 | #endif | ||
1755 | if (cnt > count) | ||
1756 | cnt = count; | ||
1757 | if (cnt <= 0) { | ||
1758 | unsigned long tmo; | ||
1759 | // There is data waiting to be played | ||
1760 | /* | ||
1761 | * Force the trigger setting since we would | ||
1762 | * deadlock with it set any other way | ||
1763 | */ | ||
1764 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
1765 | i810_update_lvi(state,0); | ||
1766 | if (file->f_flags & O_NONBLOCK) { | ||
1767 | if (!ret) ret = -EAGAIN; | ||
1768 | goto ret; | ||
1769 | } | ||
1770 | /* Not strictly correct but works */ | ||
1771 | tmo = (dmabuf->dmasize * HZ * 2) / (dmabuf->rate * 4); | ||
1772 | /* There are two situations when sleep_on_timeout returns, one is when | ||
1773 | the interrupt is serviced correctly and the process is waked up by | ||
1774 | ISR ON TIME. Another is when timeout is expired, which means that | ||
1775 | either interrupt is NOT serviced correctly (pending interrupt) or it | ||
1776 | is TOO LATE for the process to be scheduled to run (scheduler latency) | ||
1777 | which results in a (potential) buffer underrun. And worse, there is | ||
1778 | NOTHING we can do to prevent it. */ | ||
1779 | if (!schedule_timeout(tmo >= 2 ? tmo : 2)) { | ||
1780 | #ifdef DEBUG | ||
1781 | printk(KERN_ERR "i810_audio: playback schedule timeout, " | ||
1782 | "dmasz %u fragsz %u count %i hwptr %u swptr %u\n", | ||
1783 | dmabuf->dmasize, dmabuf->fragsize, dmabuf->count, | ||
1784 | dmabuf->hwptr, dmabuf->swptr); | ||
1785 | #endif | ||
1786 | /* a buffer underrun, we delay the recovery until next time the | ||
1787 | while loop begin and we REALLY have data to play */ | ||
1788 | //return ret; | ||
1789 | } | ||
1790 | if (signal_pending(current)) { | ||
1791 | if (!ret) ret = -ERESTARTSYS; | ||
1792 | goto ret; | ||
1793 | } | ||
1794 | continue; | ||
1795 | } | ||
1796 | if (copy_from_user(dmabuf->rawbuf+swptr,buffer,cnt)) { | ||
1797 | if (!ret) ret = -EFAULT; | ||
1798 | goto ret; | ||
1799 | } | ||
1800 | |||
1801 | swptr = MODULOP2(swptr + cnt, dmabuf->dmasize); | ||
1802 | |||
1803 | spin_lock_irqsave(&state->card->lock, flags); | ||
1804 | if (PM_SUSPENDED(card)) { | ||
1805 | spin_unlock_irqrestore(&card->lock, flags); | ||
1806 | continue; | ||
1807 | } | ||
1808 | |||
1809 | dmabuf->swptr = swptr; | ||
1810 | pending = dmabuf->count += cnt; | ||
1811 | |||
1812 | count -= cnt; | ||
1813 | buffer += cnt; | ||
1814 | ret += cnt; | ||
1815 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1816 | } | ||
1817 | ret: | ||
1818 | if (dmabuf->enable || pending >= dmabuf->userfragsize) | ||
1819 | i810_update_lvi(state, 0); | ||
1820 | set_current_state(TASK_RUNNING); | ||
1821 | remove_wait_queue(&dmabuf->wait, &waita); | ||
1822 | |||
1823 | return ret; | ||
1824 | } | ||
1825 | |||
1826 | /* No kernel lock - we have our own spinlock */ | ||
1827 | static unsigned int i810_poll(struct file *file, struct poll_table_struct *wait) | ||
1828 | { | ||
1829 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
1830 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1831 | unsigned long flags; | ||
1832 | unsigned int mask = 0; | ||
1833 | |||
1834 | if(!dmabuf->ready) | ||
1835 | return 0; | ||
1836 | poll_wait(file, &dmabuf->wait, wait); | ||
1837 | spin_lock_irqsave(&state->card->lock, flags); | ||
1838 | if (dmabuf->enable & ADC_RUNNING || | ||
1839 | dmabuf->trigger & PCM_ENABLE_INPUT) { | ||
1840 | if (i810_get_available_read_data(state) >= | ||
1841 | (signed)dmabuf->userfragsize) | ||
1842 | mask |= POLLIN | POLLRDNORM; | ||
1843 | } | ||
1844 | if (dmabuf->enable & DAC_RUNNING || | ||
1845 | dmabuf->trigger & PCM_ENABLE_OUTPUT) { | ||
1846 | if (i810_get_free_write_space(state) >= | ||
1847 | (signed)dmabuf->userfragsize) | ||
1848 | mask |= POLLOUT | POLLWRNORM; | ||
1849 | } | ||
1850 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1851 | return mask; | ||
1852 | } | ||
1853 | |||
1854 | static int i810_mmap(struct file *file, struct vm_area_struct *vma) | ||
1855 | { | ||
1856 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
1857 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1858 | int ret = -EINVAL; | ||
1859 | unsigned long size; | ||
1860 | |||
1861 | lock_kernel(); | ||
1862 | if (vma->vm_flags & VM_WRITE) { | ||
1863 | if (!dmabuf->write_channel && | ||
1864 | (dmabuf->write_channel = | ||
1865 | state->card->alloc_pcm_channel(state->card)) == NULL) { | ||
1866 | ret = -EBUSY; | ||
1867 | goto out; | ||
1868 | } | ||
1869 | } | ||
1870 | if (vma->vm_flags & VM_READ) { | ||
1871 | if (!dmabuf->read_channel && | ||
1872 | (dmabuf->read_channel = | ||
1873 | state->card->alloc_rec_pcm_channel(state->card)) == NULL) { | ||
1874 | ret = -EBUSY; | ||
1875 | goto out; | ||
1876 | } | ||
1877 | } | ||
1878 | if ((ret = prog_dmabuf(state, 0)) != 0) | ||
1879 | goto out; | ||
1880 | |||
1881 | ret = -EINVAL; | ||
1882 | if (vma->vm_pgoff != 0) | ||
1883 | goto out; | ||
1884 | size = vma->vm_end - vma->vm_start; | ||
1885 | if (size > (PAGE_SIZE << dmabuf->buforder)) | ||
1886 | goto out; | ||
1887 | ret = -EAGAIN; | ||
1888 | if (remap_pfn_range(vma, vma->vm_start, | ||
1889 | virt_to_phys(dmabuf->rawbuf) >> PAGE_SHIFT, | ||
1890 | size, vma->vm_page_prot)) | ||
1891 | goto out; | ||
1892 | dmabuf->mapped = 1; | ||
1893 | dmabuf->trigger = 0; | ||
1894 | ret = 0; | ||
1895 | #ifdef DEBUG_MMAP | ||
1896 | printk("i810_audio: mmap'ed %ld bytes of data space\n", size); | ||
1897 | #endif | ||
1898 | out: | ||
1899 | unlock_kernel(); | ||
1900 | return ret; | ||
1901 | } | ||
1902 | |||
1903 | static int i810_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) | ||
1904 | { | ||
1905 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
1906 | struct i810_channel *c = NULL; | ||
1907 | struct dmabuf *dmabuf = &state->dmabuf; | ||
1908 | unsigned long flags; | ||
1909 | audio_buf_info abinfo; | ||
1910 | count_info cinfo; | ||
1911 | unsigned int i_glob_cnt; | ||
1912 | int val = 0, ret; | ||
1913 | struct ac97_codec *codec = state->card->ac97_codec[0]; | ||
1914 | void __user *argp = (void __user *)arg; | ||
1915 | int __user *p = argp; | ||
1916 | |||
1917 | #ifdef DEBUG | ||
1918 | printk("i810_audio: i810_ioctl, arg=0x%x, cmd=", arg ? *p : 0); | ||
1919 | #endif | ||
1920 | |||
1921 | switch (cmd) | ||
1922 | { | ||
1923 | case OSS_GETVERSION: | ||
1924 | #ifdef DEBUG | ||
1925 | printk("OSS_GETVERSION\n"); | ||
1926 | #endif | ||
1927 | return put_user(SOUND_VERSION, p); | ||
1928 | |||
1929 | case SNDCTL_DSP_RESET: | ||
1930 | #ifdef DEBUG | ||
1931 | printk("SNDCTL_DSP_RESET\n"); | ||
1932 | #endif | ||
1933 | spin_lock_irqsave(&state->card->lock, flags); | ||
1934 | if (dmabuf->enable == DAC_RUNNING) { | ||
1935 | c = dmabuf->write_channel; | ||
1936 | __stop_dac(state); | ||
1937 | } | ||
1938 | if (dmabuf->enable == ADC_RUNNING) { | ||
1939 | c = dmabuf->read_channel; | ||
1940 | __stop_adc(state); | ||
1941 | } | ||
1942 | if (c != NULL) { | ||
1943 | I810_IOWRITEB(2, state->card, c->port+OFF_CR); /* reset DMA machine */ | ||
1944 | while ( I810_IOREADB(state->card, c->port+OFF_CR) & 2 ) | ||
1945 | cpu_relax(); | ||
1946 | I810_IOWRITEL((u32)state->card->chandma + | ||
1947 | c->num*sizeof(struct i810_channel), | ||
1948 | state->card, c->port+OFF_BDBAR); | ||
1949 | CIV_TO_LVI(state->card, c->port, 0); | ||
1950 | } | ||
1951 | |||
1952 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1953 | synchronize_irq(state->card->pci_dev->irq); | ||
1954 | dmabuf->ready = 0; | ||
1955 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
1956 | dmabuf->count = dmabuf->total_bytes = 0; | ||
1957 | return 0; | ||
1958 | |||
1959 | case SNDCTL_DSP_SYNC: | ||
1960 | #ifdef DEBUG | ||
1961 | printk("SNDCTL_DSP_SYNC\n"); | ||
1962 | #endif | ||
1963 | if (dmabuf->enable != DAC_RUNNING || file->f_flags & O_NONBLOCK) | ||
1964 | return 0; | ||
1965 | if((val = drain_dac(state, 1))) | ||
1966 | return val; | ||
1967 | dmabuf->total_bytes = 0; | ||
1968 | return 0; | ||
1969 | |||
1970 | case SNDCTL_DSP_SPEED: /* set smaple rate */ | ||
1971 | #ifdef DEBUG | ||
1972 | printk("SNDCTL_DSP_SPEED\n"); | ||
1973 | #endif | ||
1974 | if (get_user(val, p)) | ||
1975 | return -EFAULT; | ||
1976 | if (val >= 0) { | ||
1977 | if (file->f_mode & FMODE_WRITE) { | ||
1978 | if ( (state->card->ac97_status & SPDIF_ON) ) { /* S/PDIF Enabled */ | ||
1979 | /* AD1886 only supports 48000, need to check that */ | ||
1980 | if ( i810_valid_spdif_rate ( codec, val ) ) { | ||
1981 | /* Set DAC rate */ | ||
1982 | i810_set_spdif_output ( state, -1, 0 ); | ||
1983 | stop_dac(state); | ||
1984 | dmabuf->ready = 0; | ||
1985 | spin_lock_irqsave(&state->card->lock, flags); | ||
1986 | i810_set_dac_rate(state, val); | ||
1987 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
1988 | /* Set S/PDIF transmitter rate. */ | ||
1989 | i810_set_spdif_output ( state, AC97_EA_SPSA_3_4, val ); | ||
1990 | if ( ! (state->card->ac97_status & SPDIF_ON) ) { | ||
1991 | val = dmabuf->rate; | ||
1992 | } | ||
1993 | } else { /* Not a valid rate for S/PDIF, ignore it */ | ||
1994 | val = dmabuf->rate; | ||
1995 | } | ||
1996 | } else { | ||
1997 | stop_dac(state); | ||
1998 | dmabuf->ready = 0; | ||
1999 | spin_lock_irqsave(&state->card->lock, flags); | ||
2000 | i810_set_dac_rate(state, val); | ||
2001 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2002 | } | ||
2003 | } | ||
2004 | if (file->f_mode & FMODE_READ) { | ||
2005 | stop_adc(state); | ||
2006 | dmabuf->ready = 0; | ||
2007 | spin_lock_irqsave(&state->card->lock, flags); | ||
2008 | i810_set_adc_rate(state, val); | ||
2009 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2010 | } | ||
2011 | } | ||
2012 | return put_user(dmabuf->rate, p); | ||
2013 | |||
2014 | case SNDCTL_DSP_STEREO: /* set stereo or mono channel */ | ||
2015 | #ifdef DEBUG | ||
2016 | printk("SNDCTL_DSP_STEREO\n"); | ||
2017 | #endif | ||
2018 | if (dmabuf->enable & DAC_RUNNING) { | ||
2019 | stop_dac(state); | ||
2020 | } | ||
2021 | if (dmabuf->enable & ADC_RUNNING) { | ||
2022 | stop_adc(state); | ||
2023 | } | ||
2024 | return put_user(1, p); | ||
2025 | |||
2026 | case SNDCTL_DSP_GETBLKSIZE: | ||
2027 | if (file->f_mode & FMODE_WRITE) { | ||
2028 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0))) | ||
2029 | return val; | ||
2030 | } | ||
2031 | if (file->f_mode & FMODE_READ) { | ||
2032 | if (!dmabuf->ready && (val = prog_dmabuf(state, 1))) | ||
2033 | return val; | ||
2034 | } | ||
2035 | #ifdef DEBUG | ||
2036 | printk("SNDCTL_DSP_GETBLKSIZE %d\n", dmabuf->userfragsize); | ||
2037 | #endif | ||
2038 | return put_user(dmabuf->userfragsize, p); | ||
2039 | |||
2040 | case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/ | ||
2041 | #ifdef DEBUG | ||
2042 | printk("SNDCTL_DSP_GETFMTS\n"); | ||
2043 | #endif | ||
2044 | return put_user(AFMT_S16_LE, p); | ||
2045 | |||
2046 | case SNDCTL_DSP_SETFMT: /* Select sample format */ | ||
2047 | #ifdef DEBUG | ||
2048 | printk("SNDCTL_DSP_SETFMT\n"); | ||
2049 | #endif | ||
2050 | return put_user(AFMT_S16_LE, p); | ||
2051 | |||
2052 | case SNDCTL_DSP_CHANNELS: | ||
2053 | #ifdef DEBUG | ||
2054 | printk("SNDCTL_DSP_CHANNELS\n"); | ||
2055 | #endif | ||
2056 | if (get_user(val, p)) | ||
2057 | return -EFAULT; | ||
2058 | |||
2059 | if (val > 0) { | ||
2060 | if (dmabuf->enable & DAC_RUNNING) { | ||
2061 | stop_dac(state); | ||
2062 | } | ||
2063 | if (dmabuf->enable & ADC_RUNNING) { | ||
2064 | stop_adc(state); | ||
2065 | } | ||
2066 | } else { | ||
2067 | return put_user(state->card->channels, p); | ||
2068 | } | ||
2069 | |||
2070 | /* ICH and ICH0 only support 2 channels */ | ||
2071 | if ( state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AA_5 | ||
2072 | || state->card->pci_id == PCI_DEVICE_ID_INTEL_82801AB_5) | ||
2073 | return put_user(2, p); | ||
2074 | |||
2075 | /* Multi-channel support was added with ICH2. Bits in */ | ||
2076 | /* Global Status and Global Control register are now */ | ||
2077 | /* used to indicate this. */ | ||
2078 | |||
2079 | i_glob_cnt = I810_IOREADL(state->card, GLOB_CNT); | ||
2080 | |||
2081 | /* Current # of channels enabled */ | ||
2082 | if ( i_glob_cnt & 0x0100000 ) | ||
2083 | ret = 4; | ||
2084 | else if ( i_glob_cnt & 0x0200000 ) | ||
2085 | ret = 6; | ||
2086 | else | ||
2087 | ret = 2; | ||
2088 | |||
2089 | switch ( val ) { | ||
2090 | case 2: /* 2 channels is always supported */ | ||
2091 | I810_IOWRITEL(i_glob_cnt & 0xffcfffff, | ||
2092 | state->card, GLOB_CNT); | ||
2093 | /* Do we need to change mixer settings???? */ | ||
2094 | break; | ||
2095 | case 4: /* Supported on some chipsets, better check first */ | ||
2096 | if ( state->card->channels >= 4 ) { | ||
2097 | I810_IOWRITEL((i_glob_cnt & 0xffcfffff) | 0x100000, | ||
2098 | state->card, GLOB_CNT); | ||
2099 | /* Do we need to change mixer settings??? */ | ||
2100 | } else { | ||
2101 | val = ret; | ||
2102 | } | ||
2103 | break; | ||
2104 | case 6: /* Supported on some chipsets, better check first */ | ||
2105 | if ( state->card->channels >= 6 ) { | ||
2106 | I810_IOWRITEL((i_glob_cnt & 0xffcfffff) | 0x200000, | ||
2107 | state->card, GLOB_CNT); | ||
2108 | /* Do we need to change mixer settings??? */ | ||
2109 | } else { | ||
2110 | val = ret; | ||
2111 | } | ||
2112 | break; | ||
2113 | default: /* nothing else is ever supported by the chipset */ | ||
2114 | val = ret; | ||
2115 | break; | ||
2116 | } | ||
2117 | |||
2118 | return put_user(val, p); | ||
2119 | |||
2120 | case SNDCTL_DSP_POST: /* the user has sent all data and is notifying us */ | ||
2121 | /* we update the swptr to the end of the last sg segment then return */ | ||
2122 | #ifdef DEBUG | ||
2123 | printk("SNDCTL_DSP_POST\n"); | ||
2124 | #endif | ||
2125 | if(!dmabuf->ready || (dmabuf->enable != DAC_RUNNING)) | ||
2126 | return 0; | ||
2127 | if((dmabuf->swptr % dmabuf->fragsize) != 0) { | ||
2128 | val = dmabuf->fragsize - (dmabuf->swptr % dmabuf->fragsize); | ||
2129 | dmabuf->swptr += val; | ||
2130 | dmabuf->count += val; | ||
2131 | } | ||
2132 | return 0; | ||
2133 | |||
2134 | case SNDCTL_DSP_SUBDIVIDE: | ||
2135 | if (dmabuf->subdivision) | ||
2136 | return -EINVAL; | ||
2137 | if (get_user(val, p)) | ||
2138 | return -EFAULT; | ||
2139 | if (val != 1 && val != 2 && val != 4) | ||
2140 | return -EINVAL; | ||
2141 | #ifdef DEBUG | ||
2142 | printk("SNDCTL_DSP_SUBDIVIDE %d\n", val); | ||
2143 | #endif | ||
2144 | dmabuf->subdivision = val; | ||
2145 | dmabuf->ready = 0; | ||
2146 | return 0; | ||
2147 | |||
2148 | case SNDCTL_DSP_SETFRAGMENT: | ||
2149 | if (get_user(val, p)) | ||
2150 | return -EFAULT; | ||
2151 | |||
2152 | dmabuf->ossfragsize = 1<<(val & 0xffff); | ||
2153 | dmabuf->ossmaxfrags = (val >> 16) & 0xffff; | ||
2154 | if (!dmabuf->ossfragsize || !dmabuf->ossmaxfrags) | ||
2155 | return -EINVAL; | ||
2156 | /* | ||
2157 | * Bound the frag size into our allowed range of 256 - 4096 | ||
2158 | */ | ||
2159 | if (dmabuf->ossfragsize < 256) | ||
2160 | dmabuf->ossfragsize = 256; | ||
2161 | else if (dmabuf->ossfragsize > 4096) | ||
2162 | dmabuf->ossfragsize = 4096; | ||
2163 | /* | ||
2164 | * The numfrags could be something reasonable, or it could | ||
2165 | * be 0xffff meaning "Give me as much as possible". So, | ||
2166 | * we check the numfrags * fragsize doesn't exceed our | ||
2167 | * 64k buffer limit, nor is it less than our 8k minimum. | ||
2168 | * If it fails either one of these checks, then adjust the | ||
2169 | * number of fragments, not the size of them. It's OK if | ||
2170 | * our number of fragments doesn't equal 32 or anything | ||
2171 | * like our hardware based number now since we are using | ||
2172 | * a different frag count for the hardware. Before we get | ||
2173 | * into this though, bound the maxfrags to avoid overflow | ||
2174 | * issues. A reasonable bound would be 64k / 256 since our | ||
2175 | * maximum buffer size is 64k and our minimum frag size is | ||
2176 | * 256. On the other end, our minimum buffer size is 8k and | ||
2177 | * our maximum frag size is 4k, so the lower bound should | ||
2178 | * be 2. | ||
2179 | */ | ||
2180 | |||
2181 | if(dmabuf->ossmaxfrags > 256) | ||
2182 | dmabuf->ossmaxfrags = 256; | ||
2183 | else if (dmabuf->ossmaxfrags < 2) | ||
2184 | dmabuf->ossmaxfrags = 2; | ||
2185 | |||
2186 | val = dmabuf->ossfragsize * dmabuf->ossmaxfrags; | ||
2187 | while (val < 8192) { | ||
2188 | val <<= 1; | ||
2189 | dmabuf->ossmaxfrags <<= 1; | ||
2190 | } | ||
2191 | while (val > 65536) { | ||
2192 | val >>= 1; | ||
2193 | dmabuf->ossmaxfrags >>= 1; | ||
2194 | } | ||
2195 | dmabuf->ready = 0; | ||
2196 | #ifdef DEBUG | ||
2197 | printk("SNDCTL_DSP_SETFRAGMENT 0x%x, %d, %d\n", val, | ||
2198 | dmabuf->ossfragsize, dmabuf->ossmaxfrags); | ||
2199 | #endif | ||
2200 | |||
2201 | return 0; | ||
2202 | |||
2203 | case SNDCTL_DSP_GETOSPACE: | ||
2204 | if (!(file->f_mode & FMODE_WRITE)) | ||
2205 | return -EINVAL; | ||
2206 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2207 | return val; | ||
2208 | spin_lock_irqsave(&state->card->lock, flags); | ||
2209 | i810_update_ptr(state); | ||
2210 | abinfo.fragsize = dmabuf->userfragsize; | ||
2211 | abinfo.fragstotal = dmabuf->userfrags; | ||
2212 | if (dmabuf->mapped) | ||
2213 | abinfo.bytes = dmabuf->dmasize; | ||
2214 | else | ||
2215 | abinfo.bytes = i810_get_free_write_space(state); | ||
2216 | abinfo.fragments = abinfo.bytes / dmabuf->userfragsize; | ||
2217 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2218 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2219 | printk("SNDCTL_DSP_GETOSPACE %d, %d, %d, %d\n", abinfo.bytes, | ||
2220 | abinfo.fragsize, abinfo.fragments, abinfo.fragstotal); | ||
2221 | #endif | ||
2222 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2223 | |||
2224 | case SNDCTL_DSP_GETOPTR: | ||
2225 | if (!(file->f_mode & FMODE_WRITE)) | ||
2226 | return -EINVAL; | ||
2227 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2228 | return val; | ||
2229 | spin_lock_irqsave(&state->card->lock, flags); | ||
2230 | val = i810_get_free_write_space(state); | ||
2231 | cinfo.bytes = dmabuf->total_bytes; | ||
2232 | cinfo.ptr = dmabuf->hwptr; | ||
2233 | cinfo.blocks = val/dmabuf->userfragsize; | ||
2234 | if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_OUTPUT)) { | ||
2235 | dmabuf->count += val; | ||
2236 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2237 | __i810_update_lvi(state, 0); | ||
2238 | } | ||
2239 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2240 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2241 | printk("SNDCTL_DSP_GETOPTR %d, %d, %d, %d\n", cinfo.bytes, | ||
2242 | cinfo.blocks, cinfo.ptr, dmabuf->count); | ||
2243 | #endif | ||
2244 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
2245 | |||
2246 | case SNDCTL_DSP_GETISPACE: | ||
2247 | if (!(file->f_mode & FMODE_READ)) | ||
2248 | return -EINVAL; | ||
2249 | if (!dmabuf->ready && (val = prog_dmabuf(state, 1)) != 0) | ||
2250 | return val; | ||
2251 | spin_lock_irqsave(&state->card->lock, flags); | ||
2252 | abinfo.bytes = i810_get_available_read_data(state); | ||
2253 | abinfo.fragsize = dmabuf->userfragsize; | ||
2254 | abinfo.fragstotal = dmabuf->userfrags; | ||
2255 | abinfo.fragments = abinfo.bytes / dmabuf->userfragsize; | ||
2256 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2257 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2258 | printk("SNDCTL_DSP_GETISPACE %d, %d, %d, %d\n", abinfo.bytes, | ||
2259 | abinfo.fragsize, abinfo.fragments, abinfo.fragstotal); | ||
2260 | #endif | ||
2261 | return copy_to_user(argp, &abinfo, sizeof(abinfo)) ? -EFAULT : 0; | ||
2262 | |||
2263 | case SNDCTL_DSP_GETIPTR: | ||
2264 | if (!(file->f_mode & FMODE_READ)) | ||
2265 | return -EINVAL; | ||
2266 | if (!dmabuf->ready && (val = prog_dmabuf(state, 0)) != 0) | ||
2267 | return val; | ||
2268 | spin_lock_irqsave(&state->card->lock, flags); | ||
2269 | val = i810_get_available_read_data(state); | ||
2270 | cinfo.bytes = dmabuf->total_bytes; | ||
2271 | cinfo.blocks = val/dmabuf->userfragsize; | ||
2272 | cinfo.ptr = dmabuf->hwptr; | ||
2273 | if (dmabuf->mapped && (dmabuf->trigger & PCM_ENABLE_INPUT)) { | ||
2274 | dmabuf->count -= val; | ||
2275 | dmabuf->swptr = (dmabuf->swptr + val) % dmabuf->dmasize; | ||
2276 | __i810_update_lvi(state, 1); | ||
2277 | } | ||
2278 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2279 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2280 | printk("SNDCTL_DSP_GETIPTR %d, %d, %d, %d\n", cinfo.bytes, | ||
2281 | cinfo.blocks, cinfo.ptr, dmabuf->count); | ||
2282 | #endif | ||
2283 | return copy_to_user(argp, &cinfo, sizeof(cinfo)) ? -EFAULT : 0; | ||
2284 | |||
2285 | case SNDCTL_DSP_NONBLOCK: | ||
2286 | #ifdef DEBUG | ||
2287 | printk("SNDCTL_DSP_NONBLOCK\n"); | ||
2288 | #endif | ||
2289 | file->f_flags |= O_NONBLOCK; | ||
2290 | return 0; | ||
2291 | |||
2292 | case SNDCTL_DSP_GETCAPS: | ||
2293 | #ifdef DEBUG | ||
2294 | printk("SNDCTL_DSP_GETCAPS\n"); | ||
2295 | #endif | ||
2296 | return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP|DSP_CAP_BIND, | ||
2297 | p); | ||
2298 | |||
2299 | case SNDCTL_DSP_GETTRIGGER: | ||
2300 | val = 0; | ||
2301 | #ifdef DEBUG | ||
2302 | printk("SNDCTL_DSP_GETTRIGGER 0x%x\n", dmabuf->trigger); | ||
2303 | #endif | ||
2304 | return put_user(dmabuf->trigger, p); | ||
2305 | |||
2306 | case SNDCTL_DSP_SETTRIGGER: | ||
2307 | if (get_user(val, p)) | ||
2308 | return -EFAULT; | ||
2309 | #if defined(DEBUG) || defined(DEBUG_MMAP) | ||
2310 | printk("SNDCTL_DSP_SETTRIGGER 0x%x\n", val); | ||
2311 | #endif | ||
2312 | /* silently ignore invalid PCM_ENABLE_xxx bits, | ||
2313 | * like the other drivers do | ||
2314 | */ | ||
2315 | if (!(file->f_mode & FMODE_READ )) | ||
2316 | val &= ~PCM_ENABLE_INPUT; | ||
2317 | if (!(file->f_mode & FMODE_WRITE )) | ||
2318 | val &= ~PCM_ENABLE_OUTPUT; | ||
2319 | if((file->f_mode & FMODE_READ) && !(val & PCM_ENABLE_INPUT) && dmabuf->enable == ADC_RUNNING) { | ||
2320 | stop_adc(state); | ||
2321 | } | ||
2322 | if((file->f_mode & FMODE_WRITE) && !(val & PCM_ENABLE_OUTPUT) && dmabuf->enable == DAC_RUNNING) { | ||
2323 | stop_dac(state); | ||
2324 | } | ||
2325 | dmabuf->trigger = val; | ||
2326 | if((val & PCM_ENABLE_OUTPUT) && !(dmabuf->enable & DAC_RUNNING)) { | ||
2327 | if (!dmabuf->write_channel) { | ||
2328 | dmabuf->ready = 0; | ||
2329 | dmabuf->write_channel = state->card->alloc_pcm_channel(state->card); | ||
2330 | if (!dmabuf->write_channel) | ||
2331 | return -EBUSY; | ||
2332 | } | ||
2333 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 0))) | ||
2334 | return ret; | ||
2335 | if (dmabuf->mapped) { | ||
2336 | spin_lock_irqsave(&state->card->lock, flags); | ||
2337 | i810_update_ptr(state); | ||
2338 | dmabuf->count = 0; | ||
2339 | dmabuf->swptr = dmabuf->hwptr; | ||
2340 | dmabuf->count = i810_get_free_write_space(state); | ||
2341 | dmabuf->swptr = (dmabuf->swptr + dmabuf->count) % dmabuf->dmasize; | ||
2342 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2343 | } | ||
2344 | i810_update_lvi(state, 0); | ||
2345 | start_dac(state); | ||
2346 | } | ||
2347 | if((val & PCM_ENABLE_INPUT) && !(dmabuf->enable & ADC_RUNNING)) { | ||
2348 | if (!dmabuf->read_channel) { | ||
2349 | dmabuf->ready = 0; | ||
2350 | dmabuf->read_channel = state->card->alloc_rec_pcm_channel(state->card); | ||
2351 | if (!dmabuf->read_channel) | ||
2352 | return -EBUSY; | ||
2353 | } | ||
2354 | if (!dmabuf->ready && (ret = prog_dmabuf(state, 1))) | ||
2355 | return ret; | ||
2356 | if (dmabuf->mapped) { | ||
2357 | spin_lock_irqsave(&state->card->lock, flags); | ||
2358 | i810_update_ptr(state); | ||
2359 | dmabuf->swptr = dmabuf->hwptr; | ||
2360 | dmabuf->count = 0; | ||
2361 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2362 | } | ||
2363 | i810_update_lvi(state, 1); | ||
2364 | start_adc(state); | ||
2365 | } | ||
2366 | return 0; | ||
2367 | |||
2368 | case SNDCTL_DSP_SETDUPLEX: | ||
2369 | #ifdef DEBUG | ||
2370 | printk("SNDCTL_DSP_SETDUPLEX\n"); | ||
2371 | #endif | ||
2372 | return -EINVAL; | ||
2373 | |||
2374 | case SNDCTL_DSP_GETODELAY: | ||
2375 | if (!(file->f_mode & FMODE_WRITE)) | ||
2376 | return -EINVAL; | ||
2377 | spin_lock_irqsave(&state->card->lock, flags); | ||
2378 | i810_update_ptr(state); | ||
2379 | val = dmabuf->count; | ||
2380 | spin_unlock_irqrestore(&state->card->lock, flags); | ||
2381 | #ifdef DEBUG | ||
2382 | printk("SNDCTL_DSP_GETODELAY %d\n", dmabuf->count); | ||
2383 | #endif | ||
2384 | return put_user(val, p); | ||
2385 | |||
2386 | case SOUND_PCM_READ_RATE: | ||
2387 | #ifdef DEBUG | ||
2388 | printk("SOUND_PCM_READ_RATE %d\n", dmabuf->rate); | ||
2389 | #endif | ||
2390 | return put_user(dmabuf->rate, p); | ||
2391 | |||
2392 | case SOUND_PCM_READ_CHANNELS: | ||
2393 | #ifdef DEBUG | ||
2394 | printk("SOUND_PCM_READ_CHANNELS\n"); | ||
2395 | #endif | ||
2396 | return put_user(2, p); | ||
2397 | |||
2398 | case SOUND_PCM_READ_BITS: | ||
2399 | #ifdef DEBUG | ||
2400 | printk("SOUND_PCM_READ_BITS\n"); | ||
2401 | #endif | ||
2402 | return put_user(AFMT_S16_LE, p); | ||
2403 | |||
2404 | case SNDCTL_DSP_SETSPDIF: /* Set S/PDIF Control register */ | ||
2405 | #ifdef DEBUG | ||
2406 | printk("SNDCTL_DSP_SETSPDIF\n"); | ||
2407 | #endif | ||
2408 | if (get_user(val, p)) | ||
2409 | return -EFAULT; | ||
2410 | |||
2411 | /* Check to make sure the codec supports S/PDIF transmitter */ | ||
2412 | |||
2413 | if((state->card->ac97_features & 4)) { | ||
2414 | /* mask out the transmitter speed bits so the user can't set them */ | ||
2415 | val &= ~0x3000; | ||
2416 | |||
2417 | /* Add the current transmitter speed bits to the passed value */ | ||
2418 | ret = i810_ac97_get(codec, AC97_SPDIF_CONTROL); | ||
2419 | val |= (ret & 0x3000); | ||
2420 | |||
2421 | i810_ac97_set(codec, AC97_SPDIF_CONTROL, val); | ||
2422 | if(i810_ac97_get(codec, AC97_SPDIF_CONTROL) != val ) { | ||
2423 | printk(KERN_ERR "i810_audio: Unable to set S/PDIF configuration to 0x%04x.\n", val); | ||
2424 | return -EFAULT; | ||
2425 | } | ||
2426 | } | ||
2427 | #ifdef DEBUG | ||
2428 | else | ||
2429 | printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n"); | ||
2430 | #endif | ||
2431 | return put_user(val, p); | ||
2432 | |||
2433 | case SNDCTL_DSP_GETSPDIF: /* Get S/PDIF Control register */ | ||
2434 | #ifdef DEBUG | ||
2435 | printk("SNDCTL_DSP_GETSPDIF\n"); | ||
2436 | #endif | ||
2437 | if (get_user(val, p)) | ||
2438 | return -EFAULT; | ||
2439 | |||
2440 | /* Check to make sure the codec supports S/PDIF transmitter */ | ||
2441 | |||
2442 | if(!(state->card->ac97_features & 4)) { | ||
2443 | #ifdef DEBUG | ||
2444 | printk(KERN_WARNING "i810_audio: S/PDIF transmitter not avalible.\n"); | ||
2445 | #endif | ||
2446 | val = 0; | ||
2447 | } else { | ||
2448 | val = i810_ac97_get(codec, AC97_SPDIF_CONTROL); | ||
2449 | } | ||
2450 | //return put_user((val & 0xcfff), p); | ||
2451 | return put_user(val, p); | ||
2452 | |||
2453 | case SNDCTL_DSP_GETCHANNELMASK: | ||
2454 | #ifdef DEBUG | ||
2455 | printk("SNDCTL_DSP_GETCHANNELMASK\n"); | ||
2456 | #endif | ||
2457 | if (get_user(val, p)) | ||
2458 | return -EFAULT; | ||
2459 | |||
2460 | /* Based on AC'97 DAC support, not ICH hardware */ | ||
2461 | val = DSP_BIND_FRONT; | ||
2462 | if ( state->card->ac97_features & 0x0004 ) | ||
2463 | val |= DSP_BIND_SPDIF; | ||
2464 | |||
2465 | if ( state->card->ac97_features & 0x0080 ) | ||
2466 | val |= DSP_BIND_SURR; | ||
2467 | if ( state->card->ac97_features & 0x0140 ) | ||
2468 | val |= DSP_BIND_CENTER_LFE; | ||
2469 | |||
2470 | return put_user(val, p); | ||
2471 | |||
2472 | case SNDCTL_DSP_BIND_CHANNEL: | ||
2473 | #ifdef DEBUG | ||
2474 | printk("SNDCTL_DSP_BIND_CHANNEL\n"); | ||
2475 | #endif | ||
2476 | if (get_user(val, p)) | ||
2477 | return -EFAULT; | ||
2478 | if ( val == DSP_BIND_QUERY ) { | ||
2479 | val = DSP_BIND_FRONT; /* Always report this as being enabled */ | ||
2480 | if ( state->card->ac97_status & SPDIF_ON ) | ||
2481 | val |= DSP_BIND_SPDIF; | ||
2482 | else { | ||
2483 | if ( state->card->ac97_status & SURR_ON ) | ||
2484 | val |= DSP_BIND_SURR; | ||
2485 | if ( state->card->ac97_status & CENTER_LFE_ON ) | ||
2486 | val |= DSP_BIND_CENTER_LFE; | ||
2487 | } | ||
2488 | } else { /* Not a query, set it */ | ||
2489 | if (!(file->f_mode & FMODE_WRITE)) | ||
2490 | return -EINVAL; | ||
2491 | if ( dmabuf->enable == DAC_RUNNING ) { | ||
2492 | stop_dac(state); | ||
2493 | } | ||
2494 | if ( val & DSP_BIND_SPDIF ) { /* Turn on SPDIF */ | ||
2495 | /* Ok, this should probably define what slots | ||
2496 | * to use. For now, we'll only set it to the | ||
2497 | * defaults: | ||
2498 | * | ||
2499 | * non multichannel codec maps to slots 3&4 | ||
2500 | * 2 channel codec maps to slots 7&8 | ||
2501 | * 4 channel codec maps to slots 6&9 | ||
2502 | * 6 channel codec maps to slots 10&11 | ||
2503 | * | ||
2504 | * there should be some way for the app to | ||
2505 | * select the slot assignment. | ||
2506 | */ | ||
2507 | |||
2508 | i810_set_spdif_output ( state, AC97_EA_SPSA_3_4, dmabuf->rate ); | ||
2509 | if ( !(state->card->ac97_status & SPDIF_ON) ) | ||
2510 | val &= ~DSP_BIND_SPDIF; | ||
2511 | } else { | ||
2512 | int mask; | ||
2513 | int channels; | ||
2514 | |||
2515 | /* Turn off S/PDIF if it was on */ | ||
2516 | if ( state->card->ac97_status & SPDIF_ON ) | ||
2517 | i810_set_spdif_output ( state, -1, 0 ); | ||
2518 | |||
2519 | mask = val & (DSP_BIND_FRONT | DSP_BIND_SURR | DSP_BIND_CENTER_LFE); | ||
2520 | switch (mask) { | ||
2521 | case DSP_BIND_FRONT: | ||
2522 | channels = 2; | ||
2523 | break; | ||
2524 | case DSP_BIND_FRONT|DSP_BIND_SURR: | ||
2525 | channels = 4; | ||
2526 | break; | ||
2527 | case DSP_BIND_FRONT|DSP_BIND_SURR|DSP_BIND_CENTER_LFE: | ||
2528 | channels = 6; | ||
2529 | break; | ||
2530 | default: | ||
2531 | val = DSP_BIND_FRONT; | ||
2532 | channels = 2; | ||
2533 | break; | ||
2534 | } | ||
2535 | i810_set_dac_channels ( state, channels ); | ||
2536 | |||
2537 | /* check that they really got turned on */ | ||
2538 | if (!(state->card->ac97_status & SURR_ON)) | ||
2539 | val &= ~DSP_BIND_SURR; | ||
2540 | if (!(state->card->ac97_status & CENTER_LFE_ON)) | ||
2541 | val &= ~DSP_BIND_CENTER_LFE; | ||
2542 | } | ||
2543 | } | ||
2544 | return put_user(val, p); | ||
2545 | |||
2546 | case SNDCTL_DSP_MAPINBUF: | ||
2547 | case SNDCTL_DSP_MAPOUTBUF: | ||
2548 | case SNDCTL_DSP_SETSYNCRO: | ||
2549 | case SOUND_PCM_WRITE_FILTER: | ||
2550 | case SOUND_PCM_READ_FILTER: | ||
2551 | #ifdef DEBUG | ||
2552 | printk("SNDCTL_* -EINVAL\n"); | ||
2553 | #endif | ||
2554 | return -EINVAL; | ||
2555 | } | ||
2556 | return -EINVAL; | ||
2557 | } | ||
2558 | |||
2559 | static int i810_open(struct inode *inode, struct file *file) | ||
2560 | { | ||
2561 | int i = 0; | ||
2562 | struct i810_card *card = devs; | ||
2563 | struct i810_state *state = NULL; | ||
2564 | struct dmabuf *dmabuf = NULL; | ||
2565 | |||
2566 | /* find an avaiable virtual channel (instance of /dev/dsp) */ | ||
2567 | while (card != NULL) { | ||
2568 | /* | ||
2569 | * If we are initializing and then fail, card could go | ||
2570 | * away unuexpectedly while we are in the for() loop. | ||
2571 | * So, check for card on each iteration before we check | ||
2572 | * for card->initializing to avoid a possible oops. | ||
2573 | * This usually only matters for times when the driver is | ||
2574 | * autoloaded by kmod. | ||
2575 | */ | ||
2576 | for (i = 0; i < 50 && card && card->initializing; i++) { | ||
2577 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2578 | schedule_timeout(HZ/20); | ||
2579 | } | ||
2580 | for (i = 0; i < NR_HW_CH && card && !card->initializing; i++) { | ||
2581 | if (card->states[i] == NULL) { | ||
2582 | state = card->states[i] = (struct i810_state *) | ||
2583 | kzalloc(sizeof(struct i810_state), GFP_KERNEL); | ||
2584 | if (state == NULL) | ||
2585 | return -ENOMEM; | ||
2586 | dmabuf = &state->dmabuf; | ||
2587 | goto found_virt; | ||
2588 | } | ||
2589 | } | ||
2590 | card = card->next; | ||
2591 | } | ||
2592 | /* no more virtual channel avaiable */ | ||
2593 | if (!state) | ||
2594 | return -ENODEV; | ||
2595 | |||
2596 | found_virt: | ||
2597 | /* initialize the virtual channel */ | ||
2598 | state->virt = i; | ||
2599 | state->card = card; | ||
2600 | state->magic = I810_STATE_MAGIC; | ||
2601 | init_waitqueue_head(&dmabuf->wait); | ||
2602 | mutex_init(&state->open_mutex); | ||
2603 | file->private_data = state; | ||
2604 | dmabuf->trigger = 0; | ||
2605 | |||
2606 | /* allocate hardware channels */ | ||
2607 | if(file->f_mode & FMODE_READ) { | ||
2608 | if((dmabuf->read_channel = card->alloc_rec_pcm_channel(card)) == NULL) { | ||
2609 | kfree (card->states[i]); | ||
2610 | card->states[i] = NULL; | ||
2611 | return -EBUSY; | ||
2612 | } | ||
2613 | dmabuf->trigger |= PCM_ENABLE_INPUT; | ||
2614 | i810_set_adc_rate(state, 8000); | ||
2615 | } | ||
2616 | if(file->f_mode & FMODE_WRITE) { | ||
2617 | if((dmabuf->write_channel = card->alloc_pcm_channel(card)) == NULL) { | ||
2618 | /* make sure we free the record channel allocated above */ | ||
2619 | if(file->f_mode & FMODE_READ) | ||
2620 | card->free_pcm_channel(card,dmabuf->read_channel->num); | ||
2621 | kfree (card->states[i]); | ||
2622 | card->states[i] = NULL; | ||
2623 | return -EBUSY; | ||
2624 | } | ||
2625 | /* Initialize to 8kHz? What if we don't support 8kHz? */ | ||
2626 | /* Let's change this to check for S/PDIF stuff */ | ||
2627 | |||
2628 | dmabuf->trigger |= PCM_ENABLE_OUTPUT; | ||
2629 | if ( spdif_locked ) { | ||
2630 | i810_set_dac_rate(state, spdif_locked); | ||
2631 | i810_set_spdif_output(state, AC97_EA_SPSA_3_4, spdif_locked); | ||
2632 | } else { | ||
2633 | i810_set_dac_rate(state, 8000); | ||
2634 | /* Put the ACLink in 2 channel mode by default */ | ||
2635 | i = I810_IOREADL(card, GLOB_CNT); | ||
2636 | I810_IOWRITEL(i & 0xffcfffff, card, GLOB_CNT); | ||
2637 | } | ||
2638 | } | ||
2639 | |||
2640 | /* set default sample format. According to OSS Programmer's Guide /dev/dsp | ||
2641 | should be default to unsigned 8-bits, mono, with sample rate 8kHz and | ||
2642 | /dev/dspW will accept 16-bits sample, but we don't support those so we | ||
2643 | set it immediately to stereo and 16bit, which is all we do support */ | ||
2644 | dmabuf->fmt |= I810_FMT_16BIT | I810_FMT_STEREO; | ||
2645 | dmabuf->ossfragsize = 0; | ||
2646 | dmabuf->ossmaxfrags = 0; | ||
2647 | dmabuf->subdivision = 0; | ||
2648 | |||
2649 | state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
2650 | |||
2651 | return nonseekable_open(inode, file); | ||
2652 | } | ||
2653 | |||
2654 | static int i810_release(struct inode *inode, struct file *file) | ||
2655 | { | ||
2656 | struct i810_state *state = (struct i810_state *)file->private_data; | ||
2657 | struct i810_card *card = state->card; | ||
2658 | struct dmabuf *dmabuf = &state->dmabuf; | ||
2659 | unsigned long flags; | ||
2660 | |||
2661 | lock_kernel(); | ||
2662 | |||
2663 | /* stop DMA state machine and free DMA buffers/channels */ | ||
2664 | if(dmabuf->trigger & PCM_ENABLE_OUTPUT) { | ||
2665 | drain_dac(state, 0); | ||
2666 | } | ||
2667 | if(dmabuf->trigger & PCM_ENABLE_INPUT) { | ||
2668 | stop_adc(state); | ||
2669 | } | ||
2670 | spin_lock_irqsave(&card->lock, flags); | ||
2671 | dealloc_dmabuf(state); | ||
2672 | if (file->f_mode & FMODE_WRITE) { | ||
2673 | state->card->free_pcm_channel(state->card, dmabuf->write_channel->num); | ||
2674 | } | ||
2675 | if (file->f_mode & FMODE_READ) { | ||
2676 | state->card->free_pcm_channel(state->card, dmabuf->read_channel->num); | ||
2677 | } | ||
2678 | |||
2679 | state->card->states[state->virt] = NULL; | ||
2680 | kfree(state); | ||
2681 | spin_unlock_irqrestore(&card->lock, flags); | ||
2682 | unlock_kernel(); | ||
2683 | |||
2684 | return 0; | ||
2685 | } | ||
2686 | |||
2687 | static /*const*/ struct file_operations i810_audio_fops = { | ||
2688 | .owner = THIS_MODULE, | ||
2689 | .llseek = no_llseek, | ||
2690 | .read = i810_read, | ||
2691 | .write = i810_write, | ||
2692 | .poll = i810_poll, | ||
2693 | .ioctl = i810_ioctl, | ||
2694 | .mmap = i810_mmap, | ||
2695 | .open = i810_open, | ||
2696 | .release = i810_release, | ||
2697 | }; | ||
2698 | |||
2699 | /* Write AC97 codec registers */ | ||
2700 | |||
2701 | static u16 i810_ac97_get_mmio(struct ac97_codec *dev, u8 reg) | ||
2702 | { | ||
2703 | struct i810_card *card = dev->private_data; | ||
2704 | int count = 100; | ||
2705 | u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); | ||
2706 | |||
2707 | while(count-- && (readb(card->iobase_mmio + CAS) & 1)) | ||
2708 | udelay(1); | ||
2709 | |||
2710 | #ifdef DEBUG_MMIO | ||
2711 | { | ||
2712 | u16 ans = readw(card->ac97base_mmio + reg_set); | ||
2713 | printk(KERN_DEBUG "i810_audio: ac97_get_mmio(%d) -> 0x%04X\n", ((int) reg_set) & 0xffff, (u32) ans); | ||
2714 | return ans; | ||
2715 | } | ||
2716 | #else | ||
2717 | return readw(card->ac97base_mmio + reg_set); | ||
2718 | #endif | ||
2719 | } | ||
2720 | |||
2721 | static u16 i810_ac97_get_io(struct ac97_codec *dev, u8 reg) | ||
2722 | { | ||
2723 | struct i810_card *card = dev->private_data; | ||
2724 | int count = 100; | ||
2725 | u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); | ||
2726 | |||
2727 | while(count-- && (I810_IOREADB(card, CAS) & 1)) | ||
2728 | udelay(1); | ||
2729 | |||
2730 | return inw(card->ac97base + reg_set); | ||
2731 | } | ||
2732 | |||
2733 | static void i810_ac97_set_mmio(struct ac97_codec *dev, u8 reg, u16 data) | ||
2734 | { | ||
2735 | struct i810_card *card = dev->private_data; | ||
2736 | int count = 100; | ||
2737 | u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); | ||
2738 | |||
2739 | while(count-- && (readb(card->iobase_mmio + CAS) & 1)) | ||
2740 | udelay(1); | ||
2741 | |||
2742 | writew(data, card->ac97base_mmio + reg_set); | ||
2743 | |||
2744 | #ifdef DEBUG_MMIO | ||
2745 | printk(KERN_DEBUG "i810_audio: ac97_set_mmio(0x%04X, %d)\n", (u32) data, ((int) reg_set) & 0xffff); | ||
2746 | #endif | ||
2747 | } | ||
2748 | |||
2749 | static void i810_ac97_set_io(struct ac97_codec *dev, u8 reg, u16 data) | ||
2750 | { | ||
2751 | struct i810_card *card = dev->private_data; | ||
2752 | int count = 100; | ||
2753 | u16 reg_set = IO_REG_OFF(dev) | (reg&0x7f); | ||
2754 | |||
2755 | while(count-- && (I810_IOREADB(card, CAS) & 1)) | ||
2756 | udelay(1); | ||
2757 | |||
2758 | outw(data, card->ac97base + reg_set); | ||
2759 | } | ||
2760 | |||
2761 | static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg) | ||
2762 | { | ||
2763 | struct i810_card *card = dev->private_data; | ||
2764 | u16 ret; | ||
2765 | |||
2766 | spin_lock(&card->ac97_lock); | ||
2767 | if (card->use_mmio) { | ||
2768 | ret = i810_ac97_get_mmio(dev, reg); | ||
2769 | } | ||
2770 | else { | ||
2771 | ret = i810_ac97_get_io(dev, reg); | ||
2772 | } | ||
2773 | spin_unlock(&card->ac97_lock); | ||
2774 | |||
2775 | return ret; | ||
2776 | } | ||
2777 | |||
2778 | static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data) | ||
2779 | { | ||
2780 | struct i810_card *card = dev->private_data; | ||
2781 | |||
2782 | spin_lock(&card->ac97_lock); | ||
2783 | if (card->use_mmio) { | ||
2784 | i810_ac97_set_mmio(dev, reg, data); | ||
2785 | } | ||
2786 | else { | ||
2787 | i810_ac97_set_io(dev, reg, data); | ||
2788 | } | ||
2789 | spin_unlock(&card->ac97_lock); | ||
2790 | } | ||
2791 | |||
2792 | |||
2793 | /* OSS /dev/mixer file operation methods */ | ||
2794 | |||
2795 | static int i810_open_mixdev(struct inode *inode, struct file *file) | ||
2796 | { | ||
2797 | int i; | ||
2798 | int minor = iminor(inode); | ||
2799 | struct i810_card *card = devs; | ||
2800 | |||
2801 | for (card = devs; card != NULL; card = card->next) { | ||
2802 | /* | ||
2803 | * If we are initializing and then fail, card could go | ||
2804 | * away unuexpectedly while we are in the for() loop. | ||
2805 | * So, check for card on each iteration before we check | ||
2806 | * for card->initializing to avoid a possible oops. | ||
2807 | * This usually only matters for times when the driver is | ||
2808 | * autoloaded by kmod. | ||
2809 | */ | ||
2810 | for (i = 0; i < 50 && card && card->initializing; i++) { | ||
2811 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2812 | schedule_timeout(HZ/20); | ||
2813 | } | ||
2814 | for (i = 0; i < NR_AC97 && card && !card->initializing; i++) | ||
2815 | if (card->ac97_codec[i] != NULL && | ||
2816 | card->ac97_codec[i]->dev_mixer == minor) { | ||
2817 | file->private_data = card->ac97_codec[i]; | ||
2818 | return nonseekable_open(inode, file); | ||
2819 | } | ||
2820 | } | ||
2821 | return -ENODEV; | ||
2822 | } | ||
2823 | |||
2824 | static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, | ||
2825 | unsigned long arg) | ||
2826 | { | ||
2827 | struct ac97_codec *codec = (struct ac97_codec *)file->private_data; | ||
2828 | |||
2829 | return codec->mixer_ioctl(codec, cmd, arg); | ||
2830 | } | ||
2831 | |||
2832 | static /*const*/ struct file_operations i810_mixer_fops = { | ||
2833 | .owner = THIS_MODULE, | ||
2834 | .llseek = no_llseek, | ||
2835 | .ioctl = i810_ioctl_mixdev, | ||
2836 | .open = i810_open_mixdev, | ||
2837 | }; | ||
2838 | |||
2839 | /* AC97 codec initialisation. These small functions exist so we don't | ||
2840 | duplicate code between module init and apm resume */ | ||
2841 | |||
2842 | static inline int i810_ac97_exists(struct i810_card *card, int ac97_number) | ||
2843 | { | ||
2844 | u32 reg = I810_IOREADL(card, GLOB_STA); | ||
2845 | switch (ac97_number) { | ||
2846 | case 0: | ||
2847 | return reg & (1<<8); | ||
2848 | case 1: | ||
2849 | return reg & (1<<9); | ||
2850 | case 2: | ||
2851 | return reg & (1<<28); | ||
2852 | } | ||
2853 | return 0; | ||
2854 | } | ||
2855 | |||
2856 | static inline int i810_ac97_enable_variable_rate(struct ac97_codec *codec) | ||
2857 | { | ||
2858 | i810_ac97_set(codec, AC97_EXTENDED_STATUS, 9); | ||
2859 | i810_ac97_set(codec,AC97_EXTENDED_STATUS, | ||
2860 | i810_ac97_get(codec, AC97_EXTENDED_STATUS)|0xE800); | ||
2861 | |||
2862 | return (i810_ac97_get(codec, AC97_EXTENDED_STATUS)&1); | ||
2863 | } | ||
2864 | |||
2865 | |||
2866 | static int i810_ac97_probe_and_powerup(struct i810_card *card,struct ac97_codec *codec) | ||
2867 | { | ||
2868 | /* Returns 0 on failure */ | ||
2869 | int i; | ||
2870 | |||
2871 | if (ac97_probe_codec(codec) == 0) return 0; | ||
2872 | |||
2873 | /* power it all up */ | ||
2874 | i810_ac97_set(codec, AC97_POWER_CONTROL, | ||
2875 | i810_ac97_get(codec, AC97_POWER_CONTROL) & ~0x7f00); | ||
2876 | |||
2877 | /* wait for analog ready */ | ||
2878 | for (i=100; i && ((i810_ac97_get(codec, AC97_POWER_CONTROL) & 0xf) != 0xf); i--) | ||
2879 | { | ||
2880 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2881 | schedule_timeout(HZ/20); | ||
2882 | } | ||
2883 | return i; | ||
2884 | } | ||
2885 | |||
2886 | static int is_new_ich(u16 pci_id) | ||
2887 | { | ||
2888 | switch (pci_id) { | ||
2889 | case PCI_DEVICE_ID_INTEL_82801DB_5: | ||
2890 | case PCI_DEVICE_ID_INTEL_82801EB_5: | ||
2891 | case PCI_DEVICE_ID_INTEL_ESB_5: | ||
2892 | case PCI_DEVICE_ID_INTEL_ICH6_18: | ||
2893 | return 1; | ||
2894 | default: | ||
2895 | break; | ||
2896 | } | ||
2897 | |||
2898 | return 0; | ||
2899 | } | ||
2900 | |||
2901 | static inline int ich_use_mmio(struct i810_card *card) | ||
2902 | { | ||
2903 | return is_new_ich(card->pci_id) && card->use_mmio; | ||
2904 | } | ||
2905 | |||
2906 | /** | ||
2907 | * i810_ac97_power_up_bus - bring up AC97 link | ||
2908 | * @card : ICH audio device to power up | ||
2909 | * | ||
2910 | * Bring up the ACLink AC97 codec bus | ||
2911 | */ | ||
2912 | |||
2913 | static int i810_ac97_power_up_bus(struct i810_card *card) | ||
2914 | { | ||
2915 | u32 reg = I810_IOREADL(card, GLOB_CNT); | ||
2916 | int i; | ||
2917 | int primary_codec_id = 0; | ||
2918 | |||
2919 | if((reg&2)==0) /* Cold required */ | ||
2920 | reg|=2; | ||
2921 | else | ||
2922 | reg|=4; /* Warm */ | ||
2923 | |||
2924 | reg&=~8; /* ACLink on */ | ||
2925 | |||
2926 | /* At this point we deassert AC_RESET # */ | ||
2927 | I810_IOWRITEL(reg , card, GLOB_CNT); | ||
2928 | |||
2929 | /* We must now allow time for the Codec initialisation. | ||
2930 | 600mS is the specified time */ | ||
2931 | |||
2932 | for(i=0;i<10;i++) | ||
2933 | { | ||
2934 | if((I810_IOREADL(card, GLOB_CNT)&4)==0) | ||
2935 | break; | ||
2936 | |||
2937 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2938 | schedule_timeout(HZ/20); | ||
2939 | } | ||
2940 | if(i==10) | ||
2941 | { | ||
2942 | printk(KERN_ERR "i810_audio: AC'97 reset failed.\n"); | ||
2943 | return 0; | ||
2944 | } | ||
2945 | |||
2946 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2947 | schedule_timeout(HZ/2); | ||
2948 | |||
2949 | /* | ||
2950 | * See if the primary codec comes ready. This must happen | ||
2951 | * before we start doing DMA stuff | ||
2952 | */ | ||
2953 | /* see i810_ac97_init for the next 10 lines (jsaw) */ | ||
2954 | if (card->use_mmio) | ||
2955 | readw(card->ac97base_mmio); | ||
2956 | else | ||
2957 | inw(card->ac97base); | ||
2958 | if (ich_use_mmio(card)) { | ||
2959 | primary_codec_id = (int) readl(card->iobase_mmio + SDM) & 0x3; | ||
2960 | printk(KERN_INFO "i810_audio: Primary codec has ID %d\n", | ||
2961 | primary_codec_id); | ||
2962 | } | ||
2963 | |||
2964 | if(! i810_ac97_exists(card, primary_codec_id)) | ||
2965 | { | ||
2966 | printk(KERN_INFO "i810_audio: Codec not ready.. wait.. "); | ||
2967 | set_current_state(TASK_UNINTERRUPTIBLE); | ||
2968 | schedule_timeout(HZ); /* actually 600mS by the spec */ | ||
2969 | |||
2970 | if(i810_ac97_exists(card, primary_codec_id)) | ||
2971 | printk("OK\n"); | ||
2972 | else | ||
2973 | printk("no response.\n"); | ||
2974 | } | ||
2975 | if (card->use_mmio) | ||
2976 | readw(card->ac97base_mmio); | ||
2977 | else | ||
2978 | inw(card->ac97base); | ||
2979 | return 1; | ||
2980 | } | ||
2981 | |||
2982 | static int __devinit i810_ac97_init(struct i810_card *card) | ||
2983 | { | ||
2984 | int num_ac97 = 0; | ||
2985 | int ac97_id; | ||
2986 | int total_channels = 0; | ||
2987 | int nr_ac97_max = card_cap[card->pci_id_internal].nr_ac97; | ||
2988 | struct ac97_codec *codec; | ||
2989 | u16 eid; | ||
2990 | u32 reg; | ||
2991 | |||
2992 | if(!i810_ac97_power_up_bus(card)) return 0; | ||
2993 | |||
2994 | /* Number of channels supported */ | ||
2995 | /* What about the codec? Just because the ICH supports */ | ||
2996 | /* multiple channels doesn't mean the codec does. */ | ||
2997 | /* we'll have to modify this in the codec section below */ | ||
2998 | /* to reflect what the codec has. */ | ||
2999 | /* ICH and ICH0 only support 2 channels so don't bother */ | ||
3000 | /* to check.... */ | ||
3001 | |||
3002 | card->channels = 2; | ||
3003 | reg = I810_IOREADL(card, GLOB_STA); | ||
3004 | if ( reg & 0x0200000 ) | ||
3005 | card->channels = 6; | ||
3006 | else if ( reg & 0x0100000 ) | ||
3007 | card->channels = 4; | ||
3008 | printk(KERN_INFO "i810_audio: Audio Controller supports %d channels.\n", card->channels); | ||
3009 | printk(KERN_INFO "i810_audio: Defaulting to base 2 channel mode.\n"); | ||
3010 | reg = I810_IOREADL(card, GLOB_CNT); | ||
3011 | I810_IOWRITEL(reg & 0xffcfffff, card, GLOB_CNT); | ||
3012 | |||
3013 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) | ||
3014 | card->ac97_codec[num_ac97] = NULL; | ||
3015 | |||
3016 | /*@FIXME I don't know, if I'm playing to safe here... (jsaw) */ | ||
3017 | if ((nr_ac97_max > 2) && !card->use_mmio) nr_ac97_max = 2; | ||
3018 | |||
3019 | for (num_ac97 = 0; num_ac97 < nr_ac97_max; num_ac97++) { | ||
3020 | /* codec reset */ | ||
3021 | printk(KERN_INFO "i810_audio: Resetting connection %d\n", num_ac97); | ||
3022 | if (card->use_mmio) | ||
3023 | readw(card->ac97base_mmio + 0x80*num_ac97); | ||
3024 | else | ||
3025 | inw(card->ac97base + 0x80*num_ac97); | ||
3026 | |||
3027 | /* If we have the SDATA_IN Map Register, as on ICH4, we | ||
3028 | do not loop thru all possible codec IDs but thru all | ||
3029 | possible IO channels. Bit 0:1 of SDM then holds the | ||
3030 | last codec ID spoken to. | ||
3031 | */ | ||
3032 | if (ich_use_mmio(card)) { | ||
3033 | ac97_id = (int) readl(card->iobase_mmio + SDM) & 0x3; | ||
3034 | printk(KERN_INFO "i810_audio: Connection %d with codec id %d\n", | ||
3035 | num_ac97, ac97_id); | ||
3036 | } | ||
3037 | else { | ||
3038 | ac97_id = num_ac97; | ||
3039 | } | ||
3040 | |||
3041 | /* The ICH programmer's reference says you should */ | ||
3042 | /* check the ready status before probing. So we chk */ | ||
3043 | /* What do we do if it's not ready? Wait and try */ | ||
3044 | /* again, or abort? */ | ||
3045 | if (!i810_ac97_exists(card, ac97_id)) { | ||
3046 | if(num_ac97 == 0) | ||
3047 | printk(KERN_ERR "i810_audio: Primary codec not ready.\n"); | ||
3048 | } | ||
3049 | |||
3050 | if ((codec = ac97_alloc_codec()) == NULL) | ||
3051 | return -ENOMEM; | ||
3052 | |||
3053 | /* initialize some basic codec information, other fields will be filled | ||
3054 | in ac97_probe_codec */ | ||
3055 | codec->private_data = card; | ||
3056 | codec->id = ac97_id; | ||
3057 | card->ac97_id_map[ac97_id] = num_ac97 * 0x80; | ||
3058 | |||
3059 | if (card->use_mmio) { | ||
3060 | codec->codec_read = i810_ac97_get_mmio; | ||
3061 | codec->codec_write = i810_ac97_set_mmio; | ||
3062 | } | ||
3063 | else { | ||
3064 | codec->codec_read = i810_ac97_get_io; | ||
3065 | codec->codec_write = i810_ac97_set_io; | ||
3066 | } | ||
3067 | |||
3068 | if(!i810_ac97_probe_and_powerup(card,codec)) { | ||
3069 | printk(KERN_ERR "i810_audio: timed out waiting for codec %d analog ready.\n", ac97_id); | ||
3070 | ac97_release_codec(codec); | ||
3071 | break; /* it didn't work */ | ||
3072 | } | ||
3073 | /* Store state information about S/PDIF transmitter */ | ||
3074 | card->ac97_status = 0; | ||
3075 | |||
3076 | /* Don't attempt to get eid until powerup is complete */ | ||
3077 | eid = i810_ac97_get(codec, AC97_EXTENDED_ID); | ||
3078 | |||
3079 | if(eid==0xFFFF) | ||
3080 | { | ||
3081 | printk(KERN_WARNING "i810_audio: no codec attached ?\n"); | ||
3082 | ac97_release_codec(codec); | ||
3083 | break; | ||
3084 | } | ||
3085 | |||
3086 | /* Check for an AC97 1.0 soft modem (ID1) */ | ||
3087 | |||
3088 | if(codec->modem) | ||
3089 | { | ||
3090 | printk(KERN_WARNING "i810_audio: codec %d is a softmodem - skipping.\n", ac97_id); | ||
3091 | ac97_release_codec(codec); | ||
3092 | continue; | ||
3093 | } | ||
3094 | |||
3095 | card->ac97_features = eid; | ||
3096 | |||
3097 | /* Now check the codec for useful features to make up for | ||
3098 | the dumbness of the 810 hardware engine */ | ||
3099 | |||
3100 | if(!(eid&0x0001)) | ||
3101 | printk(KERN_WARNING "i810_audio: only 48Khz playback available.\n"); | ||
3102 | else | ||
3103 | { | ||
3104 | if(!i810_ac97_enable_variable_rate(codec)) { | ||
3105 | printk(KERN_WARNING "i810_audio: Codec refused to allow VRA, using 48Khz only.\n"); | ||
3106 | card->ac97_features&=~1; | ||
3107 | } | ||
3108 | } | ||
3109 | |||
3110 | /* Turn on the amplifier */ | ||
3111 | |||
3112 | codec->codec_write(codec, AC97_POWER_CONTROL, | ||
3113 | codec->codec_read(codec, AC97_POWER_CONTROL) & ~0x8000); | ||
3114 | |||
3115 | /* Determine how many channels the codec(s) support */ | ||
3116 | /* - The primary codec always supports 2 */ | ||
3117 | /* - If the codec supports AMAP, surround DACs will */ | ||
3118 | /* automaticlly get assigned to slots. */ | ||
3119 | /* * Check for surround DACs and increment if */ | ||
3120 | /* found. */ | ||
3121 | /* - Else check if the codec is revision 2.2 */ | ||
3122 | /* * If surround DACs exist, assign them to slots */ | ||
3123 | /* and increment channel count. */ | ||
3124 | |||
3125 | /* All of this only applies to ICH2 and above. ICH */ | ||
3126 | /* and ICH0 only support 2 channels. ICH2 will only */ | ||
3127 | /* support multiple codecs in a "split audio" config. */ | ||
3128 | /* as described above. */ | ||
3129 | |||
3130 | /* TODO: Remove all the debugging messages! */ | ||
3131 | |||
3132 | if((eid & 0xc000) == 0) /* primary codec */ | ||
3133 | total_channels += 2; | ||
3134 | |||
3135 | if(eid & 0x200) { /* GOOD, AMAP support */ | ||
3136 | if (eid & 0x0080) /* L/R Surround channels */ | ||
3137 | total_channels += 2; | ||
3138 | if (eid & 0x0140) /* LFE and Center channels */ | ||
3139 | total_channels += 2; | ||
3140 | printk("i810_audio: AC'97 codec %d supports AMAP, total channels = %d\n", ac97_id, total_channels); | ||
3141 | } else if (eid & 0x0400) { /* this only works on 2.2 compliant codecs */ | ||
3142 | eid &= 0xffcf; | ||
3143 | if((eid & 0xc000) != 0) { | ||
3144 | switch ( total_channels ) { | ||
3145 | case 2: | ||
3146 | /* Set dsa1, dsa0 to 01 */ | ||
3147 | eid |= 0x0010; | ||
3148 | break; | ||
3149 | case 4: | ||
3150 | /* Set dsa1, dsa0 to 10 */ | ||
3151 | eid |= 0x0020; | ||
3152 | break; | ||
3153 | case 6: | ||
3154 | /* Set dsa1, dsa0 to 11 */ | ||
3155 | eid |= 0x0030; | ||
3156 | break; | ||
3157 | } | ||
3158 | total_channels += 2; | ||
3159 | } | ||
3160 | i810_ac97_set(codec, AC97_EXTENDED_ID, eid); | ||
3161 | eid = i810_ac97_get(codec, AC97_EXTENDED_ID); | ||
3162 | printk("i810_audio: AC'97 codec %d, new EID value = 0x%04x\n", ac97_id, eid); | ||
3163 | if (eid & 0x0080) /* L/R Surround channels */ | ||
3164 | total_channels += 2; | ||
3165 | if (eid & 0x0140) /* LFE and Center channels */ | ||
3166 | total_channels += 2; | ||
3167 | printk("i810_audio: AC'97 codec %d, DAC map configured, total channels = %d\n", ac97_id, total_channels); | ||
3168 | } else { | ||
3169 | printk("i810_audio: AC'97 codec %d Unable to map surround DAC's (or DAC's not present), total channels = %d\n", ac97_id, total_channels); | ||
3170 | } | ||
3171 | |||
3172 | if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) { | ||
3173 | printk(KERN_ERR "i810_audio: couldn't register mixer!\n"); | ||
3174 | ac97_release_codec(codec); | ||
3175 | break; | ||
3176 | } | ||
3177 | |||
3178 | card->ac97_codec[num_ac97] = codec; | ||
3179 | } | ||
3180 | |||
3181 | /* tune up the primary codec */ | ||
3182 | ac97_tune_hardware(card->pci_dev, ac97_quirks, ac97_quirk); | ||
3183 | |||
3184 | /* pick the minimum of channels supported by ICHx or codec(s) */ | ||
3185 | card->channels = (card->channels > total_channels)?total_channels:card->channels; | ||
3186 | |||
3187 | return num_ac97; | ||
3188 | } | ||
3189 | |||
3190 | static void __devinit i810_configure_clocking (void) | ||
3191 | { | ||
3192 | struct i810_card *card; | ||
3193 | struct i810_state *state; | ||
3194 | struct dmabuf *dmabuf; | ||
3195 | unsigned int i, offset, new_offset; | ||
3196 | unsigned long flags; | ||
3197 | |||
3198 | card = devs; | ||
3199 | /* We could try to set the clocking for multiple cards, but can you even have | ||
3200 | * more than one i810 in a machine? Besides, clocking is global, so unless | ||
3201 | * someone actually thinks more than one i810 in a machine is possible and | ||
3202 | * decides to rewrite that little bit, setting the rate for more than one card | ||
3203 | * is a waste of time. | ||
3204 | */ | ||
3205 | if(card != NULL) { | ||
3206 | state = card->states[0] = (struct i810_state *) | ||
3207 | kzalloc(sizeof(struct i810_state), GFP_KERNEL); | ||
3208 | if (state == NULL) | ||
3209 | return; | ||
3210 | dmabuf = &state->dmabuf; | ||
3211 | |||
3212 | dmabuf->write_channel = card->alloc_pcm_channel(card); | ||
3213 | state->virt = 0; | ||
3214 | state->card = card; | ||
3215 | state->magic = I810_STATE_MAGIC; | ||
3216 | init_waitqueue_head(&dmabuf->wait); | ||
3217 | mutex_init(&state->open_mutex); | ||
3218 | dmabuf->fmt = I810_FMT_STEREO | I810_FMT_16BIT; | ||
3219 | dmabuf->trigger = PCM_ENABLE_OUTPUT; | ||
3220 | i810_set_spdif_output(state, -1, 0); | ||
3221 | i810_set_dac_channels(state, 2); | ||
3222 | i810_set_dac_rate(state, 48000); | ||
3223 | if(prog_dmabuf(state, 0) != 0) { | ||
3224 | goto config_out_nodmabuf; | ||
3225 | } | ||
3226 | if(dmabuf->dmasize < 16384) { | ||
3227 | goto config_out; | ||
3228 | } | ||
3229 | dmabuf->count = dmabuf->dmasize; | ||
3230 | CIV_TO_LVI(card, dmabuf->write_channel->port, -1); | ||
3231 | local_irq_save(flags); | ||
3232 | start_dac(state); | ||
3233 | offset = i810_get_dma_addr(state, 0); | ||
3234 | mdelay(50); | ||
3235 | new_offset = i810_get_dma_addr(state, 0); | ||
3236 | stop_dac(state); | ||
3237 | local_irq_restore(flags); | ||
3238 | i = new_offset - offset; | ||
3239 | #ifdef DEBUG_INTERRUPTS | ||
3240 | printk("i810_audio: %d bytes in 50 milliseconds\n", i); | ||
3241 | #endif | ||
3242 | if(i == 0) | ||
3243 | goto config_out; | ||
3244 | i = i / 4 * 20; | ||
3245 | if (i > 48500 || i < 47500) { | ||
3246 | clocking = clocking * clocking / i; | ||
3247 | printk("i810_audio: setting clocking to %d\n", clocking); | ||
3248 | } | ||
3249 | config_out: | ||
3250 | dealloc_dmabuf(state); | ||
3251 | config_out_nodmabuf: | ||
3252 | state->card->free_pcm_channel(state->card,state->dmabuf.write_channel->num); | ||
3253 | kfree(state); | ||
3254 | card->states[0] = NULL; | ||
3255 | } | ||
3256 | } | ||
3257 | |||
3258 | /* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered | ||
3259 | until "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */ | ||
3260 | |||
3261 | static int __devinit i810_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) | ||
3262 | { | ||
3263 | struct i810_card *card; | ||
3264 | |||
3265 | if (pci_enable_device(pci_dev)) | ||
3266 | return -EIO; | ||
3267 | |||
3268 | if (pci_set_dma_mask(pci_dev, I810_DMA_MASK)) { | ||
3269 | printk(KERN_ERR "i810_audio: architecture does not support" | ||
3270 | " 32bit PCI busmaster DMA\n"); | ||
3271 | return -ENODEV; | ||
3272 | } | ||
3273 | |||
3274 | if ((card = kzalloc(sizeof(struct i810_card), GFP_KERNEL)) == NULL) { | ||
3275 | printk(KERN_ERR "i810_audio: out of memory\n"); | ||
3276 | return -ENOMEM; | ||
3277 | } | ||
3278 | |||
3279 | card->initializing = 1; | ||
3280 | card->pci_dev = pci_dev; | ||
3281 | card->pci_id = pci_id->device; | ||
3282 | card->ac97base = pci_resource_start (pci_dev, 0); | ||
3283 | card->iobase = pci_resource_start (pci_dev, 1); | ||
3284 | |||
3285 | if (!(card->ac97base) || !(card->iobase)) { | ||
3286 | card->ac97base = 0; | ||
3287 | card->iobase = 0; | ||
3288 | } | ||
3289 | |||
3290 | /* if chipset could have mmio capability, check it */ | ||
3291 | if (card_cap[pci_id->driver_data].flags & CAP_MMIO) { | ||
3292 | card->ac97base_mmio_phys = pci_resource_start (pci_dev, 2); | ||
3293 | card->iobase_mmio_phys = pci_resource_start (pci_dev, 3); | ||
3294 | |||
3295 | if ((card->ac97base_mmio_phys) && (card->iobase_mmio_phys)) { | ||
3296 | card->use_mmio = 1; | ||
3297 | } | ||
3298 | else { | ||
3299 | card->ac97base_mmio_phys = 0; | ||
3300 | card->iobase_mmio_phys = 0; | ||
3301 | } | ||
3302 | } | ||
3303 | |||
3304 | if (!(card->use_mmio) && (!(card->iobase) || !(card->ac97base))) { | ||
3305 | printk(KERN_ERR "i810_audio: No I/O resources available.\n"); | ||
3306 | goto out_mem; | ||
3307 | } | ||
3308 | |||
3309 | card->irq = pci_dev->irq; | ||
3310 | card->next = devs; | ||
3311 | card->magic = I810_CARD_MAGIC; | ||
3312 | #ifdef CONFIG_PM | ||
3313 | card->pm_suspended=0; | ||
3314 | #endif | ||
3315 | spin_lock_init(&card->lock); | ||
3316 | spin_lock_init(&card->ac97_lock); | ||
3317 | devs = card; | ||
3318 | |||
3319 | pci_set_master(pci_dev); | ||
3320 | |||
3321 | printk(KERN_INFO "i810: %s found at IO 0x%04lx and 0x%04lx, " | ||
3322 | "MEM 0x%04lx and 0x%04lx, IRQ %d\n", | ||
3323 | card_names[pci_id->driver_data], | ||
3324 | card->iobase, card->ac97base, | ||
3325 | card->ac97base_mmio_phys, card->iobase_mmio_phys, | ||
3326 | card->irq); | ||
3327 | |||
3328 | card->alloc_pcm_channel = i810_alloc_pcm_channel; | ||
3329 | card->alloc_rec_pcm_channel = i810_alloc_rec_pcm_channel; | ||
3330 | card->alloc_rec_mic_channel = i810_alloc_rec_mic_channel; | ||
3331 | card->free_pcm_channel = i810_free_pcm_channel; | ||
3332 | |||
3333 | if ((card->channel = pci_alloc_consistent(pci_dev, | ||
3334 | sizeof(struct i810_channel)*NR_HW_CH, &card->chandma)) == NULL) { | ||
3335 | printk(KERN_ERR "i810: cannot allocate channel DMA memory\n"); | ||
3336 | goto out_mem; | ||
3337 | } | ||
3338 | |||
3339 | { /* We may dispose of this altogether some time soon, so... */ | ||
3340 | struct i810_channel *cp = card->channel; | ||
3341 | |||
3342 | cp[0].offset = 0; | ||
3343 | cp[0].port = 0x00; | ||
3344 | cp[0].num = 0; | ||
3345 | cp[1].offset = 0; | ||
3346 | cp[1].port = 0x10; | ||
3347 | cp[1].num = 1; | ||
3348 | cp[2].offset = 0; | ||
3349 | cp[2].port = 0x20; | ||
3350 | cp[2].num = 2; | ||
3351 | } | ||
3352 | |||
3353 | /* claim our iospace and irq */ | ||
3354 | if (!request_region(card->iobase, 64, card_names[pci_id->driver_data])) { | ||
3355 | printk(KERN_ERR "i810_audio: unable to allocate region %lx\n", card->iobase); | ||
3356 | goto out_region1; | ||
3357 | } | ||
3358 | if (!request_region(card->ac97base, 256, card_names[pci_id->driver_data])) { | ||
3359 | printk(KERN_ERR "i810_audio: unable to allocate region %lx\n", card->ac97base); | ||
3360 | goto out_region2; | ||
3361 | } | ||
3362 | |||
3363 | if (card->use_mmio) { | ||
3364 | if (request_mem_region(card->ac97base_mmio_phys, 512, "ich_audio MMBAR")) { | ||
3365 | if ((card->ac97base_mmio = ioremap(card->ac97base_mmio_phys, 512))) { /*@FIXME can ioremap fail? don't know (jsaw) */ | ||
3366 | if (request_mem_region(card->iobase_mmio_phys, 256, "ich_audio MBBAR")) { | ||
3367 | if ((card->iobase_mmio = ioremap(card->iobase_mmio_phys, 256))) { | ||
3368 | printk(KERN_INFO "i810: %s mmio at 0x%04lx and 0x%04lx\n", | ||
3369 | card_names[pci_id->driver_data], | ||
3370 | (unsigned long) card->ac97base_mmio, | ||
3371 | (unsigned long) card->iobase_mmio); | ||
3372 | } | ||
3373 | else { | ||
3374 | iounmap(card->ac97base_mmio); | ||
3375 | release_mem_region(card->ac97base_mmio_phys, 512); | ||
3376 | release_mem_region(card->iobase_mmio_phys, 512); | ||
3377 | card->use_mmio = 0; | ||
3378 | } | ||
3379 | } | ||
3380 | else { | ||
3381 | iounmap(card->ac97base_mmio); | ||
3382 | release_mem_region(card->ac97base_mmio_phys, 512); | ||
3383 | card->use_mmio = 0; | ||
3384 | } | ||
3385 | } | ||
3386 | } | ||
3387 | else { | ||
3388 | card->use_mmio = 0; | ||
3389 | } | ||
3390 | } | ||
3391 | |||
3392 | /* initialize AC97 codec and register /dev/mixer */ | ||
3393 | if (i810_ac97_init(card) <= 0) | ||
3394 | goto out_iospace; | ||
3395 | pci_set_drvdata(pci_dev, card); | ||
3396 | |||
3397 | if(clocking == 0) { | ||
3398 | clocking = 48000; | ||
3399 | i810_configure_clocking(); | ||
3400 | } | ||
3401 | |||
3402 | /* register /dev/dsp */ | ||
3403 | if ((card->dev_audio = register_sound_dsp(&i810_audio_fops, -1)) < 0) { | ||
3404 | int i; | ||
3405 | printk(KERN_ERR "i810_audio: couldn't register DSP device!\n"); | ||
3406 | for (i = 0; i < NR_AC97; i++) | ||
3407 | if (card->ac97_codec[i] != NULL) { | ||
3408 | unregister_sound_mixer(card->ac97_codec[i]->dev_mixer); | ||
3409 | ac97_release_codec(card->ac97_codec[i]); | ||
3410 | } | ||
3411 | goto out_iospace; | ||
3412 | } | ||
3413 | |||
3414 | if (request_irq(card->irq, &i810_interrupt, IRQF_SHARED, | ||
3415 | card_names[pci_id->driver_data], card)) { | ||
3416 | printk(KERN_ERR "i810_audio: unable to allocate irq %d\n", card->irq); | ||
3417 | goto out_iospace; | ||
3418 | } | ||
3419 | |||
3420 | |||
3421 | card->initializing = 0; | ||
3422 | return 0; | ||
3423 | |||
3424 | out_iospace: | ||
3425 | if (card->use_mmio) { | ||
3426 | iounmap(card->ac97base_mmio); | ||
3427 | iounmap(card->iobase_mmio); | ||
3428 | release_mem_region(card->ac97base_mmio_phys, 512); | ||
3429 | release_mem_region(card->iobase_mmio_phys, 256); | ||
3430 | } | ||
3431 | release_region(card->ac97base, 256); | ||
3432 | out_region2: | ||
3433 | release_region(card->iobase, 64); | ||
3434 | out_region1: | ||
3435 | pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, | ||
3436 | card->channel, card->chandma); | ||
3437 | out_mem: | ||
3438 | kfree(card); | ||
3439 | return -ENODEV; | ||
3440 | } | ||
3441 | |||
3442 | static void __devexit i810_remove(struct pci_dev *pci_dev) | ||
3443 | { | ||
3444 | int i; | ||
3445 | struct i810_card *card = pci_get_drvdata(pci_dev); | ||
3446 | /* free hardware resources */ | ||
3447 | free_irq(card->irq, devs); | ||
3448 | release_region(card->iobase, 64); | ||
3449 | release_region(card->ac97base, 256); | ||
3450 | pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, | ||
3451 | card->channel, card->chandma); | ||
3452 | if (card->use_mmio) { | ||
3453 | iounmap(card->ac97base_mmio); | ||
3454 | iounmap(card->iobase_mmio); | ||
3455 | release_mem_region(card->ac97base_mmio_phys, 512); | ||
3456 | release_mem_region(card->iobase_mmio_phys, 256); | ||
3457 | } | ||
3458 | |||
3459 | /* unregister audio devices */ | ||
3460 | for (i = 0; i < NR_AC97; i++) | ||
3461 | if (card->ac97_codec[i] != NULL) { | ||
3462 | unregister_sound_mixer(card->ac97_codec[i]->dev_mixer); | ||
3463 | ac97_release_codec(card->ac97_codec[i]); | ||
3464 | card->ac97_codec[i] = NULL; | ||
3465 | } | ||
3466 | unregister_sound_dsp(card->dev_audio); | ||
3467 | kfree(card); | ||
3468 | } | ||
3469 | |||
3470 | #ifdef CONFIG_PM | ||
3471 | static int i810_pm_suspend(struct pci_dev *dev, pm_message_t pm_state) | ||
3472 | { | ||
3473 | struct i810_card *card = pci_get_drvdata(dev); | ||
3474 | struct i810_state *state; | ||
3475 | unsigned long flags; | ||
3476 | struct dmabuf *dmabuf; | ||
3477 | int i,num_ac97; | ||
3478 | #ifdef DEBUG | ||
3479 | printk("i810_audio: i810_pm_suspend called\n"); | ||
3480 | #endif | ||
3481 | if(!card) return 0; | ||
3482 | spin_lock_irqsave(&card->lock, flags); | ||
3483 | card->pm_suspended=1; | ||
3484 | for(i=0;i<NR_HW_CH;i++) { | ||
3485 | state = card->states[i]; | ||
3486 | if(!state) continue; | ||
3487 | /* this happens only if there are open files */ | ||
3488 | dmabuf = &state->dmabuf; | ||
3489 | if(dmabuf->enable & DAC_RUNNING || | ||
3490 | (dmabuf->count && (dmabuf->trigger & PCM_ENABLE_OUTPUT))) { | ||
3491 | state->pm_saved_dac_rate=dmabuf->rate; | ||
3492 | stop_dac(state); | ||
3493 | } else { | ||
3494 | state->pm_saved_dac_rate=0; | ||
3495 | } | ||
3496 | if(dmabuf->enable & ADC_RUNNING) { | ||
3497 | state->pm_saved_adc_rate=dmabuf->rate; | ||
3498 | stop_adc(state); | ||
3499 | } else { | ||
3500 | state->pm_saved_adc_rate=0; | ||
3501 | } | ||
3502 | dmabuf->ready = 0; | ||
3503 | dmabuf->swptr = dmabuf->hwptr = 0; | ||
3504 | dmabuf->count = dmabuf->total_bytes = 0; | ||
3505 | } | ||
3506 | |||
3507 | spin_unlock_irqrestore(&card->lock, flags); | ||
3508 | |||
3509 | /* save mixer settings */ | ||
3510 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { | ||
3511 | struct ac97_codec *codec = card->ac97_codec[num_ac97]; | ||
3512 | if(!codec) continue; | ||
3513 | for(i=0;i< SOUND_MIXER_NRDEVICES ;i++) { | ||
3514 | if((supported_mixer(codec,i)) && | ||
3515 | (codec->read_mixer)) { | ||
3516 | card->pm_saved_mixer_settings[i][num_ac97]= | ||
3517 | codec->read_mixer(codec,i); | ||
3518 | } | ||
3519 | } | ||
3520 | } | ||
3521 | pci_save_state(dev); /* XXX do we need this? */ | ||
3522 | pci_disable_device(dev); /* disable busmastering */ | ||
3523 | pci_set_power_state(dev,3); /* Zzz. */ | ||
3524 | |||
3525 | return 0; | ||
3526 | } | ||
3527 | |||
3528 | |||
3529 | static int i810_pm_resume(struct pci_dev *dev) | ||
3530 | { | ||
3531 | int num_ac97,i=0; | ||
3532 | struct i810_card *card=pci_get_drvdata(dev); | ||
3533 | pci_enable_device(dev); | ||
3534 | pci_restore_state (dev); | ||
3535 | |||
3536 | /* observation of a toshiba portege 3440ct suggests that the | ||
3537 | hardware has to be more or less completely reinitialized from | ||
3538 | scratch after an apm suspend. Works For Me. -dan */ | ||
3539 | |||
3540 | i810_ac97_power_up_bus(card); | ||
3541 | |||
3542 | for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) { | ||
3543 | struct ac97_codec *codec = card->ac97_codec[num_ac97]; | ||
3544 | /* check they haven't stolen the hardware while we were | ||
3545 | away */ | ||
3546 | if(!codec || !i810_ac97_exists(card,num_ac97)) { | ||
3547 | if(num_ac97) continue; | ||
3548 | else BUG(); | ||
3549 | } | ||
3550 | if(!i810_ac97_probe_and_powerup(card,codec)) BUG(); | ||
3551 | |||
3552 | if((card->ac97_features&0x0001)) { | ||
3553 | /* at probe time we found we could do variable | ||
3554 | rates, but APM suspend has made it forget | ||
3555 | its magical powers */ | ||
3556 | if(!i810_ac97_enable_variable_rate(codec)) BUG(); | ||
3557 | } | ||
3558 | /* we lost our mixer settings, so restore them */ | ||
3559 | for(i=0;i< SOUND_MIXER_NRDEVICES ;i++) { | ||
3560 | if(supported_mixer(codec,i)){ | ||
3561 | int val=card-> | ||
3562 | pm_saved_mixer_settings[i][num_ac97]; | ||
3563 | codec->mixer_state[i]=val; | ||
3564 | codec->write_mixer(codec,i, | ||
3565 | (val & 0xff) , | ||
3566 | ((val >> 8) & 0xff) ); | ||
3567 | } | ||
3568 | } | ||
3569 | } | ||
3570 | |||
3571 | /* we need to restore the sample rate from whatever it was */ | ||
3572 | for(i=0;i<NR_HW_CH;i++) { | ||
3573 | struct i810_state * state=card->states[i]; | ||
3574 | if(state) { | ||
3575 | if(state->pm_saved_adc_rate) | ||
3576 | i810_set_adc_rate(state,state->pm_saved_adc_rate); | ||
3577 | if(state->pm_saved_dac_rate) | ||
3578 | i810_set_dac_rate(state,state->pm_saved_dac_rate); | ||
3579 | } | ||
3580 | } | ||
3581 | |||
3582 | |||
3583 | card->pm_suspended = 0; | ||
3584 | |||
3585 | /* any processes that were reading/writing during the suspend | ||
3586 | probably ended up here */ | ||
3587 | for(i=0;i<NR_HW_CH;i++) { | ||
3588 | struct i810_state *state = card->states[i]; | ||
3589 | if(state) wake_up(&state->dmabuf.wait); | ||
3590 | } | ||
3591 | |||
3592 | return 0; | ||
3593 | } | ||
3594 | #endif /* CONFIG_PM */ | ||
3595 | |||
3596 | MODULE_AUTHOR("The Linux kernel team"); | ||
3597 | MODULE_DESCRIPTION("Intel 810 audio support"); | ||
3598 | MODULE_LICENSE("GPL"); | ||
3599 | module_param(ftsodell, int, 0444); | ||
3600 | module_param(clocking, uint, 0444); | ||
3601 | module_param(strict_clocking, int, 0444); | ||
3602 | module_param(spdif_locked, int, 0444); | ||
3603 | |||
3604 | #define I810_MODULE_NAME "i810_audio" | ||
3605 | |||
3606 | static struct pci_driver i810_pci_driver = { | ||
3607 | .name = I810_MODULE_NAME, | ||
3608 | .id_table = i810_pci_tbl, | ||
3609 | .probe = i810_probe, | ||
3610 | .remove = __devexit_p(i810_remove), | ||
3611 | #ifdef CONFIG_PM | ||
3612 | .suspend = i810_pm_suspend, | ||
3613 | .resume = i810_pm_resume, | ||
3614 | #endif /* CONFIG_PM */ | ||
3615 | }; | ||
3616 | |||
3617 | |||
3618 | static int __init i810_init_module (void) | ||
3619 | { | ||
3620 | int retval; | ||
3621 | |||
3622 | printk(KERN_INFO "Intel 810 + AC97 Audio, version " | ||
3623 | DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n"); | ||
3624 | |||
3625 | retval = pci_register_driver(&i810_pci_driver); | ||
3626 | if (retval) | ||
3627 | return retval; | ||
3628 | |||
3629 | if(ftsodell != 0) { | ||
3630 | printk("i810_audio: ftsodell is now a deprecated option.\n"); | ||
3631 | } | ||
3632 | if(spdif_locked > 0 ) { | ||
3633 | if(spdif_locked == 32000 || spdif_locked == 44100 || spdif_locked == 48000) { | ||
3634 | printk("i810_audio: Enabling S/PDIF at sample rate %dHz.\n", spdif_locked); | ||
3635 | } else { | ||
3636 | printk("i810_audio: S/PDIF can only be locked to 32000, 44100, or 48000Hz.\n"); | ||
3637 | spdif_locked = 0; | ||
3638 | } | ||
3639 | } | ||
3640 | |||
3641 | return 0; | ||
3642 | } | ||
3643 | |||
3644 | static void __exit i810_cleanup_module (void) | ||
3645 | { | ||
3646 | pci_unregister_driver(&i810_pci_driver); | ||
3647 | } | ||
3648 | |||
3649 | module_init(i810_init_module); | ||
3650 | module_exit(i810_cleanup_module); | ||
3651 | |||
3652 | /* | ||
3653 | Local Variables: | ||
3654 | c-basic-offset: 8 | ||
3655 | End: | ||
3656 | */ | ||
diff --git a/sound/oss/pss.c b/sound/oss/pss.c index ece428b2ba9f..16ed06950dc1 100644 --- a/sound/oss/pss.c +++ b/sound/oss/pss.c | |||
@@ -232,14 +232,12 @@ static int set_irq(pss_confdata * devc, int dev, int irq) | |||
232 | return 1; | 232 | return 1; |
233 | } | 233 | } |
234 | 234 | ||
235 | static int set_io_base(pss_confdata * devc, int dev, int base) | 235 | static void set_io_base(pss_confdata * devc, int dev, int base) |
236 | { | 236 | { |
237 | unsigned short tmp = inw(REG(dev)) & 0x003f; | 237 | unsigned short tmp = inw(REG(dev)) & 0x003f; |
238 | unsigned short bits = (base & 0x0ffc) << 4; | 238 | unsigned short bits = (base & 0x0ffc) << 4; |
239 | 239 | ||
240 | outw(bits | tmp, REG(dev)); | 240 | outw(bits | tmp, REG(dev)); |
241 | |||
242 | return 1; | ||
243 | } | 241 | } |
244 | 242 | ||
245 | static int set_dma(pss_confdata * devc, int dev, int dma) | 243 | static int set_dma(pss_confdata * devc, int dev, int dma) |
@@ -673,20 +671,12 @@ static void configure_nonsound_components(void) | |||
673 | 671 | ||
674 | /* Configure CDROM port */ | 672 | /* Configure CDROM port */ |
675 | 673 | ||
676 | if(pss_cdrom_port == -1) /* If cdrom port enablation wasn't requested */ | 674 | if (pss_cdrom_port == -1) { /* If cdrom port enablation wasn't requested */ |
677 | { | ||
678 | printk(KERN_INFO "PSS: CDROM port not enabled.\n"); | 675 | printk(KERN_INFO "PSS: CDROM port not enabled.\n"); |
679 | } | 676 | } else if (check_region(pss_cdrom_port, 2)) { |
680 | else if(check_region(pss_cdrom_port, 2)) | ||
681 | { | ||
682 | printk(KERN_ERR "PSS: CDROM I/O port conflict.\n"); | 677 | printk(KERN_ERR "PSS: CDROM I/O port conflict.\n"); |
683 | } | 678 | } else { |
684 | else if(!set_io_base(devc, CONF_CDROM, pss_cdrom_port)) | 679 | set_io_base(devc, CONF_CDROM, pss_cdrom_port); |
685 | { | ||
686 | printk(KERN_ERR "PSS: CDROM I/O port could not be set.\n"); | ||
687 | } | ||
688 | else /* CDROM port successfully configured */ | ||
689 | { | ||
690 | printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port); | 680 | printk(KERN_INFO "PSS: CDROM I/O port set to 0x%x.\n", pss_cdrom_port); |
691 | } | 681 | } |
692 | } | 682 | } |
@@ -758,10 +748,7 @@ static int __init probe_pss_mpu(struct address_info *hw_config) | |||
758 | printk(KERN_ERR "PSS: MPU I/O port conflict\n"); | 748 | printk(KERN_ERR "PSS: MPU I/O port conflict\n"); |
759 | return 0; | 749 | return 0; |
760 | } | 750 | } |
761 | if (!set_io_base(devc, CONF_MIDI, hw_config->io_base)) { | 751 | set_io_base(devc, CONF_MIDI, hw_config->io_base); |
762 | printk(KERN_ERR "PSS: MIDI base could not be set.\n"); | ||
763 | goto fail; | ||
764 | } | ||
765 | if (!set_irq(devc, CONF_MIDI, hw_config->irq)) { | 752 | if (!set_irq(devc, CONF_MIDI, hw_config->irq)) { |
766 | printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n"); | 753 | printk(KERN_ERR "PSS: MIDI IRQ allocation error.\n"); |
767 | goto fail; | 754 | goto fail; |
@@ -1057,10 +1044,7 @@ static int __init probe_pss_mss(struct address_info *hw_config) | |||
1057 | release_region(hw_config->io_base, 4); | 1044 | release_region(hw_config->io_base, 4); |
1058 | return 0; | 1045 | return 0; |
1059 | } | 1046 | } |
1060 | if (!set_io_base(devc, CONF_WSS, hw_config->io_base)) { | 1047 | set_io_base(devc, CONF_WSS, hw_config->io_base); |
1061 | printk("PSS: WSS base not settable.\n"); | ||
1062 | goto fail; | ||
1063 | } | ||
1064 | if (!set_irq(devc, CONF_WSS, hw_config->irq)) { | 1048 | if (!set_irq(devc, CONF_WSS, hw_config->irq)) { |
1065 | printk("PSS: WSS IRQ allocation error.\n"); | 1049 | printk("PSS: WSS IRQ allocation error.\n"); |
1066 | goto fail; | 1050 | goto fail; |
diff --git a/sound/oss/sb_common.c b/sound/oss/sb_common.c index 07cbacf63824..77d0e5efda76 100644 --- a/sound/oss/sb_common.c +++ b/sound/oss/sb_common.c | |||
@@ -1228,7 +1228,8 @@ int probe_sbmpu(struct address_info *hw_config, struct module *owner) | |||
1228 | } | 1228 | } |
1229 | attach_mpu401(hw_config, owner); | 1229 | attach_mpu401(hw_config, owner); |
1230 | if (last_sb->irq == -hw_config->irq) | 1230 | if (last_sb->irq == -hw_config->irq) |
1231 | last_sb->midi_irq_cookie=(void *)hw_config->slots[1]; | 1231 | last_sb->midi_irq_cookie = |
1232 | (void *)(long) hw_config->slots[1]; | ||
1232 | return 1; | 1233 | return 1; |
1233 | } | 1234 | } |
1234 | #endif | 1235 | #endif |
diff --git a/sound/oss/trident.c b/sound/oss/trident.c index 96adc47917aa..6959ee1bd17f 100644 --- a/sound/oss/trident.c +++ b/sound/oss/trident.c | |||
@@ -2935,7 +2935,7 @@ trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val) | |||
2935 | do { | 2935 | do { |
2936 | if ((inw(TRID_REG(card, address)) & busy) == 0) | 2936 | if ((inw(TRID_REG(card, address)) & busy) == 0) |
2937 | break; | 2937 | break; |
2938 | } while (count--); | 2938 | } while (--count); |
2939 | 2939 | ||
2940 | data |= (mask | (reg & AC97_REG_ADDR)); | 2940 | data |= (mask | (reg & AC97_REG_ADDR)); |
2941 | 2941 | ||
@@ -2996,7 +2996,7 @@ trident_ac97_get(struct ac97_codec *codec, u8 reg) | |||
2996 | data = inl(TRID_REG(card, address)); | 2996 | data = inl(TRID_REG(card, address)); |
2997 | if ((data & busy) == 0) | 2997 | if ((data & busy) == 0) |
2998 | break; | 2998 | break; |
2999 | } while (count--); | 2999 | } while (--count); |
3000 | spin_unlock_irqrestore(&card->lock, flags); | 3000 | spin_unlock_irqrestore(&card->lock, flags); |
3001 | 3001 | ||
3002 | if (count == 0) { | 3002 | if (count == 0) { |
diff --git a/sound/oss/via82cxxx_audio.c b/sound/oss/via82cxxx_audio.c deleted file mode 100644 index f95aa0946758..000000000000 --- a/sound/oss/via82cxxx_audio.c +++ /dev/null | |||
@@ -1,3616 +0,0 @@ | |||
1 | /* | ||
2 | * Support for VIA 82Cxxx Audio Codecs | ||
3 | * Copyright 1999,2000 Jeff Garzik | ||
4 | * | ||
5 | * Updated to support the VIA 8233/8235 audio subsystem | ||
6 | * Alan Cox <alan@redhat.com> (C) Copyright 2002, 2003 Red Hat Inc | ||
7 | * | ||
8 | * Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2. | ||
9 | * See the "COPYING" file distributed with this software for more info. | ||
10 | * NO WARRANTY | ||
11 | * | ||
12 | * For a list of known bugs (errata) and documentation, | ||
13 | * see via-audio.pdf in Documentation/DocBook. | ||
14 | * If this documentation does not exist, run "make pdfdocs". | ||
15 | */ | ||
16 | |||
17 | |||
18 | #define VIA_VERSION "1.9.1-ac4-2.5" | ||
19 | |||
20 | |||
21 | #include <linux/module.h> | ||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/fs.h> | ||
24 | #include <linux/mm.h> | ||
25 | #include <linux/pci.h> | ||
26 | #include <linux/poison.h> | ||
27 | #include <linux/init.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/proc_fs.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/sound.h> | ||
32 | #include <linux/poll.h> | ||
33 | #include <linux/soundcard.h> | ||
34 | #include <linux/ac97_codec.h> | ||
35 | #include <linux/ioport.h> | ||
36 | #include <linux/delay.h> | ||
37 | #include <linux/dma-mapping.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | #include <linux/mutex.h> | ||
41 | |||
42 | #include "sound_config.h" | ||
43 | #include "dev_table.h" | ||
44 | #include "mpu401.h" | ||
45 | |||
46 | |||
47 | #undef VIA_DEBUG /* define to enable debugging output and checks */ | ||
48 | #ifdef VIA_DEBUG | ||
49 | /* note: prints function name for you */ | ||
50 | #define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) | ||
51 | #else | ||
52 | #define DPRINTK(fmt, args...) | ||
53 | #endif | ||
54 | |||
55 | #undef VIA_NDEBUG /* define to disable lightweight runtime checks */ | ||
56 | #ifdef VIA_NDEBUG | ||
57 | #define assert(expr) | ||
58 | #else | ||
59 | #define assert(expr) \ | ||
60 | if(!(expr)) { \ | ||
61 | printk( "Assertion failed! %s,%s,%s,line=%d\n", \ | ||
62 | #expr,__FILE__,__FUNCTION__,__LINE__); \ | ||
63 | } | ||
64 | #endif | ||
65 | |||
66 | #define VIA_SUPPORT_MMAP 1 /* buggy, for now... */ | ||
67 | |||
68 | #define MAX_CARDS 1 | ||
69 | |||
70 | #define VIA_CARD_NAME "VIA 82Cxxx Audio driver " VIA_VERSION | ||
71 | #define VIA_MODULE_NAME "via82cxxx" | ||
72 | #define PFX VIA_MODULE_NAME ": " | ||
73 | |||
74 | #define VIA_COUNTER_LIMIT 100000 | ||
75 | |||
76 | /* size of DMA buffers */ | ||
77 | #define VIA_MAX_BUFFER_DMA_PAGES 32 | ||
78 | |||
79 | /* buffering default values in ms */ | ||
80 | #define VIA_DEFAULT_FRAG_TIME 20 | ||
81 | #define VIA_DEFAULT_BUFFER_TIME 500 | ||
82 | |||
83 | /* the hardware has a 256 fragment limit */ | ||
84 | #define VIA_MIN_FRAG_NUMBER 2 | ||
85 | #define VIA_MAX_FRAG_NUMBER 128 | ||
86 | |||
87 | #define VIA_MAX_FRAG_SIZE PAGE_SIZE | ||
88 | #define VIA_MIN_FRAG_SIZE (VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE / VIA_MAX_FRAG_NUMBER) | ||
89 | |||
90 | |||
91 | /* 82C686 function 5 (audio codec) PCI configuration registers */ | ||
92 | #define VIA_ACLINK_STATUS 0x40 | ||
93 | #define VIA_ACLINK_CTRL 0x41 | ||
94 | #define VIA_FUNC_ENABLE 0x42 | ||
95 | #define VIA_PNP_CONTROL 0x43 | ||
96 | #define VIA_FM_NMI_CTRL 0x48 | ||
97 | |||
98 | /* | ||
99 | * controller base 0 (scatter-gather) registers | ||
100 | * | ||
101 | * NOTE: Via datasheet lists first channel as "read" | ||
102 | * channel and second channel as "write" channel. | ||
103 | * I changed the naming of the constants to be more | ||
104 | * clear than I felt the datasheet to be. | ||
105 | */ | ||
106 | |||
107 | #define VIA_BASE0_PCM_OUT_CHAN 0x00 /* output PCM to user */ | ||
108 | #define VIA_BASE0_PCM_OUT_CHAN_STATUS 0x00 | ||
109 | #define VIA_BASE0_PCM_OUT_CHAN_CTRL 0x01 | ||
110 | #define VIA_BASE0_PCM_OUT_CHAN_TYPE 0x02 | ||
111 | |||
112 | #define VIA_BASE0_PCM_IN_CHAN 0x10 /* input PCM from user */ | ||
113 | #define VIA_BASE0_PCM_IN_CHAN_STATUS 0x10 | ||
114 | #define VIA_BASE0_PCM_IN_CHAN_CTRL 0x11 | ||
115 | #define VIA_BASE0_PCM_IN_CHAN_TYPE 0x12 | ||
116 | |||
117 | /* offsets from base */ | ||
118 | #define VIA_PCM_STATUS 0x00 | ||
119 | #define VIA_PCM_CONTROL 0x01 | ||
120 | #define VIA_PCM_TYPE 0x02 | ||
121 | #define VIA_PCM_LEFTVOL 0x02 | ||
122 | #define VIA_PCM_RIGHTVOL 0x03 | ||
123 | #define VIA_PCM_TABLE_ADDR 0x04 | ||
124 | #define VIA_PCM_STOPRATE 0x08 /* 8233+ */ | ||
125 | #define VIA_PCM_BLOCK_COUNT 0x0C | ||
126 | |||
127 | /* XXX unused DMA channel for FM PCM data */ | ||
128 | #define VIA_BASE0_FM_OUT_CHAN 0x20 | ||
129 | #define VIA_BASE0_FM_OUT_CHAN_STATUS 0x20 | ||
130 | #define VIA_BASE0_FM_OUT_CHAN_CTRL 0x21 | ||
131 | #define VIA_BASE0_FM_OUT_CHAN_TYPE 0x22 | ||
132 | |||
133 | /* Six channel audio output on 8233 */ | ||
134 | #define VIA_BASE0_MULTI_OUT_CHAN 0x40 | ||
135 | #define VIA_BASE0_MULTI_OUT_CHAN_STATUS 0x40 | ||
136 | #define VIA_BASE0_MULTI_OUT_CHAN_CTRL 0x41 | ||
137 | #define VIA_BASE0_MULTI_OUT_CHAN_TYPE 0x42 | ||
138 | |||
139 | #define VIA_BASE0_AC97_CTRL 0x80 | ||
140 | #define VIA_BASE0_SGD_STATUS_SHADOW 0x84 | ||
141 | #define VIA_BASE0_GPI_INT_ENABLE 0x8C | ||
142 | #define VIA_INTR_OUT ((1<<0) | (1<<4) | (1<<8)) | ||
143 | #define VIA_INTR_IN ((1<<1) | (1<<5) | (1<<9)) | ||
144 | #define VIA_INTR_FM ((1<<2) | (1<<6) | (1<<10)) | ||
145 | #define VIA_INTR_MASK (VIA_INTR_OUT | VIA_INTR_IN | VIA_INTR_FM) | ||
146 | |||
147 | /* Newer VIA we need to monitor the low 3 bits of each channel. This | ||
148 | mask covers the channels we don't yet use as well | ||
149 | */ | ||
150 | |||
151 | #define VIA_NEW_INTR_MASK 0x77077777UL | ||
152 | |||
153 | /* VIA_BASE0_AUDIO_xxx_CHAN_TYPE bits */ | ||
154 | #define VIA_IRQ_ON_FLAG (1<<0) /* int on each flagged scatter block */ | ||
155 | #define VIA_IRQ_ON_EOL (1<<1) /* int at end of scatter list */ | ||
156 | #define VIA_INT_SEL_PCI_LAST_LINE_READ (0) /* int at PCI read of last line */ | ||
157 | #define VIA_INT_SEL_LAST_SAMPLE_SENT (1<<2) /* int at last sample sent */ | ||
158 | #define VIA_INT_SEL_ONE_LINE_LEFT (1<<3) /* int at less than one line to send */ | ||
159 | #define VIA_PCM_FMT_STEREO (1<<4) /* PCM stereo format (bit clear == mono) */ | ||
160 | #define VIA_PCM_FMT_16BIT (1<<5) /* PCM 16-bit format (bit clear == 8-bit) */ | ||
161 | #define VIA_PCM_REC_FIFO (1<<6) /* PCM Recording FIFO */ | ||
162 | #define VIA_RESTART_SGD_ON_EOL (1<<7) /* restart scatter-gather at EOL */ | ||
163 | #define VIA_PCM_FMT_MASK (VIA_PCM_FMT_STEREO|VIA_PCM_FMT_16BIT) | ||
164 | #define VIA_CHAN_TYPE_MASK (VIA_RESTART_SGD_ON_EOL | \ | ||
165 | VIA_IRQ_ON_FLAG | \ | ||
166 | VIA_IRQ_ON_EOL) | ||
167 | #define VIA_CHAN_TYPE_INT_SELECT (VIA_INT_SEL_LAST_SAMPLE_SENT) | ||
168 | |||
169 | /* PCI configuration register bits and masks */ | ||
170 | #define VIA_CR40_AC97_READY 0x01 | ||
171 | #define VIA_CR40_AC97_LOW_POWER 0x02 | ||
172 | #define VIA_CR40_SECONDARY_READY 0x04 | ||
173 | |||
174 | #define VIA_CR41_AC97_ENABLE 0x80 /* enable AC97 codec */ | ||
175 | #define VIA_CR41_AC97_RESET 0x40 /* clear bit to reset AC97 */ | ||
176 | #define VIA_CR41_AC97_WAKEUP 0x20 /* wake up from power-down mode */ | ||
177 | #define VIA_CR41_AC97_SDO 0x10 /* force Serial Data Out (SDO) high */ | ||
178 | #define VIA_CR41_VRA 0x08 /* enable variable sample rate */ | ||
179 | #define VIA_CR41_PCM_ENABLE 0x04 /* AC Link SGD Read Channel PCM Data Output */ | ||
180 | #define VIA_CR41_FM_PCM_ENABLE 0x02 /* AC Link FM Channel PCM Data Out */ | ||
181 | #define VIA_CR41_SB_PCM_ENABLE 0x01 /* AC Link SB PCM Data Output */ | ||
182 | #define VIA_CR41_BOOT_MASK (VIA_CR41_AC97_ENABLE | \ | ||
183 | VIA_CR41_AC97_WAKEUP | \ | ||
184 | VIA_CR41_AC97_SDO) | ||
185 | #define VIA_CR41_RUN_MASK (VIA_CR41_AC97_ENABLE | \ | ||
186 | VIA_CR41_AC97_RESET | \ | ||
187 | VIA_CR41_VRA | \ | ||
188 | VIA_CR41_PCM_ENABLE) | ||
189 | |||
190 | #define VIA_CR42_SB_ENABLE 0x01 | ||
191 | #define VIA_CR42_MIDI_ENABLE 0x02 | ||
192 | #define VIA_CR42_FM_ENABLE 0x04 | ||
193 | #define VIA_CR42_GAME_ENABLE 0x08 | ||
194 | #define VIA_CR42_MIDI_IRQMASK 0x40 | ||
195 | #define VIA_CR42_MIDI_PNP 0x80 | ||
196 | |||
197 | #define VIA_CR44_SECOND_CODEC_SUPPORT (1 << 6) | ||
198 | #define VIA_CR44_AC_LINK_ACCESS (1 << 7) | ||
199 | |||
200 | #define VIA_CR48_FM_TRAP_TO_NMI (1 << 2) | ||
201 | |||
202 | /* controller base 0 register bitmasks */ | ||
203 | #define VIA_INT_DISABLE_MASK (~(0x01|0x02)) | ||
204 | #define VIA_SGD_STOPPED (1 << 2) | ||
205 | #define VIA_SGD_PAUSED (1 << 6) | ||
206 | #define VIA_SGD_ACTIVE (1 << 7) | ||
207 | #define VIA_SGD_TERMINATE (1 << 6) | ||
208 | #define VIA_SGD_FLAG (1 << 0) | ||
209 | #define VIA_SGD_EOL (1 << 1) | ||
210 | #define VIA_SGD_START (1 << 7) | ||
211 | |||
212 | #define VIA_CR80_FIRST_CODEC 0 | ||
213 | #define VIA_CR80_SECOND_CODEC (1 << 30) | ||
214 | #define VIA_CR80_FIRST_CODEC_VALID (1 << 25) | ||
215 | #define VIA_CR80_VALID (1 << 25) | ||
216 | #define VIA_CR80_SECOND_CODEC_VALID (1 << 27) | ||
217 | #define VIA_CR80_BUSY (1 << 24) | ||
218 | #define VIA_CR83_BUSY (1) | ||
219 | #define VIA_CR83_FIRST_CODEC_VALID (1 << 1) | ||
220 | #define VIA_CR80_READ (1 << 23) | ||
221 | #define VIA_CR80_WRITE_MODE 0 | ||
222 | #define VIA_CR80_REG_IDX(idx) ((((idx) & 0xFF) >> 1) << 16) | ||
223 | |||
224 | /* capabilities we announce */ | ||
225 | #ifdef VIA_SUPPORT_MMAP | ||
226 | #define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | DSP_CAP_MMAP | \ | ||
227 | DSP_CAP_TRIGGER | DSP_CAP_REALTIME) | ||
228 | #else | ||
229 | #define VIA_DSP_CAP (DSP_CAP_REVISION | DSP_CAP_DUPLEX | \ | ||
230 | DSP_CAP_TRIGGER | DSP_CAP_REALTIME) | ||
231 | #endif | ||
232 | |||
233 | /* scatter-gather DMA table entry, exactly as passed to hardware */ | ||
234 | struct via_sgd_table { | ||
235 | u32 addr; | ||
236 | u32 count; /* includes additional VIA_xxx bits also */ | ||
237 | }; | ||
238 | |||
239 | #define VIA_EOL (1 << 31) | ||
240 | #define VIA_FLAG (1 << 30) | ||
241 | #define VIA_STOP (1 << 29) | ||
242 | |||
243 | |||
244 | enum via_channel_states { | ||
245 | sgd_stopped = 0, | ||
246 | sgd_in_progress = 1, | ||
247 | }; | ||
248 | |||
249 | |||
250 | struct via_buffer_pgtbl { | ||
251 | dma_addr_t handle; | ||
252 | void *cpuaddr; | ||
253 | }; | ||
254 | |||
255 | |||
256 | struct via_channel { | ||
257 | atomic_t n_frags; | ||
258 | atomic_t hw_ptr; | ||
259 | wait_queue_head_t wait; | ||
260 | |||
261 | unsigned int sw_ptr; | ||
262 | unsigned int slop_len; | ||
263 | unsigned int n_irqs; | ||
264 | int bytes; | ||
265 | |||
266 | unsigned is_active : 1; | ||
267 | unsigned is_record : 1; | ||
268 | unsigned is_mapped : 1; | ||
269 | unsigned is_enabled : 1; | ||
270 | unsigned is_multi: 1; /* 8233 6 channel */ | ||
271 | u8 pcm_fmt; /* VIA_PCM_FMT_xxx */ | ||
272 | u8 channels; /* Channel count */ | ||
273 | |||
274 | unsigned rate; /* sample rate */ | ||
275 | unsigned int frag_size; | ||
276 | unsigned int frag_number; | ||
277 | |||
278 | unsigned char intmask; | ||
279 | |||
280 | volatile struct via_sgd_table *sgtable; | ||
281 | dma_addr_t sgt_handle; | ||
282 | |||
283 | unsigned int page_number; | ||
284 | struct via_buffer_pgtbl pgtbl[VIA_MAX_BUFFER_DMA_PAGES]; | ||
285 | |||
286 | long iobase; | ||
287 | |||
288 | const char *name; | ||
289 | }; | ||
290 | |||
291 | |||
292 | /* data stored for each chip */ | ||
293 | struct via_info { | ||
294 | struct pci_dev *pdev; | ||
295 | long baseaddr; | ||
296 | |||
297 | struct ac97_codec *ac97; | ||
298 | spinlock_t ac97_lock; | ||
299 | spinlock_t lock; | ||
300 | int card_num; /* unique card number, from 0 */ | ||
301 | |||
302 | int dev_dsp; /* /dev/dsp index from register_sound_dsp() */ | ||
303 | |||
304 | unsigned rev_h : 1; | ||
305 | unsigned legacy: 1; /* Has legacy ports */ | ||
306 | unsigned intmask: 1; /* Needs int bits */ | ||
307 | unsigned sixchannel: 1; /* 8233/35 with 6 channel support */ | ||
308 | unsigned volume: 1; | ||
309 | |||
310 | unsigned locked_rate : 1; | ||
311 | |||
312 | int mixer_vol; /* 8233/35 volume - not yet implemented */ | ||
313 | |||
314 | struct mutex syscall_mutex; | ||
315 | struct mutex open_mutex; | ||
316 | |||
317 | /* The 8233/8235 have 4 DX audio channels, two record and | ||
318 | one six channel out. We bind ch_in to DX 1, ch_out to multichannel | ||
319 | and ch_fm to DX 2. DX 3 and REC0/REC1 are unused at the | ||
320 | moment */ | ||
321 | |||
322 | struct via_channel ch_in; | ||
323 | struct via_channel ch_out; | ||
324 | struct via_channel ch_fm; | ||
325 | |||
326 | #ifdef CONFIG_MIDI_VIA82CXXX | ||
327 | void *midi_devc; | ||
328 | struct address_info midi_info; | ||
329 | #endif | ||
330 | }; | ||
331 | |||
332 | |||
333 | /* number of cards, used for assigning unique numbers to cards */ | ||
334 | static unsigned via_num_cards; | ||
335 | |||
336 | |||
337 | |||
338 | /**************************************************************** | ||
339 | * | ||
340 | * prototypes | ||
341 | * | ||
342 | * | ||
343 | */ | ||
344 | |||
345 | static int via_init_one (struct pci_dev *dev, const struct pci_device_id *id); | ||
346 | static void __devexit via_remove_one (struct pci_dev *pdev); | ||
347 | |||
348 | static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos); | ||
349 | static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos); | ||
350 | static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wait); | ||
351 | static int via_dsp_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg); | ||
352 | static int via_dsp_open (struct inode *inode, struct file *file); | ||
353 | static int via_dsp_release(struct inode *inode, struct file *file); | ||
354 | static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma); | ||
355 | |||
356 | static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg); | ||
357 | static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value); | ||
358 | static u8 via_ac97_wait_idle (struct via_info *card); | ||
359 | |||
360 | static void via_chan_free (struct via_info *card, struct via_channel *chan); | ||
361 | static void via_chan_clear (struct via_info *card, struct via_channel *chan); | ||
362 | static void via_chan_pcm_fmt (struct via_channel *chan, int reset); | ||
363 | static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan); | ||
364 | |||
365 | |||
366 | /**************************************************************** | ||
367 | * | ||
368 | * Various data the driver needs | ||
369 | * | ||
370 | * | ||
371 | */ | ||
372 | |||
373 | |||
374 | static struct pci_device_id via_pci_tbl[] = { | ||
375 | { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_5, | ||
376 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
377 | { PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8233_5, | ||
378 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | ||
379 | { 0, } | ||
380 | }; | ||
381 | MODULE_DEVICE_TABLE(pci,via_pci_tbl); | ||
382 | |||
383 | |||
384 | static struct pci_driver via_driver = { | ||
385 | .name = VIA_MODULE_NAME, | ||
386 | .id_table = via_pci_tbl, | ||
387 | .probe = via_init_one, | ||
388 | .remove = __devexit_p(via_remove_one), | ||
389 | }; | ||
390 | |||
391 | |||
392 | /**************************************************************** | ||
393 | * | ||
394 | * Low-level base 0 register read/write helpers | ||
395 | * | ||
396 | * | ||
397 | */ | ||
398 | |||
399 | /** | ||
400 | * via_chan_stop - Terminate DMA on specified PCM channel | ||
401 | * @iobase: PCI base address for SGD channel registers | ||
402 | * | ||
403 | * Terminate scatter-gather DMA operation for given | ||
404 | * channel (derived from @iobase), if DMA is active. | ||
405 | * | ||
406 | * Note that @iobase is not the PCI base address, | ||
407 | * but the PCI base address plus an offset to | ||
408 | * one of three PCM channels supported by the chip. | ||
409 | * | ||
410 | */ | ||
411 | |||
412 | static inline void via_chan_stop (long iobase) | ||
413 | { | ||
414 | if (inb (iobase + VIA_PCM_STATUS) & VIA_SGD_ACTIVE) | ||
415 | outb (VIA_SGD_TERMINATE, iobase + VIA_PCM_CONTROL); | ||
416 | } | ||
417 | |||
418 | |||
419 | /** | ||
420 | * via_chan_status_clear - Clear status flags on specified DMA channel | ||
421 | * @iobase: PCI base address for SGD channel registers | ||
422 | * | ||
423 | * Clear any pending status flags for the given | ||
424 | * DMA channel (derived from @iobase), if any | ||
425 | * flags are asserted. | ||
426 | * | ||
427 | * Note that @iobase is not the PCI base address, | ||
428 | * but the PCI base address plus an offset to | ||
429 | * one of three PCM channels supported by the chip. | ||
430 | * | ||
431 | */ | ||
432 | |||
433 | static inline void via_chan_status_clear (long iobase) | ||
434 | { | ||
435 | u8 tmp = inb (iobase + VIA_PCM_STATUS); | ||
436 | |||
437 | if (tmp != 0) | ||
438 | outb (tmp, iobase + VIA_PCM_STATUS); | ||
439 | } | ||
440 | |||
441 | |||
442 | /** | ||
443 | * sg_begin - Begin recording or playback on a PCM channel | ||
444 | * @chan: Channel for which DMA operation shall begin | ||
445 | * | ||
446 | * Start scatter-gather DMA for the given channel. | ||
447 | * | ||
448 | */ | ||
449 | |||
450 | static inline void sg_begin (struct via_channel *chan) | ||
451 | { | ||
452 | DPRINTK("Start with intmask %d\n", chan->intmask); | ||
453 | DPRINTK("About to start from %d to %d\n", | ||
454 | inl(chan->iobase + VIA_PCM_BLOCK_COUNT), | ||
455 | inb(chan->iobase + VIA_PCM_STOPRATE + 3)); | ||
456 | outb (VIA_SGD_START|chan->intmask, chan->iobase + VIA_PCM_CONTROL); | ||
457 | DPRINTK("Status is now %02X\n", inb(chan->iobase + VIA_PCM_STATUS)); | ||
458 | DPRINTK("Control is now %02X\n", inb(chan->iobase + VIA_PCM_CONTROL)); | ||
459 | } | ||
460 | |||
461 | |||
462 | static int sg_active (long iobase) | ||
463 | { | ||
464 | u8 tmp = inb (iobase + VIA_PCM_STATUS); | ||
465 | if ((tmp & VIA_SGD_STOPPED) || (tmp & VIA_SGD_PAUSED)) { | ||
466 | printk(KERN_WARNING "via82cxxx warning: SG stopped or paused\n"); | ||
467 | return 0; | ||
468 | } | ||
469 | if (tmp & VIA_SGD_ACTIVE) | ||
470 | return 1; | ||
471 | return 0; | ||
472 | } | ||
473 | |||
474 | static int via_sg_offset(struct via_channel *chan) | ||
475 | { | ||
476 | return inl (chan->iobase + VIA_PCM_BLOCK_COUNT) & 0x00FFFFFF; | ||
477 | } | ||
478 | |||
479 | /**************************************************************** | ||
480 | * | ||
481 | * Miscellaneous debris | ||
482 | * | ||
483 | * | ||
484 | */ | ||
485 | |||
486 | |||
487 | /** | ||
488 | * via_syscall_down - down the card-specific syscell semaphore | ||
489 | * @card: Private info for specified board | ||
490 | * @nonblock: boolean, non-zero if O_NONBLOCK is set | ||
491 | * | ||
492 | * Encapsulates standard method of acquiring the syscall sem. | ||
493 | * | ||
494 | * Returns negative errno on error, or zero for success. | ||
495 | */ | ||
496 | |||
497 | static inline int via_syscall_down (struct via_info *card, int nonblock) | ||
498 | { | ||
499 | /* Thomas Sailer: | ||
500 | * EAGAIN is supposed to be used if IO is pending, | ||
501 | * not if there is contention on some internal | ||
502 | * synchronization primitive which should be | ||
503 | * held only for a short time anyway | ||
504 | */ | ||
505 | nonblock = 0; | ||
506 | |||
507 | if (nonblock) { | ||
508 | if (!mutex_trylock(&card->syscall_mutex)) | ||
509 | return -EAGAIN; | ||
510 | } else { | ||
511 | if (mutex_lock_interruptible(&card->syscall_mutex)) | ||
512 | return -ERESTARTSYS; | ||
513 | } | ||
514 | |||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | |||
519 | /** | ||
520 | * via_stop_everything - Stop all audio operations | ||
521 | * @card: Private info for specified board | ||
522 | * | ||
523 | * Stops all DMA operations and interrupts, and clear | ||
524 | * any pending status bits resulting from those operations. | ||
525 | */ | ||
526 | |||
527 | static void via_stop_everything (struct via_info *card) | ||
528 | { | ||
529 | u8 tmp, new_tmp; | ||
530 | |||
531 | DPRINTK ("ENTER\n"); | ||
532 | |||
533 | assert (card != NULL); | ||
534 | |||
535 | /* | ||
536 | * terminate any existing operations on audio read/write channels | ||
537 | */ | ||
538 | via_chan_stop (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN); | ||
539 | via_chan_stop (card->baseaddr + VIA_BASE0_PCM_IN_CHAN); | ||
540 | via_chan_stop (card->baseaddr + VIA_BASE0_FM_OUT_CHAN); | ||
541 | if(card->sixchannel) | ||
542 | via_chan_stop (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN); | ||
543 | |||
544 | /* | ||
545 | * clear any existing stops / flags (sanity check mainly) | ||
546 | */ | ||
547 | via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN); | ||
548 | via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_IN_CHAN); | ||
549 | via_chan_status_clear (card->baseaddr + VIA_BASE0_FM_OUT_CHAN); | ||
550 | if(card->sixchannel) | ||
551 | via_chan_status_clear (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN); | ||
552 | |||
553 | /* | ||
554 | * clear any enabled interrupt bits | ||
555 | */ | ||
556 | tmp = inb (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN_TYPE); | ||
557 | new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL); | ||
558 | if (tmp != new_tmp) | ||
559 | outb (0, card->baseaddr + VIA_BASE0_PCM_OUT_CHAN_TYPE); | ||
560 | |||
561 | tmp = inb (card->baseaddr + VIA_BASE0_PCM_IN_CHAN_TYPE); | ||
562 | new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL); | ||
563 | if (tmp != new_tmp) | ||
564 | outb (0, card->baseaddr + VIA_BASE0_PCM_IN_CHAN_TYPE); | ||
565 | |||
566 | tmp = inb (card->baseaddr + VIA_BASE0_FM_OUT_CHAN_TYPE); | ||
567 | new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL); | ||
568 | if (tmp != new_tmp) | ||
569 | outb (0, card->baseaddr + VIA_BASE0_FM_OUT_CHAN_TYPE); | ||
570 | |||
571 | if(card->sixchannel) | ||
572 | { | ||
573 | tmp = inb (card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN_TYPE); | ||
574 | new_tmp = tmp & ~(VIA_IRQ_ON_FLAG|VIA_IRQ_ON_EOL|VIA_RESTART_SGD_ON_EOL); | ||
575 | if (tmp != new_tmp) | ||
576 | outb (0, card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN_TYPE); | ||
577 | } | ||
578 | |||
579 | udelay(10); | ||
580 | |||
581 | /* | ||
582 | * clear any existing flags | ||
583 | */ | ||
584 | via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_OUT_CHAN); | ||
585 | via_chan_status_clear (card->baseaddr + VIA_BASE0_PCM_IN_CHAN); | ||
586 | via_chan_status_clear (card->baseaddr + VIA_BASE0_FM_OUT_CHAN); | ||
587 | |||
588 | DPRINTK ("EXIT\n"); | ||
589 | } | ||
590 | |||
591 | |||
592 | /** | ||
593 | * via_set_rate - Set PCM rate for given channel | ||
594 | * @ac97: Pointer to generic codec info struct | ||
595 | * @chan: Private info for specified channel | ||
596 | * @rate: Desired PCM sample rate, in Khz | ||
597 | * | ||
598 | * Sets the PCM sample rate for a channel. | ||
599 | * | ||
600 | * Values for @rate are clamped to a range of 4000 Khz through 48000 Khz, | ||
601 | * due to hardware constraints. | ||
602 | */ | ||
603 | |||
604 | static int via_set_rate (struct ac97_codec *ac97, | ||
605 | struct via_channel *chan, unsigned rate) | ||
606 | { | ||
607 | struct via_info *card = ac97->private_data; | ||
608 | int rate_reg; | ||
609 | u32 dacp; | ||
610 | u32 mast_vol, phone_vol, mono_vol, pcm_vol; | ||
611 | u32 mute_vol = 0x8000; /* The mute volume? -- Seems to work! */ | ||
612 | |||
613 | DPRINTK ("ENTER, rate = %d\n", rate); | ||
614 | |||
615 | if (chan->rate == rate) | ||
616 | goto out; | ||
617 | if (card->locked_rate) { | ||
618 | chan->rate = 48000; | ||
619 | goto out; | ||
620 | } | ||
621 | |||
622 | if (rate > 48000) rate = 48000; | ||
623 | if (rate < 4000) rate = 4000; | ||
624 | |||
625 | rate_reg = chan->is_record ? AC97_PCM_LR_ADC_RATE : | ||
626 | AC97_PCM_FRONT_DAC_RATE; | ||
627 | |||
628 | /* Save current state */ | ||
629 | dacp=via_ac97_read_reg(ac97, AC97_POWER_CONTROL); | ||
630 | mast_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_STEREO); | ||
631 | mono_vol = via_ac97_read_reg(ac97, AC97_MASTER_VOL_MONO); | ||
632 | phone_vol = via_ac97_read_reg(ac97, AC97_HEADPHONE_VOL); | ||
633 | pcm_vol = via_ac97_read_reg(ac97, AC97_PCMOUT_VOL); | ||
634 | /* Mute - largely reduces popping */ | ||
635 | via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mute_vol); | ||
636 | via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mute_vol); | ||
637 | via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, mute_vol); | ||
638 | via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, mute_vol); | ||
639 | /* Power down the DAC */ | ||
640 | via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp|0x0200); | ||
641 | |||
642 | /* Set new rate */ | ||
643 | via_ac97_write_reg (ac97, rate_reg, rate); | ||
644 | |||
645 | /* Power DAC back up */ | ||
646 | via_ac97_write_reg(ac97, AC97_POWER_CONTROL, dacp); | ||
647 | udelay (200); /* reduces popping */ | ||
648 | |||
649 | /* Restore volumes */ | ||
650 | via_ac97_write_reg(ac97, AC97_MASTER_VOL_STEREO, mast_vol); | ||
651 | via_ac97_write_reg(ac97, AC97_MASTER_VOL_MONO, mono_vol); | ||
652 | via_ac97_write_reg(ac97, AC97_HEADPHONE_VOL, phone_vol); | ||
653 | via_ac97_write_reg(ac97, AC97_PCMOUT_VOL, pcm_vol); | ||
654 | |||
655 | /* the hardware might return a value different than what we | ||
656 | * passed to it, so read the rate value back from hardware | ||
657 | * to see what we came up with | ||
658 | */ | ||
659 | chan->rate = via_ac97_read_reg (ac97, rate_reg); | ||
660 | |||
661 | if (chan->rate == 0) { | ||
662 | card->locked_rate = 1; | ||
663 | chan->rate = 48000; | ||
664 | printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n"); | ||
665 | } | ||
666 | |||
667 | out: | ||
668 | DPRINTK ("EXIT, returning rate %d Hz\n", chan->rate); | ||
669 | return chan->rate; | ||
670 | } | ||
671 | |||
672 | |||
673 | /**************************************************************** | ||
674 | * | ||
675 | * Channel-specific operations | ||
676 | * | ||
677 | * | ||
678 | */ | ||
679 | |||
680 | |||
681 | /** | ||
682 | * via_chan_init_defaults - Initialize a struct via_channel | ||
683 | * @card: Private audio chip info | ||
684 | * @chan: Channel to be initialized | ||
685 | * | ||
686 | * Zero @chan, and then set all static defaults for the structure. | ||
687 | */ | ||
688 | |||
689 | static void via_chan_init_defaults (struct via_info *card, struct via_channel *chan) | ||
690 | { | ||
691 | memset (chan, 0, sizeof (*chan)); | ||
692 | |||
693 | if(card->intmask) | ||
694 | chan->intmask = 0x23; /* Turn on the IRQ bits */ | ||
695 | |||
696 | if (chan == &card->ch_out) { | ||
697 | chan->name = "PCM-OUT"; | ||
698 | if(card->sixchannel) | ||
699 | { | ||
700 | chan->iobase = card->baseaddr + VIA_BASE0_MULTI_OUT_CHAN; | ||
701 | chan->is_multi = 1; | ||
702 | DPRINTK("Using multichannel for pcm out\n"); | ||
703 | } | ||
704 | else | ||
705 | chan->iobase = card->baseaddr + VIA_BASE0_PCM_OUT_CHAN; | ||
706 | } else if (chan == &card->ch_in) { | ||
707 | chan->name = "PCM-IN"; | ||
708 | chan->iobase = card->baseaddr + VIA_BASE0_PCM_IN_CHAN; | ||
709 | chan->is_record = 1; | ||
710 | } else if (chan == &card->ch_fm) { | ||
711 | chan->name = "PCM-OUT-FM"; | ||
712 | chan->iobase = card->baseaddr + VIA_BASE0_FM_OUT_CHAN; | ||
713 | } else { | ||
714 | BUG(); | ||
715 | } | ||
716 | |||
717 | init_waitqueue_head (&chan->wait); | ||
718 | |||
719 | chan->pcm_fmt = VIA_PCM_FMT_MASK; | ||
720 | chan->is_enabled = 1; | ||
721 | |||
722 | chan->frag_number = 0; | ||
723 | chan->frag_size = 0; | ||
724 | atomic_set(&chan->n_frags, 0); | ||
725 | atomic_set (&chan->hw_ptr, 0); | ||
726 | } | ||
727 | |||
728 | /** | ||
729 | * via_chan_init - Initialize PCM channel | ||
730 | * @card: Private audio chip info | ||
731 | * @chan: Channel to be initialized | ||
732 | * | ||
733 | * Performs some of the preparations necessary to begin | ||
734 | * using a PCM channel. | ||
735 | * | ||
736 | * Currently the preparations consist of | ||
737 | * setting the PCM channel to a known state. | ||
738 | */ | ||
739 | |||
740 | |||
741 | static void via_chan_init (struct via_info *card, struct via_channel *chan) | ||
742 | { | ||
743 | |||
744 | DPRINTK ("ENTER\n"); | ||
745 | |||
746 | /* bzero channel structure, and init members to defaults */ | ||
747 | via_chan_init_defaults (card, chan); | ||
748 | |||
749 | /* stop any existing channel output */ | ||
750 | via_chan_clear (card, chan); | ||
751 | via_chan_status_clear (chan->iobase); | ||
752 | via_chan_pcm_fmt (chan, 1); | ||
753 | |||
754 | DPRINTK ("EXIT\n"); | ||
755 | } | ||
756 | |||
757 | /** | ||
758 | * via_chan_buffer_init - Initialize PCM channel buffer | ||
759 | * @card: Private audio chip info | ||
760 | * @chan: Channel to be initialized | ||
761 | * | ||
762 | * Performs some of the preparations necessary to begin | ||
763 | * using a PCM channel. | ||
764 | * | ||
765 | * Currently the preparations include allocating the | ||
766 | * scatter-gather DMA table and buffers, | ||
767 | * and passing the | ||
768 | * address of the DMA table to the hardware. | ||
769 | * | ||
770 | * Note that special care is taken when passing the | ||
771 | * DMA table address to hardware, because it was found | ||
772 | * during driver development that the hardware did not | ||
773 | * always "take" the address. | ||
774 | */ | ||
775 | |||
776 | static int via_chan_buffer_init (struct via_info *card, struct via_channel *chan) | ||
777 | { | ||
778 | int page, offset; | ||
779 | int i; | ||
780 | |||
781 | DPRINTK ("ENTER\n"); | ||
782 | |||
783 | |||
784 | chan->intmask = 0; | ||
785 | if(card->intmask) | ||
786 | chan->intmask = 0x23; /* Turn on the IRQ bits */ | ||
787 | |||
788 | if (chan->sgtable != NULL) { | ||
789 | DPRINTK ("EXIT\n"); | ||
790 | return 0; | ||
791 | } | ||
792 | |||
793 | /* alloc DMA-able memory for scatter-gather table */ | ||
794 | chan->sgtable = pci_alloc_consistent (card->pdev, | ||
795 | (sizeof (struct via_sgd_table) * chan->frag_number), | ||
796 | &chan->sgt_handle); | ||
797 | if (!chan->sgtable) { | ||
798 | printk (KERN_ERR PFX "DMA table alloc fail, aborting\n"); | ||
799 | DPRINTK ("EXIT\n"); | ||
800 | return -ENOMEM; | ||
801 | } | ||
802 | |||
803 | memset ((void*)chan->sgtable, 0, | ||
804 | (sizeof (struct via_sgd_table) * chan->frag_number)); | ||
805 | |||
806 | /* alloc DMA-able memory for scatter-gather buffers */ | ||
807 | |||
808 | chan->page_number = (chan->frag_number * chan->frag_size) / PAGE_SIZE + | ||
809 | (((chan->frag_number * chan->frag_size) % PAGE_SIZE) ? 1 : 0); | ||
810 | |||
811 | for (i = 0; i < chan->page_number; i++) { | ||
812 | chan->pgtbl[i].cpuaddr = pci_alloc_consistent (card->pdev, PAGE_SIZE, | ||
813 | &chan->pgtbl[i].handle); | ||
814 | |||
815 | if (!chan->pgtbl[i].cpuaddr) { | ||
816 | chan->page_number = i; | ||
817 | goto err_out_nomem; | ||
818 | } | ||
819 | |||
820 | #ifndef VIA_NDEBUG | ||
821 | memset (chan->pgtbl[i].cpuaddr, 0xBC, chan->frag_size); | ||
822 | #endif | ||
823 | |||
824 | #if 1 | ||
825 | DPRINTK ("dmabuf_pg #%d (h=%lx, v2p=%lx, a=%p)\n", | ||
826 | i, (long)chan->pgtbl[i].handle, | ||
827 | virt_to_phys(chan->pgtbl[i].cpuaddr), | ||
828 | chan->pgtbl[i].cpuaddr); | ||
829 | #endif | ||
830 | } | ||
831 | |||
832 | for (i = 0; i < chan->frag_number; i++) { | ||
833 | |||
834 | page = i / (PAGE_SIZE / chan->frag_size); | ||
835 | offset = (i % (PAGE_SIZE / chan->frag_size)) * chan->frag_size; | ||
836 | |||
837 | chan->sgtable[i].count = cpu_to_le32 (chan->frag_size | VIA_FLAG); | ||
838 | chan->sgtable[i].addr = cpu_to_le32 (chan->pgtbl[page].handle + offset); | ||
839 | |||
840 | #if 1 | ||
841 | DPRINTK ("dmabuf #%d (32(h)=%lx)\n", | ||
842 | i, | ||
843 | (long)chan->sgtable[i].addr); | ||
844 | #endif | ||
845 | } | ||
846 | |||
847 | /* overwrite the last buffer information */ | ||
848 | chan->sgtable[chan->frag_number - 1].count = cpu_to_le32 (chan->frag_size | VIA_EOL); | ||
849 | |||
850 | /* set location of DMA-able scatter-gather info table */ | ||
851 | DPRINTK ("outl (0x%X, 0x%04lX)\n", | ||
852 | chan->sgt_handle, chan->iobase + VIA_PCM_TABLE_ADDR); | ||
853 | |||
854 | via_ac97_wait_idle (card); | ||
855 | outl (chan->sgt_handle, chan->iobase + VIA_PCM_TABLE_ADDR); | ||
856 | udelay (20); | ||
857 | via_ac97_wait_idle (card); | ||
858 | /* load no rate adaption, stereo 16bit, set up ring slots */ | ||
859 | if(card->sixchannel) | ||
860 | { | ||
861 | if(!chan->is_multi) | ||
862 | { | ||
863 | outl (0xFFFFF | (0x3 << 20) | (chan->frag_number << 24), chan->iobase + VIA_PCM_STOPRATE); | ||
864 | udelay (20); | ||
865 | via_ac97_wait_idle (card); | ||
866 | } | ||
867 | } | ||
868 | |||
869 | DPRINTK ("inl (0x%lX) = %x\n", | ||
870 | chan->iobase + VIA_PCM_TABLE_ADDR, | ||
871 | inl(chan->iobase + VIA_PCM_TABLE_ADDR)); | ||
872 | |||
873 | DPRINTK ("EXIT\n"); | ||
874 | return 0; | ||
875 | |||
876 | err_out_nomem: | ||
877 | printk (KERN_ERR PFX "DMA buffer alloc fail, aborting\n"); | ||
878 | via_chan_buffer_free (card, chan); | ||
879 | DPRINTK ("EXIT\n"); | ||
880 | return -ENOMEM; | ||
881 | } | ||
882 | |||
883 | |||
884 | /** | ||
885 | * via_chan_free - Release a PCM channel | ||
886 | * @card: Private audio chip info | ||
887 | * @chan: Channel to be released | ||
888 | * | ||
889 | * Performs all the functions necessary to clean up | ||
890 | * an initialized channel. | ||
891 | * | ||
892 | * Currently these functions include disabled any | ||
893 | * active DMA operations, setting the PCM channel | ||
894 | * back to a known state, and releasing any allocated | ||
895 | * sound buffers. | ||
896 | */ | ||
897 | |||
898 | static void via_chan_free (struct via_info *card, struct via_channel *chan) | ||
899 | { | ||
900 | DPRINTK ("ENTER\n"); | ||
901 | |||
902 | spin_lock_irq (&card->lock); | ||
903 | |||
904 | /* stop any existing channel output */ | ||
905 | via_chan_status_clear (chan->iobase); | ||
906 | via_chan_stop (chan->iobase); | ||
907 | via_chan_status_clear (chan->iobase); | ||
908 | |||
909 | spin_unlock_irq (&card->lock); | ||
910 | |||
911 | synchronize_irq(card->pdev->irq); | ||
912 | |||
913 | DPRINTK ("EXIT\n"); | ||
914 | } | ||
915 | |||
916 | static void via_chan_buffer_free (struct via_info *card, struct via_channel *chan) | ||
917 | { | ||
918 | int i; | ||
919 | |||
920 | DPRINTK ("ENTER\n"); | ||
921 | |||
922 | /* zero location of DMA-able scatter-gather info table */ | ||
923 | via_ac97_wait_idle(card); | ||
924 | outl (0, chan->iobase + VIA_PCM_TABLE_ADDR); | ||
925 | |||
926 | for (i = 0; i < chan->page_number; i++) | ||
927 | if (chan->pgtbl[i].cpuaddr) { | ||
928 | pci_free_consistent (card->pdev, PAGE_SIZE, | ||
929 | chan->pgtbl[i].cpuaddr, | ||
930 | chan->pgtbl[i].handle); | ||
931 | chan->pgtbl[i].cpuaddr = NULL; | ||
932 | chan->pgtbl[i].handle = 0; | ||
933 | } | ||
934 | |||
935 | chan->page_number = 0; | ||
936 | |||
937 | if (chan->sgtable) { | ||
938 | pci_free_consistent (card->pdev, | ||
939 | (sizeof (struct via_sgd_table) * chan->frag_number), | ||
940 | (void*)chan->sgtable, chan->sgt_handle); | ||
941 | chan->sgtable = NULL; | ||
942 | } | ||
943 | |||
944 | DPRINTK ("EXIT\n"); | ||
945 | } | ||
946 | |||
947 | |||
948 | /** | ||
949 | * via_chan_pcm_fmt - Update PCM channel settings | ||
950 | * @chan: Channel to be updated | ||
951 | * @reset: Boolean. If non-zero, channel will be reset | ||
952 | * to 8-bit mono mode. | ||
953 | * | ||
954 | * Stores the settings of the current PCM format, | ||
955 | * 8-bit or 16-bit, and mono/stereo, into the | ||
956 | * hardware settings for the specified channel. | ||
957 | * If @reset is non-zero, the channel is reset | ||
958 | * to 8-bit mono mode. Otherwise, the channel | ||
959 | * is set to the values stored in the channel | ||
960 | * information struct @chan. | ||
961 | */ | ||
962 | |||
963 | static void via_chan_pcm_fmt (struct via_channel *chan, int reset) | ||
964 | { | ||
965 | DPRINTK ("ENTER, pcm_fmt=0x%02X, reset=%s\n", | ||
966 | chan->pcm_fmt, reset ? "yes" : "no"); | ||
967 | |||
968 | assert (chan != NULL); | ||
969 | |||
970 | if (reset) | ||
971 | { | ||
972 | /* reset to 8-bit mono mode */ | ||
973 | chan->pcm_fmt = 0; | ||
974 | chan->channels = 1; | ||
975 | } | ||
976 | |||
977 | /* enable interrupts on FLAG and EOL */ | ||
978 | chan->pcm_fmt |= VIA_CHAN_TYPE_MASK; | ||
979 | |||
980 | /* if we are recording, enable recording fifo bit */ | ||
981 | if (chan->is_record) | ||
982 | chan->pcm_fmt |= VIA_PCM_REC_FIFO; | ||
983 | /* set interrupt select bits where applicable (PCM in & out channels) */ | ||
984 | if (!chan->is_record) | ||
985 | chan->pcm_fmt |= VIA_CHAN_TYPE_INT_SELECT; | ||
986 | |||
987 | DPRINTK("SET FMT - %02x %02x\n", chan->intmask , chan->is_multi); | ||
988 | |||
989 | if(chan->intmask) | ||
990 | { | ||
991 | u32 m; | ||
992 | |||
993 | /* | ||
994 | * Channel 0x4 is up to 6 x 16bit and has to be | ||
995 | * programmed differently | ||
996 | */ | ||
997 | |||
998 | if(chan->is_multi) | ||
999 | { | ||
1000 | u8 c = 0; | ||
1001 | |||
1002 | /* | ||
1003 | * Load the type bit for num channels | ||
1004 | * and 8/16bit | ||
1005 | */ | ||
1006 | |||
1007 | if(chan->pcm_fmt & VIA_PCM_FMT_16BIT) | ||
1008 | c = 1 << 7; | ||
1009 | if(chan->pcm_fmt & VIA_PCM_FMT_STEREO) | ||
1010 | c |= (2<<4); | ||
1011 | else | ||
1012 | c |= (1<<4); | ||
1013 | |||
1014 | outb(c, chan->iobase + VIA_PCM_TYPE); | ||
1015 | |||
1016 | /* | ||
1017 | * Set the channel steering | ||
1018 | * Mono | ||
1019 | * Channel 0 to slot 3 | ||
1020 | * Channel 0 to slot 4 | ||
1021 | * Stereo | ||
1022 | * Channel 0 to slot 3 | ||
1023 | * Channel 1 to slot 4 | ||
1024 | */ | ||
1025 | |||
1026 | switch(chan->channels) | ||
1027 | { | ||
1028 | case 1: | ||
1029 | outl(0xFF000000 | (1<<0) | (1<<4) , chan->iobase + VIA_PCM_STOPRATE); | ||
1030 | break; | ||
1031 | case 2: | ||
1032 | outl(0xFF000000 | (1<<0) | (2<<4) , chan->iobase + VIA_PCM_STOPRATE); | ||
1033 | break; | ||
1034 | case 4: | ||
1035 | outl(0xFF000000 | (1<<0) | (2<<4) | (3<<8) | (4<<12), chan->iobase + VIA_PCM_STOPRATE); | ||
1036 | break; | ||
1037 | case 6: | ||
1038 | outl(0xFF000000 | (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20), chan->iobase + VIA_PCM_STOPRATE); | ||
1039 | break; | ||
1040 | } | ||
1041 | } | ||
1042 | else | ||
1043 | { | ||
1044 | /* | ||
1045 | * New style, turn off channel volume | ||
1046 | * control, set bits in the right register | ||
1047 | */ | ||
1048 | outb(0x0, chan->iobase + VIA_PCM_LEFTVOL); | ||
1049 | outb(0x0, chan->iobase + VIA_PCM_RIGHTVOL); | ||
1050 | |||
1051 | m = inl(chan->iobase + VIA_PCM_STOPRATE); | ||
1052 | m &= ~(3<<20); | ||
1053 | if(chan->pcm_fmt & VIA_PCM_FMT_STEREO) | ||
1054 | m |= (1 << 20); | ||
1055 | if(chan->pcm_fmt & VIA_PCM_FMT_16BIT) | ||
1056 | m |= (1 << 21); | ||
1057 | outl(m, chan->iobase + VIA_PCM_STOPRATE); | ||
1058 | } | ||
1059 | } | ||
1060 | else | ||
1061 | outb (chan->pcm_fmt, chan->iobase + VIA_PCM_TYPE); | ||
1062 | |||
1063 | |||
1064 | DPRINTK ("EXIT, pcm_fmt = 0x%02X, reg = 0x%02X\n", | ||
1065 | chan->pcm_fmt, | ||
1066 | inb (chan->iobase + VIA_PCM_TYPE)); | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | /** | ||
1071 | * via_chan_clear - Stop DMA channel operation, and reset pointers | ||
1072 | * @card: the chip to accessed | ||
1073 | * @chan: Channel to be cleared | ||
1074 | * | ||
1075 | * Call via_chan_stop to halt DMA operations, and then resets | ||
1076 | * all software pointers which track DMA operation. | ||
1077 | */ | ||
1078 | |||
1079 | static void via_chan_clear (struct via_info *card, struct via_channel *chan) | ||
1080 | { | ||
1081 | DPRINTK ("ENTER\n"); | ||
1082 | via_chan_stop (chan->iobase); | ||
1083 | via_chan_buffer_free(card, chan); | ||
1084 | chan->is_active = 0; | ||
1085 | chan->is_mapped = 0; | ||
1086 | chan->is_enabled = 1; | ||
1087 | chan->slop_len = 0; | ||
1088 | chan->sw_ptr = 0; | ||
1089 | chan->n_irqs = 0; | ||
1090 | atomic_set (&chan->hw_ptr, 0); | ||
1091 | DPRINTK ("EXIT\n"); | ||
1092 | } | ||
1093 | |||
1094 | |||
1095 | /** | ||
1096 | * via_chan_set_speed - Set PCM sample rate for given channel | ||
1097 | * @card: Private info for specified board | ||
1098 | * @chan: Channel whose sample rate will be adjusted | ||
1099 | * @val: New sample rate, in Khz | ||
1100 | * | ||
1101 | * Helper function for the %SNDCTL_DSP_SPEED ioctl. OSS semantics | ||
1102 | * demand that all audio operations halt (if they are not already | ||
1103 | * halted) when the %SNDCTL_DSP_SPEED is given. | ||
1104 | * | ||
1105 | * This function halts all audio operations for the given channel | ||
1106 | * @chan, and then calls via_set_rate to set the audio hardware | ||
1107 | * to the new rate. | ||
1108 | */ | ||
1109 | |||
1110 | static int via_chan_set_speed (struct via_info *card, | ||
1111 | struct via_channel *chan, int val) | ||
1112 | { | ||
1113 | DPRINTK ("ENTER, requested rate = %d\n", val); | ||
1114 | |||
1115 | via_chan_clear (card, chan); | ||
1116 | |||
1117 | val = via_set_rate (card->ac97, chan, val); | ||
1118 | |||
1119 | DPRINTK ("EXIT, returning %d\n", val); | ||
1120 | return val; | ||
1121 | } | ||
1122 | |||
1123 | |||
1124 | /** | ||
1125 | * via_chan_set_fmt - Set PCM sample size for given channel | ||
1126 | * @card: Private info for specified board | ||
1127 | * @chan: Channel whose sample size will be adjusted | ||
1128 | * @val: New sample size, use the %AFMT_xxx constants | ||
1129 | * | ||
1130 | * Helper function for the %SNDCTL_DSP_SETFMT ioctl. OSS semantics | ||
1131 | * demand that all audio operations halt (if they are not already | ||
1132 | * halted) when the %SNDCTL_DSP_SETFMT is given. | ||
1133 | * | ||
1134 | * This function halts all audio operations for the given channel | ||
1135 | * @chan, and then calls via_chan_pcm_fmt to set the audio hardware | ||
1136 | * to the new sample size, either 8-bit or 16-bit. | ||
1137 | */ | ||
1138 | |||
1139 | static int via_chan_set_fmt (struct via_info *card, | ||
1140 | struct via_channel *chan, int val) | ||
1141 | { | ||
1142 | DPRINTK ("ENTER, val=%s\n", | ||
1143 | val == AFMT_U8 ? "AFMT_U8" : | ||
1144 | val == AFMT_S16_LE ? "AFMT_S16_LE" : | ||
1145 | "unknown"); | ||
1146 | |||
1147 | via_chan_clear (card, chan); | ||
1148 | |||
1149 | assert (val != AFMT_QUERY); /* this case is handled elsewhere */ | ||
1150 | |||
1151 | switch (val) { | ||
1152 | case AFMT_S16_LE: | ||
1153 | if ((chan->pcm_fmt & VIA_PCM_FMT_16BIT) == 0) { | ||
1154 | chan->pcm_fmt |= VIA_PCM_FMT_16BIT; | ||
1155 | via_chan_pcm_fmt (chan, 0); | ||
1156 | } | ||
1157 | break; | ||
1158 | |||
1159 | case AFMT_U8: | ||
1160 | if (chan->pcm_fmt & VIA_PCM_FMT_16BIT) { | ||
1161 | chan->pcm_fmt &= ~VIA_PCM_FMT_16BIT; | ||
1162 | via_chan_pcm_fmt (chan, 0); | ||
1163 | } | ||
1164 | break; | ||
1165 | |||
1166 | default: | ||
1167 | DPRINTK ("unknown AFMT: 0x%X\n", val); | ||
1168 | val = AFMT_S16_LE; | ||
1169 | } | ||
1170 | |||
1171 | DPRINTK ("EXIT\n"); | ||
1172 | return val; | ||
1173 | } | ||
1174 | |||
1175 | |||
1176 | /** | ||
1177 | * via_chan_set_stereo - Enable or disable stereo for a DMA channel | ||
1178 | * @card: Private info for specified board | ||
1179 | * @chan: Channel whose stereo setting will be adjusted | ||
1180 | * @val: New sample size, use the %AFMT_xxx constants | ||
1181 | * | ||
1182 | * Helper function for the %SNDCTL_DSP_CHANNELS and %SNDCTL_DSP_STEREO ioctls. OSS semantics | ||
1183 | * demand that all audio operations halt (if they are not already | ||
1184 | * halted) when %SNDCTL_DSP_CHANNELS or SNDCTL_DSP_STEREO is given. | ||
1185 | * | ||
1186 | * This function halts all audio operations for the given channel | ||
1187 | * @chan, and then calls via_chan_pcm_fmt to set the audio hardware | ||
1188 | * to enable or disable stereo. | ||
1189 | */ | ||
1190 | |||
1191 | static int via_chan_set_stereo (struct via_info *card, | ||
1192 | struct via_channel *chan, int val) | ||
1193 | { | ||
1194 | DPRINTK ("ENTER, channels = %d\n", val); | ||
1195 | |||
1196 | via_chan_clear (card, chan); | ||
1197 | |||
1198 | switch (val) { | ||
1199 | |||
1200 | /* mono */ | ||
1201 | case 1: | ||
1202 | chan->pcm_fmt &= ~VIA_PCM_FMT_STEREO; | ||
1203 | chan->channels = 1; | ||
1204 | via_chan_pcm_fmt (chan, 0); | ||
1205 | break; | ||
1206 | |||
1207 | /* stereo */ | ||
1208 | case 2: | ||
1209 | chan->pcm_fmt |= VIA_PCM_FMT_STEREO; | ||
1210 | chan->channels = 2; | ||
1211 | via_chan_pcm_fmt (chan, 0); | ||
1212 | break; | ||
1213 | |||
1214 | case 4: | ||
1215 | case 6: | ||
1216 | if(chan->is_multi) | ||
1217 | { | ||
1218 | chan->pcm_fmt |= VIA_PCM_FMT_STEREO; | ||
1219 | chan->channels = val; | ||
1220 | break; | ||
1221 | } | ||
1222 | /* unknown */ | ||
1223 | default: | ||
1224 | val = -EINVAL; | ||
1225 | break; | ||
1226 | } | ||
1227 | |||
1228 | DPRINTK ("EXIT, returning %d\n", val); | ||
1229 | return val; | ||
1230 | } | ||
1231 | |||
1232 | static int via_chan_set_buffering (struct via_info *card, | ||
1233 | struct via_channel *chan, int val) | ||
1234 | { | ||
1235 | int shift; | ||
1236 | |||
1237 | DPRINTK ("ENTER\n"); | ||
1238 | |||
1239 | /* in both cases the buffer cannot be changed */ | ||
1240 | if (chan->is_active || chan->is_mapped) { | ||
1241 | DPRINTK ("EXIT\n"); | ||
1242 | return -EINVAL; | ||
1243 | } | ||
1244 | |||
1245 | /* called outside SETFRAGMENT */ | ||
1246 | /* set defaults or do nothing */ | ||
1247 | if (val < 0) { | ||
1248 | |||
1249 | if (chan->frag_size && chan->frag_number) | ||
1250 | goto out; | ||
1251 | |||
1252 | DPRINTK ("\n"); | ||
1253 | |||
1254 | chan->frag_size = (VIA_DEFAULT_FRAG_TIME * chan->rate * chan->channels | ||
1255 | * ((chan->pcm_fmt & VIA_PCM_FMT_16BIT) ? 2 : 1)) / 1000 - 1; | ||
1256 | |||
1257 | shift = 0; | ||
1258 | while (chan->frag_size) { | ||
1259 | chan->frag_size >>= 1; | ||
1260 | shift++; | ||
1261 | } | ||
1262 | chan->frag_size = 1 << shift; | ||
1263 | |||
1264 | chan->frag_number = (VIA_DEFAULT_BUFFER_TIME / VIA_DEFAULT_FRAG_TIME); | ||
1265 | |||
1266 | DPRINTK ("setting default values %d %d\n", chan->frag_size, chan->frag_number); | ||
1267 | } else { | ||
1268 | chan->frag_size = 1 << (val & 0xFFFF); | ||
1269 | chan->frag_number = (val >> 16) & 0xFFFF; | ||
1270 | |||
1271 | DPRINTK ("using user values %d %d\n", chan->frag_size, chan->frag_number); | ||
1272 | } | ||
1273 | |||
1274 | /* quake3 wants frag_number to be a power of two */ | ||
1275 | shift = 0; | ||
1276 | while (chan->frag_number) { | ||
1277 | chan->frag_number >>= 1; | ||
1278 | shift++; | ||
1279 | } | ||
1280 | chan->frag_number = 1 << shift; | ||
1281 | |||
1282 | if (chan->frag_size > VIA_MAX_FRAG_SIZE) | ||
1283 | chan->frag_size = VIA_MAX_FRAG_SIZE; | ||
1284 | else if (chan->frag_size < VIA_MIN_FRAG_SIZE) | ||
1285 | chan->frag_size = VIA_MIN_FRAG_SIZE; | ||
1286 | |||
1287 | if (chan->frag_number < VIA_MIN_FRAG_NUMBER) | ||
1288 | chan->frag_number = VIA_MIN_FRAG_NUMBER; | ||
1289 | if (chan->frag_number > VIA_MAX_FRAG_NUMBER) | ||
1290 | chan->frag_number = VIA_MAX_FRAG_NUMBER; | ||
1291 | |||
1292 | if ((chan->frag_number * chan->frag_size) / PAGE_SIZE > VIA_MAX_BUFFER_DMA_PAGES) | ||
1293 | chan->frag_number = (VIA_MAX_BUFFER_DMA_PAGES * PAGE_SIZE) / chan->frag_size; | ||
1294 | |||
1295 | out: | ||
1296 | if (chan->is_record) | ||
1297 | atomic_set (&chan->n_frags, 0); | ||
1298 | else | ||
1299 | atomic_set (&chan->n_frags, chan->frag_number); | ||
1300 | |||
1301 | DPRINTK ("EXIT\n"); | ||
1302 | |||
1303 | return 0; | ||
1304 | } | ||
1305 | |||
1306 | #ifdef VIA_CHAN_DUMP_BUFS | ||
1307 | /** | ||
1308 | * via_chan_dump_bufs - Display DMA table contents | ||
1309 | * @chan: Channel whose DMA table will be displayed | ||
1310 | * | ||
1311 | * Debugging function which displays the contents of the | ||
1312 | * scatter-gather DMA table for the given channel @chan. | ||
1313 | */ | ||
1314 | |||
1315 | static void via_chan_dump_bufs (struct via_channel *chan) | ||
1316 | { | ||
1317 | int i; | ||
1318 | |||
1319 | for (i = 0; i < chan->frag_number; i++) { | ||
1320 | DPRINTK ("#%02d: addr=%x, count=%u, flag=%d, eol=%d\n", | ||
1321 | i, chan->sgtable[i].addr, | ||
1322 | chan->sgtable[i].count & 0x00FFFFFF, | ||
1323 | chan->sgtable[i].count & VIA_FLAG ? 1 : 0, | ||
1324 | chan->sgtable[i].count & VIA_EOL ? 1 : 0); | ||
1325 | } | ||
1326 | DPRINTK ("buf_in_use = %d, nextbuf = %d\n", | ||
1327 | atomic_read (&chan->buf_in_use), | ||
1328 | atomic_read (&chan->sw_ptr)); | ||
1329 | } | ||
1330 | #endif /* VIA_CHAN_DUMP_BUFS */ | ||
1331 | |||
1332 | |||
1333 | /** | ||
1334 | * via_chan_flush_frag - Flush partially-full playback buffer to hardware | ||
1335 | * @chan: Channel whose DMA table will be flushed | ||
1336 | * | ||
1337 | * Flushes partially-full playback buffer to hardware. | ||
1338 | */ | ||
1339 | |||
1340 | static void via_chan_flush_frag (struct via_channel *chan) | ||
1341 | { | ||
1342 | DPRINTK ("ENTER\n"); | ||
1343 | |||
1344 | assert (chan->slop_len > 0); | ||
1345 | |||
1346 | if (chan->sw_ptr == (chan->frag_number - 1)) | ||
1347 | chan->sw_ptr = 0; | ||
1348 | else | ||
1349 | chan->sw_ptr++; | ||
1350 | |||
1351 | chan->slop_len = 0; | ||
1352 | |||
1353 | assert (atomic_read (&chan->n_frags) > 0); | ||
1354 | atomic_dec (&chan->n_frags); | ||
1355 | |||
1356 | DPRINTK ("EXIT\n"); | ||
1357 | } | ||
1358 | |||
1359 | |||
1360 | |||
1361 | /** | ||
1362 | * via_chan_maybe_start - Initiate audio hardware DMA operation | ||
1363 | * @chan: Channel whose DMA is to be started | ||
1364 | * | ||
1365 | * Initiate DMA operation, if the DMA engine for the given | ||
1366 | * channel @chan is not already active. | ||
1367 | */ | ||
1368 | |||
1369 | static inline void via_chan_maybe_start (struct via_channel *chan) | ||
1370 | { | ||
1371 | assert (chan->is_active == sg_active(chan->iobase)); | ||
1372 | |||
1373 | DPRINTK ("MAYBE START %s\n", chan->name); | ||
1374 | if (!chan->is_active && chan->is_enabled) { | ||
1375 | chan->is_active = 1; | ||
1376 | sg_begin (chan); | ||
1377 | DPRINTK ("starting channel %s\n", chan->name); | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | |||
1382 | /**************************************************************** | ||
1383 | * | ||
1384 | * Interface to ac97-codec module | ||
1385 | * | ||
1386 | * | ||
1387 | */ | ||
1388 | |||
1389 | /** | ||
1390 | * via_ac97_wait_idle - Wait until AC97 codec is not busy | ||
1391 | * @card: Private info for specified board | ||
1392 | * | ||
1393 | * Sleep until the AC97 codec is no longer busy. | ||
1394 | * Returns the final value read from the SGD | ||
1395 | * register being polled. | ||
1396 | */ | ||
1397 | |||
1398 | static u8 via_ac97_wait_idle (struct via_info *card) | ||
1399 | { | ||
1400 | u8 tmp8; | ||
1401 | int counter = VIA_COUNTER_LIMIT; | ||
1402 | |||
1403 | DPRINTK ("ENTER/EXIT\n"); | ||
1404 | |||
1405 | assert (card != NULL); | ||
1406 | assert (card->pdev != NULL); | ||
1407 | |||
1408 | do { | ||
1409 | udelay (15); | ||
1410 | |||
1411 | tmp8 = inb (card->baseaddr + 0x83); | ||
1412 | } while ((tmp8 & VIA_CR83_BUSY) && (counter-- > 0)); | ||
1413 | |||
1414 | if (tmp8 & VIA_CR83_BUSY) | ||
1415 | printk (KERN_WARNING PFX "timeout waiting on AC97 codec\n"); | ||
1416 | return tmp8; | ||
1417 | } | ||
1418 | |||
1419 | |||
1420 | /** | ||
1421 | * via_ac97_read_reg - Read AC97 standard register | ||
1422 | * @codec: Pointer to generic AC97 codec info | ||
1423 | * @reg: Index of AC97 register to be read | ||
1424 | * | ||
1425 | * Read the value of a single AC97 codec register, | ||
1426 | * as defined by the Intel AC97 specification. | ||
1427 | * | ||
1428 | * Defines the standard AC97 read-register operation | ||
1429 | * required by the kernel's ac97_codec interface. | ||
1430 | * | ||
1431 | * Returns the 16-bit value stored in the specified | ||
1432 | * register. | ||
1433 | */ | ||
1434 | |||
1435 | static u16 via_ac97_read_reg (struct ac97_codec *codec, u8 reg) | ||
1436 | { | ||
1437 | unsigned long data; | ||
1438 | struct via_info *card; | ||
1439 | int counter; | ||
1440 | |||
1441 | DPRINTK ("ENTER\n"); | ||
1442 | |||
1443 | assert (codec != NULL); | ||
1444 | assert (codec->private_data != NULL); | ||
1445 | |||
1446 | card = codec->private_data; | ||
1447 | |||
1448 | spin_lock(&card->ac97_lock); | ||
1449 | |||
1450 | /* Every time we write to register 80 we cause a transaction. | ||
1451 | The only safe way to clear the valid bit is to write it at | ||
1452 | the same time as the command */ | ||
1453 | data = (reg << 16) | VIA_CR80_READ | VIA_CR80_VALID; | ||
1454 | |||
1455 | outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL); | ||
1456 | udelay (20); | ||
1457 | |||
1458 | for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) { | ||
1459 | udelay (1); | ||
1460 | if ((((data = inl(card->baseaddr + VIA_BASE0_AC97_CTRL)) & | ||
1461 | (VIA_CR80_VALID|VIA_CR80_BUSY)) == VIA_CR80_VALID)) | ||
1462 | goto out; | ||
1463 | } | ||
1464 | |||
1465 | printk (KERN_WARNING PFX "timeout while reading AC97 codec (0x%lX)\n", data); | ||
1466 | goto err_out; | ||
1467 | |||
1468 | out: | ||
1469 | /* Once the valid bit has become set, we must wait a complete AC97 | ||
1470 | frame before the data has settled. */ | ||
1471 | udelay(25); | ||
1472 | data = (unsigned long) inl (card->baseaddr + VIA_BASE0_AC97_CTRL); | ||
1473 | |||
1474 | outb (0x02, card->baseaddr + 0x83); | ||
1475 | |||
1476 | if (((data & 0x007F0000) >> 16) == reg) { | ||
1477 | DPRINTK ("EXIT, success, data=0x%lx, retval=0x%lx\n", | ||
1478 | data, data & 0x0000FFFF); | ||
1479 | spin_unlock(&card->ac97_lock); | ||
1480 | return data & 0x0000FFFF; | ||
1481 | } | ||
1482 | |||
1483 | printk (KERN_WARNING "via82cxxx_audio: not our index: reg=0x%x, newreg=0x%lx\n", | ||
1484 | reg, ((data & 0x007F0000) >> 16)); | ||
1485 | |||
1486 | err_out: | ||
1487 | spin_unlock(&card->ac97_lock); | ||
1488 | DPRINTK ("EXIT, returning 0\n"); | ||
1489 | return 0; | ||
1490 | } | ||
1491 | |||
1492 | |||
1493 | /** | ||
1494 | * via_ac97_write_reg - Write AC97 standard register | ||
1495 | * @codec: Pointer to generic AC97 codec info | ||
1496 | * @reg: Index of AC97 register to be written | ||
1497 | * @value: Value to be written to AC97 register | ||
1498 | * | ||
1499 | * Write the value of a single AC97 codec register, | ||
1500 | * as defined by the Intel AC97 specification. | ||
1501 | * | ||
1502 | * Defines the standard AC97 write-register operation | ||
1503 | * required by the kernel's ac97_codec interface. | ||
1504 | */ | ||
1505 | |||
1506 | static void via_ac97_write_reg (struct ac97_codec *codec, u8 reg, u16 value) | ||
1507 | { | ||
1508 | u32 data; | ||
1509 | struct via_info *card; | ||
1510 | int counter; | ||
1511 | |||
1512 | DPRINTK ("ENTER\n"); | ||
1513 | |||
1514 | assert (codec != NULL); | ||
1515 | assert (codec->private_data != NULL); | ||
1516 | |||
1517 | card = codec->private_data; | ||
1518 | |||
1519 | spin_lock(&card->ac97_lock); | ||
1520 | |||
1521 | data = (reg << 16) + value; | ||
1522 | outl (data, card->baseaddr + VIA_BASE0_AC97_CTRL); | ||
1523 | udelay (10); | ||
1524 | |||
1525 | for (counter = VIA_COUNTER_LIMIT; counter > 0; counter--) { | ||
1526 | if ((inb (card->baseaddr + 0x83) & VIA_CR83_BUSY) == 0) | ||
1527 | goto out; | ||
1528 | |||
1529 | udelay (15); | ||
1530 | } | ||
1531 | |||
1532 | printk (KERN_WARNING PFX "timeout after AC97 codec write (0x%X, 0x%X)\n", reg, value); | ||
1533 | |||
1534 | out: | ||
1535 | spin_unlock(&card->ac97_lock); | ||
1536 | DPRINTK ("EXIT\n"); | ||
1537 | } | ||
1538 | |||
1539 | |||
1540 | static int via_mixer_open (struct inode *inode, struct file *file) | ||
1541 | { | ||
1542 | int minor = iminor(inode); | ||
1543 | struct via_info *card; | ||
1544 | struct pci_dev *pdev = NULL; | ||
1545 | struct pci_driver *drvr; | ||
1546 | |||
1547 | DPRINTK ("ENTER\n"); | ||
1548 | |||
1549 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | ||
1550 | drvr = pci_dev_driver (pdev); | ||
1551 | if (drvr == &via_driver) { | ||
1552 | assert (pci_get_drvdata (pdev) != NULL); | ||
1553 | |||
1554 | card = pci_get_drvdata (pdev); | ||
1555 | if (card->ac97->dev_mixer == minor) | ||
1556 | goto match; | ||
1557 | } | ||
1558 | } | ||
1559 | |||
1560 | DPRINTK ("EXIT, returning -ENODEV\n"); | ||
1561 | return -ENODEV; | ||
1562 | |||
1563 | match: | ||
1564 | pci_dev_put(pdev); | ||
1565 | file->private_data = card->ac97; | ||
1566 | |||
1567 | DPRINTK ("EXIT, returning 0\n"); | ||
1568 | return nonseekable_open(inode, file); | ||
1569 | } | ||
1570 | |||
1571 | static int via_mixer_ioctl (struct inode *inode, struct file *file, unsigned int cmd, | ||
1572 | unsigned long arg) | ||
1573 | { | ||
1574 | struct ac97_codec *codec = file->private_data; | ||
1575 | struct via_info *card; | ||
1576 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
1577 | int rc; | ||
1578 | |||
1579 | DPRINTK ("ENTER\n"); | ||
1580 | |||
1581 | assert (codec != NULL); | ||
1582 | card = codec->private_data; | ||
1583 | assert (card != NULL); | ||
1584 | |||
1585 | rc = via_syscall_down (card, nonblock); | ||
1586 | if (rc) goto out; | ||
1587 | |||
1588 | #if 0 | ||
1589 | /* | ||
1590 | * Intercept volume control on 8233 and 8235 | ||
1591 | */ | ||
1592 | if(card->volume) | ||
1593 | { | ||
1594 | switch(cmd) | ||
1595 | { | ||
1596 | case SOUND_MIXER_READ_VOLUME: | ||
1597 | return card->mixer_vol; | ||
1598 | case SOUND_MIXER_WRITE_VOLUME: | ||
1599 | { | ||
1600 | int v; | ||
1601 | if(get_user(v, (int *)arg)) | ||
1602 | { | ||
1603 | rc = -EFAULT; | ||
1604 | goto out; | ||
1605 | } | ||
1606 | card->mixer_vol = v; | ||
1607 | } | ||
1608 | } | ||
1609 | } | ||
1610 | #endif | ||
1611 | rc = codec->mixer_ioctl(codec, cmd, arg); | ||
1612 | |||
1613 | mutex_unlock(&card->syscall_mutex); | ||
1614 | |||
1615 | out: | ||
1616 | DPRINTK ("EXIT, returning %d\n", rc); | ||
1617 | return rc; | ||
1618 | } | ||
1619 | |||
1620 | |||
1621 | static const struct file_operations via_mixer_fops = { | ||
1622 | .owner = THIS_MODULE, | ||
1623 | .open = via_mixer_open, | ||
1624 | .llseek = no_llseek, | ||
1625 | .ioctl = via_mixer_ioctl, | ||
1626 | }; | ||
1627 | |||
1628 | |||
1629 | static int __devinit via_ac97_reset (struct via_info *card) | ||
1630 | { | ||
1631 | struct pci_dev *pdev = card->pdev; | ||
1632 | u8 tmp8; | ||
1633 | u16 tmp16; | ||
1634 | |||
1635 | DPRINTK ("ENTER\n"); | ||
1636 | |||
1637 | assert (pdev != NULL); | ||
1638 | |||
1639 | #ifndef NDEBUG | ||
1640 | { | ||
1641 | u8 r40,r41,r42,r43,r44,r48; | ||
1642 | pci_read_config_byte (card->pdev, 0x40, &r40); | ||
1643 | pci_read_config_byte (card->pdev, 0x41, &r41); | ||
1644 | pci_read_config_byte (card->pdev, 0x42, &r42); | ||
1645 | pci_read_config_byte (card->pdev, 0x43, &r43); | ||
1646 | pci_read_config_byte (card->pdev, 0x44, &r44); | ||
1647 | pci_read_config_byte (card->pdev, 0x48, &r48); | ||
1648 | DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n", | ||
1649 | r40,r41,r42,r43,r44,r48); | ||
1650 | |||
1651 | spin_lock_irq (&card->lock); | ||
1652 | DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", | ||
1653 | inb (card->baseaddr + 0x00), | ||
1654 | inb (card->baseaddr + 0x01), | ||
1655 | inb (card->baseaddr + 0x02), | ||
1656 | inl (card->baseaddr + 0x04), | ||
1657 | inl (card->baseaddr + 0x0C), | ||
1658 | inl (card->baseaddr + 0x80), | ||
1659 | inl (card->baseaddr + 0x84)); | ||
1660 | spin_unlock_irq (&card->lock); | ||
1661 | |||
1662 | } | ||
1663 | #endif | ||
1664 | |||
1665 | /* | ||
1666 | * Reset AC97 controller: enable, disable, enable, | ||
1667 | * pausing after each command for good luck. Only | ||
1668 | * do this if the codec is not ready, because it causes | ||
1669 | * loud pops and such due to such a hard codec reset. | ||
1670 | */ | ||
1671 | pci_read_config_byte (pdev, VIA_ACLINK_STATUS, &tmp8); | ||
1672 | if ((tmp8 & VIA_CR40_AC97_READY) == 0) { | ||
1673 | pci_write_config_byte (pdev, VIA_ACLINK_CTRL, | ||
1674 | VIA_CR41_AC97_ENABLE | | ||
1675 | VIA_CR41_AC97_RESET | | ||
1676 | VIA_CR41_AC97_WAKEUP); | ||
1677 | udelay (100); | ||
1678 | |||
1679 | pci_write_config_byte (pdev, VIA_ACLINK_CTRL, 0); | ||
1680 | udelay (100); | ||
1681 | |||
1682 | pci_write_config_byte (pdev, VIA_ACLINK_CTRL, | ||
1683 | VIA_CR41_AC97_ENABLE | | ||
1684 | VIA_CR41_PCM_ENABLE | | ||
1685 | VIA_CR41_VRA | VIA_CR41_AC97_RESET); | ||
1686 | udelay (100); | ||
1687 | } | ||
1688 | |||
1689 | /* Make sure VRA is enabled, in case we didn't do a | ||
1690 | * complete codec reset, above | ||
1691 | */ | ||
1692 | pci_read_config_byte (pdev, VIA_ACLINK_CTRL, &tmp8); | ||
1693 | if (((tmp8 & VIA_CR41_VRA) == 0) || | ||
1694 | ((tmp8 & VIA_CR41_AC97_ENABLE) == 0) || | ||
1695 | ((tmp8 & VIA_CR41_PCM_ENABLE) == 0) || | ||
1696 | ((tmp8 & VIA_CR41_AC97_RESET) == 0)) { | ||
1697 | pci_write_config_byte (pdev, VIA_ACLINK_CTRL, | ||
1698 | VIA_CR41_AC97_ENABLE | | ||
1699 | VIA_CR41_PCM_ENABLE | | ||
1700 | VIA_CR41_VRA | VIA_CR41_AC97_RESET); | ||
1701 | udelay (100); | ||
1702 | } | ||
1703 | |||
1704 | if(card->legacy) | ||
1705 | { | ||
1706 | #if 0 /* this breaks on K7M */ | ||
1707 | /* disable legacy stuff */ | ||
1708 | pci_write_config_byte (pdev, 0x42, 0x00); | ||
1709 | udelay(10); | ||
1710 | #endif | ||
1711 | |||
1712 | /* route FM trap to IRQ, disable FM trap */ | ||
1713 | pci_write_config_byte (pdev, 0x48, 0x05); | ||
1714 | udelay(10); | ||
1715 | } | ||
1716 | |||
1717 | /* disable all codec GPI interrupts */ | ||
1718 | outl (0, pci_resource_start (pdev, 0) + 0x8C); | ||
1719 | |||
1720 | /* WARNING: this line is magic. Remove this | ||
1721 | * and things break. */ | ||
1722 | /* enable variable rate */ | ||
1723 | tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS); | ||
1724 | if ((tmp16 & 1) == 0) | ||
1725 | via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1); | ||
1726 | |||
1727 | DPRINTK ("EXIT, returning 0\n"); | ||
1728 | return 0; | ||
1729 | } | ||
1730 | |||
1731 | |||
1732 | static void via_ac97_codec_wait (struct ac97_codec *codec) | ||
1733 | { | ||
1734 | assert (codec->private_data != NULL); | ||
1735 | via_ac97_wait_idle (codec->private_data); | ||
1736 | } | ||
1737 | |||
1738 | |||
1739 | static int __devinit via_ac97_init (struct via_info *card) | ||
1740 | { | ||
1741 | int rc; | ||
1742 | u16 tmp16; | ||
1743 | |||
1744 | DPRINTK ("ENTER\n"); | ||
1745 | |||
1746 | assert (card != NULL); | ||
1747 | |||
1748 | card->ac97 = ac97_alloc_codec(); | ||
1749 | if(card->ac97 == NULL) | ||
1750 | return -ENOMEM; | ||
1751 | |||
1752 | card->ac97->private_data = card; | ||
1753 | card->ac97->codec_read = via_ac97_read_reg; | ||
1754 | card->ac97->codec_write = via_ac97_write_reg; | ||
1755 | card->ac97->codec_wait = via_ac97_codec_wait; | ||
1756 | |||
1757 | card->ac97->dev_mixer = register_sound_mixer (&via_mixer_fops, -1); | ||
1758 | if (card->ac97->dev_mixer < 0) { | ||
1759 | printk (KERN_ERR PFX "unable to register AC97 mixer, aborting\n"); | ||
1760 | DPRINTK ("EXIT, returning -EIO\n"); | ||
1761 | ac97_release_codec(card->ac97); | ||
1762 | return -EIO; | ||
1763 | } | ||
1764 | |||
1765 | rc = via_ac97_reset (card); | ||
1766 | if (rc) { | ||
1767 | printk (KERN_ERR PFX "unable to reset AC97 codec, aborting\n"); | ||
1768 | goto err_out; | ||
1769 | } | ||
1770 | |||
1771 | mdelay(10); | ||
1772 | |||
1773 | if (ac97_probe_codec (card->ac97) == 0) { | ||
1774 | printk (KERN_ERR PFX "unable to probe AC97 codec, aborting\n"); | ||
1775 | rc = -EIO; | ||
1776 | goto err_out; | ||
1777 | } | ||
1778 | |||
1779 | /* enable variable rate */ | ||
1780 | tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS); | ||
1781 | via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1); | ||
1782 | |||
1783 | /* | ||
1784 | * If we cannot enable VRA, we have a locked-rate codec. | ||
1785 | * We try again to enable VRA before assuming so, however. | ||
1786 | */ | ||
1787 | tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS); | ||
1788 | if ((tmp16 & 1) == 0) { | ||
1789 | via_ac97_write_reg (card->ac97, AC97_EXTENDED_STATUS, tmp16 | 1); | ||
1790 | tmp16 = via_ac97_read_reg (card->ac97, AC97_EXTENDED_STATUS); | ||
1791 | if ((tmp16 & 1) == 0) { | ||
1792 | card->locked_rate = 1; | ||
1793 | printk (KERN_WARNING PFX "Codec rate locked at 48Khz\n"); | ||
1794 | } | ||
1795 | } | ||
1796 | |||
1797 | DPRINTK ("EXIT, returning 0\n"); | ||
1798 | return 0; | ||
1799 | |||
1800 | err_out: | ||
1801 | unregister_sound_mixer (card->ac97->dev_mixer); | ||
1802 | DPRINTK ("EXIT, returning %d\n", rc); | ||
1803 | ac97_release_codec(card->ac97); | ||
1804 | return rc; | ||
1805 | } | ||
1806 | |||
1807 | |||
1808 | static void via_ac97_cleanup (struct via_info *card) | ||
1809 | { | ||
1810 | DPRINTK ("ENTER\n"); | ||
1811 | |||
1812 | assert (card != NULL); | ||
1813 | assert (card->ac97->dev_mixer >= 0); | ||
1814 | |||
1815 | unregister_sound_mixer (card->ac97->dev_mixer); | ||
1816 | ac97_release_codec(card->ac97); | ||
1817 | |||
1818 | DPRINTK ("EXIT\n"); | ||
1819 | } | ||
1820 | |||
1821 | |||
1822 | |||
1823 | /**************************************************************** | ||
1824 | * | ||
1825 | * Interrupt-related code | ||
1826 | * | ||
1827 | */ | ||
1828 | |||
1829 | /** | ||
1830 | * via_intr_channel - handle an interrupt for a single channel | ||
1831 | * @card: unused | ||
1832 | * @chan: handle interrupt for this channel | ||
1833 | * | ||
1834 | * This is the "meat" of the interrupt handler, | ||
1835 | * containing the actions taken each time an interrupt | ||
1836 | * occurs. All communication and coordination with | ||
1837 | * userspace takes place here. | ||
1838 | * | ||
1839 | * Locking: inside card->lock | ||
1840 | */ | ||
1841 | |||
1842 | static void via_intr_channel (struct via_info *card, struct via_channel *chan) | ||
1843 | { | ||
1844 | u8 status; | ||
1845 | int n; | ||
1846 | |||
1847 | /* check pertinent bits of status register for action bits */ | ||
1848 | status = inb (chan->iobase) & (VIA_SGD_FLAG | VIA_SGD_EOL | VIA_SGD_STOPPED); | ||
1849 | if (!status) | ||
1850 | return; | ||
1851 | |||
1852 | /* acknowledge any flagged bits ASAP */ | ||
1853 | outb (status, chan->iobase); | ||
1854 | |||
1855 | if (!chan->sgtable) /* XXX: temporary solution */ | ||
1856 | return; | ||
1857 | |||
1858 | /* grab current h/w ptr value */ | ||
1859 | n = atomic_read (&chan->hw_ptr); | ||
1860 | |||
1861 | /* sanity check: make sure our h/w ptr doesn't have a weird value */ | ||
1862 | assert (n >= 0); | ||
1863 | assert (n < chan->frag_number); | ||
1864 | |||
1865 | |||
1866 | /* reset SGD data structure in memory to reflect a full buffer, | ||
1867 | * and advance the h/w ptr, wrapping around to zero if needed | ||
1868 | */ | ||
1869 | if (n == (chan->frag_number - 1)) { | ||
1870 | chan->sgtable[n].count = cpu_to_le32(chan->frag_size | VIA_EOL); | ||
1871 | atomic_set (&chan->hw_ptr, 0); | ||
1872 | } else { | ||
1873 | chan->sgtable[n].count = cpu_to_le32(chan->frag_size | VIA_FLAG); | ||
1874 | atomic_inc (&chan->hw_ptr); | ||
1875 | } | ||
1876 | |||
1877 | /* accounting crap for SNDCTL_DSP_GETxPTR */ | ||
1878 | chan->n_irqs++; | ||
1879 | chan->bytes += chan->frag_size; | ||
1880 | /* FIXME - signed overflow is undefined */ | ||
1881 | if (chan->bytes < 0) /* handle overflow of 31-bit value */ | ||
1882 | chan->bytes = chan->frag_size; | ||
1883 | /* all following checks only occur when not in mmap(2) mode */ | ||
1884 | if (!chan->is_mapped) | ||
1885 | { | ||
1886 | /* If we are recording, then n_frags represents the number | ||
1887 | * of fragments waiting to be handled by userspace. | ||
1888 | * If we are playback, then n_frags represents the number | ||
1889 | * of fragments remaining to be filled by userspace. | ||
1890 | * We increment here. If we reach max number of fragments, | ||
1891 | * this indicates an underrun/overrun. For this case under OSS, | ||
1892 | * we stop the record/playback process. | ||
1893 | */ | ||
1894 | if (atomic_read (&chan->n_frags) < chan->frag_number) | ||
1895 | atomic_inc (&chan->n_frags); | ||
1896 | assert (atomic_read (&chan->n_frags) <= chan->frag_number); | ||
1897 | if (atomic_read (&chan->n_frags) == chan->frag_number) { | ||
1898 | chan->is_active = 0; | ||
1899 | via_chan_stop (chan->iobase); | ||
1900 | } | ||
1901 | } | ||
1902 | /* wake up anyone listening to see when interrupts occur */ | ||
1903 | wake_up_all (&chan->wait); | ||
1904 | |||
1905 | DPRINTK ("%s intr, status=0x%02X, hwptr=0x%lX, chan->hw_ptr=%d\n", | ||
1906 | chan->name, status, (long) inl (chan->iobase + 0x04), | ||
1907 | atomic_read (&chan->hw_ptr)); | ||
1908 | |||
1909 | DPRINTK ("%s intr, channel n_frags == %d, missed %d\n", chan->name, | ||
1910 | atomic_read (&chan->n_frags), missed); | ||
1911 | } | ||
1912 | |||
1913 | |||
1914 | static irqreturn_t via_interrupt(int irq, void *dev_id) | ||
1915 | { | ||
1916 | struct via_info *card = dev_id; | ||
1917 | u32 status32; | ||
1918 | |||
1919 | /* to minimize interrupt sharing costs, we use the SGD status | ||
1920 | * shadow register to check the status of all inputs and | ||
1921 | * outputs with a single 32-bit bus read. If no interrupt | ||
1922 | * conditions are flagged, we exit immediately | ||
1923 | */ | ||
1924 | status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW); | ||
1925 | if (!(status32 & VIA_INTR_MASK)) | ||
1926 | { | ||
1927 | #ifdef CONFIG_MIDI_VIA82CXXX | ||
1928 | if (card->midi_devc) | ||
1929 | uart401intr(irq, card->midi_devc); | ||
1930 | #endif | ||
1931 | return IRQ_HANDLED; | ||
1932 | } | ||
1933 | DPRINTK ("intr, status32 == 0x%08X\n", status32); | ||
1934 | |||
1935 | /* synchronize interrupt handling under SMP. this spinlock | ||
1936 | * goes away completely on UP | ||
1937 | */ | ||
1938 | spin_lock (&card->lock); | ||
1939 | |||
1940 | if (status32 & VIA_INTR_OUT) | ||
1941 | via_intr_channel (card, &card->ch_out); | ||
1942 | if (status32 & VIA_INTR_IN) | ||
1943 | via_intr_channel (card, &card->ch_in); | ||
1944 | if (status32 & VIA_INTR_FM) | ||
1945 | via_intr_channel (card, &card->ch_fm); | ||
1946 | |||
1947 | spin_unlock (&card->lock); | ||
1948 | |||
1949 | return IRQ_HANDLED; | ||
1950 | } | ||
1951 | |||
1952 | static irqreturn_t via_new_interrupt(int irq, void *dev_id) | ||
1953 | { | ||
1954 | struct via_info *card = dev_id; | ||
1955 | u32 status32; | ||
1956 | |||
1957 | /* to minimize interrupt sharing costs, we use the SGD status | ||
1958 | * shadow register to check the status of all inputs and | ||
1959 | * outputs with a single 32-bit bus read. If no interrupt | ||
1960 | * conditions are flagged, we exit immediately | ||
1961 | */ | ||
1962 | status32 = inl (card->baseaddr + VIA_BASE0_SGD_STATUS_SHADOW); | ||
1963 | if (!(status32 & VIA_NEW_INTR_MASK)) | ||
1964 | return IRQ_NONE; | ||
1965 | /* | ||
1966 | * goes away completely on UP | ||
1967 | */ | ||
1968 | spin_lock (&card->lock); | ||
1969 | |||
1970 | via_intr_channel (card, &card->ch_out); | ||
1971 | via_intr_channel (card, &card->ch_in); | ||
1972 | via_intr_channel (card, &card->ch_fm); | ||
1973 | |||
1974 | spin_unlock (&card->lock); | ||
1975 | return IRQ_HANDLED; | ||
1976 | } | ||
1977 | |||
1978 | |||
1979 | /** | ||
1980 | * via_interrupt_init - Initialize interrupt handling | ||
1981 | * @card: Private info for specified board | ||
1982 | * | ||
1983 | * Obtain and reserve IRQ for using in handling audio events. | ||
1984 | * Also, disable any IRQ-generating resources, to make sure | ||
1985 | * we don't get interrupts before we want them. | ||
1986 | */ | ||
1987 | |||
1988 | static int via_interrupt_init (struct via_info *card) | ||
1989 | { | ||
1990 | u8 tmp8; | ||
1991 | |||
1992 | DPRINTK ("ENTER\n"); | ||
1993 | |||
1994 | assert (card != NULL); | ||
1995 | assert (card->pdev != NULL); | ||
1996 | |||
1997 | /* check for sane IRQ number. can this ever happen? */ | ||
1998 | if (card->pdev->irq < 2) { | ||
1999 | printk (KERN_ERR PFX "insane IRQ %d, aborting\n", | ||
2000 | card->pdev->irq); | ||
2001 | DPRINTK ("EXIT, returning -EIO\n"); | ||
2002 | return -EIO; | ||
2003 | } | ||
2004 | |||
2005 | /* VIA requires this is done */ | ||
2006 | pci_write_config_byte(card->pdev, PCI_INTERRUPT_LINE, card->pdev->irq); | ||
2007 | |||
2008 | if(card->legacy) | ||
2009 | { | ||
2010 | /* make sure FM irq is not routed to us */ | ||
2011 | pci_read_config_byte (card->pdev, VIA_FM_NMI_CTRL, &tmp8); | ||
2012 | if ((tmp8 & VIA_CR48_FM_TRAP_TO_NMI) == 0) { | ||
2013 | tmp8 |= VIA_CR48_FM_TRAP_TO_NMI; | ||
2014 | pci_write_config_byte (card->pdev, VIA_FM_NMI_CTRL, tmp8); | ||
2015 | } | ||
2016 | if (request_irq (card->pdev->irq, via_interrupt, IRQF_SHARED, VIA_MODULE_NAME, card)) { | ||
2017 | printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n", | ||
2018 | card->pdev->irq); | ||
2019 | DPRINTK ("EXIT, returning -EBUSY\n"); | ||
2020 | return -EBUSY; | ||
2021 | } | ||
2022 | } | ||
2023 | else | ||
2024 | { | ||
2025 | if (request_irq (card->pdev->irq, via_new_interrupt, IRQF_SHARED, VIA_MODULE_NAME, card)) { | ||
2026 | printk (KERN_ERR PFX "unable to obtain IRQ %d, aborting\n", | ||
2027 | card->pdev->irq); | ||
2028 | DPRINTK ("EXIT, returning -EBUSY\n"); | ||
2029 | return -EBUSY; | ||
2030 | } | ||
2031 | } | ||
2032 | |||
2033 | DPRINTK ("EXIT, returning 0\n"); | ||
2034 | return 0; | ||
2035 | } | ||
2036 | |||
2037 | |||
2038 | /**************************************************************** | ||
2039 | * | ||
2040 | * OSS DSP device | ||
2041 | * | ||
2042 | */ | ||
2043 | |||
2044 | static const struct file_operations via_dsp_fops = { | ||
2045 | .owner = THIS_MODULE, | ||
2046 | .open = via_dsp_open, | ||
2047 | .release = via_dsp_release, | ||
2048 | .read = via_dsp_read, | ||
2049 | .write = via_dsp_write, | ||
2050 | .poll = via_dsp_poll, | ||
2051 | .llseek = no_llseek, | ||
2052 | .ioctl = via_dsp_ioctl, | ||
2053 | .mmap = via_dsp_mmap, | ||
2054 | }; | ||
2055 | |||
2056 | |||
2057 | static int __devinit via_dsp_init (struct via_info *card) | ||
2058 | { | ||
2059 | u8 tmp8; | ||
2060 | |||
2061 | DPRINTK ("ENTER\n"); | ||
2062 | |||
2063 | assert (card != NULL); | ||
2064 | |||
2065 | if(card->legacy) | ||
2066 | { | ||
2067 | /* turn off legacy features, if not already */ | ||
2068 | pci_read_config_byte (card->pdev, VIA_FUNC_ENABLE, &tmp8); | ||
2069 | if (tmp8 & (VIA_CR42_SB_ENABLE | VIA_CR42_FM_ENABLE)) { | ||
2070 | tmp8 &= ~(VIA_CR42_SB_ENABLE | VIA_CR42_FM_ENABLE); | ||
2071 | pci_write_config_byte (card->pdev, VIA_FUNC_ENABLE, tmp8); | ||
2072 | } | ||
2073 | } | ||
2074 | |||
2075 | via_stop_everything (card); | ||
2076 | |||
2077 | card->dev_dsp = register_sound_dsp (&via_dsp_fops, -1); | ||
2078 | if (card->dev_dsp < 0) { | ||
2079 | DPRINTK ("EXIT, returning -ENODEV\n"); | ||
2080 | return -ENODEV; | ||
2081 | } | ||
2082 | DPRINTK ("EXIT, returning 0\n"); | ||
2083 | return 0; | ||
2084 | } | ||
2085 | |||
2086 | |||
2087 | static void via_dsp_cleanup (struct via_info *card) | ||
2088 | { | ||
2089 | DPRINTK ("ENTER\n"); | ||
2090 | |||
2091 | assert (card != NULL); | ||
2092 | assert (card->dev_dsp >= 0); | ||
2093 | |||
2094 | via_stop_everything (card); | ||
2095 | |||
2096 | unregister_sound_dsp (card->dev_dsp); | ||
2097 | |||
2098 | DPRINTK ("EXIT\n"); | ||
2099 | } | ||
2100 | |||
2101 | |||
2102 | static struct page * via_mm_nopage (struct vm_area_struct * vma, | ||
2103 | unsigned long address, int *type) | ||
2104 | { | ||
2105 | struct via_info *card = vma->vm_private_data; | ||
2106 | struct via_channel *chan = &card->ch_out; | ||
2107 | unsigned long max_bufs; | ||
2108 | struct page *dmapage; | ||
2109 | unsigned long pgoff; | ||
2110 | int rd, wr; | ||
2111 | |||
2112 | DPRINTK ("ENTER, start %lXh, ofs %lXh, pgoff %ld, addr %lXh\n", | ||
2113 | vma->vm_start, | ||
2114 | address - vma->vm_start, | ||
2115 | (address - vma->vm_start) >> PAGE_SHIFT, | ||
2116 | address); | ||
2117 | |||
2118 | if (address > vma->vm_end) { | ||
2119 | DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n"); | ||
2120 | return NOPAGE_SIGBUS; /* Disallow mremap */ | ||
2121 | } | ||
2122 | if (!card) { | ||
2123 | DPRINTK ("EXIT, returning NOPAGE_SIGBUS\n"); | ||
2124 | return NOPAGE_SIGBUS; /* Nothing allocated */ | ||
2125 | } | ||
2126 | |||
2127 | pgoff = vma->vm_pgoff + ((address - vma->vm_start) >> PAGE_SHIFT); | ||
2128 | rd = card->ch_in.is_mapped; | ||
2129 | wr = card->ch_out.is_mapped; | ||
2130 | |||
2131 | max_bufs = chan->frag_number; | ||
2132 | if (rd && wr) | ||
2133 | max_bufs *= 2; | ||
2134 | if (pgoff >= max_bufs) | ||
2135 | return NOPAGE_SIGBUS; | ||
2136 | |||
2137 | /* if full-duplex (read+write) and we have two sets of bufs, | ||
2138 | * then the playback buffers come first, sez soundcard.c */ | ||
2139 | if (pgoff >= chan->page_number) { | ||
2140 | pgoff -= chan->page_number; | ||
2141 | chan = &card->ch_in; | ||
2142 | } else if (!wr) | ||
2143 | chan = &card->ch_in; | ||
2144 | |||
2145 | assert ((((unsigned long)chan->pgtbl[pgoff].cpuaddr) % PAGE_SIZE) == 0); | ||
2146 | |||
2147 | dmapage = virt_to_page (chan->pgtbl[pgoff].cpuaddr); | ||
2148 | DPRINTK ("EXIT, returning page %p for cpuaddr %lXh\n", | ||
2149 | dmapage, (unsigned long) chan->pgtbl[pgoff].cpuaddr); | ||
2150 | get_page (dmapage); | ||
2151 | if (type) | ||
2152 | *type = VM_FAULT_MINOR; | ||
2153 | return dmapage; | ||
2154 | } | ||
2155 | |||
2156 | |||
2157 | #ifndef VM_RESERVED | ||
2158 | static int via_mm_swapout (struct page *page, struct file *filp) | ||
2159 | { | ||
2160 | return 0; | ||
2161 | } | ||
2162 | #endif /* VM_RESERVED */ | ||
2163 | |||
2164 | |||
2165 | static struct vm_operations_struct via_mm_ops = { | ||
2166 | .nopage = via_mm_nopage, | ||
2167 | |||
2168 | #ifndef VM_RESERVED | ||
2169 | .swapout = via_mm_swapout, | ||
2170 | #endif | ||
2171 | }; | ||
2172 | |||
2173 | |||
2174 | static int via_dsp_mmap(struct file *file, struct vm_area_struct *vma) | ||
2175 | { | ||
2176 | struct via_info *card; | ||
2177 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
2178 | int rc = -EINVAL, rd=0, wr=0; | ||
2179 | unsigned long max_size, size, start, offset; | ||
2180 | |||
2181 | assert (file != NULL); | ||
2182 | assert (vma != NULL); | ||
2183 | card = file->private_data; | ||
2184 | assert (card != NULL); | ||
2185 | |||
2186 | DPRINTK ("ENTER, start %lXh, size %ld, pgoff %ld\n", | ||
2187 | vma->vm_start, | ||
2188 | vma->vm_end - vma->vm_start, | ||
2189 | vma->vm_pgoff); | ||
2190 | |||
2191 | max_size = 0; | ||
2192 | if (vma->vm_flags & VM_READ) { | ||
2193 | rd = 1; | ||
2194 | via_chan_set_buffering(card, &card->ch_in, -1); | ||
2195 | via_chan_buffer_init (card, &card->ch_in); | ||
2196 | max_size += card->ch_in.page_number << PAGE_SHIFT; | ||
2197 | } | ||
2198 | if (vma->vm_flags & VM_WRITE) { | ||
2199 | wr = 1; | ||
2200 | via_chan_set_buffering(card, &card->ch_out, -1); | ||
2201 | via_chan_buffer_init (card, &card->ch_out); | ||
2202 | max_size += card->ch_out.page_number << PAGE_SHIFT; | ||
2203 | } | ||
2204 | |||
2205 | start = vma->vm_start; | ||
2206 | offset = (vma->vm_pgoff << PAGE_SHIFT); | ||
2207 | size = vma->vm_end - vma->vm_start; | ||
2208 | |||
2209 | /* some basic size/offset sanity checks */ | ||
2210 | if (size > max_size) | ||
2211 | goto out; | ||
2212 | if (offset > max_size - size) | ||
2213 | goto out; | ||
2214 | |||
2215 | rc = via_syscall_down (card, nonblock); | ||
2216 | if (rc) goto out; | ||
2217 | |||
2218 | vma->vm_ops = &via_mm_ops; | ||
2219 | vma->vm_private_data = card; | ||
2220 | |||
2221 | #ifdef VM_RESERVED | ||
2222 | vma->vm_flags |= VM_RESERVED; | ||
2223 | #endif | ||
2224 | |||
2225 | if (rd) | ||
2226 | card->ch_in.is_mapped = 1; | ||
2227 | if (wr) | ||
2228 | card->ch_out.is_mapped = 1; | ||
2229 | |||
2230 | mutex_unlock(&card->syscall_mutex); | ||
2231 | rc = 0; | ||
2232 | |||
2233 | out: | ||
2234 | DPRINTK ("EXIT, returning %d\n", rc); | ||
2235 | return rc; | ||
2236 | } | ||
2237 | |||
2238 | |||
2239 | static ssize_t via_dsp_do_read (struct via_info *card, | ||
2240 | char __user *userbuf, size_t count, | ||
2241 | int nonblock) | ||
2242 | { | ||
2243 | DECLARE_WAITQUEUE(wait, current); | ||
2244 | const char __user *orig_userbuf = userbuf; | ||
2245 | struct via_channel *chan = &card->ch_in; | ||
2246 | size_t size; | ||
2247 | int n, tmp; | ||
2248 | ssize_t ret = 0; | ||
2249 | |||
2250 | /* if SGD has not yet been started, start it */ | ||
2251 | via_chan_maybe_start (chan); | ||
2252 | |||
2253 | handle_one_block: | ||
2254 | /* just to be a nice neighbor */ | ||
2255 | /* Thomas Sailer: | ||
2256 | * But also to ourselves, release semaphore if we do so */ | ||
2257 | if (need_resched()) { | ||
2258 | mutex_unlock(&card->syscall_mutex); | ||
2259 | schedule (); | ||
2260 | ret = via_syscall_down (card, nonblock); | ||
2261 | if (ret) | ||
2262 | goto out; | ||
2263 | } | ||
2264 | |||
2265 | /* grab current channel software pointer. In the case of | ||
2266 | * recording, this is pointing to the next buffer that | ||
2267 | * will receive data from the audio hardware. | ||
2268 | */ | ||
2269 | n = chan->sw_ptr; | ||
2270 | |||
2271 | /* n_frags represents the number of fragments waiting | ||
2272 | * to be copied to userland. sleep until at least | ||
2273 | * one buffer has been read from the audio hardware. | ||
2274 | */ | ||
2275 | add_wait_queue(&chan->wait, &wait); | ||
2276 | for (;;) { | ||
2277 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2278 | tmp = atomic_read (&chan->n_frags); | ||
2279 | assert (tmp >= 0); | ||
2280 | assert (tmp <= chan->frag_number); | ||
2281 | if (tmp) | ||
2282 | break; | ||
2283 | if (nonblock || !chan->is_active) { | ||
2284 | ret = -EAGAIN; | ||
2285 | break; | ||
2286 | } | ||
2287 | |||
2288 | mutex_unlock(&card->syscall_mutex); | ||
2289 | |||
2290 | DPRINTK ("Sleeping on block %d\n", n); | ||
2291 | schedule(); | ||
2292 | |||
2293 | ret = via_syscall_down (card, nonblock); | ||
2294 | if (ret) | ||
2295 | break; | ||
2296 | |||
2297 | if (signal_pending (current)) { | ||
2298 | ret = -ERESTARTSYS; | ||
2299 | break; | ||
2300 | } | ||
2301 | } | ||
2302 | set_current_state(TASK_RUNNING); | ||
2303 | remove_wait_queue(&chan->wait, &wait); | ||
2304 | if (ret) | ||
2305 | goto out; | ||
2306 | |||
2307 | /* Now that we have a buffer we can read from, send | ||
2308 | * as much as sample data possible to userspace. | ||
2309 | */ | ||
2310 | while ((count > 0) && (chan->slop_len < chan->frag_size)) { | ||
2311 | size_t slop_left = chan->frag_size - chan->slop_len; | ||
2312 | void *base = chan->pgtbl[n / (PAGE_SIZE / chan->frag_size)].cpuaddr; | ||
2313 | unsigned ofs = (n % (PAGE_SIZE / chan->frag_size)) * chan->frag_size; | ||
2314 | |||
2315 | size = (count < slop_left) ? count : slop_left; | ||
2316 | if (copy_to_user (userbuf, | ||
2317 | base + ofs + chan->slop_len, | ||
2318 | size)) { | ||
2319 | ret = -EFAULT; | ||
2320 | goto out; | ||
2321 | } | ||
2322 | |||
2323 | count -= size; | ||
2324 | chan->slop_len += size; | ||
2325 | userbuf += size; | ||
2326 | } | ||
2327 | |||
2328 | /* If we didn't copy the buffer completely to userspace, | ||
2329 | * stop now. | ||
2330 | */ | ||
2331 | if (chan->slop_len < chan->frag_size) | ||
2332 | goto out; | ||
2333 | |||
2334 | /* | ||
2335 | * If we get to this point, we copied one buffer completely | ||
2336 | * to userspace, give the buffer back to the hardware. | ||
2337 | */ | ||
2338 | |||
2339 | /* advance channel software pointer to point to | ||
2340 | * the next buffer from which we will copy | ||
2341 | */ | ||
2342 | if (chan->sw_ptr == (chan->frag_number - 1)) | ||
2343 | chan->sw_ptr = 0; | ||
2344 | else | ||
2345 | chan->sw_ptr++; | ||
2346 | |||
2347 | /* mark one less buffer waiting to be processed */ | ||
2348 | assert (atomic_read (&chan->n_frags) > 0); | ||
2349 | atomic_dec (&chan->n_frags); | ||
2350 | |||
2351 | /* we are at a block boundary, there is no fragment data */ | ||
2352 | chan->slop_len = 0; | ||
2353 | |||
2354 | DPRINTK ("Flushed block %u, sw_ptr now %u, n_frags now %d\n", | ||
2355 | n, chan->sw_ptr, atomic_read (&chan->n_frags)); | ||
2356 | |||
2357 | DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", | ||
2358 | inb (card->baseaddr + 0x00), | ||
2359 | inb (card->baseaddr + 0x01), | ||
2360 | inb (card->baseaddr + 0x02), | ||
2361 | inl (card->baseaddr + 0x04), | ||
2362 | inl (card->baseaddr + 0x0C), | ||
2363 | inl (card->baseaddr + 0x80), | ||
2364 | inl (card->baseaddr + 0x84)); | ||
2365 | |||
2366 | if (count > 0) | ||
2367 | goto handle_one_block; | ||
2368 | |||
2369 | out: | ||
2370 | return (userbuf != orig_userbuf) ? (userbuf - orig_userbuf) : ret; | ||
2371 | } | ||
2372 | |||
2373 | |||
2374 | static ssize_t via_dsp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | ||
2375 | { | ||
2376 | struct via_info *card; | ||
2377 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
2378 | int rc; | ||
2379 | |||
2380 | DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n", | ||
2381 | file, buffer, count, ppos ? ((unsigned long)*ppos) : 0); | ||
2382 | |||
2383 | assert (file != NULL); | ||
2384 | card = file->private_data; | ||
2385 | assert (card != NULL); | ||
2386 | |||
2387 | rc = via_syscall_down (card, nonblock); | ||
2388 | if (rc) goto out; | ||
2389 | |||
2390 | if (card->ch_in.is_mapped) { | ||
2391 | rc = -ENXIO; | ||
2392 | goto out_up; | ||
2393 | } | ||
2394 | |||
2395 | via_chan_set_buffering(card, &card->ch_in, -1); | ||
2396 | rc = via_chan_buffer_init (card, &card->ch_in); | ||
2397 | |||
2398 | if (rc) | ||
2399 | goto out_up; | ||
2400 | |||
2401 | rc = via_dsp_do_read (card, buffer, count, nonblock); | ||
2402 | |||
2403 | out_up: | ||
2404 | mutex_unlock(&card->syscall_mutex); | ||
2405 | out: | ||
2406 | DPRINTK ("EXIT, returning %ld\n",(long) rc); | ||
2407 | return rc; | ||
2408 | } | ||
2409 | |||
2410 | |||
2411 | static ssize_t via_dsp_do_write (struct via_info *card, | ||
2412 | const char __user *userbuf, size_t count, | ||
2413 | int nonblock) | ||
2414 | { | ||
2415 | DECLARE_WAITQUEUE(wait, current); | ||
2416 | const char __user *orig_userbuf = userbuf; | ||
2417 | struct via_channel *chan = &card->ch_out; | ||
2418 | volatile struct via_sgd_table *sgtable = chan->sgtable; | ||
2419 | size_t size; | ||
2420 | int n, tmp; | ||
2421 | ssize_t ret = 0; | ||
2422 | |||
2423 | handle_one_block: | ||
2424 | /* just to be a nice neighbor */ | ||
2425 | /* Thomas Sailer: | ||
2426 | * But also to ourselves, release semaphore if we do so */ | ||
2427 | if (need_resched()) { | ||
2428 | mutex_unlock(&card->syscall_mutex); | ||
2429 | schedule (); | ||
2430 | ret = via_syscall_down (card, nonblock); | ||
2431 | if (ret) | ||
2432 | goto out; | ||
2433 | } | ||
2434 | |||
2435 | /* grab current channel fragment pointer. In the case of | ||
2436 | * playback, this is pointing to the next fragment that | ||
2437 | * should receive data from userland. | ||
2438 | */ | ||
2439 | n = chan->sw_ptr; | ||
2440 | |||
2441 | /* n_frags represents the number of fragments remaining | ||
2442 | * to be filled by userspace. Sleep until | ||
2443 | * at least one fragment is available for our use. | ||
2444 | */ | ||
2445 | add_wait_queue(&chan->wait, &wait); | ||
2446 | for (;;) { | ||
2447 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2448 | tmp = atomic_read (&chan->n_frags); | ||
2449 | assert (tmp >= 0); | ||
2450 | assert (tmp <= chan->frag_number); | ||
2451 | if (tmp) | ||
2452 | break; | ||
2453 | if (nonblock || !chan->is_active) { | ||
2454 | ret = -EAGAIN; | ||
2455 | break; | ||
2456 | } | ||
2457 | |||
2458 | mutex_unlock(&card->syscall_mutex); | ||
2459 | |||
2460 | DPRINTK ("Sleeping on page %d, tmp==%d, ir==%d\n", n, tmp, chan->is_record); | ||
2461 | schedule(); | ||
2462 | |||
2463 | ret = via_syscall_down (card, nonblock); | ||
2464 | if (ret) | ||
2465 | break; | ||
2466 | |||
2467 | if (signal_pending (current)) { | ||
2468 | ret = -ERESTARTSYS; | ||
2469 | break; | ||
2470 | } | ||
2471 | } | ||
2472 | set_current_state(TASK_RUNNING); | ||
2473 | remove_wait_queue(&chan->wait, &wait); | ||
2474 | if (ret) | ||
2475 | goto out; | ||
2476 | |||
2477 | /* Now that we have at least one fragment we can write to, fill the buffer | ||
2478 | * as much as possible with data from userspace. | ||
2479 | */ | ||
2480 | while ((count > 0) && (chan->slop_len < chan->frag_size)) { | ||
2481 | size_t slop_left = chan->frag_size - chan->slop_len; | ||
2482 | |||
2483 | size = (count < slop_left) ? count : slop_left; | ||
2484 | if (copy_from_user (chan->pgtbl[n / (PAGE_SIZE / chan->frag_size)].cpuaddr + (n % (PAGE_SIZE / chan->frag_size)) * chan->frag_size + chan->slop_len, | ||
2485 | userbuf, size)) { | ||
2486 | ret = -EFAULT; | ||
2487 | goto out; | ||
2488 | } | ||
2489 | |||
2490 | count -= size; | ||
2491 | chan->slop_len += size; | ||
2492 | userbuf += size; | ||
2493 | } | ||
2494 | |||
2495 | /* If we didn't fill up the buffer with data, stop now. | ||
2496 | * Put a 'stop' marker in the DMA table too, to tell the | ||
2497 | * audio hardware to stop if it gets here. | ||
2498 | */ | ||
2499 | if (chan->slop_len < chan->frag_size) { | ||
2500 | sgtable[n].count = cpu_to_le32 (chan->slop_len | VIA_EOL | VIA_STOP); | ||
2501 | goto out; | ||
2502 | } | ||
2503 | |||
2504 | /* | ||
2505 | * If we get to this point, we have filled a buffer with | ||
2506 | * audio data, flush the buffer to audio hardware. | ||
2507 | */ | ||
2508 | |||
2509 | /* Record the true size for the audio hardware to notice */ | ||
2510 | if (n == (chan->frag_number - 1)) | ||
2511 | sgtable[n].count = cpu_to_le32 (chan->frag_size | VIA_EOL); | ||
2512 | else | ||
2513 | sgtable[n].count = cpu_to_le32 (chan->frag_size | VIA_FLAG); | ||
2514 | |||
2515 | /* advance channel software pointer to point to | ||
2516 | * the next buffer we will fill with data | ||
2517 | */ | ||
2518 | if (chan->sw_ptr == (chan->frag_number - 1)) | ||
2519 | chan->sw_ptr = 0; | ||
2520 | else | ||
2521 | chan->sw_ptr++; | ||
2522 | |||
2523 | /* mark one less buffer as being available for userspace consumption */ | ||
2524 | assert (atomic_read (&chan->n_frags) > 0); | ||
2525 | atomic_dec (&chan->n_frags); | ||
2526 | |||
2527 | /* we are at a block boundary, there is no fragment data */ | ||
2528 | chan->slop_len = 0; | ||
2529 | |||
2530 | /* if SGD has not yet been started, start it */ | ||
2531 | via_chan_maybe_start (chan); | ||
2532 | |||
2533 | DPRINTK ("Flushed block %u, sw_ptr now %u, n_frags now %d\n", | ||
2534 | n, chan->sw_ptr, atomic_read (&chan->n_frags)); | ||
2535 | |||
2536 | DPRINTK ("regs==S=%02X C=%02X TP=%02X BP=%08X RT=%08X SG=%08X CC=%08X SS=%08X\n", | ||
2537 | inb (card->baseaddr + 0x00), | ||
2538 | inb (card->baseaddr + 0x01), | ||
2539 | inb (card->baseaddr + 0x02), | ||
2540 | inl (card->baseaddr + 0x04), | ||
2541 | inl (card->baseaddr + 0x08), | ||
2542 | inl (card->baseaddr + 0x0C), | ||
2543 | inl (card->baseaddr + 0x80), | ||
2544 | inl (card->baseaddr + 0x84)); | ||
2545 | |||
2546 | if (count > 0) | ||
2547 | goto handle_one_block; | ||
2548 | |||
2549 | out: | ||
2550 | if (userbuf - orig_userbuf) | ||
2551 | return userbuf - orig_userbuf; | ||
2552 | else | ||
2553 | return ret; | ||
2554 | } | ||
2555 | |||
2556 | |||
2557 | static ssize_t via_dsp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | ||
2558 | { | ||
2559 | struct via_info *card; | ||
2560 | ssize_t rc; | ||
2561 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
2562 | |||
2563 | DPRINTK ("ENTER, file=%p, buffer=%p, count=%u, ppos=%lu\n", | ||
2564 | file, buffer, count, ppos ? ((unsigned long)*ppos) : 0); | ||
2565 | |||
2566 | assert (file != NULL); | ||
2567 | card = file->private_data; | ||
2568 | assert (card != NULL); | ||
2569 | |||
2570 | rc = via_syscall_down (card, nonblock); | ||
2571 | if (rc) goto out; | ||
2572 | |||
2573 | if (card->ch_out.is_mapped) { | ||
2574 | rc = -ENXIO; | ||
2575 | goto out_up; | ||
2576 | } | ||
2577 | |||
2578 | via_chan_set_buffering(card, &card->ch_out, -1); | ||
2579 | rc = via_chan_buffer_init (card, &card->ch_out); | ||
2580 | |||
2581 | if (rc) | ||
2582 | goto out_up; | ||
2583 | |||
2584 | rc = via_dsp_do_write (card, buffer, count, nonblock); | ||
2585 | |||
2586 | out_up: | ||
2587 | mutex_unlock(&card->syscall_mutex); | ||
2588 | out: | ||
2589 | DPRINTK ("EXIT, returning %ld\n",(long) rc); | ||
2590 | return rc; | ||
2591 | } | ||
2592 | |||
2593 | |||
2594 | static unsigned int via_dsp_poll(struct file *file, struct poll_table_struct *wait) | ||
2595 | { | ||
2596 | struct via_info *card; | ||
2597 | struct via_channel *chan; | ||
2598 | unsigned int mask = 0; | ||
2599 | |||
2600 | DPRINTK ("ENTER\n"); | ||
2601 | |||
2602 | assert (file != NULL); | ||
2603 | card = file->private_data; | ||
2604 | assert (card != NULL); | ||
2605 | |||
2606 | if (file->f_mode & FMODE_READ) { | ||
2607 | chan = &card->ch_in; | ||
2608 | if (sg_active (chan->iobase)) | ||
2609 | poll_wait(file, &chan->wait, wait); | ||
2610 | if (atomic_read (&chan->n_frags) > 0) | ||
2611 | mask |= POLLIN | POLLRDNORM; | ||
2612 | } | ||
2613 | |||
2614 | if (file->f_mode & FMODE_WRITE) { | ||
2615 | chan = &card->ch_out; | ||
2616 | if (sg_active (chan->iobase)) | ||
2617 | poll_wait(file, &chan->wait, wait); | ||
2618 | if (atomic_read (&chan->n_frags) > 0) | ||
2619 | mask |= POLLOUT | POLLWRNORM; | ||
2620 | } | ||
2621 | |||
2622 | DPRINTK ("EXIT, returning %u\n", mask); | ||
2623 | return mask; | ||
2624 | } | ||
2625 | |||
2626 | |||
2627 | /** | ||
2628 | * via_dsp_drain_playback - sleep until all playback samples are flushed | ||
2629 | * @card: Private info for specified board | ||
2630 | * @chan: Channel to drain | ||
2631 | * @nonblock: boolean, non-zero if O_NONBLOCK is set | ||
2632 | * | ||
2633 | * Sleeps until all playback has been flushed to the audio | ||
2634 | * hardware. | ||
2635 | * | ||
2636 | * Locking: inside card->syscall_mutex | ||
2637 | */ | ||
2638 | |||
2639 | static int via_dsp_drain_playback (struct via_info *card, | ||
2640 | struct via_channel *chan, int nonblock) | ||
2641 | { | ||
2642 | DECLARE_WAITQUEUE(wait, current); | ||
2643 | int ret = 0; | ||
2644 | |||
2645 | DPRINTK ("ENTER, nonblock = %d\n", nonblock); | ||
2646 | |||
2647 | if (chan->slop_len > 0) | ||
2648 | via_chan_flush_frag (chan); | ||
2649 | |||
2650 | if (atomic_read (&chan->n_frags) == chan->frag_number) | ||
2651 | goto out; | ||
2652 | |||
2653 | via_chan_maybe_start (chan); | ||
2654 | |||
2655 | add_wait_queue(&chan->wait, &wait); | ||
2656 | for (;;) { | ||
2657 | DPRINTK ("FRAGS %d FRAGNUM %d\n", atomic_read(&chan->n_frags), chan->frag_number); | ||
2658 | __set_current_state(TASK_INTERRUPTIBLE); | ||
2659 | if (atomic_read (&chan->n_frags) >= chan->frag_number) | ||
2660 | break; | ||
2661 | |||
2662 | if (nonblock) { | ||
2663 | DPRINTK ("EXIT, returning -EAGAIN\n"); | ||
2664 | ret = -EAGAIN; | ||
2665 | break; | ||
2666 | } | ||
2667 | |||
2668 | #ifdef VIA_DEBUG | ||
2669 | { | ||
2670 | u8 r40,r41,r42,r43,r44,r48; | ||
2671 | pci_read_config_byte (card->pdev, 0x40, &r40); | ||
2672 | pci_read_config_byte (card->pdev, 0x41, &r41); | ||
2673 | pci_read_config_byte (card->pdev, 0x42, &r42); | ||
2674 | pci_read_config_byte (card->pdev, 0x43, &r43); | ||
2675 | pci_read_config_byte (card->pdev, 0x44, &r44); | ||
2676 | pci_read_config_byte (card->pdev, 0x48, &r48); | ||
2677 | DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n", | ||
2678 | r40,r41,r42,r43,r44,r48); | ||
2679 | |||
2680 | DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", | ||
2681 | inb (card->baseaddr + 0x00), | ||
2682 | inb (card->baseaddr + 0x01), | ||
2683 | inb (card->baseaddr + 0x02), | ||
2684 | inl (card->baseaddr + 0x04), | ||
2685 | inl (card->baseaddr + 0x0C), | ||
2686 | inl (card->baseaddr + 0x80), | ||
2687 | inl (card->baseaddr + 0x84)); | ||
2688 | } | ||
2689 | |||
2690 | if (!chan->is_active) | ||
2691 | printk (KERN_ERR "sleeping but not active\n"); | ||
2692 | #endif | ||
2693 | |||
2694 | mutex_unlock(&card->syscall_mutex); | ||
2695 | |||
2696 | DPRINTK ("sleeping, nbufs=%d\n", atomic_read (&chan->n_frags)); | ||
2697 | schedule(); | ||
2698 | |||
2699 | if ((ret = via_syscall_down (card, nonblock))) | ||
2700 | break; | ||
2701 | |||
2702 | if (signal_pending (current)) { | ||
2703 | DPRINTK ("EXIT, returning -ERESTARTSYS\n"); | ||
2704 | ret = -ERESTARTSYS; | ||
2705 | break; | ||
2706 | } | ||
2707 | } | ||
2708 | set_current_state(TASK_RUNNING); | ||
2709 | remove_wait_queue(&chan->wait, &wait); | ||
2710 | |||
2711 | #ifdef VIA_DEBUG | ||
2712 | { | ||
2713 | u8 r40,r41,r42,r43,r44,r48; | ||
2714 | pci_read_config_byte (card->pdev, 0x40, &r40); | ||
2715 | pci_read_config_byte (card->pdev, 0x41, &r41); | ||
2716 | pci_read_config_byte (card->pdev, 0x42, &r42); | ||
2717 | pci_read_config_byte (card->pdev, 0x43, &r43); | ||
2718 | pci_read_config_byte (card->pdev, 0x44, &r44); | ||
2719 | pci_read_config_byte (card->pdev, 0x48, &r48); | ||
2720 | DPRINTK ("PCI config: %02X %02X %02X %02X %02X %02X\n", | ||
2721 | r40,r41,r42,r43,r44,r48); | ||
2722 | |||
2723 | DPRINTK ("regs==%02X %02X %02X %08X %08X %08X %08X\n", | ||
2724 | inb (card->baseaddr + 0x00), | ||
2725 | inb (card->baseaddr + 0x01), | ||
2726 | inb (card->baseaddr + 0x02), | ||
2727 | inl (card->baseaddr + 0x04), | ||
2728 | inl (card->baseaddr + 0x0C), | ||
2729 | inl (card->baseaddr + 0x80), | ||
2730 | inl (card->baseaddr + 0x84)); | ||
2731 | |||
2732 | DPRINTK ("final nbufs=%d\n", atomic_read (&chan->n_frags)); | ||
2733 | } | ||
2734 | #endif | ||
2735 | |||
2736 | out: | ||
2737 | DPRINTK ("EXIT, returning %d\n", ret); | ||
2738 | return ret; | ||
2739 | } | ||
2740 | |||
2741 | |||
2742 | /** | ||
2743 | * via_dsp_ioctl_space - get information about channel buffering | ||
2744 | * @card: Private info for specified board | ||
2745 | * @chan: pointer to channel-specific info | ||
2746 | * @arg: user buffer for returned information | ||
2747 | * | ||
2748 | * Handles SNDCTL_DSP_GETISPACE and SNDCTL_DSP_GETOSPACE. | ||
2749 | * | ||
2750 | * Locking: inside card->syscall_mutex | ||
2751 | */ | ||
2752 | |||
2753 | static int via_dsp_ioctl_space (struct via_info *card, | ||
2754 | struct via_channel *chan, | ||
2755 | void __user *arg) | ||
2756 | { | ||
2757 | audio_buf_info info; | ||
2758 | |||
2759 | via_chan_set_buffering(card, chan, -1); | ||
2760 | |||
2761 | info.fragstotal = chan->frag_number; | ||
2762 | info.fragsize = chan->frag_size; | ||
2763 | |||
2764 | /* number of full fragments we can read/write without blocking */ | ||
2765 | info.fragments = atomic_read (&chan->n_frags); | ||
2766 | |||
2767 | if ((chan->slop_len % chan->frag_size > 0) && (info.fragments > 0)) | ||
2768 | info.fragments--; | ||
2769 | |||
2770 | /* number of bytes that can be read or written immediately | ||
2771 | * without blocking. | ||
2772 | */ | ||
2773 | info.bytes = (info.fragments * chan->frag_size); | ||
2774 | if (chan->slop_len % chan->frag_size > 0) | ||
2775 | info.bytes += chan->frag_size - (chan->slop_len % chan->frag_size); | ||
2776 | |||
2777 | DPRINTK ("EXIT, returning fragstotal=%d, fragsize=%d, fragments=%d, bytes=%d\n", | ||
2778 | info.fragstotal, | ||
2779 | info.fragsize, | ||
2780 | info.fragments, | ||
2781 | info.bytes); | ||
2782 | |||
2783 | return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0; | ||
2784 | } | ||
2785 | |||
2786 | |||
2787 | /** | ||
2788 | * via_dsp_ioctl_ptr - get information about hardware buffer ptr | ||
2789 | * @card: Private info for specified board | ||
2790 | * @chan: pointer to channel-specific info | ||
2791 | * @arg: user buffer for returned information | ||
2792 | * | ||
2793 | * Handles SNDCTL_DSP_GETIPTR and SNDCTL_DSP_GETOPTR. | ||
2794 | * | ||
2795 | * Locking: inside card->syscall_mutex | ||
2796 | */ | ||
2797 | |||
2798 | static int via_dsp_ioctl_ptr (struct via_info *card, | ||
2799 | struct via_channel *chan, | ||
2800 | void __user *arg) | ||
2801 | { | ||
2802 | count_info info; | ||
2803 | |||
2804 | spin_lock_irq (&card->lock); | ||
2805 | |||
2806 | info.bytes = chan->bytes; | ||
2807 | info.blocks = chan->n_irqs; | ||
2808 | chan->n_irqs = 0; | ||
2809 | |||
2810 | spin_unlock_irq (&card->lock); | ||
2811 | |||
2812 | if (chan->is_active) { | ||
2813 | unsigned long extra; | ||
2814 | info.ptr = atomic_read (&chan->hw_ptr) * chan->frag_size; | ||
2815 | extra = chan->frag_size - via_sg_offset(chan); | ||
2816 | info.ptr += extra; | ||
2817 | info.bytes += extra; | ||
2818 | } else { | ||
2819 | info.ptr = 0; | ||
2820 | } | ||
2821 | |||
2822 | DPRINTK ("EXIT, returning bytes=%d, blocks=%d, ptr=%d\n", | ||
2823 | info.bytes, | ||
2824 | info.blocks, | ||
2825 | info.ptr); | ||
2826 | |||
2827 | return copy_to_user (arg, &info, sizeof (info))?-EFAULT:0; | ||
2828 | } | ||
2829 | |||
2830 | |||
2831 | static int via_dsp_ioctl_trigger (struct via_channel *chan, int val) | ||
2832 | { | ||
2833 | int enable, do_something; | ||
2834 | |||
2835 | if (chan->is_record) | ||
2836 | enable = (val & PCM_ENABLE_INPUT); | ||
2837 | else | ||
2838 | enable = (val & PCM_ENABLE_OUTPUT); | ||
2839 | |||
2840 | if (!chan->is_enabled && enable) { | ||
2841 | do_something = 1; | ||
2842 | } else if (chan->is_enabled && !enable) { | ||
2843 | do_something = -1; | ||
2844 | } else { | ||
2845 | do_something = 0; | ||
2846 | } | ||
2847 | |||
2848 | DPRINTK ("enable=%d, do_something=%d\n", | ||
2849 | enable, do_something); | ||
2850 | |||
2851 | if (chan->is_active && do_something) | ||
2852 | return -EINVAL; | ||
2853 | |||
2854 | if (do_something == 1) { | ||
2855 | chan->is_enabled = 1; | ||
2856 | via_chan_maybe_start (chan); | ||
2857 | DPRINTK ("Triggering input\n"); | ||
2858 | } | ||
2859 | |||
2860 | else if (do_something == -1) { | ||
2861 | chan->is_enabled = 0; | ||
2862 | DPRINTK ("Setup input trigger\n"); | ||
2863 | } | ||
2864 | |||
2865 | return 0; | ||
2866 | } | ||
2867 | |||
2868 | |||
2869 | static int via_dsp_ioctl (struct inode *inode, struct file *file, | ||
2870 | unsigned int cmd, unsigned long arg) | ||
2871 | { | ||
2872 | int rc, rd=0, wr=0, val=0; | ||
2873 | struct via_info *card; | ||
2874 | struct via_channel *chan; | ||
2875 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
2876 | int __user *ip = (int __user *)arg; | ||
2877 | void __user *p = (void __user *)arg; | ||
2878 | |||
2879 | assert (file != NULL); | ||
2880 | card = file->private_data; | ||
2881 | assert (card != NULL); | ||
2882 | |||
2883 | if (file->f_mode & FMODE_WRITE) | ||
2884 | wr = 1; | ||
2885 | if (file->f_mode & FMODE_READ) | ||
2886 | rd = 1; | ||
2887 | |||
2888 | rc = via_syscall_down (card, nonblock); | ||
2889 | if (rc) | ||
2890 | return rc; | ||
2891 | rc = -EINVAL; | ||
2892 | |||
2893 | switch (cmd) { | ||
2894 | |||
2895 | /* OSS API version. XXX unverified */ | ||
2896 | case OSS_GETVERSION: | ||
2897 | DPRINTK ("ioctl OSS_GETVERSION, EXIT, returning SOUND_VERSION\n"); | ||
2898 | rc = put_user (SOUND_VERSION, ip); | ||
2899 | break; | ||
2900 | |||
2901 | /* list of supported PCM data formats */ | ||
2902 | case SNDCTL_DSP_GETFMTS: | ||
2903 | DPRINTK ("DSP_GETFMTS, EXIT, returning AFMT U8|S16_LE\n"); | ||
2904 | rc = put_user (AFMT_U8 | AFMT_S16_LE, ip); | ||
2905 | break; | ||
2906 | |||
2907 | /* query or set current channel's PCM data format */ | ||
2908 | case SNDCTL_DSP_SETFMT: | ||
2909 | if (get_user(val, ip)) { | ||
2910 | rc = -EFAULT; | ||
2911 | break; | ||
2912 | } | ||
2913 | DPRINTK ("DSP_SETFMT, val==%d\n", val); | ||
2914 | if (val != AFMT_QUERY) { | ||
2915 | rc = 0; | ||
2916 | |||
2917 | if (rd) | ||
2918 | rc = via_chan_set_fmt (card, &card->ch_in, val); | ||
2919 | |||
2920 | if (rc >= 0 && wr) | ||
2921 | rc = via_chan_set_fmt (card, &card->ch_out, val); | ||
2922 | |||
2923 | if (rc < 0) | ||
2924 | break; | ||
2925 | |||
2926 | val = rc; | ||
2927 | } else { | ||
2928 | if ((rd && (card->ch_in.pcm_fmt & VIA_PCM_FMT_16BIT)) || | ||
2929 | (wr && (card->ch_out.pcm_fmt & VIA_PCM_FMT_16BIT))) | ||
2930 | val = AFMT_S16_LE; | ||
2931 | else | ||
2932 | val = AFMT_U8; | ||
2933 | } | ||
2934 | DPRINTK ("SETFMT EXIT, returning %d\n", val); | ||
2935 | rc = put_user (val, ip); | ||
2936 | break; | ||
2937 | |||
2938 | /* query or set number of channels (1=mono, 2=stereo, 4/6 for multichannel) */ | ||
2939 | case SNDCTL_DSP_CHANNELS: | ||
2940 | if (get_user(val, ip)) { | ||
2941 | rc = -EFAULT; | ||
2942 | break; | ||
2943 | } | ||
2944 | DPRINTK ("DSP_CHANNELS, val==%d\n", val); | ||
2945 | if (val != 0) { | ||
2946 | rc = 0; | ||
2947 | |||
2948 | if (rd) | ||
2949 | rc = via_chan_set_stereo (card, &card->ch_in, val); | ||
2950 | |||
2951 | if (rc >= 0 && wr) | ||
2952 | rc = via_chan_set_stereo (card, &card->ch_out, val); | ||
2953 | |||
2954 | if (rc < 0) | ||
2955 | break; | ||
2956 | |||
2957 | val = rc; | ||
2958 | } else { | ||
2959 | if (rd) | ||
2960 | val = card->ch_in.channels; | ||
2961 | else | ||
2962 | val = card->ch_out.channels; | ||
2963 | } | ||
2964 | DPRINTK ("CHANNELS EXIT, returning %d\n", val); | ||
2965 | rc = put_user (val, ip); | ||
2966 | break; | ||
2967 | |||
2968 | /* enable (val is not zero) or disable (val == 0) stereo */ | ||
2969 | case SNDCTL_DSP_STEREO: | ||
2970 | if (get_user(val, ip)) { | ||
2971 | rc = -EFAULT; | ||
2972 | break; | ||
2973 | } | ||
2974 | DPRINTK ("DSP_STEREO, val==%d\n", val); | ||
2975 | rc = 0; | ||
2976 | |||
2977 | if (rd) | ||
2978 | rc = via_chan_set_stereo (card, &card->ch_in, val ? 2 : 1); | ||
2979 | if (rc >= 0 && wr) | ||
2980 | rc = via_chan_set_stereo (card, &card->ch_out, val ? 2 : 1); | ||
2981 | |||
2982 | if (rc < 0) | ||
2983 | break; | ||
2984 | |||
2985 | val = rc - 1; | ||
2986 | |||
2987 | DPRINTK ("STEREO EXIT, returning %d\n", val); | ||
2988 | rc = put_user(val, ip); | ||
2989 | break; | ||
2990 | |||
2991 | /* query or set sampling rate */ | ||
2992 | case SNDCTL_DSP_SPEED: | ||
2993 | if (get_user(val, ip)) { | ||
2994 | rc = -EFAULT; | ||
2995 | break; | ||
2996 | } | ||
2997 | DPRINTK ("DSP_SPEED, val==%d\n", val); | ||
2998 | if (val < 0) { | ||
2999 | rc = -EINVAL; | ||
3000 | break; | ||
3001 | } | ||
3002 | if (val > 0) { | ||
3003 | rc = 0; | ||
3004 | |||
3005 | if (rd) | ||
3006 | rc = via_chan_set_speed (card, &card->ch_in, val); | ||
3007 | if (rc >= 0 && wr) | ||
3008 | rc = via_chan_set_speed (card, &card->ch_out, val); | ||
3009 | |||
3010 | if (rc < 0) | ||
3011 | break; | ||
3012 | |||
3013 | val = rc; | ||
3014 | } else { | ||
3015 | if (rd) | ||
3016 | val = card->ch_in.rate; | ||
3017 | else if (wr) | ||
3018 | val = card->ch_out.rate; | ||
3019 | else | ||
3020 | val = 0; | ||
3021 | } | ||
3022 | DPRINTK ("SPEED EXIT, returning %d\n", val); | ||
3023 | rc = put_user (val, ip); | ||
3024 | break; | ||
3025 | |||
3026 | /* wait until all buffers have been played, and then stop device */ | ||
3027 | case SNDCTL_DSP_SYNC: | ||
3028 | DPRINTK ("DSP_SYNC\n"); | ||
3029 | rc = 0; | ||
3030 | if (wr) { | ||
3031 | DPRINTK ("SYNC EXIT (after calling via_dsp_drain_playback)\n"); | ||
3032 | rc = via_dsp_drain_playback (card, &card->ch_out, nonblock); | ||
3033 | } | ||
3034 | break; | ||
3035 | |||
3036 | /* stop recording/playback immediately */ | ||
3037 | case SNDCTL_DSP_RESET: | ||
3038 | DPRINTK ("DSP_RESET\n"); | ||
3039 | if (rd) { | ||
3040 | via_chan_clear (card, &card->ch_in); | ||
3041 | card->ch_in.frag_number = 0; | ||
3042 | card->ch_in.frag_size = 0; | ||
3043 | atomic_set(&card->ch_in.n_frags, 0); | ||
3044 | } | ||
3045 | |||
3046 | if (wr) { | ||
3047 | via_chan_clear (card, &card->ch_out); | ||
3048 | card->ch_out.frag_number = 0; | ||
3049 | card->ch_out.frag_size = 0; | ||
3050 | atomic_set(&card->ch_out.n_frags, 0); | ||
3051 | } | ||
3052 | |||
3053 | rc = 0; | ||
3054 | break; | ||
3055 | |||
3056 | case SNDCTL_DSP_NONBLOCK: | ||
3057 | file->f_flags |= O_NONBLOCK; | ||
3058 | rc = 0; | ||
3059 | break; | ||
3060 | |||
3061 | /* obtain bitmask of device capabilities, such as mmap, full duplex, etc. */ | ||
3062 | case SNDCTL_DSP_GETCAPS: | ||
3063 | DPRINTK ("DSP_GETCAPS\n"); | ||
3064 | rc = put_user(VIA_DSP_CAP, ip); | ||
3065 | break; | ||
3066 | |||
3067 | /* obtain buffer fragment size */ | ||
3068 | case SNDCTL_DSP_GETBLKSIZE: | ||
3069 | DPRINTK ("DSP_GETBLKSIZE\n"); | ||
3070 | |||
3071 | if (rd) { | ||
3072 | via_chan_set_buffering(card, &card->ch_in, -1); | ||
3073 | rc = put_user(card->ch_in.frag_size, ip); | ||
3074 | } else if (wr) { | ||
3075 | via_chan_set_buffering(card, &card->ch_out, -1); | ||
3076 | rc = put_user(card->ch_out.frag_size, ip); | ||
3077 | } | ||
3078 | break; | ||
3079 | |||
3080 | /* obtain information about input buffering */ | ||
3081 | case SNDCTL_DSP_GETISPACE: | ||
3082 | DPRINTK ("DSP_GETISPACE\n"); | ||
3083 | if (rd) | ||
3084 | rc = via_dsp_ioctl_space (card, &card->ch_in, p); | ||
3085 | break; | ||
3086 | |||
3087 | /* obtain information about output buffering */ | ||
3088 | case SNDCTL_DSP_GETOSPACE: | ||
3089 | DPRINTK ("DSP_GETOSPACE\n"); | ||
3090 | if (wr) | ||
3091 | rc = via_dsp_ioctl_space (card, &card->ch_out, p); | ||
3092 | break; | ||
3093 | |||
3094 | /* obtain information about input hardware pointer */ | ||
3095 | case SNDCTL_DSP_GETIPTR: | ||
3096 | DPRINTK ("DSP_GETIPTR\n"); | ||
3097 | if (rd) | ||
3098 | rc = via_dsp_ioctl_ptr (card, &card->ch_in, p); | ||
3099 | break; | ||
3100 | |||
3101 | /* obtain information about output hardware pointer */ | ||
3102 | case SNDCTL_DSP_GETOPTR: | ||
3103 | DPRINTK ("DSP_GETOPTR\n"); | ||
3104 | if (wr) | ||
3105 | rc = via_dsp_ioctl_ptr (card, &card->ch_out, p); | ||
3106 | break; | ||
3107 | |||
3108 | /* return number of bytes remaining to be played by DMA engine */ | ||
3109 | case SNDCTL_DSP_GETODELAY: | ||
3110 | { | ||
3111 | DPRINTK ("DSP_GETODELAY\n"); | ||
3112 | |||
3113 | chan = &card->ch_out; | ||
3114 | |||
3115 | if (!wr) | ||
3116 | break; | ||
3117 | |||
3118 | if (chan->is_active) { | ||
3119 | |||
3120 | val = chan->frag_number - atomic_read (&chan->n_frags); | ||
3121 | |||
3122 | assert(val >= 0); | ||
3123 | |||
3124 | if (val > 0) { | ||
3125 | val *= chan->frag_size; | ||
3126 | val -= chan->frag_size - via_sg_offset(chan); | ||
3127 | } | ||
3128 | val += chan->slop_len % chan->frag_size; | ||
3129 | } else | ||
3130 | val = 0; | ||
3131 | |||
3132 | assert (val <= (chan->frag_size * chan->frag_number)); | ||
3133 | |||
3134 | DPRINTK ("GETODELAY EXIT, val = %d bytes\n", val); | ||
3135 | rc = put_user (val, ip); | ||
3136 | break; | ||
3137 | } | ||
3138 | |||
3139 | /* handle the quick-start of a channel, | ||
3140 | * or the notification that a quick-start will | ||
3141 | * occur in the future | ||
3142 | */ | ||
3143 | case SNDCTL_DSP_SETTRIGGER: | ||
3144 | if (get_user(val, ip)) { | ||
3145 | rc = -EFAULT; | ||
3146 | break; | ||
3147 | } | ||
3148 | DPRINTK ("DSP_SETTRIGGER, rd=%d, wr=%d, act=%d/%d, en=%d/%d\n", | ||
3149 | rd, wr, card->ch_in.is_active, card->ch_out.is_active, | ||
3150 | card->ch_in.is_enabled, card->ch_out.is_enabled); | ||
3151 | |||
3152 | rc = 0; | ||
3153 | |||
3154 | if (rd) | ||
3155 | rc = via_dsp_ioctl_trigger (&card->ch_in, val); | ||
3156 | |||
3157 | if (!rc && wr) | ||
3158 | rc = via_dsp_ioctl_trigger (&card->ch_out, val); | ||
3159 | |||
3160 | break; | ||
3161 | |||
3162 | case SNDCTL_DSP_GETTRIGGER: | ||
3163 | val = 0; | ||
3164 | if ((file->f_mode & FMODE_READ) && card->ch_in.is_enabled) | ||
3165 | val |= PCM_ENABLE_INPUT; | ||
3166 | if ((file->f_mode & FMODE_WRITE) && card->ch_out.is_enabled) | ||
3167 | val |= PCM_ENABLE_OUTPUT; | ||
3168 | rc = put_user(val, ip); | ||
3169 | break; | ||
3170 | |||
3171 | /* Enable full duplex. Since we do this as soon as we are opened | ||
3172 | * with O_RDWR, this is mainly a no-op that always returns success. | ||
3173 | */ | ||
3174 | case SNDCTL_DSP_SETDUPLEX: | ||
3175 | DPRINTK ("DSP_SETDUPLEX\n"); | ||
3176 | if (!rd || !wr) | ||
3177 | break; | ||
3178 | rc = 0; | ||
3179 | break; | ||
3180 | |||
3181 | /* set fragment size. implemented as a successful no-op for now */ | ||
3182 | case SNDCTL_DSP_SETFRAGMENT: | ||
3183 | if (get_user(val, ip)) { | ||
3184 | rc = -EFAULT; | ||
3185 | break; | ||
3186 | } | ||
3187 | DPRINTK ("DSP_SETFRAGMENT, val==%d\n", val); | ||
3188 | |||
3189 | if (rd) | ||
3190 | rc = via_chan_set_buffering(card, &card->ch_in, val); | ||
3191 | |||
3192 | if (wr) | ||
3193 | rc = via_chan_set_buffering(card, &card->ch_out, val); | ||
3194 | |||
3195 | DPRINTK ("SNDCTL_DSP_SETFRAGMENT (fragshift==0x%04X (%d), maxfrags==0x%04X (%d))\n", | ||
3196 | val & 0xFFFF, | ||
3197 | val & 0xFFFF, | ||
3198 | (val >> 16) & 0xFFFF, | ||
3199 | (val >> 16) & 0xFFFF); | ||
3200 | |||
3201 | rc = 0; | ||
3202 | break; | ||
3203 | |||
3204 | /* inform device of an upcoming pause in input (or output). */ | ||
3205 | case SNDCTL_DSP_POST: | ||
3206 | DPRINTK ("DSP_POST\n"); | ||
3207 | if (wr) { | ||
3208 | if (card->ch_out.slop_len > 0) | ||
3209 | via_chan_flush_frag (&card->ch_out); | ||
3210 | via_chan_maybe_start (&card->ch_out); | ||
3211 | } | ||
3212 | |||
3213 | rc = 0; | ||
3214 | break; | ||
3215 | |||
3216 | /* not implemented */ | ||
3217 | default: | ||
3218 | DPRINTK ("unhandled ioctl, cmd==%u, arg==%p\n", | ||
3219 | cmd, p); | ||
3220 | break; | ||
3221 | } | ||
3222 | |||
3223 | mutex_unlock(&card->syscall_mutex); | ||
3224 | DPRINTK ("EXIT, returning %d\n", rc); | ||
3225 | return rc; | ||
3226 | } | ||
3227 | |||
3228 | |||
3229 | static int via_dsp_open (struct inode *inode, struct file *file) | ||
3230 | { | ||
3231 | int minor = iminor(inode); | ||
3232 | struct via_info *card; | ||
3233 | struct pci_dev *pdev = NULL; | ||
3234 | struct via_channel *chan; | ||
3235 | struct pci_driver *drvr; | ||
3236 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
3237 | |||
3238 | DPRINTK ("ENTER, minor=%d, file->f_mode=0x%x\n", minor, file->f_mode); | ||
3239 | |||
3240 | if (!(file->f_mode & (FMODE_READ | FMODE_WRITE))) { | ||
3241 | DPRINTK ("EXIT, returning -EINVAL\n"); | ||
3242 | return -EINVAL; | ||
3243 | } | ||
3244 | |||
3245 | card = NULL; | ||
3246 | while ((pdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pdev)) != NULL) { | ||
3247 | drvr = pci_dev_driver (pdev); | ||
3248 | if (drvr == &via_driver) { | ||
3249 | assert (pci_get_drvdata (pdev) != NULL); | ||
3250 | |||
3251 | card = pci_get_drvdata (pdev); | ||
3252 | DPRINTK ("dev_dsp = %d, minor = %d, assn = %d\n", | ||
3253 | card->dev_dsp, minor, | ||
3254 | (card->dev_dsp ^ minor) & ~0xf); | ||
3255 | |||
3256 | if (((card->dev_dsp ^ minor) & ~0xf) == 0) | ||
3257 | goto match; | ||
3258 | } | ||
3259 | } | ||
3260 | |||
3261 | DPRINTK ("no matching %s found\n", card ? "minor" : "driver"); | ||
3262 | return -ENODEV; | ||
3263 | |||
3264 | match: | ||
3265 | pci_dev_put(pdev); | ||
3266 | if (nonblock) { | ||
3267 | if (!mutex_trylock(&card->open_mutex)) { | ||
3268 | DPRINTK ("EXIT, returning -EAGAIN\n"); | ||
3269 | return -EAGAIN; | ||
3270 | } | ||
3271 | } else { | ||
3272 | if (mutex_lock_interruptible(&card->open_mutex)) { | ||
3273 | DPRINTK ("EXIT, returning -ERESTARTSYS\n"); | ||
3274 | return -ERESTARTSYS; | ||
3275 | } | ||
3276 | } | ||
3277 | |||
3278 | file->private_data = card; | ||
3279 | DPRINTK ("file->f_mode == 0x%x\n", file->f_mode); | ||
3280 | |||
3281 | /* handle input from analog source */ | ||
3282 | if (file->f_mode & FMODE_READ) { | ||
3283 | chan = &card->ch_in; | ||
3284 | |||
3285 | via_chan_init (card, chan); | ||
3286 | |||
3287 | /* why is this forced to 16-bit stereo in all drivers? */ | ||
3288 | chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO; | ||
3289 | chan->channels = 2; | ||
3290 | |||
3291 | // TO DO - use FIFO: via_capture_fifo(card, 1); | ||
3292 | via_chan_pcm_fmt (chan, 0); | ||
3293 | via_set_rate (card->ac97, chan, 44100); | ||
3294 | } | ||
3295 | |||
3296 | /* handle output to analog source */ | ||
3297 | if (file->f_mode & FMODE_WRITE) { | ||
3298 | chan = &card->ch_out; | ||
3299 | |||
3300 | via_chan_init (card, chan); | ||
3301 | |||
3302 | if (file->f_mode & FMODE_READ) { | ||
3303 | /* if in duplex mode make the recording and playback channels | ||
3304 | have the same settings */ | ||
3305 | chan->pcm_fmt = VIA_PCM_FMT_16BIT | VIA_PCM_FMT_STEREO; | ||
3306 | chan->channels = 2; | ||
3307 | via_chan_pcm_fmt (chan, 0); | ||
3308 | via_set_rate (card->ac97, chan, 44100); | ||
3309 | } else { | ||
3310 | if ((minor & 0xf) == SND_DEV_DSP16) { | ||
3311 | chan->pcm_fmt = VIA_PCM_FMT_16BIT; | ||
3312 | via_chan_pcm_fmt (chan, 0); | ||
3313 | via_set_rate (card->ac97, chan, 44100); | ||
3314 | } else { | ||
3315 | via_chan_pcm_fmt (chan, 1); | ||
3316 | via_set_rate (card->ac97, chan, 8000); | ||
3317 | } | ||
3318 | } | ||
3319 | } | ||
3320 | |||
3321 | DPRINTK ("EXIT, returning 0\n"); | ||
3322 | return nonseekable_open(inode, file); | ||
3323 | } | ||
3324 | |||
3325 | |||
3326 | static int via_dsp_release(struct inode *inode, struct file *file) | ||
3327 | { | ||
3328 | struct via_info *card; | ||
3329 | int nonblock = (file->f_flags & O_NONBLOCK); | ||
3330 | int rc; | ||
3331 | |||
3332 | DPRINTK ("ENTER\n"); | ||
3333 | |||
3334 | assert (file != NULL); | ||
3335 | card = file->private_data; | ||
3336 | assert (card != NULL); | ||
3337 | |||
3338 | rc = via_syscall_down (card, nonblock); | ||
3339 | if (rc) { | ||
3340 | DPRINTK ("EXIT (syscall_down error), rc=%d\n", rc); | ||
3341 | return rc; | ||
3342 | } | ||
3343 | |||
3344 | if (file->f_mode & FMODE_WRITE) { | ||
3345 | rc = via_dsp_drain_playback (card, &card->ch_out, nonblock); | ||
3346 | if (rc && rc != -ERESTARTSYS) /* Nobody needs to know about ^C */ | ||
3347 | printk (KERN_DEBUG "via_audio: ignoring drain playback error %d\n", rc); | ||
3348 | |||
3349 | via_chan_free (card, &card->ch_out); | ||
3350 | via_chan_buffer_free(card, &card->ch_out); | ||
3351 | } | ||
3352 | |||
3353 | if (file->f_mode & FMODE_READ) { | ||
3354 | via_chan_free (card, &card->ch_in); | ||
3355 | via_chan_buffer_free (card, &card->ch_in); | ||
3356 | } | ||
3357 | |||
3358 | mutex_unlock(&card->syscall_mutex); | ||
3359 | mutex_unlock(&card->open_mutex); | ||
3360 | |||
3361 | DPRINTK ("EXIT, returning 0\n"); | ||
3362 | return 0; | ||
3363 | } | ||
3364 | |||
3365 | |||
3366 | /**************************************************************** | ||
3367 | * | ||
3368 | * Chip setup and kernel registration | ||
3369 | * | ||
3370 | * | ||
3371 | */ | ||
3372 | |||
3373 | static int __devinit via_init_one (struct pci_dev *pdev, const struct pci_device_id *id) | ||
3374 | { | ||
3375 | #ifdef CONFIG_MIDI_VIA82CXXX | ||
3376 | u8 r42; | ||
3377 | #endif | ||
3378 | int rc; | ||
3379 | struct via_info *card; | ||
3380 | static int printed_version; | ||
3381 | |||
3382 | DPRINTK ("ENTER\n"); | ||
3383 | |||
3384 | if (printed_version++ == 0) | ||
3385 | printk (KERN_INFO "Via 686a/8233/8235 audio driver " VIA_VERSION "\n"); | ||
3386 | |||
3387 | rc = pci_enable_device (pdev); | ||
3388 | if (rc) | ||
3389 | goto err_out; | ||
3390 | |||
3391 | rc = pci_request_regions (pdev, "via82cxxx_audio"); | ||
3392 | if (rc) | ||
3393 | goto err_out_disable; | ||
3394 | |||
3395 | rc = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
3396 | if (rc) | ||
3397 | goto err_out_res; | ||
3398 | rc = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK); | ||
3399 | if (rc) | ||
3400 | goto err_out_res; | ||
3401 | |||
3402 | card = kmalloc (sizeof (*card), GFP_KERNEL); | ||
3403 | if (!card) { | ||
3404 | printk (KERN_ERR PFX "out of memory, aborting\n"); | ||
3405 | rc = -ENOMEM; | ||
3406 | goto err_out_res; | ||
3407 | } | ||
3408 | |||
3409 | pci_set_drvdata (pdev, card); | ||
3410 | |||
3411 | memset (card, 0, sizeof (*card)); | ||
3412 | card->pdev = pdev; | ||
3413 | card->baseaddr = pci_resource_start (pdev, 0); | ||
3414 | card->card_num = via_num_cards++; | ||
3415 | spin_lock_init (&card->lock); | ||
3416 | spin_lock_init (&card->ac97_lock); | ||
3417 | mutex_init(&card->syscall_mutex); | ||
3418 | mutex_init(&card->open_mutex); | ||
3419 | |||
3420 | /* we must init these now, in case the intr handler needs them */ | ||
3421 | via_chan_init_defaults (card, &card->ch_out); | ||
3422 | via_chan_init_defaults (card, &card->ch_in); | ||
3423 | via_chan_init_defaults (card, &card->ch_fm); | ||
3424 | |||
3425 | /* if BAR 2 is present, chip is Rev H or later, | ||
3426 | * which means it has a few extra features */ | ||
3427 | if (pci_resource_start (pdev, 2) > 0) | ||
3428 | card->rev_h = 1; | ||
3429 | |||
3430 | /* Overkill for now, but more flexible done right */ | ||
3431 | |||
3432 | card->intmask = id->driver_data; | ||
3433 | card->legacy = !card->intmask; | ||
3434 | card->sixchannel = id->driver_data; | ||
3435 | |||
3436 | if(card->sixchannel) | ||
3437 | printk(KERN_INFO PFX "Six channel audio available\n"); | ||
3438 | if (pdev->irq < 1) { | ||
3439 | printk (KERN_ERR PFX "invalid PCI IRQ %d, aborting\n", pdev->irq); | ||
3440 | rc = -ENODEV; | ||
3441 | goto err_out_kfree; | ||
3442 | } | ||
3443 | |||
3444 | if (!(pci_resource_flags (pdev, 0) & IORESOURCE_IO)) { | ||
3445 | printk (KERN_ERR PFX "unable to locate I/O resources, aborting\n"); | ||
3446 | rc = -ENODEV; | ||
3447 | goto err_out_kfree; | ||
3448 | } | ||
3449 | |||
3450 | pci_set_master(pdev); | ||
3451 | |||
3452 | /* | ||
3453 | * init AC97 mixer and codec | ||
3454 | */ | ||
3455 | rc = via_ac97_init (card); | ||
3456 | if (rc) { | ||
3457 | printk (KERN_ERR PFX "AC97 init failed, aborting\n"); | ||
3458 | goto err_out_kfree; | ||
3459 | } | ||
3460 | |||
3461 | /* | ||
3462 | * init DSP device | ||
3463 | */ | ||
3464 | rc = via_dsp_init (card); | ||
3465 | if (rc) { | ||
3466 | printk (KERN_ERR PFX "DSP device init failed, aborting\n"); | ||
3467 | goto err_out_have_mixer; | ||
3468 | } | ||
3469 | |||
3470 | /* | ||
3471 | * init and turn on interrupts, as the last thing we do | ||
3472 | */ | ||
3473 | rc = via_interrupt_init (card); | ||
3474 | if (rc) { | ||
3475 | printk (KERN_ERR PFX "interrupt init failed, aborting\n"); | ||
3476 | goto err_out_have_dsp; | ||
3477 | } | ||
3478 | |||
3479 | printk (KERN_INFO PFX "board #%d at 0x%04lX, IRQ %d\n", | ||
3480 | card->card_num + 1, card->baseaddr, pdev->irq); | ||
3481 | |||
3482 | #ifdef CONFIG_MIDI_VIA82CXXX | ||
3483 | /* Disable by default */ | ||
3484 | card->midi_info.io_base = 0; | ||
3485 | |||
3486 | if(card->legacy) | ||
3487 | { | ||
3488 | pci_read_config_byte (pdev, 0x42, &r42); | ||
3489 | /* Disable MIDI interrupt */ | ||
3490 | pci_write_config_byte (pdev, 0x42, r42 | VIA_CR42_MIDI_IRQMASK); | ||
3491 | if (r42 & VIA_CR42_MIDI_ENABLE) | ||
3492 | { | ||
3493 | if (r42 & VIA_CR42_MIDI_PNP) /* Address selected by iobase 2 - not tested */ | ||
3494 | card->midi_info.io_base = pci_resource_start (pdev, 2); | ||
3495 | else /* Address selected by byte 0x43 */ | ||
3496 | { | ||
3497 | u8 r43; | ||
3498 | pci_read_config_byte (pdev, 0x43, &r43); | ||
3499 | card->midi_info.io_base = 0x300 + ((r43 & 0x0c) << 2); | ||
3500 | } | ||
3501 | |||
3502 | card->midi_info.irq = -pdev->irq; | ||
3503 | if (probe_uart401(& card->midi_info, THIS_MODULE)) | ||
3504 | { | ||
3505 | card->midi_devc=midi_devs[card->midi_info.slots[4]]->devc; | ||
3506 | pci_write_config_byte(pdev, 0x42, r42 & ~VIA_CR42_MIDI_IRQMASK); | ||
3507 | printk("Enabled Via MIDI\n"); | ||
3508 | } | ||
3509 | } | ||
3510 | } | ||
3511 | #endif | ||
3512 | |||
3513 | DPRINTK ("EXIT, returning 0\n"); | ||
3514 | return 0; | ||
3515 | |||
3516 | err_out_have_dsp: | ||
3517 | via_dsp_cleanup (card); | ||
3518 | |||
3519 | err_out_have_mixer: | ||
3520 | via_ac97_cleanup (card); | ||
3521 | |||
3522 | err_out_kfree: | ||
3523 | #ifndef VIA_NDEBUG | ||
3524 | memset (card, OSS_POISON_FREE, sizeof (*card)); /* poison memory */ | ||
3525 | #endif | ||
3526 | kfree (card); | ||
3527 | |||
3528 | err_out_res: | ||
3529 | pci_release_regions (pdev); | ||
3530 | |||
3531 | err_out_disable: | ||
3532 | pci_disable_device (pdev); | ||
3533 | |||
3534 | err_out: | ||
3535 | pci_set_drvdata (pdev, NULL); | ||
3536 | DPRINTK ("EXIT - returning %d\n", rc); | ||
3537 | return rc; | ||
3538 | } | ||
3539 | |||
3540 | |||
3541 | static void __devexit via_remove_one (struct pci_dev *pdev) | ||
3542 | { | ||
3543 | struct via_info *card; | ||
3544 | |||
3545 | DPRINTK ("ENTER\n"); | ||
3546 | |||
3547 | assert (pdev != NULL); | ||
3548 | card = pci_get_drvdata (pdev); | ||
3549 | assert (card != NULL); | ||
3550 | |||
3551 | #ifdef CONFIG_MIDI_VIA82CXXX | ||
3552 | if (card->midi_info.io_base) | ||
3553 | unload_uart401(&card->midi_info); | ||
3554 | #endif | ||
3555 | |||
3556 | free_irq (card->pdev->irq, card); | ||
3557 | via_dsp_cleanup (card); | ||
3558 | via_ac97_cleanup (card); | ||
3559 | |||
3560 | #ifndef VIA_NDEBUG | ||
3561 | memset (card, OSS_POISON_FREE, sizeof (*card)); /* poison memory */ | ||
3562 | #endif | ||
3563 | kfree (card); | ||
3564 | |||
3565 | pci_set_drvdata (pdev, NULL); | ||
3566 | |||
3567 | pci_release_regions (pdev); | ||
3568 | pci_disable_device (pdev); | ||
3569 | pci_set_power_state (pdev, 3); /* ...zzzzzz */ | ||
3570 | |||
3571 | DPRINTK ("EXIT\n"); | ||
3572 | return; | ||
3573 | } | ||
3574 | |||
3575 | |||
3576 | /**************************************************************** | ||
3577 | * | ||
3578 | * Driver initialization and cleanup | ||
3579 | * | ||
3580 | * | ||
3581 | */ | ||
3582 | |||
3583 | static int __init init_via82cxxx_audio(void) | ||
3584 | { | ||
3585 | int rc; | ||
3586 | |||
3587 | DPRINTK ("ENTER\n"); | ||
3588 | |||
3589 | rc = pci_register_driver (&via_driver); | ||
3590 | if (rc) { | ||
3591 | DPRINTK ("EXIT, returning %d\n", rc); | ||
3592 | return rc; | ||
3593 | } | ||
3594 | |||
3595 | DPRINTK ("EXIT, returning 0\n"); | ||
3596 | return 0; | ||
3597 | } | ||
3598 | |||
3599 | |||
3600 | static void __exit cleanup_via82cxxx_audio(void) | ||
3601 | { | ||
3602 | DPRINTK ("ENTER\n"); | ||
3603 | |||
3604 | pci_unregister_driver (&via_driver); | ||
3605 | |||
3606 | DPRINTK ("EXIT\n"); | ||
3607 | } | ||
3608 | |||
3609 | |||
3610 | module_init(init_via82cxxx_audio); | ||
3611 | module_exit(cleanup_via82cxxx_audio); | ||
3612 | |||
3613 | MODULE_AUTHOR("Jeff Garzik"); | ||
3614 | MODULE_DESCRIPTION("DSP audio and mixer driver for Via 82Cxxx audio devices"); | ||
3615 | MODULE_LICENSE("GPL"); | ||
3616 | |||