diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-05-21 17:00:02 -0400 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-21 17:00:02 -0400 |
commit | 67394f8f069c2fdf90f3b6d851824c07815442af (patch) | |
tree | 0c33e62d34dbaecea434ae9ece3cc0c56db8b1f7 | |
parent | 450cbfbbbd88876e3ccec1d277f613221ca82bb7 (diff) | |
parent | 9636273dae265b9354b861b373cd43cd76a6d0fe (diff) |
Merge with /usr/src/ntfs-2.6.git
645 files changed, 14859 insertions, 9780 deletions
@@ -339,7 +339,7 @@ W: http://tomas.nocrew.org/ | |||
339 | D: dsp56k device driver | 339 | D: dsp56k device driver |
340 | 340 | ||
341 | N: Ross Biro | 341 | N: Ross Biro |
342 | E: bir7@leland.Stanford.Edu | 342 | E: ross.biro@gmail.com |
343 | D: Original author of the Linux networking code | 343 | D: Original author of the Linux networking code |
344 | 344 | ||
345 | N: Anton Blanchard | 345 | N: Anton Blanchard |
@@ -882,13 +882,12 @@ S: Blacksburg, Virginia 24061 | |||
882 | S: USA | 882 | S: USA |
883 | 883 | ||
884 | N: Randy Dunlap | 884 | N: Randy Dunlap |
885 | E: rddunlap@osdl.org | 885 | E: rdunlap@xenotime.net |
886 | W: http://www.xenotime.net/linux/linux.html | 886 | W: http://www.xenotime.net/linux/linux.html |
887 | W: http://www.linux-usb.org | 887 | W: http://www.linux-usb.org |
888 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers | 888 | D: Linux-USB subsystem, USB core/UHCI/printer/storage drivers |
889 | D: x86 SMP, ACPI, bootflag hacking | 889 | D: x86 SMP, ACPI, bootflag hacking |
890 | S: 12725 SW Millikan Way, Suite 400 | 890 | S: (ask for current address) |
891 | S: Beaverton, Oregon 97005 | ||
892 | S: USA | 891 | S: USA |
893 | 892 | ||
894 | N: Bob Dunlop | 893 | N: Bob Dunlop |
diff --git a/Documentation/00-INDEX b/Documentation/00-INDEX index 72dc90f8f4a7..8de8a01a2474 100644 --- a/Documentation/00-INDEX +++ b/Documentation/00-INDEX | |||
@@ -12,8 +12,6 @@ Following translations are available on the WWW: | |||
12 | 12 | ||
13 | 00-INDEX | 13 | 00-INDEX |
14 | - this file. | 14 | - this file. |
15 | BK-usage/ | ||
16 | - directory with info on BitKeeper. | ||
17 | BUG-HUNTING | 15 | BUG-HUNTING |
18 | - brute force method of doing binary search of patches to find bug. | 16 | - brute force method of doing binary search of patches to find bug. |
19 | Changes | 17 | Changes |
diff --git a/Documentation/BK-usage/00-INDEX b/Documentation/BK-usage/00-INDEX deleted file mode 100644 index 82768784ea52..000000000000 --- a/Documentation/BK-usage/00-INDEX +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | bk-kernel-howto.txt: Description of kernel workflow under BitKeeper | ||
2 | |||
3 | bk-make-sum: Create summary of changesets in one repository and not | ||
4 | another, typically in preparation to be sent to an upstream maintainer. | ||
5 | Typical usage: | ||
6 | cd my-updated-repo | ||
7 | bk-make-sum ~/repo/original-repo | ||
8 | mv /tmp/linus.txt ../original-repo.txt | ||
9 | |||
10 | bksend: Create readable text output containing summary of changes, GNU | ||
11 | patch of the changes, and BK metadata of changes (as needed for proper | ||
12 | importing into BitKeeper by an upstream maintainer). This output is | ||
13 | suitable for emailing BitKeeper changes. The recipient of this output | ||
14 | may pipe it directly to 'bk receive'. | ||
15 | |||
16 | bz64wrap: helper script. Uncompressed input is piped to this script, | ||
17 | which compresses its input, and then outputs the uu-/base64-encoded | ||
18 | version of the compressed input. | ||
19 | |||
20 | cpcset: Copy changeset between unrelated repositories. | ||
21 | Attempts to preserve changeset user, user address, description, in | ||
22 | addition to the changeset (the patch) itself. | ||
23 | Typical usage: | ||
24 | cd my-updated-repo | ||
25 | bk changes # looking for a changeset... | ||
26 | cpcset 1.1511 . ../another-repo | ||
27 | |||
28 | csets-to-patches: Produces a delta of two BK repositories, in the form | ||
29 | of individual files, each containing a single cset as a GNU patch. | ||
30 | Output is several files, each with the filename "/tmp/rev-$REV.patch" | ||
31 | Typical usage: | ||
32 | cd my-updated-repo | ||
33 | bk changes -L ~/repo/original-repo 2>&1 | \ | ||
34 | perl csets-to-patches | ||
35 | |||
36 | cset-to-linus: Produces a delta of two BK repositories, in the form of | ||
37 | changeset descriptions, with 'diffstat' output created for each | ||
38 | individual changset. | ||
39 | Typical usage: | ||
40 | cd my-updated-repo | ||
41 | bk changes -L ~/repo/original-repo 2>&1 | \ | ||
42 | perl cset-to-linus > summary.txt | ||
43 | |||
44 | gcapatch: Generates patch containing changes in local repository. | ||
45 | Typical usage: | ||
46 | cd my-updated-repo | ||
47 | gcapatch > foo.patch | ||
48 | |||
49 | unbz64wrap: Reverse an encoded, compressed data stream created by | ||
50 | bz64wrap into an uncompressed, typically text/plain output. | ||
51 | |||
diff --git a/Documentation/BK-usage/bk-kernel-howto.txt b/Documentation/BK-usage/bk-kernel-howto.txt deleted file mode 100644 index b7b9075d2910..000000000000 --- a/Documentation/BK-usage/bk-kernel-howto.txt +++ /dev/null | |||
@@ -1,283 +0,0 @@ | |||
1 | |||
2 | Doing the BK Thing, Penguin-Style | ||
3 | |||
4 | |||
5 | |||
6 | |||
7 | This set of notes is intended mainly for kernel developers, occasional | ||
8 | or full-time, but sysadmins and power users may find parts of it useful | ||
9 | as well. It assumes at least a basic familiarity with CVS, both at a | ||
10 | user level (use on the cmd line) and at a higher level (client-server model). | ||
11 | Due to the author's background, an operation may be described in terms | ||
12 | of CVS, or in terms of how that operation differs from CVS. | ||
13 | |||
14 | This is -not- intended to be BitKeeper documentation. Always run | ||
15 | "bk help <command>" or in X "bk helptool <command>" for reference | ||
16 | documentation. | ||
17 | |||
18 | |||
19 | BitKeeper Concepts | ||
20 | ------------------ | ||
21 | |||
22 | In the true nature of the Internet itself, BitKeeper is a distributed | ||
23 | system. When applied to revision control, this means doing away with | ||
24 | client-server, and changing to a parent-child model... essentially | ||
25 | peer-to-peer. On the developer's end, this also represents a | ||
26 | fundamental disruption in the standard workflow of changes, commits, | ||
27 | and merges. You will need to take a few minutes to think about | ||
28 | how to best work under BitKeeper, and re-optimize things a bit. | ||
29 | In some sense it is a bit radical, because it might described as | ||
30 | tossing changes out into a maelstrom and having them magically | ||
31 | land at the right destination... but I'm getting ahead of myself. | ||
32 | |||
33 | Let's start with this progression: | ||
34 | Each BitKeeper source tree on disk is a repository unto itself. | ||
35 | Each repository has a parent (except the root/original, of course). | ||
36 | Each repository contains a set of a changesets ("csets"). | ||
37 | Each cset is one or more changed files, bundled together. | ||
38 | |||
39 | Each tree is a repository, so all changes are checked into the local | ||
40 | tree. When a change is checked in, all modified files are grouped | ||
41 | into a logical unit, the changeset. Internally, BK links these | ||
42 | changesets in a tree, representing various converging and diverging | ||
43 | lines of development. These changesets are the bread and butter of | ||
44 | the BK system. | ||
45 | |||
46 | After the concept of changesets, the next thing you need to get used | ||
47 | to is having multiple copies of source trees lying around. This -really- | ||
48 | takes some getting used to, for some people. Separate source trees | ||
49 | are the means in BitKeeper by which you delineate parallel lines | ||
50 | of development, both minor and major. What would be branches in | ||
51 | CVS become separate source trees, or "clones" in BitKeeper [heh, | ||
52 | or Star Wars] terminology. | ||
53 | |||
54 | Clones and changesets are the tools from which most of the power of | ||
55 | BitKeeper is derived. As mentioned earlier, each clone has a parent, | ||
56 | the tree used as the source when the new clone was created. In a | ||
57 | CVS-like setup, the parent would be a remote server on the Internet, | ||
58 | and the child is your local clone of that tree. | ||
59 | |||
60 | Once you have established a common baseline between two source trees -- | ||
61 | a common parent -- then you can merge changesets between those two | ||
62 | trees with ease. Merging changes into a tree is called a "pull", and | ||
63 | is analagous to 'cvs update'. A pull downloads all the changesets in | ||
64 | the remote tree you do not have, and merges them. Sending changes in | ||
65 | one tree to another tree is called a "push". Push sends all changes | ||
66 | in the local tree the remote does not yet have, and merges them. | ||
67 | |||
68 | From these concepts come some initial command examples: | ||
69 | |||
70 | 1) bk clone -q http://linux.bkbits.net/linux-2.5 linus-2.5 | ||
71 | Download a 2.5 stock kernel tree, naming it "linus-2.5" in the local dir. | ||
72 | The "-q" disables listing every single file as it is downloaded. | ||
73 | |||
74 | 2) bk clone -ql linus-2.5 alpha-2.5 | ||
75 | Create a separate source tree for the Alpha AXP architecture. | ||
76 | The "-l" uses hard links instead of copying data, since both trees are | ||
77 | on the local disk. You can also replace the above with "bk lclone -q ..." | ||
78 | |||
79 | You only clone a tree -once-. After cloning the tree lives a long time | ||
80 | on disk, being updating by pushes and pulls. | ||
81 | |||
82 | 3) cd alpha-2.5 ; bk pull http://gkernel.bkbits.net/alpha-2.5 | ||
83 | Download changes in "alpha-2.5" repository which are not present | ||
84 | in the local repository, and merge them into the source tree. | ||
85 | |||
86 | 4) bk -r co -q | ||
87 | Because every tree is a repository, files must be checked out before | ||
88 | they will be in their standard places in the source tree. | ||
89 | |||
90 | 5) bk vi fs/inode.c # example change... | ||
91 | bk citool # checkin, using X tool | ||
92 | bk push bk://gkernel@bkbits.net/alpha-2.5 # upload change | ||
93 | Typical example of a BK sequence that would replace the analagous CVS | ||
94 | situation, | ||
95 | vi fs/inode.c | ||
96 | cvs commit | ||
97 | |||
98 | As this is just supposed to be a quick BK intro, for more in-depth | ||
99 | tutorials, live working demos, and docs, see http://www.bitkeeper.com/ | ||
100 | |||
101 | |||
102 | |||
103 | BK and Kernel Development Workflow | ||
104 | ---------------------------------- | ||
105 | Currently the latest 2.5 tree is available via "bk clone $URL" | ||
106 | and "bk pull $URL" at http://linux.bkbits.net/linux-2.5 | ||
107 | This should change in a few weeks to a kernel.org URL. | ||
108 | |||
109 | |||
110 | A big part of using BitKeeper is organizing the various trees you have | ||
111 | on your local disk, and organizing the flow of changes among those | ||
112 | trees, and remote trees. If one were to graph the relationships between | ||
113 | a desired BK setup, you are likely to see a few-many-few graph, like | ||
114 | this: | ||
115 | |||
116 | linux-2.5 | ||
117 | | | ||
118 | merge-to-linus-2.5 | ||
119 | / | | | ||
120 | / | | | ||
121 | vm-hacks bugfixes filesys personal-hacks | ||
122 | \ | | / | ||
123 | \ | | / | ||
124 | \ | | / | ||
125 | testing-and-validation | ||
126 | |||
127 | Since a "bk push" sends all changes not in the target tree, and | ||
128 | since a "bk pull" receives all changes not in the source tree, you want | ||
129 | to make sure you are only pushing specific changes to the desired tree, | ||
130 | not all changes from "peer parent" trees. For example, pushing a change | ||
131 | from the testing-and-validation tree would probably be a bad idea, | ||
132 | because it will push all changes from vm-hacks, bugfixes, filesys, and | ||
133 | personal-hacks trees into the target tree. | ||
134 | |||
135 | One would typically work on only one "theme" at a time, either | ||
136 | vm-hacks or bugfixes or filesys, keeping those changes isolated in | ||
137 | their own tree during development, and only merge the isolated with | ||
138 | other changes when going upstream (to Linus or other maintainers) or | ||
139 | downstream (to your "union" trees, like testing-and-validation above). | ||
140 | |||
141 | It should be noted that some of this separation is not just recommended | ||
142 | practice, it's actually [for now] -enforced- by BitKeeper. BitKeeper | ||
143 | requires that changesets maintain a certain order, which is the reason | ||
144 | that "bk push" sends all local changesets the remote doesn't have. This | ||
145 | separation may look like a lot of wasted disk space at first, but it | ||
146 | helps when two unrelated changes may "pollute" the same area of code, or | ||
147 | don't follow the same pace of development, or any other of the standard | ||
148 | reasons why one creates a development branch. | ||
149 | |||
150 | Small development branches (clones) will appear and disappear: | ||
151 | |||
152 | -------- A --------- B --------- C --------- D ------- | ||
153 | \ / | ||
154 | -----short-term devel branch----- | ||
155 | |||
156 | While long-term branches will parallel a tree (or trees), with period | ||
157 | merge points. In this first example, we pull from a tree (pulls, | ||
158 | "\") periodically, such as what occurs when tracking changes in a | ||
159 | vendor tree, never pushing changes back up the line: | ||
160 | |||
161 | -------- A --------- B --------- C --------- D ------- | ||
162 | \ \ \ | ||
163 | ----long-term devel branch----------------- | ||
164 | |||
165 | And then a more common case in Linux kernel development, a long term | ||
166 | branch with periodic merges back into the tree (pushes, "/"): | ||
167 | |||
168 | -------- A --------- B --------- C --------- D ------- | ||
169 | \ \ / \ | ||
170 | ----long-term devel branch----------------- | ||
171 | |||
172 | |||
173 | |||
174 | |||
175 | |||
176 | Submitting Changes to Linus | ||
177 | --------------------------- | ||
178 | There's a bit of an art, or style, of submitting changes to Linus. | ||
179 | Since Linus's tree is now (you might say) fully integrated into the | ||
180 | distributed BitKeeper system, there are several prerequisites to | ||
181 | properly submitting a BitKeeper change. All these prereq's are just | ||
182 | general cleanliness of BK usage, so as people become experts at BK, feel | ||
183 | free to optimize this process further (assuming Linus agrees, of | ||
184 | course). | ||
185 | |||
186 | |||
187 | |||
188 | 0) Make sure your tree was originally cloned from the linux-2.5 tree | ||
189 | created by Linus. If your tree does not have this as its ancestor, it | ||
190 | is impossible to reliably exchange changesets. | ||
191 | |||
192 | |||
193 | |||
194 | 1) Pay attention to your commit text. The commit message that | ||
195 | accompanies each changeset you submit will live on forever in history, | ||
196 | and is used by Linus to accurately summarize the changes in each | ||
197 | pre-patch. Remember that there is no context, so | ||
198 | "fix for new scheduler changes" | ||
199 | would be too vague, but | ||
200 | "fix mips64 arch for new scheduler switch_to(), TIF_xxx semantics" | ||
201 | would be much better. | ||
202 | |||
203 | You can and should use the command "bk comment -C<rev>" to update the | ||
204 | commit text, and improve it after the fact. This is very useful for | ||
205 | development: poor, quick descriptions during development, which get | ||
206 | cleaned up using "bk comment" before issuing the "bk push" to submit the | ||
207 | changes. | ||
208 | |||
209 | |||
210 | |||
211 | 2) Include an Internet-available URL for Linus to pull from, such as | ||
212 | |||
213 | Pull from: http://gkernel.bkbits.net/net-drivers-2.5 | ||
214 | |||
215 | |||
216 | |||
217 | 3) Include a summary and "diffstat -p1" of each changeset that will be | ||
218 | downloaded, when Linus issues a "bk pull". The author auto-generates | ||
219 | these summaries using "bk changes -L <parent>", to obtain a listing | ||
220 | of all the pending-to-send changesets, and their commit messages. | ||
221 | |||
222 | It is important to show Linus what he will be downloading when he issues | ||
223 | a "bk pull", to reduce the time required to sift the changes once they | ||
224 | are downloaded to Linus's local machine. | ||
225 | |||
226 | IMPORTANT NOTE: One of the features of BK is that your repository does | ||
227 | not have to be up to date, in order for Linus to receive your changes. | ||
228 | It is considered a courtesy to keep your repository fairly recent, to | ||
229 | lessen any potential merge work Linus may need to do. | ||
230 | |||
231 | |||
232 | 4) Split up your changes. Each maintainer<->Linus situation is likely | ||
233 | to be slightly different here, so take this just as general advice. The | ||
234 | author splits up changes according to "themes" when merging with Linus. | ||
235 | Simultaneous pushes from local development go to special trees which | ||
236 | exist solely to house changes "queued" for Linus. Example of the trees: | ||
237 | |||
238 | net-drivers-2.5 -- on-going net driver maintenance | ||
239 | vm-2.5 -- VM-related changes | ||
240 | fs-2.5 -- filesystem-related changes | ||
241 | |||
242 | Linus then has much more freedom for pulling changes. He could (for | ||
243 | example) issue a "bk pull" on vm-2.5 and fs-2.5 trees, to merge their | ||
244 | changes, but hold off net-drivers-2.5 because of a change that needs | ||
245 | more discussion. | ||
246 | |||
247 | Other maintainers may find that a single linus-pull-from tree is | ||
248 | adequate for passing BK changesets to him. | ||
249 | |||
250 | |||
251 | |||
252 | Frequently Answered Questions | ||
253 | ----------------------------- | ||
254 | 1) How do I change the e-mail address shown in the changelog? | ||
255 | A. When you run "bk citool" or "bk commit", set environment | ||
256 | variables BK_USER and BK_HOST to the desired username | ||
257 | and host/domain name. | ||
258 | |||
259 | |||
260 | 2) How do I use tags / get a diff between two kernel versions? | ||
261 | A. Pass the tags Linus uses to 'bk export'. | ||
262 | |||
263 | ChangeSets are in a forward-progressing order, so it's pretty easy | ||
264 | to get a snapshot starting and ending at any two points in time. | ||
265 | Linus puts tags on each release and pre-release, so you could use | ||
266 | these two examples: | ||
267 | |||
268 | bk export -tpatch -hdu -rv2.5.4,v2.5.5 | less | ||
269 | # creates patch-2.5.5 essentially | ||
270 | bk export -tpatch -du -rv2.5.5-pre1,v2.5.5 | less | ||
271 | # changes from pre1 to final | ||
272 | |||
273 | A tag is just an alias for a specific changeset... and since changesets | ||
274 | are ordered, a tag is thus a marker for a specific point in time (or | ||
275 | specific state of the tree). | ||
276 | |||
277 | |||
278 | 3) Is there an easy way to generate One Big Patch versus mainline, | ||
279 | for my long-lived kernel branch? | ||
280 | A. Yes. This requires BK 3.x, though. | ||
281 | |||
282 | bk export -tpatch -r`bk repogca bk://linux.bkbits.net/linux-2.5`,+ | ||
283 | |||
diff --git a/Documentation/BK-usage/bk-make-sum b/Documentation/BK-usage/bk-make-sum deleted file mode 100755 index 58ca46a0fcc6..000000000000 --- a/Documentation/BK-usage/bk-make-sum +++ /dev/null | |||
@@ -1,34 +0,0 @@ | |||
1 | #!/bin/sh -e | ||
2 | # DIR=$HOME/BK/axp-2.5 | ||
3 | # cd $DIR | ||
4 | |||
5 | LINUS_REPO=$1 | ||
6 | DIRBASE=`basename $PWD` | ||
7 | |||
8 | { | ||
9 | cat <<EOT | ||
10 | Please do a | ||
11 | |||
12 | bk pull bk://gkernel.bkbits.net/$DIRBASE | ||
13 | |||
14 | This will update the following files: | ||
15 | |||
16 | EOT | ||
17 | |||
18 | bk export -tpatch -hdu -r`bk repogca $LINUS_REPO`,+ | diffstat -p1 2>/dev/null | ||
19 | |||
20 | cat <<EOT | ||
21 | |||
22 | through these ChangeSets: | ||
23 | |||
24 | EOT | ||
25 | |||
26 | bk changes -L -d'$unless(:MERGE:){ChangeSet|:CSETREV:\n}' $LINUS_REPO | | ||
27 | bk -R prs -h -d'$unless(:MERGE:){<:P:@:HOST:> (:D: :I:)\n$each(:C:){ (:C:)\n}\n}' - | ||
28 | |||
29 | } > /tmp/linus.txt | ||
30 | |||
31 | cat <<EOT | ||
32 | Mail text in /tmp/linus.txt; please check and send using your favourite | ||
33 | mailer. | ||
34 | EOT | ||
diff --git a/Documentation/BK-usage/bksend b/Documentation/BK-usage/bksend deleted file mode 100755 index 836ca943694f..000000000000 --- a/Documentation/BK-usage/bksend +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # A script to format BK changeset output in a manner that is easy to read. | ||
3 | # Andreas Dilger <adilger@turbolabs.com> 13/02/2002 | ||
4 | # | ||
5 | # Add diffstat output after Changelog <adilger@turbolabs.com> 21/02/2002 | ||
6 | |||
7 | PROG=bksend | ||
8 | |||
9 | usage() { | ||
10 | echo "usage: $PROG -r<rev>" | ||
11 | echo -e "\twhere <rev> is of the form '1.23', '1.23..', '1.23..1.27'," | ||
12 | echo -e "\tor '+' to indicate the most recent revision" | ||
13 | |||
14 | exit 1 | ||
15 | } | ||
16 | |||
17 | case $1 in | ||
18 | -r) REV=$2; shift ;; | ||
19 | -r*) REV=`echo $1 | sed 's/^-r//'` ;; | ||
20 | *) echo "$PROG: no revision given, you probably don't want that";; | ||
21 | esac | ||
22 | |||
23 | [ -z "$REV" ] && usage | ||
24 | |||
25 | echo "You can import this changeset into BK by piping this whole message to:" | ||
26 | echo "'| bk receive [path to repository]' or apply the patch as usual." | ||
27 | |||
28 | SEP="\n===================================================================\n\n" | ||
29 | echo -e $SEP | ||
30 | env PAGER=/bin/cat bk changes -r$REV | ||
31 | echo | ||
32 | bk export -tpatch -du -h -r$REV | diffstat | ||
33 | echo; echo | ||
34 | bk export -tpatch -du -h -r$REV | ||
35 | echo -e $SEP | ||
36 | bk send -wgzip_uu -r$REV - | ||
diff --git a/Documentation/BK-usage/bz64wrap b/Documentation/BK-usage/bz64wrap deleted file mode 100755 index be780876849f..000000000000 --- a/Documentation/BK-usage/bz64wrap +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # bz64wrap - the sending side of a bzip2 | base64 stream | ||
4 | # Andreas Dilger <adilger@clusterfs.com> Jan 2002 | ||
5 | |||
6 | |||
7 | PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin | ||
8 | |||
9 | # A program to generate base64 encoding on stdout | ||
10 | BASE64_ENCODE="uuencode -m /dev/stdout" | ||
11 | BASE64_BEGIN= | ||
12 | BASE64_END= | ||
13 | |||
14 | BZIP=NO | ||
15 | BASE64=NO | ||
16 | |||
17 | # Test if we have the bzip program installed | ||
18 | bzip2 -c /dev/null > /dev/null 2>&1 && BZIP=YES | ||
19 | |||
20 | # Test if uuencode can handle the -m (MIME) encoding option | ||
21 | $BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES | ||
22 | |||
23 | if [ $BASE64 = NO ]; then | ||
24 | BASE64_ENCODE=mimencode | ||
25 | BASE64_BEGIN="begin-base64 644 -" | ||
26 | BASE64_END="====" | ||
27 | |||
28 | $BASE64_ENCODE < /dev/null > /dev/null 2>&1 && BASE64=YES | ||
29 | fi | ||
30 | |||
31 | if [ $BZIP = NO -o $BASE64 = NO ]; then | ||
32 | echo "$0: can't use bz64 encoding: bzip2=$BZIP, $BASE64_ENCODE=$BASE64" | ||
33 | exit 1 | ||
34 | fi | ||
35 | |||
36 | # Sadly, mimencode does not appear to have good "begin" and "end" markers | ||
37 | # like uuencode does, and it is picky about getting the right start/end of | ||
38 | # the base64 stream, so we handle this internally. | ||
39 | echo "$BASE64_BEGIN" | ||
40 | bzip2 -9 | $BASE64_ENCODE | ||
41 | echo "$BASE64_END" | ||
diff --git a/Documentation/BK-usage/cpcset b/Documentation/BK-usage/cpcset deleted file mode 100755 index b8faca97dab9..000000000000 --- a/Documentation/BK-usage/cpcset +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Purpose: Copy changeset patch and description from one | ||
4 | # repository to another, unrelated one. | ||
5 | # | ||
6 | # usage: cpcset [revision] [from-repository] [to-repository] | ||
7 | # | ||
8 | |||
9 | REV=$1 | ||
10 | FROM=$2 | ||
11 | TO=$3 | ||
12 | TMPF=/tmp/cpcset.$$ | ||
13 | |||
14 | rm -f $TMPF* | ||
15 | |||
16 | CWD_SAVE=`pwd` | ||
17 | cd $FROM | ||
18 | bk changes -r$REV | \ | ||
19 | grep -v '^ChangeSet' | \ | ||
20 | sed -e 's/^ //g' > $TMPF.log | ||
21 | |||
22 | USERHOST=`bk changes -r$REV | grep '^ChangeSet' | awk '{print $4}'` | ||
23 | export BK_USER=`echo $USERHOST | awk '-F@' '{print $1}'` | ||
24 | export BK_HOST=`echo $USERHOST | awk '-F@' '{print $2}'` | ||
25 | |||
26 | bk export -tpatch -hdu -r$REV > $TMPF.patch && \ | ||
27 | cd $CWD_SAVE && \ | ||
28 | cd $TO && \ | ||
29 | bk import -tpatch -CFR -y"`cat $TMPF.log`" $TMPF.patch . && \ | ||
30 | bk commit -y"`cat $TMPF.log`" | ||
31 | |||
32 | rm -f $TMPF* | ||
33 | |||
34 | echo changeset $REV copied. | ||
35 | echo "" | ||
36 | |||
diff --git a/Documentation/BK-usage/cset-to-linus b/Documentation/BK-usage/cset-to-linus deleted file mode 100755 index d28a96f8c618..000000000000 --- a/Documentation/BK-usage/cset-to-linus +++ /dev/null | |||
@@ -1,49 +0,0 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | my ($lhs, $rev, $tmp, $rhs, $s); | ||
6 | my @cset_text = (); | ||
7 | my @pipe_text = (); | ||
8 | my $have_cset = 0; | ||
9 | |||
10 | while (<>) { | ||
11 | next if /^---/; | ||
12 | |||
13 | if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) { | ||
14 | &cset_rev if ($have_cset); | ||
15 | |||
16 | $rev = $tmp; | ||
17 | $have_cset = 1; | ||
18 | |||
19 | push(@cset_text, $_); | ||
20 | } | ||
21 | |||
22 | elsif ($have_cset) { | ||
23 | push(@cset_text, $_); | ||
24 | } | ||
25 | } | ||
26 | &cset_rev if ($have_cset); | ||
27 | exit(0); | ||
28 | |||
29 | |||
30 | sub cset_rev { | ||
31 | my $empty_cset = 0; | ||
32 | |||
33 | open PIPE, "bk export -tpatch -hdu -r $rev | diffstat -p1 2>/dev/null |" or die; | ||
34 | while ($s = <PIPE>) { | ||
35 | $empty_cset = 1 if ($s =~ /0 files changed/); | ||
36 | push(@pipe_text, $s); | ||
37 | } | ||
38 | close(PIPE); | ||
39 | |||
40 | if (! $empty_cset) { | ||
41 | print @cset_text; | ||
42 | print @pipe_text; | ||
43 | print "\n\n"; | ||
44 | } | ||
45 | |||
46 | @pipe_text = (); | ||
47 | @cset_text = (); | ||
48 | } | ||
49 | |||
diff --git a/Documentation/BK-usage/csets-to-patches b/Documentation/BK-usage/csets-to-patches deleted file mode 100755 index e2b81c35883f..000000000000 --- a/Documentation/BK-usage/csets-to-patches +++ /dev/null | |||
@@ -1,44 +0,0 @@ | |||
1 | #!/usr/bin/perl -w | ||
2 | |||
3 | use strict; | ||
4 | |||
5 | my ($lhs, $rev, $tmp, $rhs, $s); | ||
6 | my @cset_text = (); | ||
7 | my @pipe_text = (); | ||
8 | my $have_cset = 0; | ||
9 | |||
10 | while (<>) { | ||
11 | next if /^---/; | ||
12 | |||
13 | if (($lhs, $tmp, $rhs) = (/^(ChangeSet\@)([^,]+)(, .*)$/)) { | ||
14 | &cset_rev if ($have_cset); | ||
15 | |||
16 | $rev = $tmp; | ||
17 | $have_cset = 1; | ||
18 | |||
19 | push(@cset_text, $_); | ||
20 | } | ||
21 | |||
22 | elsif ($have_cset) { | ||
23 | push(@cset_text, $_); | ||
24 | } | ||
25 | } | ||
26 | &cset_rev if ($have_cset); | ||
27 | exit(0); | ||
28 | |||
29 | |||
30 | sub cset_rev { | ||
31 | my $empty_cset = 0; | ||
32 | |||
33 | system("bk export -tpatch -du -r $rev > /tmp/rev-$rev.patch"); | ||
34 | |||
35 | if (! $empty_cset) { | ||
36 | print @cset_text; | ||
37 | print @pipe_text; | ||
38 | print "\n\n"; | ||
39 | } | ||
40 | |||
41 | @pipe_text = (); | ||
42 | @cset_text = (); | ||
43 | } | ||
44 | |||
diff --git a/Documentation/BK-usage/gcapatch b/Documentation/BK-usage/gcapatch deleted file mode 100755 index aaeb17dc7c7f..000000000000 --- a/Documentation/BK-usage/gcapatch +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | # | ||
3 | # Purpose: Generate GNU diff of local changes versus canonical top-of-tree | ||
4 | # | ||
5 | # Usage: gcapatch > foo.patch | ||
6 | # | ||
7 | |||
8 | bk export -tpatch -hdu -r`bk repogca bk://linux.bkbits.net/linux-2.5`,+ | ||
diff --git a/Documentation/BK-usage/unbz64wrap b/Documentation/BK-usage/unbz64wrap deleted file mode 100755 index 4fc3e73e9a81..000000000000 --- a/Documentation/BK-usage/unbz64wrap +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | # unbz64wrap - the receiving side of a bzip2 | base64 stream | ||
4 | # Andreas Dilger <adilger@clusterfs.com> Jan 2002 | ||
5 | |||
6 | # Sadly, mimencode does not appear to have good "begin" and "end" markers | ||
7 | # like uuencode does, and it is picky about getting the right start/end of | ||
8 | # the base64 stream, so we handle this explicitly here. | ||
9 | |||
10 | PATH=$PATH:/usr/bin:/usr/local/bin:/usr/freeware/bin | ||
11 | |||
12 | if mimencode -u < /dev/null > /dev/null 2>&1 ; then | ||
13 | SHOW= | ||
14 | while read LINE; do | ||
15 | case $LINE in | ||
16 | begin-base64*) SHOW=YES ;; | ||
17 | ====) SHOW= ;; | ||
18 | *) [ "$SHOW" ] && echo "$LINE" ;; | ||
19 | esac | ||
20 | done | mimencode -u | bunzip2 | ||
21 | exit $? | ||
22 | else | ||
23 | cat - | uudecode -o /dev/stdout | bunzip2 | ||
24 | exit $? | ||
25 | fi | ||
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt index 1ad26d2c20ae..2f8f24eaefd9 100644 --- a/Documentation/cpusets.txt +++ b/Documentation/cpusets.txt | |||
@@ -252,8 +252,7 @@ in a tasks processor placement. | |||
252 | There is an exception to the above. If hotplug funtionality is used | 252 | There is an exception to the above. If hotplug funtionality is used |
253 | to remove all the CPUs that are currently assigned to a cpuset, | 253 | to remove all the CPUs that are currently assigned to a cpuset, |
254 | then the kernel will automatically update the cpus_allowed of all | 254 | then the kernel will automatically update the cpus_allowed of all |
255 | tasks attached to CPUs in that cpuset with the online CPUs of the | 255 | tasks attached to CPUs in that cpuset to allow all CPUs. When memory |
256 | nearest parent cpuset that still has some CPUs online. When memory | ||
257 | hotplug functionality for removing Memory Nodes is available, a | 256 | hotplug functionality for removing Memory Nodes is available, a |
258 | similar exception is expected to apply there as well. In general, | 257 | similar exception is expected to apply there as well. In general, |
259 | the kernel prefers to violate cpuset placement, over starving a task | 258 | the kernel prefers to violate cpuset placement, over starving a task |
diff --git a/Documentation/dontdiff b/Documentation/dontdiff index 7c2496426ab9..9a33bb94f74f 100644 --- a/Documentation/dontdiff +++ b/Documentation/dontdiff | |||
@@ -27,6 +27,7 @@ | |||
27 | *.so | 27 | *.so |
28 | *.tex | 28 | *.tex |
29 | *.ver | 29 | *.ver |
30 | *.xml | ||
30 | *_MODULES | 31 | *_MODULES |
31 | *_vga16.c | 32 | *_vga16.c |
32 | *cscope* | 33 | *cscope* |
@@ -110,6 +111,7 @@ mkdep | |||
110 | mktables | 111 | mktables |
111 | modpost | 112 | modpost |
112 | modversions.h* | 113 | modversions.h* |
114 | offsets.h | ||
113 | oui.c* | 115 | oui.c* |
114 | parse.c* | 116 | parse.c* |
115 | parse.h* | 117 | parse.h* |
@@ -134,4 +136,5 @@ vmlinux-* | |||
134 | vmlinux.lds | 136 | vmlinux.lds |
135 | vsyscall.lds | 137 | vsyscall.lds |
136 | wanxlfw.inc | 138 | wanxlfw.inc |
139 | uImage | ||
137 | zImage | 140 | zImage |
diff --git a/Documentation/dvb/README.flexcop b/Documentation/dvb/README.flexcop new file mode 100644 index 000000000000..a50c70f9ca72 --- /dev/null +++ b/Documentation/dvb/README.flexcop | |||
@@ -0,0 +1,205 @@ | |||
1 | This README escorted the skystar2-driver rewriting procedure. It describes the | ||
2 | state of the new flexcop-driver set and some internals are written down here | ||
3 | too. | ||
4 | |||
5 | This document hopefully describes things about the flexcop and its | ||
6 | device-offsprings. Goal was to write an easy-to-write and easy-to-read set of | ||
7 | drivers based on the skystar2.c and other information. | ||
8 | |||
9 | Remark: flexcop-pci.c was a copy of skystar2.c, but every line has been | ||
10 | touched and rewritten. | ||
11 | |||
12 | History & News | ||
13 | ============== | ||
14 | 2005-04-01 - correct USB ISOC transfers (thanks to Vadim Catana) | ||
15 | |||
16 | |||
17 | |||
18 | |||
19 | General coding processing | ||
20 | ========================= | ||
21 | |||
22 | We should proceed as follows (as long as no one complains): | ||
23 | |||
24 | 0) Think before start writing code! | ||
25 | |||
26 | 1) rewriting the skystar2.c with the help of the flexcop register descriptions | ||
27 | and splitting up the files to a pci-bus-part and a flexcop-part. | ||
28 | The new driver will be called b2c2-flexcop-pci.ko/b2c2-flexcop-usb.ko for the | ||
29 | device-specific part and b2c2-flexcop.ko for the common flexcop-functions. | ||
30 | |||
31 | 2) Search for errors in the leftover of flexcop-pci.c (compare with pluto2.c | ||
32 | and other pci drivers) | ||
33 | |||
34 | 3) make some beautification (see 'Improvements when rewriting (refactoring) is | ||
35 | done') | ||
36 | |||
37 | 4) Testing the new driver and maybe substitute the skystar2.c with it, to reach | ||
38 | a wider tester audience. | ||
39 | |||
40 | 5) creating an usb-bus-part using the already written flexcop code for the pci | ||
41 | card. | ||
42 | |||
43 | Idea: create a kernel-object for the flexcop and export all important | ||
44 | functions. This option saves kernel-memory, but maybe a lot of functions have | ||
45 | to be exported to kernel namespace. | ||
46 | |||
47 | |||
48 | Current situation | ||
49 | ================= | ||
50 | |||
51 | 0) Done :) | ||
52 | 1) Done (some minor issues left) | ||
53 | 2) Done | ||
54 | 3) Not ready yet, more information is necessary | ||
55 | 4) next to be done (see the table below) | ||
56 | 5) USB driver is working (yes, there are some minor issues) | ||
57 | |||
58 | What seems to be ready? | ||
59 | ----------------------- | ||
60 | |||
61 | 1) Rewriting | ||
62 | 1a) i2c is cut off from the flexcop-pci.c and seems to work | ||
63 | 1b) moved tuner and demod stuff from flexcop-pci.c to flexcop-tuner-fe.c | ||
64 | 1c) moved lnb and diseqc stuff from flexcop-pci.c to flexcop-tuner-fe.c | ||
65 | 1e) eeprom (reading MAC address) | ||
66 | 1d) sram (no dynamic sll size detection (commented out) (using default as JJ told me)) | ||
67 | 1f) misc. register accesses for reading parameters (e.g. resetting, revision) | ||
68 | 1g) pid/mac filter (flexcop-hw-filter.c) | ||
69 | 1i) dvb-stuff initialization in flexcop.c (done) | ||
70 | 1h) dma stuff (now just using the size-irq, instead of all-together, to be done) | ||
71 | 1j) remove flexcop initialization from flexcop-pci.c completely (done) | ||
72 | 1l) use a well working dma IRQ method (done, see 'Known bugs and problems and TODO') | ||
73 | 1k) cleanup flexcop-files (remove unused EXPORT_SYMBOLs, make static from | ||
74 | non-static where possible, moved code to proper places) | ||
75 | |||
76 | 2) Search for errors in the leftover of flexcop-pci.c (partially done) | ||
77 | 5a) add MAC address reading | ||
78 | 5c) feeding of ISOC data to the software demux (format of the isochronous data | ||
79 | and speed optimization, no real error) (thanks to Vadim Catana) | ||
80 | |||
81 | What to do in the near future? | ||
82 | -------------------------------------- | ||
83 | (no special order here) | ||
84 | |||
85 | 5) USB driver | ||
86 | 5b) optimize isoc-transfer (submitting/killing isoc URBs when transfer is starting) | ||
87 | |||
88 | Testing changes | ||
89 | --------------- | ||
90 | |||
91 | O = item is working | ||
92 | P = item is partially working | ||
93 | X = item is not working | ||
94 | N = item does not apply here | ||
95 | <empty field> = item need to be examined | ||
96 | |||
97 | | PCI | USB | ||
98 | item | mt352 | nxt2002 | stv0299 | mt312 | mt352 | nxt2002 | stv0299 | mt312 | ||
99 | -------+-------+---------+---------+-------+-------+---------+---------+------- | ||
100 | 1a) | O | | | | N | N | N | N | ||
101 | 1b) | O | | | | | | O | | ||
102 | 1c) | N | N | | | N | N | O | | ||
103 | 1d) | O | O | ||
104 | 1e) | O | O | ||
105 | 1f) | P | ||
106 | 1g) | O | ||
107 | 1h) | P | | ||
108 | 1i) | O | N | ||
109 | 1j) | O | N | ||
110 | 1l) | O | N | ||
111 | 2) | O | N | ||
112 | 5a) | N | O | ||
113 | 5b)* | N | | ||
114 | 5c) | N | O | ||
115 | |||
116 | * - not done yet | ||
117 | |||
118 | Known bugs and problems and TODO | ||
119 | -------------------------------- | ||
120 | |||
121 | 1g/h/l) when pid filtering is enabled on the pci card | ||
122 | |||
123 | DMA usage currently: | ||
124 | The DMA is splitted in 2 equal-sized subbuffers. The Flexcop writes to first | ||
125 | address and triggers an IRQ when it's full and starts writing to the second | ||
126 | address. When the second address is full, the IRQ is triggered again, and | ||
127 | the flexcop writes to first address again, and so on. | ||
128 | The buffersize of each address is currently 640*188 bytes. | ||
129 | |||
130 | Problem is, when using hw-pid-filtering and doing some low-bandwidth | ||
131 | operation (like scanning) the buffers won't be filled enough to trigger | ||
132 | the IRQ. That's why: | ||
133 | |||
134 | When PID filtering is activated, the timer IRQ is used. Every 1.97 ms the IRQ | ||
135 | is triggered. Is the current write address of DMA1 different to the one | ||
136 | during the last IRQ, then the data is passed to the demuxer. | ||
137 | |||
138 | There is an additional DMA-IRQ-method: packet count IRQ. This isn't | ||
139 | implemented correctly yet. | ||
140 | |||
141 | The solution is to disable HW PID filtering, but I don't know how the DVB | ||
142 | API software demux behaves on slow systems with 45MBit/s TS. | ||
143 | |||
144 | Solved bugs :) | ||
145 | -------------- | ||
146 | 1g) pid-filtering (somehow pid index 4 and 5 (EMM_PID and ECM_PID) aren't | ||
147 | working) | ||
148 | SOLUTION: also index 0 was affected, because net_translation is done for | ||
149 | these indexes by default | ||
150 | |||
151 | 5b) isochronous transfer does only work in the first attempt (for the Sky2PC | ||
152 | USB, Air2PC is working) SOLUTION: the flexcop was going asleep and never really | ||
153 | woke up again (don't know if this need fixes, see | ||
154 | flexcop-fe-tuner.c:flexcop_sleep) | ||
155 | |||
156 | NEWS: when the driver is loaded and unloaded and loaded again (w/o doing | ||
157 | anything in the while the driver is loaded the first time), no transfers take | ||
158 | place anymore. | ||
159 | |||
160 | Improvements when rewriting (refactoring) is done | ||
161 | ================================================= | ||
162 | |||
163 | - split sleeping of the flexcop (misc_204.ACPI3_sig = 1;) from lnb_control | ||
164 | (enable sleeping for other demods than dvb-s) | ||
165 | - add support for CableStar (stv0297 Microtune 203x/ALPS) (almost done, incompatibilities with the Nexus-CA) | ||
166 | |||
167 | Debugging | ||
168 | --------- | ||
169 | - add verbose debugging to skystar2.c (dump the reg_dw_data) and compare it | ||
170 | with this flexcop, this is important, because i2c is now using the | ||
171 | flexcop_ibi_value union from flexcop-reg.h (do you have a better idea for | ||
172 | that, please tell us so). | ||
173 | |||
174 | Everything which is identical in the following table, can be put into a common | ||
175 | flexcop-module. | ||
176 | |||
177 | PCI USB | ||
178 | ------------------------------------------------------------------------------- | ||
179 | Different: | ||
180 | Register access: accessing IO memory USB control message | ||
181 | I2C bus: I2C bus of the FC USB control message | ||
182 | Data transfer: DMA isochronous transfer | ||
183 | EEPROM transfer: through i2c bus not clear yet | ||
184 | |||
185 | Identical: | ||
186 | Streaming: accessing registers | ||
187 | PID Filtering: accessing registers | ||
188 | Sram destinations: accessing registers | ||
189 | Tuner/Demod: I2C bus | ||
190 | DVB-stuff: can be written for common use | ||
191 | |||
192 | Acknowledgements (just for the rewriting part) | ||
193 | ================ | ||
194 | |||
195 | Bjarne Steinsbo thought a lot in the first place of the pci part for this code | ||
196 | sharing idea. | ||
197 | |||
198 | Andreas Oberritter for providing a recent PCI initialization template | ||
199 | (pluto2.c). | ||
200 | |||
201 | Boleslaw Ciesielski for pointing out a problem with firmware loader. | ||
202 | |||
203 | Vadim Catana for correcting the USB transfer. | ||
204 | |||
205 | comments, critics and ideas to linux-dvb@linuxtv.org. | ||
diff --git a/Documentation/dvb/bt8xx.txt b/Documentation/dvb/bt8xx.txt index e3cacf4f2345..d64430bf4bb6 100644 --- a/Documentation/dvb/bt8xx.txt +++ b/Documentation/dvb/bt8xx.txt | |||
@@ -17,74 +17,53 @@ Because of this, you need to enable | |||
17 | "Device drivers" => "Multimedia devices" | 17 | "Device drivers" => "Multimedia devices" |
18 | => "Video For Linux" => "BT848 Video For Linux" | 18 | => "Video For Linux" => "BT848 Video For Linux" |
19 | 19 | ||
20 | Furthermore you need to enable | ||
21 | "Device drivers" => "Multimedia devices" => "Digital Video Broadcasting Devices" | ||
22 | => "DVB for Linux" "DVB Core Support" "Nebula/Pinnacle PCTV/TwinHan PCI Cards" | ||
23 | |||
20 | 2) Loading Modules | 24 | 2) Loading Modules |
21 | ================== | 25 | ================== |
22 | 26 | ||
23 | In general you need to load the bttv driver, which will handle the gpio and | 27 | In general you need to load the bttv driver, which will handle the gpio and |
24 | i2c communication for us. Next you need the common dvb-bt8xx device driver | 28 | i2c communication for us, plus the common dvb-bt8xx device driver. |
25 | and one frontend driver. | 29 | The frontends for Nebula (nxt6000), Pinnacle PCTV (cx24110) and |
26 | 30 | TwinHan (dst) are loaded automatically by the dvb-bt8xx device driver. | |
27 | The bttv driver will HANG YOUR SYSTEM IF YOU DO NOT SPECIFY THE CORRECT | ||
28 | CARD ID! | ||
29 | |||
30 | (If you don't get your card running and you suspect that the card id you're | ||
31 | using is wrong, have a look at "bttv-cards.c" for a list of possible card | ||
32 | ids.) | ||
33 | |||
34 | Pay attention to failures when you load the frontend drivers | ||
35 | (e.g. dmesg, /var/log/messages). | ||
36 | 31 | ||
37 | 3a) Nebula / Pinnacle PCTV | 32 | 3a) Nebula / Pinnacle PCTV |
38 | -------------------------- | 33 | -------------------------- |
39 | 34 | ||
40 | $ modprobe bttv i2c_hw=1 card=0x68 | 35 | $ modprobe bttv (normally bttv is being loaded automatically by kmod) |
41 | $ modprobe dvb-bt8xx | 36 | $ modprobe dvb-bt8xx (or just place dvb-bt8xx in /etc/modules for automatic loading) |
42 | |||
43 | For Nebula cards use the "nxt6000" frontend driver: | ||
44 | $ modprobe nxt6000 | ||
45 | 37 | ||
46 | For Pinnacle PCTV cards use the "cx24110" frontend driver: | ||
47 | $ modprobe cx24110 | ||
48 | 38 | ||
49 | 3b) TwinHan | 39 | 3b) TwinHan and Clones |
50 | ----------- | 40 | -------------------------- |
51 | 41 | ||
52 | $ modprobe bttv i2c_hw=1 card=0x71 | 42 | $ modprobe bttv i2c_hw=1 card=0x71 |
53 | $ modprobe dvb-bt8xx | 43 | $ modprobe dvb-bt8xx |
54 | $ modprobe dst | 44 | $ modprobe dst |
55 | 45 | ||
56 | The value 0x71 will override the PCI type detection for dvb-bt8xx, which | 46 | The value 0x71 will override the PCI type detection for dvb-bt8xx, |
57 | is necessary for TwinHan cards.# | 47 | which is necessary for TwinHan cards. |
58 | 48 | ||
59 | If you're having an older card (blue color circuit) and card=0x71 locks your | 49 | If you're having an older card (blue color circuit) and card=0x71 locks |
60 | machine, try using 0x68, too. If that does not work, ask on the DVB mailing list. | 50 | your machine, try using 0x68, too. If that does not work, ask on the |
51 | mailing list. | ||
61 | 52 | ||
62 | The DST module takes a couple of useful parameters, in case the | 53 | The DST module takes a couple of useful parameters. |
63 | dst drivers fails to detect your type of card correctly. | ||
64 | 54 | ||
65 | dst_type takes values 0 (satellite), 1 (terrestial TV), 2 (cable). | 55 | verbose takes values 0 to 5. These values control the verbosity level. |
66 | 56 | ||
67 | dst_type_flags takes bit combined values: | 57 | debug takes values 0 and 1. You can either disable or enable debugging. |
68 | 1 = new tuner type packets. You can use this if your card is detected | ||
69 | and you have debug and you continually see the tuner packets not | ||
70 | working (make sure not a basic problem like dish alignment etc.) | ||
71 | 58 | ||
72 | 2 = TS 204. If your card tunes OK, but the picture is terrible, seemingly | 59 | dst_addons takes values 0 and 0x20. A value of 0 means it is a FTA card. |
73 | breaking up in one half continually, and crc fails a lot, then | 60 | 0x20 means it has a Conditional Access slot. |
74 | this is worth a try (or trying to turn off) | ||
75 | 61 | ||
76 | 4 = has symdiv. Some cards, mostly without new tuner packets, require | 62 | The autodected values are determined bythe cards 'response |
77 | a symbol division algorithm. Doesn't apply to terrestial TV. | ||
78 | |||
79 | You can also specify a value to have the autodetected values turned off | ||
80 | (e.g. 0). The autodected values are determined bythe cards 'response | ||
81 | string' which you can see in your logs e.g. | 63 | string' which you can see in your logs e.g. |
82 | 64 | ||
83 | dst_check_ci: recognize DST-MOT | 65 | dst_get_device_id: Recognise [DSTMCI] |
84 | |||
85 | or | ||
86 | 66 | ||
87 | dst_check_ci: unable to recognize DSTXCI or STXCI | ||
88 | 67 | ||
89 | -- | 68 | -- |
90 | Authors: Richard Walker, Jamie Honan, Michael Hunold | 69 | Authors: Richard Walker, Jamie Honan, Michael Hunold, Manu Abraham |
diff --git a/Documentation/dvb/ci.txt b/Documentation/dvb/ci.txt new file mode 100644 index 000000000000..62e0701b542a --- /dev/null +++ b/Documentation/dvb/ci.txt | |||
@@ -0,0 +1,219 @@ | |||
1 | * For the user | ||
2 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
3 | NOTE: This document describes the usage of the high level CI API as | ||
4 | in accordance to the Linux DVB API. This is a not a documentation for the, | ||
5 | existing low level CI API. | ||
6 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
7 | |||
8 | To utilize the High Level CI capabilities, | ||
9 | |||
10 | (1*) This point is valid only for the Twinhan/clones | ||
11 | For the Twinhan/Twinhan clones, the dst_ca module handles the CI | ||
12 | hardware handling.This module is loaded automatically if a CI | ||
13 | (Common Interface, that holds the CAM (Conditional Access Module) | ||
14 | is detected. | ||
15 | |||
16 | (2) one requires a userspace application, ca_zap. This small userland | ||
17 | application is in charge of sending the descrambling related information | ||
18 | to the CAM. | ||
19 | |||
20 | This application requires the following to function properly as of now. | ||
21 | |||
22 | (a) Tune to a valid channel, with szap. | ||
23 | eg: $ szap -c channels.conf -r "TMC" -x | ||
24 | |||
25 | (b) a channels.conf containing a valid PMT PID | ||
26 | |||
27 | eg: TMC:11996:h:0:27500:278:512:650:321 | ||
28 | |||
29 | here 278 is a valid PMT PID. the rest of the values are the | ||
30 | same ones that szap uses. | ||
31 | |||
32 | (c) after running a szap, you have to run ca_zap, for the | ||
33 | descrambler to function, | ||
34 | |||
35 | eg: $ ca_zap patched_channels.conf "TMC" | ||
36 | |||
37 | The patched means a patch to apply to scan, such that scan can | ||
38 | generate a channels.conf_with pmt, which has this PMT PID info | ||
39 | (NOTE: szap cannot use this channels.conf with the PMT_PID) | ||
40 | |||
41 | |||
42 | (d) Hopeflly Enjoy your favourite subscribed channel as you do with | ||
43 | a FTA card. | ||
44 | |||
45 | (3) Currently ca_zap, and dst_test, both are meant for demonstration | ||
46 | purposes only, they can become full fledged applications if necessary. | ||
47 | |||
48 | |||
49 | * Cards that fall in this category | ||
50 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
51 | At present the cards that fall in this category are the Twinhan and it's | ||
52 | clones, these cards are available as VVMER, Tomato, Hercules, Orange and | ||
53 | so on. | ||
54 | |||
55 | * CI modules that are supported | ||
56 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
57 | The CI module support is largely dependant upon the firmware on the cards | ||
58 | Some cards do support almost all of the available CI modules. There is | ||
59 | nothing much that can be done in order to make additional CI modules | ||
60 | working with these cards. | ||
61 | |||
62 | Modules that have been tested by this driver at present are | ||
63 | |||
64 | (1) Irdeto 1 and 2 from SCM | ||
65 | (2) Viaccess from SCM | ||
66 | (3) Dragoncam | ||
67 | |||
68 | * The High level CI API | ||
69 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
70 | |||
71 | * For the programmer | ||
72 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
73 | With the High Level CI approach any new card with almost any random | ||
74 | architecture can be implemented with this style, the definitions | ||
75 | insidethe switch statement can be easily adapted for any card, thereby | ||
76 | eliminating the need for any additional ioctls. | ||
77 | |||
78 | The disadvantage is that the driver/hardware has to manage the rest. For | ||
79 | the application programmer it would be as simple as sending/receiving an | ||
80 | array to/from the CI ioctls as defined in the Linux DVB API. No changes | ||
81 | have been made in the API to accomodate this feature. | ||
82 | |||
83 | |||
84 | * Why the need for another CI interface ? | ||
85 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
86 | This is one of the most commonly asked question. Well a nice question. | ||
87 | Strictly speaking this is not a new interface. | ||
88 | |||
89 | The CI interface is defined in the DVB API in ca.h as | ||
90 | |||
91 | typedef struct ca_slot_info { | ||
92 | int num; /* slot number */ | ||
93 | |||
94 | int type; /* CA interface this slot supports */ | ||
95 | #define CA_CI 1 /* CI high level interface */ | ||
96 | #define CA_CI_LINK 2 /* CI link layer level interface */ | ||
97 | #define CA_CI_PHYS 4 /* CI physical layer level interface */ | ||
98 | #define CA_DESCR 8 /* built-in descrambler */ | ||
99 | #define CA_SC 128 /* simple smart card interface */ | ||
100 | |||
101 | unsigned int flags; | ||
102 | #define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ | ||
103 | #define CA_CI_MODULE_READY 2 | ||
104 | } ca_slot_info_t; | ||
105 | |||
106 | |||
107 | |||
108 | This CI interface follows the CI high level interface, which is not | ||
109 | implemented by most applications. Hence this area is revisited. | ||
110 | |||
111 | This CI interface is quite different in the case that it tries to | ||
112 | accomodate all other CI based devices, that fall into the other categories | ||
113 | |||
114 | This means that this CI interface handles the EN50221 style tags in the | ||
115 | Application layer only and no session management is taken care of by the | ||
116 | application. The driver/hardware will take care of all that. | ||
117 | |||
118 | This interface is purely an EN50221 interface exchanging APDU's. This | ||
119 | means that no session management, link layer or a transport layer do | ||
120 | exist in this case in the application to driver communication. It is | ||
121 | as simple as that. The driver/hardware has to take care of that. | ||
122 | |||
123 | |||
124 | With this High Level CI interface, the interface can be defined with the | ||
125 | regular ioctls. | ||
126 | |||
127 | All these ioctls are also valid for the High level CI interface | ||
128 | |||
129 | #define CA_RESET _IO('o', 128) | ||
130 | #define CA_GET_CAP _IOR('o', 129, ca_caps_t) | ||
131 | #define CA_GET_SLOT_INFO _IOR('o', 130, ca_slot_info_t) | ||
132 | #define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) | ||
133 | #define CA_GET_MSG _IOR('o', 132, ca_msg_t) | ||
134 | #define CA_SEND_MSG _IOW('o', 133, ca_msg_t) | ||
135 | #define CA_SET_DESCR _IOW('o', 134, ca_descr_t) | ||
136 | #define CA_SET_PID _IOW('o', 135, ca_pid_t) | ||
137 | |||
138 | |||
139 | On querying the device, the device yields information thus | ||
140 | |||
141 | CA_GET_SLOT_INFO | ||
142 | ---------------------------- | ||
143 | Command = [info] | ||
144 | APP: Number=[1] | ||
145 | APP: Type=[1] | ||
146 | APP: flags=[1] | ||
147 | APP: CI High level interface | ||
148 | APP: CA/CI Module Present | ||
149 | |||
150 | CA_GET_CAP | ||
151 | ---------------------------- | ||
152 | Command = [caps] | ||
153 | APP: Slots=[1] | ||
154 | APP: Type=[1] | ||
155 | APP: Descrambler keys=[16] | ||
156 | APP: Type=[1] | ||
157 | |||
158 | CA_SEND_MSG | ||
159 | ---------------------------- | ||
160 | Descriptors(Program Level)=[ 09 06 06 04 05 50 ff f1] | ||
161 | Found CA descriptor @ program level | ||
162 | |||
163 | (20) ES type=[2] ES pid=[201] ES length =[0 (0x0)] | ||
164 | (25) ES type=[4] ES pid=[301] ES length =[0 (0x0)] | ||
165 | ca_message length is 25 (0x19) bytes | ||
166 | EN50221 CA MSG=[ 9f 80 32 19 03 01 2d d1 f0 08 01 09 06 06 04 05 50 ff f1 02 e0 c9 00 00 04 e1 2d 00 00] | ||
167 | |||
168 | |||
169 | Not all ioctl's are implemented in the driver from the API, the other | ||
170 | features of the hardware that cannot be implemented by the API are achieved | ||
171 | using the CA_GET_MSG and CA_SEND_MSG ioctls. An EN50221 style wrapper is | ||
172 | used to exchange the data to maintain compatibility with other hardware. | ||
173 | |||
174 | |||
175 | /* a message to/from a CI-CAM */ | ||
176 | typedef struct ca_msg { | ||
177 | unsigned int index; | ||
178 | unsigned int type; | ||
179 | unsigned int length; | ||
180 | unsigned char msg[256]; | ||
181 | } ca_msg_t; | ||
182 | |||
183 | |||
184 | The flow of data can be described thus, | ||
185 | |||
186 | |||
187 | |||
188 | |||
189 | |||
190 | App (User) | ||
191 | ----- | ||
192 | parse | ||
193 | | | ||
194 | | | ||
195 | v | ||
196 | en50221 APDU (package) | ||
197 | -------------------------------------- | ||
198 | | | | High Level CI driver | ||
199 | | | | | ||
200 | | v | | ||
201 | | en50221 APDU (unpackage) | | ||
202 | | | | | ||
203 | | | | | ||
204 | | v | | ||
205 | | sanity checks | | ||
206 | | | | | ||
207 | | | | | ||
208 | | v | | ||
209 | | do (H/W dep) | | ||
210 | -------------------------------------- | ||
211 | | Hardware | ||
212 | | | ||
213 | v | ||
214 | |||
215 | |||
216 | |||
217 | |||
218 | The High Level CI interface uses the EN50221 DVB standard, following a | ||
219 | standard ensures futureproofness. | ||
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware index 3ffdcb394299..a750f0101d9d 100644 --- a/Documentation/dvb/get_dvb_firmware +++ b/Documentation/dvb/get_dvb_firmware | |||
@@ -107,7 +107,7 @@ sub tda10045 { | |||
107 | sub tda10046 { | 107 | sub tda10046 { |
108 | my $sourcefile = "tt_budget_217g.zip"; | 108 | my $sourcefile = "tt_budget_217g.zip"; |
109 | my $url = "http://www.technotrend.de/new/217g/$sourcefile"; | 109 | my $url = "http://www.technotrend.de/new/217g/$sourcefile"; |
110 | my $hash = "a25b579e37109af60f4a36c37893957c"; | 110 | my $hash = "6a7e1e2f2644b162ff0502367553c72d"; |
111 | my $outfile = "dvb-fe-tda10046.fw"; | 111 | my $outfile = "dvb-fe-tda10046.fw"; |
112 | my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); | 112 | my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1); |
113 | 113 | ||
@@ -115,7 +115,7 @@ sub tda10046 { | |||
115 | 115 | ||
116 | wgetfile($sourcefile, $url); | 116 | wgetfile($sourcefile, $url); |
117 | unzip($sourcefile, $tmpdir); | 117 | unzip($sourcefile, $tmpdir); |
118 | extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24479, "$tmpdir/fwtmp"); | 118 | extract("$tmpdir/software/OEM/PCI/App/ttlcdacc.dll", 0x3f731, 24478, "$tmpdir/fwtmp"); |
119 | verify("$tmpdir/fwtmp", $hash); | 119 | verify("$tmpdir/fwtmp", $hash); |
120 | copy("$tmpdir/fwtmp", $outfile); | 120 | copy("$tmpdir/fwtmp", $outfile); |
121 | 121 | ||
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index d3c52dd24a2a..b9eb209318ab 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -63,3 +63,23 @@ Why: Outside of Linux, the only implementations of anything even | |||
63 | people, who might be using implementations that I am not aware | 63 | people, who might be using implementations that I am not aware |
64 | of, to adjust to this upcoming change. | 64 | of, to adjust to this upcoming change. |
65 | Who: Paul E. McKenney <paulmck@us.ibm.com> | 65 | Who: Paul E. McKenney <paulmck@us.ibm.com> |
66 | |||
67 | --------------------------- | ||
68 | |||
69 | What: IEEE1394 Audio and Music Data Transmission Protocol driver, | ||
70 | Connection Management Procedures driver | ||
71 | When: November 2005 | ||
72 | Files: drivers/ieee1394/{amdtp,cmp}* | ||
73 | Why: These are incomplete, have never worked, and are better implemented | ||
74 | in userland via raw1394 (see http://freebob.sourceforge.net/ for | ||
75 | example.) | ||
76 | Who: Jody McIntyre <scjody@steamballoon.com> | ||
77 | |||
78 | --------------------------- | ||
79 | |||
80 | What: raw1394: requests of type RAW1394_REQ_ISO_SEND, RAW1394_REQ_ISO_LISTEN | ||
81 | When: November 2005 | ||
82 | Why: Deprecated in favour of the new ioctl-based rawiso interface, which is | ||
83 | more efficient. You should really be using libraw1394 for raw1394 | ||
84 | access anyway. | ||
85 | Who: Jody McIntyre <scjody@steamballoon.com> | ||
diff --git a/Documentation/filesystems/sysfs-pci.txt b/Documentation/filesystems/sysfs-pci.txt index e97d024eae77..988a62fae11f 100644 --- a/Documentation/filesystems/sysfs-pci.txt +++ b/Documentation/filesystems/sysfs-pci.txt | |||
@@ -7,7 +7,6 @@ that support it. For example, a given bus might look like this: | |||
7 | |-- 0000:17:00.0 | 7 | |-- 0000:17:00.0 |
8 | | |-- class | 8 | | |-- class |
9 | | |-- config | 9 | | |-- config |
10 | | |-- detach_state | ||
11 | | |-- device | 10 | | |-- device |
12 | | |-- irq | 11 | | |-- irq |
13 | | |-- local_cpus | 12 | | |-- local_cpus |
@@ -19,7 +18,7 @@ that support it. For example, a given bus might look like this: | |||
19 | | |-- subsystem_device | 18 | | |-- subsystem_device |
20 | | |-- subsystem_vendor | 19 | | |-- subsystem_vendor |
21 | | `-- vendor | 20 | | `-- vendor |
22 | `-- detach_state | 21 | `-- ... |
23 | 22 | ||
24 | The topmost element describes the PCI domain and bus number. In this case, | 23 | The topmost element describes the PCI domain and bus number. In this case, |
25 | the domain number is 0000 and the bus number is 17 (both values are in hex). | 24 | the domain number is 0000 and the bus number is 17 (both values are in hex). |
@@ -31,7 +30,6 @@ files, each with their own function. | |||
31 | ---- -------- | 30 | ---- -------- |
32 | class PCI class (ascii, ro) | 31 | class PCI class (ascii, ro) |
33 | config PCI config space (binary, rw) | 32 | config PCI config space (binary, rw) |
34 | detach_state connection status (bool, rw) | ||
35 | device PCI device (ascii, ro) | 33 | device PCI device (ascii, ro) |
36 | irq IRQ number (ascii, ro) | 34 | irq IRQ number (ascii, ro) |
37 | local_cpus nearby CPU mask (cpumask, ro) | 35 | local_cpus nearby CPU mask (cpumask, ro) |
@@ -85,4 +83,4 @@ useful return codes should be provided. | |||
85 | 83 | ||
86 | Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms | 84 | Legacy resources are protected by the HAVE_PCI_LEGACY define. Platforms |
87 | wishing to support legacy functionality should define it and provide | 85 | wishing to support legacy functionality should define it and provide |
88 | pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions. \ No newline at end of file | 86 | pci_legacy_read, pci_legacy_write and pci_mmap_legacy_page_range functions. |
diff --git a/Documentation/networking/DLINK.txt b/Documentation/networking/DLINK.txt index 083d24752b83..55d24433d151 100644 --- a/Documentation/networking/DLINK.txt +++ b/Documentation/networking/DLINK.txt | |||
@@ -178,10 +178,9 @@ Released 1994-06-13 | |||
178 | 7. ACKNOWLEDGMENTS. | 178 | 7. ACKNOWLEDGMENTS. |
179 | 179 | ||
180 | These drivers wouldn't have been done without the base | 180 | These drivers wouldn't have been done without the base |
181 | (and support) from Ross Biro <bir7@leland.stanford.edu>, | 181 | (and support) from Ross Biro, and D-Link Systems Inc. |
182 | and D-Link Systems Inc. The driver relies upon GPL-ed | 182 | The driver relies upon GPL-ed source from D-Link Systems Inc. |
183 | source from D-Link Systems Inc. and from Russel Nelson at | 183 | and from Russel Nelson at Crynwr Software <nelson@crynwr.com>. |
184 | Crynwr Software <nelson@crynwr.com>. | ||
185 | 184 | ||
186 | Additional input also from: | 185 | Additional input also from: |
187 | Donald Becker <becker@super.org>, Alan Cox <A.Cox@swansea.ac.uk> | 186 | Donald Becker <becker@super.org>, Alan Cox <A.Cox@swansea.ac.uk> |
diff --git a/Documentation/power/devices.txt b/Documentation/power/devices.txt index 5d4ae9a39f1d..f987afe43e28 100644 --- a/Documentation/power/devices.txt +++ b/Documentation/power/devices.txt | |||
@@ -207,27 +207,6 @@ SYSTEM_SHUTDOWN, I do not understand this one too much. probably event | |||
207 | #READY_AFTER_RESUME | 207 | #READY_AFTER_RESUME |
208 | # | 208 | # |
209 | 209 | ||
210 | Driver Detach Power Management | ||
211 | |||
212 | The kernel now supports the ability to place a device in a low-power | ||
213 | state when it is detached from its driver, which happens when its | ||
214 | module is removed. | ||
215 | |||
216 | Each device contains a 'detach_state' file in its sysfs directory | ||
217 | which can be used to control this state. Reading from this file | ||
218 | displays what the current detach state is set to. This is 0 (On) by | ||
219 | default. A user may write a positive integer value to this file in the | ||
220 | range of 1-4 inclusive. | ||
221 | |||
222 | A value of 1-3 will indicate the device should be placed in that | ||
223 | low-power state, which will cause ->suspend() to be called for that | ||
224 | device. A value of 4 indicates that the device should be shutdown, so | ||
225 | ->shutdown() will be called for that device. | ||
226 | |||
227 | The driver is responsible for reinitializing the device when the | ||
228 | module is re-inserted during it's ->probe() (or equivalent) method. | ||
229 | The driver core will not call any extra functions when binding the | ||
230 | device to the driver. | ||
231 | 210 | ||
232 | pm_message_t meaning | 211 | pm_message_t meaning |
233 | 212 | ||
diff --git a/Documentation/powerpc/hvcs.txt b/Documentation/powerpc/hvcs.txt index c0a62e116e6e..dca75cbda6f8 100644 --- a/Documentation/powerpc/hvcs.txt +++ b/Documentation/powerpc/hvcs.txt | |||
@@ -347,8 +347,8 @@ address that is created by firmware. An example vty-server sysfs entry | |||
347 | looks like the following: | 347 | looks like the following: |
348 | 348 | ||
349 | Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls | 349 | Pow5:/sys/bus/vio/drivers/hvcs/30000004 # ls |
350 | . current_vty devspec name partner_vtys | 350 | . current_vty devspec name partner_vtys |
351 | .. detach_state index partner_clcs vterm_state | 351 | .. index partner_clcs vterm_state |
352 | 352 | ||
353 | Each entry is provided, by default with a "name" attribute. Reading the | 353 | Each entry is provided, by default with a "name" attribute. Reading the |
354 | "name" attribute will reveal the device type as shown in the following | 354 | "name" attribute will reveal the device type as shown in the following |
diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index 44b6eea60ece..b9e6be00cadf 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt | |||
@@ -25,6 +25,9 @@ APICs | |||
25 | 25 | ||
26 | noapictimer Don't set up the APIC timer | 26 | noapictimer Don't set up the APIC timer |
27 | 27 | ||
28 | no_timer_check Don't check the IO-APIC timer. This can work around | ||
29 | problems with incorrect timer initialization on some boards. | ||
30 | |||
28 | Early Console | 31 | Early Console |
29 | 32 | ||
30 | syntax: earlyprintk=vga | 33 | syntax: earlyprintk=vga |
diff --git a/MAINTAINERS b/MAINTAINERS index f384a9758fc0..5b8483334de1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1699,7 +1699,9 @@ P: Pavel Roskin | |||
1699 | M: proski@gnu.org | 1699 | M: proski@gnu.org |
1700 | P: David Gibson | 1700 | P: David Gibson |
1701 | M: hermes@gibson.dropbear.id.au | 1701 | M: hermes@gibson.dropbear.id.au |
1702 | W: http://www.ozlabs.org/people/dgibson/dldwd | 1702 | L: orinoco-users@lists.sourceforge.net |
1703 | L: orinoco-devel@lists.sourceforge.net | ||
1704 | W: http://www.nongnu.org/orinoco/ | ||
1703 | S: Maintained | 1705 | S: Maintained |
1704 | 1706 | ||
1705 | PARALLEL PORT SUPPORT | 1707 | PARALLEL PORT SUPPORT |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 12 | 3 | SUBLEVEL = 12 |
4 | EXTRAVERSION =-rc3 | 4 | EXTRAVERSION =-rc4 |
5 | NAME=Woozy Numbat | 5 | NAME=Woozy Numbat |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -530,7 +530,7 @@ endif | |||
530 | include $(srctree)/arch/$(ARCH)/Makefile | 530 | include $(srctree)/arch/$(ARCH)/Makefile |
531 | 531 | ||
532 | # arch Makefile may override CC so keep this after arch Makefile is included | 532 | # arch Makefile may override CC so keep this after arch Makefile is included |
533 | NOSTDINC_FLAGS := -nostdinc -isystem $(shell $(CC) -print-file-name=include) | 533 | NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) |
534 | CHECKFLAGS += $(NOSTDINC_FLAGS) | 534 | CHECKFLAGS += $(NOSTDINC_FLAGS) |
535 | 535 | ||
536 | # warn about C99 declaration after statement | 536 | # warn about C99 declaration after statement |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 64e450dddb49..167fd89f8707 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -1150,16 +1150,13 @@ osf_usleep_thread(struct timeval32 __user *sleep, struct timeval32 __user *remai | |||
1150 | if (get_tv32(&tmp, sleep)) | 1150 | if (get_tv32(&tmp, sleep)) |
1151 | goto fault; | 1151 | goto fault; |
1152 | 1152 | ||
1153 | ticks = tmp.tv_usec; | 1153 | ticks = timeval_to_jiffies(&tmp); |
1154 | ticks = (ticks + (1000000 / HZ) - 1) / (1000000 / HZ); | ||
1155 | ticks += tmp.tv_sec * HZ; | ||
1156 | 1154 | ||
1157 | current->state = TASK_INTERRUPTIBLE; | 1155 | current->state = TASK_INTERRUPTIBLE; |
1158 | ticks = schedule_timeout(ticks); | 1156 | ticks = schedule_timeout(ticks); |
1159 | 1157 | ||
1160 | if (remain) { | 1158 | if (remain) { |
1161 | tmp.tv_sec = ticks / HZ; | 1159 | jiffies_to_timeval(ticks, &tmp); |
1162 | tmp.tv_usec = ticks % HZ; | ||
1163 | if (put_tv32(remain, &tmp)) | 1160 | if (put_tv32(remain, &tmp)) |
1164 | goto fault; | 1161 | goto fault; |
1165 | } | 1162 | } |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 8bfcb37460fa..bf397a9f8ac2 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -85,6 +85,7 @@ choice | |||
85 | config ARCH_CLPS7500 | 85 | config ARCH_CLPS7500 |
86 | bool "Cirrus-CL-PS7500FE" | 86 | bool "Cirrus-CL-PS7500FE" |
87 | select TIMER_ACORN | 87 | select TIMER_ACORN |
88 | select ISA | ||
88 | 89 | ||
89 | config ARCH_CLPS711X | 90 | config ARCH_CLPS711X |
90 | bool "CLPS711x/EP721x-based" | 91 | bool "CLPS711x/EP721x-based" |
@@ -96,6 +97,7 @@ config ARCH_CO285 | |||
96 | 97 | ||
97 | config ARCH_EBSA110 | 98 | config ARCH_EBSA110 |
98 | bool "EBSA-110" | 99 | bool "EBSA-110" |
100 | select ISA | ||
99 | help | 101 | help |
100 | This is an evaluation board for the StrongARM processor available | 102 | This is an evaluation board for the StrongARM processor available |
101 | from Digital. It has limited hardware on-board, including an onboard | 103 | from Digital. It has limited hardware on-board, including an onboard |
@@ -120,13 +122,16 @@ config ARCH_INTEGRATOR | |||
120 | 122 | ||
121 | config ARCH_IOP3XX | 123 | config ARCH_IOP3XX |
122 | bool "IOP3xx-based" | 124 | bool "IOP3xx-based" |
125 | select PCI | ||
123 | 126 | ||
124 | config ARCH_IXP4XX | 127 | config ARCH_IXP4XX |
125 | bool "IXP4xx-based" | 128 | bool "IXP4xx-based" |
126 | select DMABOUNCE | 129 | select DMABOUNCE |
130 | select PCI | ||
127 | 131 | ||
128 | config ARCH_IXP2000 | 132 | config ARCH_IXP2000 |
129 | bool "IXP2400/2800-based" | 133 | bool "IXP2400/2800-based" |
134 | select PCI | ||
130 | 135 | ||
131 | config ARCH_L7200 | 136 | config ARCH_L7200 |
132 | bool "LinkUp-L7200" | 137 | bool "LinkUp-L7200" |
@@ -155,6 +160,8 @@ config ARCH_RPC | |||
155 | 160 | ||
156 | config ARCH_SA1100 | 161 | config ARCH_SA1100 |
157 | bool "SA1100-based" | 162 | bool "SA1100-based" |
163 | select ISA | ||
164 | select DISCONTIGMEM | ||
158 | 165 | ||
159 | config ARCH_S3C2410 | 166 | config ARCH_S3C2410 |
160 | bool "Samsung S3C2410" | 167 | bool "Samsung S3C2410" |
@@ -165,6 +172,9 @@ config ARCH_S3C2410 | |||
165 | 172 | ||
166 | config ARCH_SHARK | 173 | config ARCH_SHARK |
167 | bool "Shark" | 174 | bool "Shark" |
175 | select ISA | ||
176 | select ISA_DMA | ||
177 | select PCI | ||
168 | 178 | ||
169 | config ARCH_LH7A40X | 179 | config ARCH_LH7A40X |
170 | bool "Sharp LH7A40X" | 180 | bool "Sharp LH7A40X" |
@@ -252,8 +262,6 @@ config ARM_AMBA | |||
252 | 262 | ||
253 | config ISA | 263 | config ISA |
254 | bool | 264 | bool |
255 | depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100 || ARCH_MX1ADS | ||
256 | default y | ||
257 | help | 265 | help |
258 | Find out whether you have ISA slots on your motherboard. ISA is the | 266 | Find out whether you have ISA slots on your motherboard. ISA is the |
259 | name of a bus system, i.e. the way the CPU talks to the other stuff | 267 | name of a bus system, i.e. the way the CPU talks to the other stuff |
@@ -263,8 +271,6 @@ config ISA | |||
263 | 271 | ||
264 | config ISA_DMA | 272 | config ISA_DMA |
265 | bool | 273 | bool |
266 | depends on FOOTBRIDGE_HOST || ARCH_SHARK | ||
267 | default y | ||
268 | 274 | ||
269 | config ISA_DMA_API | 275 | config ISA_DMA_API |
270 | bool | 276 | bool |
@@ -272,7 +278,6 @@ config ISA_DMA_API | |||
272 | 278 | ||
273 | config PCI | 279 | config PCI |
274 | bool "PCI support" if ARCH_INTEGRATOR_AP | 280 | bool "PCI support" if ARCH_INTEGRATOR_AP |
275 | default y if ARCH_SHARK || FOOTBRIDGE_HOST || ARCH_IOP3XX || ARCH_IXP4XX || ARCH_IXP2000 | ||
276 | help | 281 | help |
277 | Find out whether you have a PCI motherboard. PCI is the name of a | 282 | Find out whether you have a PCI motherboard. PCI is the name of a |
278 | bus system, i.e. the way the CPU talks to the other stuff inside | 283 | bus system, i.e. the way the CPU talks to the other stuff inside |
@@ -300,7 +305,7 @@ menu "Kernel Features" | |||
300 | 305 | ||
301 | config SMP | 306 | config SMP |
302 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 307 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
303 | depends on EXPERIMENTAL && n | 308 | depends on EXPERIMENTAL #&& n |
304 | help | 309 | help |
305 | This enables support for systems with more than one CPU. If you have | 310 | This enables support for systems with more than one CPU. If you have |
306 | a system with only one CPU, like most personal computers, say N. If | 311 | a system with only one CPU, like most personal computers, say N. If |
@@ -340,8 +345,7 @@ config PREEMPT | |||
340 | 345 | ||
341 | config DISCONTIGMEM | 346 | config DISCONTIGMEM |
342 | bool | 347 | bool |
343 | depends on ARCH_EDB7211 || ARCH_SA1100 || (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) | 348 | default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM) |
344 | default y | ||
345 | help | 349 | help |
346 | Say Y to support efficient handling of discontiguous physical memory, | 350 | Say Y to support efficient handling of discontiguous physical memory, |
347 | for architectures which are either NUMA (Non-Uniform Memory Access) | 351 | for architectures which are either NUMA (Non-Uniform Memory Access) |
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S index 080df907f242..4eb36155dc93 100644 --- a/arch/arm/kernel/entry-armv.S +++ b/arch/arm/kernel/entry-armv.S | |||
@@ -17,8 +17,8 @@ | |||
17 | 17 | ||
18 | #include <asm/glue.h> | 18 | #include <asm/glue.h> |
19 | #include <asm/vfpmacros.h> | 19 | #include <asm/vfpmacros.h> |
20 | #include <asm/hardware.h> @ should be moved into entry-macro.S | 20 | #include <asm/hardware.h> /* should be moved into entry-macro.S */ |
21 | #include <asm/arch/irqs.h> @ should be moved into entry-macro.S | 21 | #include <asm/arch/irqs.h> /* should be moved into entry-macro.S */ |
22 | #include <asm/arch/entry-macro.S> | 22 | #include <asm/arch/entry-macro.S> |
23 | 23 | ||
24 | #include "entry-header.S" | 24 | #include "entry-header.S" |
@@ -505,9 +505,9 @@ ENTRY(__switch_to) | |||
505 | mra r4, r5, acc0 | 505 | mra r4, r5, acc0 |
506 | stmia ip, {r4, r5} | 506 | stmia ip, {r4, r5} |
507 | #endif | 507 | #endif |
508 | #ifdef CONFIG_HAS_TLS_REG | 508 | #if defined(CONFIG_HAS_TLS_REG) |
509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register | 509 | mcr p15, 0, r3, c13, c0, 3 @ set TLS register |
510 | #else | 510 | #elif !defined(CONFIG_TLS_REG_EMUL) |
511 | mov r4, #0xffff0fff | 511 | mov r4, #0xffff0fff |
512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 | 512 | str r3, [r4, #-15] @ TLS val at 0xffff0ff0 |
513 | #endif | 513 | #endif |
@@ -690,11 +690,7 @@ __kuser_cmpxchg: @ 0xffff0fc0 | |||
690 | 690 | ||
691 | __kuser_get_tls: @ 0xffff0fe0 | 691 | __kuser_get_tls: @ 0xffff0fe0 |
692 | 692 | ||
693 | #ifndef CONFIG_HAS_TLS_REG | 693 | #if !defined(CONFIG_HAS_TLS_REG) && !defined(CONFIG_TLS_REG_EMUL) |
694 | |||
695 | #ifdef CONFIG_SMP /* sanity check */ | ||
696 | #error "CONFIG_SMP without CONFIG_HAS_TLS_REG is wrong" | ||
697 | #endif | ||
698 | 694 | ||
699 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 | 695 | ldr r0, [pc, #(16 - 8)] @ TLS stored at 0xffff0ff0 |
700 | mov pc, lr | 696 | mov pc, lr |
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index 171b3e811c71..4733877296d4 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <asm/procinfo.h> | 19 | #include <asm/procinfo.h> |
20 | #include <asm/ptrace.h> | 20 | #include <asm/ptrace.h> |
21 | #include <asm/constants.h> | 21 | #include <asm/constants.h> |
22 | #include <asm/thread_info.h> | ||
22 | #include <asm/system.h> | 23 | #include <asm/system.h> |
23 | 24 | ||
24 | #define PROCINFO_MMUFLAGS 8 | 25 | #define PROCINFO_MMUFLAGS 8 |
@@ -131,7 +132,7 @@ __switch_data: | |||
131 | .long processor_id @ r4 | 132 | .long processor_id @ r4 |
132 | .long __machine_arch_type @ r5 | 133 | .long __machine_arch_type @ r5 |
133 | .long cr_alignment @ r6 | 134 | .long cr_alignment @ r6 |
134 | .long init_thread_union+8192 @ sp | 135 | .long init_thread_union + THREAD_START_SP @ sp |
135 | 136 | ||
136 | /* | 137 | /* |
137 | * The following fragment of code is executed with the MMU on, and uses | 138 | * The following fragment of code is executed with the MMU on, and uses |
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 26eacd3e5def..8f146a4b4752 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c | |||
@@ -256,8 +256,6 @@ static unsigned long *thread_info_head; | |||
256 | static unsigned int nr_thread_info; | 256 | static unsigned int nr_thread_info; |
257 | 257 | ||
258 | #define EXTRA_TASK_STRUCT 4 | 258 | #define EXTRA_TASK_STRUCT 4 |
259 | #define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) | ||
260 | #define ll_free_task_struct(p) free_pages((unsigned long)(p),1) | ||
261 | 259 | ||
262 | struct thread_info *alloc_thread_info(struct task_struct *task) | 260 | struct thread_info *alloc_thread_info(struct task_struct *task) |
263 | { | 261 | { |
@@ -274,17 +272,16 @@ struct thread_info *alloc_thread_info(struct task_struct *task) | |||
274 | } | 272 | } |
275 | 273 | ||
276 | if (!thread) | 274 | if (!thread) |
277 | thread = ll_alloc_task_struct(); | 275 | thread = (struct thread_info *) |
276 | __get_free_pages(GFP_KERNEL, THREAD_SIZE_ORDER); | ||
278 | 277 | ||
279 | #ifdef CONFIG_MAGIC_SYSRQ | 278 | #ifdef CONFIG_DEBUG_STACK_USAGE |
280 | /* | 279 | /* |
281 | * The stack must be cleared if you want SYSRQ-T to | 280 | * The stack must be cleared if you want SYSRQ-T to |
282 | * give sensible stack usage information | 281 | * give sensible stack usage information |
283 | */ | 282 | */ |
284 | if (thread) { | 283 | if (thread) |
285 | char *p = (char *)thread; | 284 | memzero(thread, THREAD_SIZE); |
286 | memzero(p+KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); | ||
287 | } | ||
288 | #endif | 285 | #endif |
289 | return thread; | 286 | return thread; |
290 | } | 287 | } |
@@ -297,7 +294,7 @@ void free_thread_info(struct thread_info *thread) | |||
297 | thread_info_head = p; | 294 | thread_info_head = p; |
298 | nr_thread_info += 1; | 295 | nr_thread_info += 1; |
299 | } else | 296 | } else |
300 | ll_free_task_struct(thread); | 297 | free_pages((unsigned long)thread, THREAD_SIZE_ORDER); |
301 | } | 298 | } |
302 | 299 | ||
303 | /* | 300 | /* |
@@ -350,7 +347,7 @@ copy_thread(int nr, unsigned long clone_flags, unsigned long stack_start, | |||
350 | struct thread_info *thread = p->thread_info; | 347 | struct thread_info *thread = p->thread_info; |
351 | struct pt_regs *childregs; | 348 | struct pt_regs *childregs; |
352 | 349 | ||
353 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; | 350 | childregs = ((struct pt_regs *)((unsigned long)thread + THREAD_START_SP)) - 1; |
354 | *childregs = *regs; | 351 | *childregs = *regs; |
355 | childregs->ARM_r0 = 0; | 352 | childregs->ARM_r0 = 0; |
356 | childregs->ARM_sp = stack_start; | 353 | childregs->ARM_sp = stack_start; |
@@ -447,15 +444,17 @@ EXPORT_SYMBOL(kernel_thread); | |||
447 | unsigned long get_wchan(struct task_struct *p) | 444 | unsigned long get_wchan(struct task_struct *p) |
448 | { | 445 | { |
449 | unsigned long fp, lr; | 446 | unsigned long fp, lr; |
450 | unsigned long stack_page; | 447 | unsigned long stack_start, stack_end; |
451 | int count = 0; | 448 | int count = 0; |
452 | if (!p || p == current || p->state == TASK_RUNNING) | 449 | if (!p || p == current || p->state == TASK_RUNNING) |
453 | return 0; | 450 | return 0; |
454 | 451 | ||
455 | stack_page = 4096 + (unsigned long)p->thread_info; | 452 | stack_start = (unsigned long)(p->thread_info + 1); |
453 | stack_end = ((unsigned long)p->thread_info) + THREAD_SIZE; | ||
454 | |||
456 | fp = thread_saved_fp(p); | 455 | fp = thread_saved_fp(p); |
457 | do { | 456 | do { |
458 | if (fp < stack_page || fp > 4092+stack_page) | 457 | if (fp < stack_start || fp > stack_end) |
459 | return 0; | 458 | return 0; |
460 | lr = pc_pointer (((unsigned long *)fp)[-1]); | 459 | lr = pc_pointer (((unsigned long *)fp)[-1]); |
461 | if (!in_sched_functions(lr)) | 460 | if (!in_sched_functions(lr)) |
diff --git a/arch/arm/kernel/sys_arm.c b/arch/arm/kernel/sys_arm.c index ef32577da304..f897ce2ccf0d 100644 --- a/arch/arm/kernel/sys_arm.c +++ b/arch/arm/kernel/sys_arm.c | |||
@@ -302,7 +302,7 @@ long execve(const char *filename, char **argv, char **envp) | |||
302 | "b ret_to_user" | 302 | "b ret_to_user" |
303 | : | 303 | : |
304 | : "r" (current_thread_info()), | 304 | : "r" (current_thread_info()), |
305 | "Ir" (THREAD_SIZE - 8 - sizeof(regs)), | 305 | "Ir" (THREAD_START_SP - sizeof(regs)), |
306 | "r" (®s), | 306 | "r" (®s), |
307 | "Ir" (sizeof(regs)) | 307 | "Ir" (sizeof(regs)) |
308 | : "r0", "r1", "r2", "r3", "ip", "memory"); | 308 | : "r0", "r1", "r2", "r3", "ip", "memory"); |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 3a001fe5540b..14df16b983f4 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -218,7 +218,8 @@ NORET_TYPE void die(const char *str, struct pt_regs *regs, int err) | |||
218 | tsk->comm, tsk->pid, tsk->thread_info + 1); | 218 | tsk->comm, tsk->pid, tsk->thread_info + 1); |
219 | 219 | ||
220 | if (!user_mode(regs) || in_interrupt()) { | 220 | if (!user_mode(regs) || in_interrupt()) { |
221 | dump_mem("Stack: ", regs->ARM_sp, 8192+(unsigned long)tsk->thread_info); | 221 | dump_mem("Stack: ", regs->ARM_sp, |
222 | THREAD_SIZE + (unsigned long)tsk->thread_info); | ||
222 | dump_backtrace(regs, tsk); | 223 | dump_backtrace(regs, tsk); |
223 | dump_instr(regs); | 224 | dump_instr(regs); |
224 | } | 225 | } |
@@ -450,9 +451,9 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
450 | 451 | ||
451 | case NR(set_tls): | 452 | case NR(set_tls): |
452 | thread->tp_value = regs->ARM_r0; | 453 | thread->tp_value = regs->ARM_r0; |
453 | #ifdef CONFIG_HAS_TLS_REG | 454 | #if defined(CONFIG_HAS_TLS_REG) |
454 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); | 455 | asm ("mcr p15, 0, %0, c13, c0, 3" : : "r" (regs->ARM_r0) ); |
455 | #else | 456 | #elif !defined(CONFIG_TLS_REG_EMUL) |
456 | /* | 457 | /* |
457 | * User space must never try to access this directly. | 458 | * User space must never try to access this directly. |
458 | * Expect your app to break eventually if you do so. | 459 | * Expect your app to break eventually if you do so. |
@@ -497,11 +498,14 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs) | |||
497 | return 0; | 498 | return 0; |
498 | } | 499 | } |
499 | 500 | ||
500 | #if defined(CONFIG_CPU_32v6) && !defined(CONFIG_HAS_TLS_REG) | 501 | #ifdef CONFIG_TLS_REG_EMUL |
501 | 502 | ||
502 | /* | 503 | /* |
503 | * We might be running on an ARMv6+ processor which should have the TLS | 504 | * We might be running on an ARMv6+ processor which should have the TLS |
504 | * register, but for some reason we can't use it and have to emulate it. | 505 | * register but for some reason we can't use it, or maybe an SMP system |
506 | * using a pre-ARMv6 processor (there are apparently a few prototypes like | ||
507 | * that in existence) and therefore access to that register must be | ||
508 | * emulated. | ||
505 | */ | 509 | */ |
506 | 510 | ||
507 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) | 511 | static int get_tp_trap(struct pt_regs *regs, unsigned int instr) |
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S index a39c6a42d68a..ad2d66c93a5c 100644 --- a/arch/arm/kernel/vmlinux.lds.S +++ b/arch/arm/kernel/vmlinux.lds.S | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <asm-generic/vmlinux.lds.h> | 6 | #include <asm-generic/vmlinux.lds.h> |
7 | #include <linux/config.h> | 7 | #include <linux/config.h> |
8 | #include <asm/thread_info.h> | ||
8 | 9 | ||
9 | OUTPUT_ARCH(arm) | 10 | OUTPUT_ARCH(arm) |
10 | ENTRY(stext) | 11 | ENTRY(stext) |
@@ -103,7 +104,7 @@ SECTIONS | |||
103 | __data_loc = ALIGN(4); /* location in binary */ | 104 | __data_loc = ALIGN(4); /* location in binary */ |
104 | . = DATAADDR; | 105 | . = DATAADDR; |
105 | #else | 106 | #else |
106 | . = ALIGN(8192); | 107 | . = ALIGN(THREAD_SIZE); |
107 | __data_loc = .; | 108 | __data_loc = .; |
108 | #endif | 109 | #endif |
109 | 110 | ||
diff --git a/arch/arm/mach-clps711x/Kconfig b/arch/arm/mach-clps711x/Kconfig index f6e676322ca9..45c930ccd064 100644 --- a/arch/arm/mach-clps711x/Kconfig +++ b/arch/arm/mach-clps711x/Kconfig | |||
@@ -10,6 +10,7 @@ config ARCH_AUTCPU12 | |||
10 | 10 | ||
11 | config ARCH_CDB89712 | 11 | config ARCH_CDB89712 |
12 | bool "CDB89712" | 12 | bool "CDB89712" |
13 | select ISA | ||
13 | help | 14 | help |
14 | This is an evaluation board from Cirrus for the CS89712 processor. | 15 | This is an evaluation board from Cirrus for the CS89712 processor. |
15 | The board includes 2 serial ports, Ethernet, IRDA, and expansion | 16 | The board includes 2 serial ports, Ethernet, IRDA, and expansion |
@@ -26,6 +27,8 @@ config ARCH_CLEP7312 | |||
26 | 27 | ||
27 | config ARCH_EDB7211 | 28 | config ARCH_EDB7211 |
28 | bool "EDB7211" | 29 | bool "EDB7211" |
30 | select ISA | ||
31 | select DISCONTIGMEM | ||
29 | help | 32 | help |
30 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 | 33 | Say Y here if you intend to run this kernel on a Cirrus Logic EDB-7211 |
31 | evaluation board. | 34 | evaluation board. |
diff --git a/arch/arm/mach-footbridge/Kconfig b/arch/arm/mach-footbridge/Kconfig index 1090c680b6dd..324d9edeec38 100644 --- a/arch/arm/mach-footbridge/Kconfig +++ b/arch/arm/mach-footbridge/Kconfig | |||
@@ -5,6 +5,9 @@ menu "Footbridge Implementations" | |||
5 | config ARCH_CATS | 5 | config ARCH_CATS |
6 | bool "CATS" | 6 | bool "CATS" |
7 | select FOOTBRIDGE_HOST | 7 | select FOOTBRIDGE_HOST |
8 | select ISA | ||
9 | select ISA_DMA | ||
10 | select PCI | ||
8 | help | 11 | help |
9 | Say Y here if you intend to run this kernel on the CATS. | 12 | Say Y here if you intend to run this kernel on the CATS. |
10 | 13 | ||
@@ -13,6 +16,9 @@ config ARCH_CATS | |||
13 | config ARCH_PERSONAL_SERVER | 16 | config ARCH_PERSONAL_SERVER |
14 | bool "Compaq Personal Server" | 17 | bool "Compaq Personal Server" |
15 | select FOOTBRIDGE_HOST | 18 | select FOOTBRIDGE_HOST |
19 | select ISA | ||
20 | select ISA_DMA | ||
21 | select PCI | ||
16 | ---help--- | 22 | ---help--- |
17 | Say Y here if you intend to run this kernel on the Compaq | 23 | Say Y here if you intend to run this kernel on the Compaq |
18 | Personal Server. | 24 | Personal Server. |
@@ -42,6 +48,9 @@ config ARCH_EBSA285_HOST | |||
42 | bool "EBSA285 (host mode)" | 48 | bool "EBSA285 (host mode)" |
43 | select ARCH_EBSA285 | 49 | select ARCH_EBSA285 |
44 | select FOOTBRIDGE_HOST | 50 | select FOOTBRIDGE_HOST |
51 | select ISA | ||
52 | select ISA_DMA | ||
53 | select PCI | ||
45 | help | 54 | help |
46 | Say Y here if you intend to run this kernel on the EBSA285 card | 55 | Say Y here if you intend to run this kernel on the EBSA285 card |
47 | in host ("central function") mode. | 56 | in host ("central function") mode. |
@@ -51,6 +60,9 @@ config ARCH_EBSA285_HOST | |||
51 | config ARCH_NETWINDER | 60 | config ARCH_NETWINDER |
52 | bool "NetWinder" | 61 | bool "NetWinder" |
53 | select FOOTBRIDGE_HOST | 62 | select FOOTBRIDGE_HOST |
63 | select ISA | ||
64 | select ISA_DMA | ||
65 | select PCI | ||
54 | help | 66 | help |
55 | Say Y here if you intend to run this kernel on the Rebel.COM | 67 | Say Y here if you intend to run this kernel on the Rebel.COM |
56 | NetWinder. Information about this machine can be found at: | 68 | NetWinder. Information about this machine can be found at: |
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index ec85813ee5dc..cddd194ac6eb 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig | |||
@@ -4,6 +4,7 @@ menu "IMX Implementations" | |||
4 | config ARCH_MX1ADS | 4 | config ARCH_MX1ADS |
5 | bool "mx1ads" | 5 | bool "mx1ads" |
6 | depends on ARCH_IMX | 6 | depends on ARCH_IMX |
7 | select ISA | ||
7 | help | 8 | help |
8 | Say Y here if you are using the Motorola MX1ADS board | 9 | Say Y here if you are using the Motorola MX1ADS board |
9 | 10 | ||
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c index e23f534d4e1d..8d986b8401c2 100644 --- a/arch/arm/mach-s3c2410/clock.c +++ b/arch/arm/mach-s3c2410/clock.c | |||
@@ -478,7 +478,7 @@ static int s3c2440_clk_add(struct sys_device *sysdev) | |||
478 | { | 478 | { |
479 | unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); | 479 | unsigned long upllcon = __raw_readl(S3C2410_UPLLCON); |
480 | 480 | ||
481 | s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate) * 2; | 481 | s3c2440_clk_upll.rate = s3c2410_get_pll(upllcon, clk_xtal.rate); |
482 | 482 | ||
483 | printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", | 483 | printk("S3C2440: Clock Support, UPLL %ld.%03ld MHz\n", |
484 | print_mhz(s3c2440_clk_upll.rate)); | 484 | print_mhz(s3c2440_clk_upll.rate)); |
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2410/s3c2440.c index 9a8cc5ae2255..d4c8281b55f6 100644 --- a/arch/arm/mach-s3c2410/s3c2440.c +++ b/arch/arm/mach-s3c2410/s3c2440.c | |||
@@ -192,9 +192,11 @@ void __init s3c2440_map_io(struct map_desc *mach_desc, int size) | |||
192 | 192 | ||
193 | iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); | 193 | iotable_init(s3c2440_iodesc, ARRAY_SIZE(s3c2440_iodesc)); |
194 | iotable_init(mach_desc, size); | 194 | iotable_init(mach_desc, size); |
195 | |||
195 | /* rename any peripherals used differing from the s3c2410 */ | 196 | /* rename any peripherals used differing from the s3c2410 */ |
196 | 197 | ||
197 | s3c_device_i2c.name = "s3c2440-i2c"; | 198 | s3c_device_i2c.name = "s3c2440-i2c"; |
199 | s3c_device_nand.name = "s3c2440-nand"; | ||
198 | 200 | ||
199 | /* change irq for watchdog */ | 201 | /* change irq for watchdog */ |
200 | 202 | ||
@@ -225,7 +227,7 @@ void __init s3c2440_init_clocks(int xtal) | |||
225 | break; | 227 | break; |
226 | 228 | ||
227 | case S3C2440_CLKDIVN_HDIVN_2: | 229 | case S3C2440_CLKDIVN_HDIVN_2: |
228 | hdiv = 1; | 230 | hdiv = 2; |
229 | break; | 231 | break; |
230 | 232 | ||
231 | case S3C2440_CLKDIVN_HDIVN_4_8: | 233 | case S3C2440_CLKDIVN_HDIVN_4_8: |
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 27892e34b060..48bac7da8c70 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig | |||
@@ -410,17 +410,22 @@ config CPU_BPREDICT_DISABLE | |||
410 | help | 410 | help |
411 | Say Y here to disable branch prediction. If unsure, say N. | 411 | Say Y here to disable branch prediction. If unsure, say N. |
412 | 412 | ||
413 | config TLS_REG_EMUL | ||
414 | bool | ||
415 | default y if SMP && (CPU_32v5 || CPU_32v4 || CPU_32v3) | ||
416 | help | ||
417 | An SMP system using a pre-ARMv6 processor (there are apparently | ||
418 | a few prototypes like that in existence) and therefore access to | ||
419 | that required register must be emulated. | ||
420 | |||
413 | config HAS_TLS_REG | 421 | config HAS_TLS_REG |
414 | bool | 422 | bool |
415 | depends on CPU_32v6 && !CPU_32v5 && !CPU_32v4 && !CPU_32v3 | 423 | depends on !TLS_REG_EMUL |
416 | default y | 424 | default y if SMP || CPU_32v7 |
417 | help | 425 | help |
418 | This selects support for the CP15 thread register. | 426 | This selects support for the CP15 thread register. |
419 | It is defined to be available on ARMv6 or later. However | 427 | It is defined to be available on some ARMv6 processors (including |
420 | if the kernel is configured to support multiple CPUs including | 428 | all SMP capable ARMv6's) or later processors. User space may |
421 | a pre-ARMv6 processors, or if a given ARMv6 processor doesn't | 429 | assume directly accessing that register and always obtain the |
422 | implement the thread register for some reason, then access to | 430 | expected value only on ARMv7 and above. |
423 | this register from user space must be trapped and emulated. | ||
424 | If user space is relying on the __kuser_get_tls code then | ||
425 | there should not be any impact. | ||
426 | 431 | ||
diff --git a/arch/arm/mm/copypage-v4mc.S b/arch/arm/mm/copypage-v4mc.S deleted file mode 100644 index 305af3dab3d8..000000000000 --- a/arch/arm/mm/copypage-v4mc.S +++ /dev/null | |||
@@ -1,80 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copy_page-armv4mc.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2001 Russell King | ||
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 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * ASM optimised string functions | ||
11 | */ | ||
12 | #include <linux/linkage.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <asm/constants.h> | ||
15 | |||
16 | .text | ||
17 | .align 5 | ||
18 | /* | ||
19 | * ARMv4 mini-dcache optimised copy_user_page | ||
20 | * | ||
21 | * We flush the destination cache lines just before we write the data into the | ||
22 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
23 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
24 | * and merged as appropriate. | ||
25 | * | ||
26 | * Note: We rely on all ARMv4 processors implementing the "invalidate D line" | ||
27 | * instruction. If your processor does not supply this, you have to write your | ||
28 | * own copy_user_page that does the right thing. | ||
29 | */ | ||
30 | ENTRY(v4_mc_copy_user_page) | ||
31 | stmfd sp!, {r4, lr} @ 2 | ||
32 | mov r4, r0 | ||
33 | mov r0, r1 | ||
34 | bl map_page_minicache | ||
35 | mov r1, #PAGE_SZ/64 @ 1 | ||
36 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
37 | 1: mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line | ||
38 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
39 | ldmia r0!, {r2, r3, ip, lr} @ 4+1 | ||
40 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
41 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
42 | mcr p15, 0, r4, c7, c6, 1 @ 1 invalidate D line | ||
43 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
44 | ldmia r0!, {r2, r3, ip, lr} @ 4 | ||
45 | subs r1, r1, #1 @ 1 | ||
46 | stmia r4!, {r2, r3, ip, lr} @ 4 | ||
47 | ldmneia r0!, {r2, r3, ip, lr} @ 4 | ||
48 | bne 1b @ 1 | ||
49 | ldmfd sp!, {r4, pc} @ 3 | ||
50 | |||
51 | .align 5 | ||
52 | /* | ||
53 | * ARMv4 optimised clear_user_page | ||
54 | * | ||
55 | * Same story as above. | ||
56 | */ | ||
57 | ENTRY(v4_mc_clear_user_page) | ||
58 | str lr, [sp, #-4]! | ||
59 | mov r1, #PAGE_SZ/64 @ 1 | ||
60 | mov r2, #0 @ 1 | ||
61 | mov r3, #0 @ 1 | ||
62 | mov ip, #0 @ 1 | ||
63 | mov lr, #0 @ 1 | ||
64 | 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line | ||
65 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
66 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
67 | mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line | ||
68 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
69 | stmia r0!, {r2, r3, ip, lr} @ 4 | ||
70 | subs r1, r1, #1 @ 1 | ||
71 | bne 1b @ 1 | ||
72 | ldr pc, [sp], #4 | ||
73 | |||
74 | __INITDATA | ||
75 | |||
76 | .type v4_mc_user_fns, #object | ||
77 | ENTRY(v4_mc_user_fns) | ||
78 | .long v4_mc_clear_user_page | ||
79 | .long v4_mc_copy_user_page | ||
80 | .size v4_mc_user_fns, . - v4_mc_user_fns | ||
diff --git a/arch/arm/mm/copypage-v4mc.c b/arch/arm/mm/copypage-v4mc.c new file mode 100644 index 000000000000..fc69dccdace1 --- /dev/null +++ b/arch/arm/mm/copypage-v4mc.c | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/copypage-armv4mc.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2005 Russell King | ||
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 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * This handles the mini data cache, as found on SA11x0 and XScale | ||
11 | * processors. When we copy a user page page, we map it in such a way | ||
12 | * that accesses to this page will not touch the main data cache, but | ||
13 | * will be cached in the mini data cache. This prevents us thrashing | ||
14 | * the main data cache on page faults. | ||
15 | */ | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/page.h> | ||
20 | #include <asm/pgtable.h> | ||
21 | #include <asm/tlbflush.h> | ||
22 | |||
23 | /* | ||
24 | * 0xffff8000 to 0xffffffff is reserved for any ARM architecture | ||
25 | * specific hacks for copying pages efficiently. | ||
26 | */ | ||
27 | #define minicache_pgprot __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | \ | ||
28 | L_PTE_CACHEABLE) | ||
29 | |||
30 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
31 | |||
32 | static DEFINE_SPINLOCK(minicache_lock); | ||
33 | |||
34 | /* | ||
35 | * ARMv4 mini-dcache optimised copy_user_page | ||
36 | * | ||
37 | * We flush the destination cache lines just before we write the data into the | ||
38 | * corresponding address. Since the Dcache is read-allocate, this removes the | ||
39 | * Dcache aliasing issue. The writes will be forwarded to the write buffer, | ||
40 | * and merged as appropriate. | ||
41 | * | ||
42 | * Note: We rely on all ARMv4 processors implementing the "invalidate D line" | ||
43 | * instruction. If your processor does not supply this, you have to write your | ||
44 | * own copy_user_page that does the right thing. | ||
45 | */ | ||
46 | static void __attribute__((naked)) | ||
47 | mc_copy_user_page(void *from, void *to) | ||
48 | { | ||
49 | asm volatile( | ||
50 | "stmfd sp!, {r4, lr} @ 2\n\ | ||
51 | mov r4, %2 @ 1\n\ | ||
52 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
53 | 1: mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ | ||
54 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
55 | ldmia %0!, {r2, r3, ip, lr} @ 4+1\n\ | ||
56 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
57 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
58 | mcr p15, 0, %1, c7, c6, 1 @ 1 invalidate D line\n\ | ||
59 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
60 | ldmia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
61 | subs r4, r4, #1 @ 1\n\ | ||
62 | stmia %1!, {r2, r3, ip, lr} @ 4\n\ | ||
63 | ldmneia %0!, {r2, r3, ip, lr} @ 4\n\ | ||
64 | bne 1b @ 1\n\ | ||
65 | ldmfd sp!, {r4, pc} @ 3" | ||
66 | : | ||
67 | : "r" (from), "r" (to), "I" (PAGE_SIZE / 64)); | ||
68 | } | ||
69 | |||
70 | void v4_mc_copy_user_page(void *kto, const void *kfrom, unsigned long vaddr) | ||
71 | { | ||
72 | spin_lock(&minicache_lock); | ||
73 | |||
74 | set_pte(TOP_PTE(0xffff8000), pfn_pte(__pa(kfrom) >> PAGE_SHIFT, minicache_pgprot)); | ||
75 | flush_tlb_kernel_page(0xffff8000); | ||
76 | |||
77 | mc_copy_user_page((void *)0xffff8000, kto); | ||
78 | |||
79 | spin_unlock(&minicache_lock); | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * ARMv4 optimised clear_user_page | ||
84 | */ | ||
85 | void __attribute__((naked)) | ||
86 | v4_mc_clear_user_page(void *kaddr, unsigned long vaddr) | ||
87 | { | ||
88 | asm volatile( | ||
89 | "str lr, [sp, #-4]!\n\ | ||
90 | mov r1, %0 @ 1\n\ | ||
91 | mov r2, #0 @ 1\n\ | ||
92 | mov r3, #0 @ 1\n\ | ||
93 | mov ip, #0 @ 1\n\ | ||
94 | mov lr, #0 @ 1\n\ | ||
95 | 1: mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ | ||
96 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
97 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
98 | mcr p15, 0, r0, c7, c6, 1 @ 1 invalidate D line\n\ | ||
99 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
100 | stmia r0!, {r2, r3, ip, lr} @ 4\n\ | ||
101 | subs r1, r1, #1 @ 1\n\ | ||
102 | bne 1b @ 1\n\ | ||
103 | ldr pc, [sp], #4" | ||
104 | : | ||
105 | : "I" (PAGE_SIZE / 64)); | ||
106 | } | ||
107 | |||
108 | struct cpu_user_fns v4_mc_user_fns __initdata = { | ||
109 | .cpu_clear_user_page = v4_mc_clear_user_page, | ||
110 | .cpu_copy_user_page = v4_mc_copy_user_page, | ||
111 | }; | ||
diff --git a/arch/arm/mm/copypage-v6.c b/arch/arm/mm/copypage-v6.c index 694ac8208858..a8c00236bd3d 100644 --- a/arch/arm/mm/copypage-v6.c +++ b/arch/arm/mm/copypage-v6.c | |||
@@ -26,8 +26,8 @@ | |||
26 | #define to_address (0xffffc000) | 26 | #define to_address (0xffffc000) |
27 | #define to_pgprot PAGE_KERNEL | 27 | #define to_pgprot PAGE_KERNEL |
28 | 28 | ||
29 | static pte_t *from_pte; | 29 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) |
30 | static pte_t *to_pte; | 30 | |
31 | static DEFINE_SPINLOCK(v6_lock); | 31 | static DEFINE_SPINLOCK(v6_lock); |
32 | 32 | ||
33 | #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) | 33 | #define DCACHE_COLOUR(vaddr) ((vaddr & (SHMLBA - 1)) >> PAGE_SHIFT) |
@@ -74,8 +74,8 @@ void v6_copy_user_page_aliasing(void *kto, const void *kfrom, unsigned long vadd | |||
74 | */ | 74 | */ |
75 | spin_lock(&v6_lock); | 75 | spin_lock(&v6_lock); |
76 | 76 | ||
77 | set_pte(from_pte + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); | 77 | set_pte(TOP_PTE(from_address) + offset, pfn_pte(__pa(kfrom) >> PAGE_SHIFT, from_pgprot)); |
78 | set_pte(to_pte + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); | 78 | set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kto) >> PAGE_SHIFT, to_pgprot)); |
79 | 79 | ||
80 | from = from_address + (offset << PAGE_SHIFT); | 80 | from = from_address + (offset << PAGE_SHIFT); |
81 | to = to_address + (offset << PAGE_SHIFT); | 81 | to = to_address + (offset << PAGE_SHIFT); |
@@ -114,7 +114,7 @@ void v6_clear_user_page_aliasing(void *kaddr, unsigned long vaddr) | |||
114 | */ | 114 | */ |
115 | spin_lock(&v6_lock); | 115 | spin_lock(&v6_lock); |
116 | 116 | ||
117 | set_pte(to_pte + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); | 117 | set_pte(TOP_PTE(to_address) + offset, pfn_pte(__pa(kaddr) >> PAGE_SHIFT, to_pgprot)); |
118 | flush_tlb_kernel_page(to); | 118 | flush_tlb_kernel_page(to); |
119 | clear_page((void *)to); | 119 | clear_page((void *)to); |
120 | 120 | ||
@@ -129,21 +129,6 @@ struct cpu_user_fns v6_user_fns __initdata = { | |||
129 | static int __init v6_userpage_init(void) | 129 | static int __init v6_userpage_init(void) |
130 | { | 130 | { |
131 | if (cache_is_vipt_aliasing()) { | 131 | if (cache_is_vipt_aliasing()) { |
132 | pgd_t *pgd; | ||
133 | pmd_t *pmd; | ||
134 | |||
135 | pgd = pgd_offset_k(from_address); | ||
136 | pmd = pmd_alloc(&init_mm, pgd, from_address); | ||
137 | if (!pmd) | ||
138 | BUG(); | ||
139 | from_pte = pte_alloc_kernel(&init_mm, pmd, from_address); | ||
140 | if (!from_pte) | ||
141 | BUG(); | ||
142 | |||
143 | to_pte = pte_alloc_kernel(&init_mm, pmd, to_address); | ||
144 | if (!to_pte) | ||
145 | BUG(); | ||
146 | |||
147 | cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; | 132 | cpu_user.cpu_clear_user_page = v6_clear_user_page_aliasing; |
148 | cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; | 133 | cpu_user.cpu_copy_user_page = v6_copy_user_page_aliasing; |
149 | } | 134 | } |
@@ -151,5 +136,4 @@ static int __init v6_userpage_init(void) | |||
151 | return 0; | 136 | return 0; |
152 | } | 137 | } |
153 | 138 | ||
154 | __initcall(v6_userpage_init); | 139 | core_initcall(v6_userpage_init); |
155 | |||
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index c6de48d89503..4085ed983e46 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -13,6 +13,29 @@ | |||
13 | 13 | ||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/system.h> | 15 | #include <asm/system.h> |
16 | #include <asm/tlbflush.h> | ||
17 | |||
18 | #ifdef CONFIG_CPU_CACHE_VIPT | ||
19 | #define ALIAS_FLUSH_START 0xffff4000 | ||
20 | |||
21 | #define TOP_PTE(x) pte_offset_kernel(top_pmd, x) | ||
22 | |||
23 | static void flush_pfn_alias(unsigned long pfn, unsigned long vaddr) | ||
24 | { | ||
25 | unsigned long to = ALIAS_FLUSH_START + (CACHE_COLOUR(vaddr) << PAGE_SHIFT); | ||
26 | |||
27 | set_pte(TOP_PTE(to), pfn_pte(pfn, PAGE_KERNEL)); | ||
28 | flush_tlb_kernel_page(to); | ||
29 | |||
30 | asm( "mcrr p15, 0, %1, %0, c14\n" | ||
31 | " mcrr p15, 0, %1, %0, c5\n" | ||
32 | : | ||
33 | : "r" (to), "r" (to + PAGE_SIZE - L1_CACHE_BYTES) | ||
34 | : "cc"); | ||
35 | } | ||
36 | #else | ||
37 | #define flush_pfn_alias(pfn,vaddr) do { } while (0) | ||
38 | #endif | ||
16 | 39 | ||
17 | static void __flush_dcache_page(struct address_space *mapping, struct page *page) | 40 | static void __flush_dcache_page(struct address_space *mapping, struct page *page) |
18 | { | 41 | { |
@@ -37,6 +60,18 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
37 | return; | 60 | return; |
38 | 61 | ||
39 | /* | 62 | /* |
63 | * This is a page cache page. If we have a VIPT cache, we | ||
64 | * only need to do one flush - which would be at the relevant | ||
65 | * userspace colour, which is congruent with page->index. | ||
66 | */ | ||
67 | if (cache_is_vipt()) { | ||
68 | if (cache_is_vipt_aliasing()) | ||
69 | flush_pfn_alias(page_to_pfn(page), | ||
70 | page->index << PAGE_CACHE_SHIFT); | ||
71 | return; | ||
72 | } | ||
73 | |||
74 | /* | ||
40 | * There are possible user space mappings of this page: | 75 | * There are possible user space mappings of this page: |
41 | * - VIVT cache: we need to also write back and invalidate all user | 76 | * - VIVT cache: we need to also write back and invalidate all user |
42 | * data in the current VM view associated with this page. | 77 | * data in the current VM view associated with this page. |
@@ -57,8 +92,6 @@ static void __flush_dcache_page(struct address_space *mapping, struct page *page | |||
57 | continue; | 92 | continue; |
58 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; | 93 | offset = (pgoff - mpnt->vm_pgoff) << PAGE_SHIFT; |
59 | flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); | 94 | flush_cache_page(mpnt, mpnt->vm_start + offset, page_to_pfn(page)); |
60 | if (cache_is_vipt()) | ||
61 | break; | ||
62 | } | 95 | } |
63 | flush_dcache_mmap_unlock(mapping); | 96 | flush_dcache_mmap_unlock(mapping); |
64 | } | 97 | } |
diff --git a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c index 585dfb8e20b9..2c2b93d77d43 100644 --- a/arch/arm/mm/mm-armv.c +++ b/arch/arm/mm/mm-armv.c | |||
@@ -37,6 +37,8 @@ pgprot_t pgprot_kernel; | |||
37 | 37 | ||
38 | EXPORT_SYMBOL(pgprot_kernel); | 38 | EXPORT_SYMBOL(pgprot_kernel); |
39 | 39 | ||
40 | pmd_t *top_pmd; | ||
41 | |||
40 | struct cachepolicy { | 42 | struct cachepolicy { |
41 | const char policy[16]; | 43 | const char policy[16]; |
42 | unsigned int cr_mask; | 44 | unsigned int cr_mask; |
@@ -142,6 +144,16 @@ __setup("noalign", noalign_setup); | |||
142 | 144 | ||
143 | #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) | 145 | #define FIRST_KERNEL_PGD_NR (FIRST_USER_PGD_NR + USER_PTRS_PER_PGD) |
144 | 146 | ||
147 | static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) | ||
148 | { | ||
149 | return pmd_offset(pgd, virt); | ||
150 | } | ||
151 | |||
152 | static inline pmd_t *pmd_off_k(unsigned long virt) | ||
153 | { | ||
154 | return pmd_off(pgd_offset_k(virt), virt); | ||
155 | } | ||
156 | |||
145 | /* | 157 | /* |
146 | * need to get a 16k page for level 1 | 158 | * need to get a 16k page for level 1 |
147 | */ | 159 | */ |
@@ -220,7 +232,7 @@ void free_pgd_slow(pgd_t *pgd) | |||
220 | return; | 232 | return; |
221 | 233 | ||
222 | /* pgd is always present and good */ | 234 | /* pgd is always present and good */ |
223 | pmd = (pmd_t *)pgd; | 235 | pmd = pmd_off(pgd, 0); |
224 | if (pmd_none(*pmd)) | 236 | if (pmd_none(*pmd)) |
225 | goto free; | 237 | goto free; |
226 | if (pmd_bad(*pmd)) { | 238 | if (pmd_bad(*pmd)) { |
@@ -246,9 +258,8 @@ free: | |||
246 | static inline void | 258 | static inline void |
247 | alloc_init_section(unsigned long virt, unsigned long phys, int prot) | 259 | alloc_init_section(unsigned long virt, unsigned long phys, int prot) |
248 | { | 260 | { |
249 | pmd_t *pmdp; | 261 | pmd_t *pmdp = pmd_off_k(virt); |
250 | 262 | ||
251 | pmdp = pmd_offset(pgd_offset_k(virt), virt); | ||
252 | if (virt & (1 << 20)) | 263 | if (virt & (1 << 20)) |
253 | pmdp++; | 264 | pmdp++; |
254 | 265 | ||
@@ -283,11 +294,9 @@ alloc_init_supersection(unsigned long virt, unsigned long phys, int prot) | |||
283 | static inline void | 294 | static inline void |
284 | alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) | 295 | alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pgprot_t prot) |
285 | { | 296 | { |
286 | pmd_t *pmdp; | 297 | pmd_t *pmdp = pmd_off_k(virt); |
287 | pte_t *ptep; | 298 | pte_t *ptep; |
288 | 299 | ||
289 | pmdp = pmd_offset(pgd_offset_k(virt), virt); | ||
290 | |||
291 | if (pmd_none(*pmdp)) { | 300 | if (pmd_none(*pmdp)) { |
292 | unsigned long pmdval; | 301 | unsigned long pmdval; |
293 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * | 302 | ptep = alloc_bootmem_low_pages(2 * PTRS_PER_PTE * |
@@ -310,7 +319,7 @@ alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, pg | |||
310 | */ | 319 | */ |
311 | static inline void clear_mapping(unsigned long virt) | 320 | static inline void clear_mapping(unsigned long virt) |
312 | { | 321 | { |
313 | pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); | 322 | pmd_clear(pmd_off_k(virt)); |
314 | } | 323 | } |
315 | 324 | ||
316 | struct mem_types { | 325 | struct mem_types { |
@@ -578,7 +587,7 @@ void setup_mm_for_reboot(char mode) | |||
578 | PMD_TYPE_SECT; | 587 | PMD_TYPE_SECT; |
579 | if (cpu_arch <= CPU_ARCH_ARMv5) | 588 | if (cpu_arch <= CPU_ARCH_ARMv5) |
580 | pmdval |= PMD_BIT4; | 589 | pmdval |= PMD_BIT4; |
581 | pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); | 590 | pmd = pmd_off(pgd, i << PGDIR_SHIFT); |
582 | pmd[0] = __pmd(pmdval); | 591 | pmd[0] = __pmd(pmdval); |
583 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); | 592 | pmd[1] = __pmd(pmdval + (1 << (PGDIR_SHIFT - 1))); |
584 | flush_pmd_entry(pmd); | 593 | flush_pmd_entry(pmd); |
@@ -675,6 +684,8 @@ void __init memtable_init(struct meminfo *mi) | |||
675 | 684 | ||
676 | flush_cache_all(); | 685 | flush_cache_all(); |
677 | flush_tlb_all(); | 686 | flush_tlb_all(); |
687 | |||
688 | top_pmd = pmd_off_k(0xffff0000); | ||
678 | } | 689 | } |
679 | 690 | ||
680 | /* | 691 | /* |
diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index fee589119606..e382f32d435e 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig | |||
@@ -183,7 +183,7 @@ config M386 | |||
183 | - "Winchip-C6" for original IDT Winchip. | 183 | - "Winchip-C6" for original IDT Winchip. |
184 | - "Winchip-2" for IDT Winchip 2. | 184 | - "Winchip-2" for IDT Winchip 2. |
185 | - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. | 185 | - "Winchip-2A" for IDT Winchips with 3dNow! capabilities. |
186 | - "MediaGX/Geode" for Cyrix MediaGX aka Geode. | 186 | - "GeodeGX1" for Geode GX1 (Cyrix MediaGX). |
187 | - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. | 187 | - "CyrixIII/VIA C3" for VIA Cyrix III or VIA C3. |
188 | - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). | 188 | - "VIA C3-2 for VIA C3-2 "Nehemiah" (model 9 and above). |
189 | 189 | ||
@@ -311,12 +311,10 @@ config MWINCHIP3D | |||
311 | stores for this CPU, which can increase performance of some | 311 | stores for this CPU, which can increase performance of some |
312 | operations. | 312 | operations. |
313 | 313 | ||
314 | config MGEODE | 314 | config MGEODEGX1 |
315 | bool "MediaGX/Geode" | 315 | bool "GeodeGX1" |
316 | help | 316 | help |
317 | Select this for a Cyrix MediaGX aka Geode chip. Linux and GCC | 317 | Select this for a Geode GX1 (Cyrix MediaGX) chip. |
318 | treat this chip as a 586TSC with some extended instructions | ||
319 | and alignment reqirements. | ||
320 | 318 | ||
321 | config MCYRIXIII | 319 | config MCYRIXIII |
322 | bool "CyrixIII/VIA-C3" | 320 | bool "CyrixIII/VIA-C3" |
@@ -368,7 +366,7 @@ config X86_L1_CACHE_SHIFT | |||
368 | int | 366 | int |
369 | default "7" if MPENTIUM4 || X86_GENERIC | 367 | default "7" if MPENTIUM4 || X86_GENERIC |
370 | default "4" if X86_ELAN || M486 || M386 | 368 | default "4" if X86_ELAN || M486 || M386 |
371 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODE | 369 | default "5" if MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCRUSOE || MEFFICEON || MCYRIXIII || MK6 || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || M586 || MVIAC3_2 || MGEODEGX1 |
372 | default "6" if MK7 || MK8 || MPENTIUMM | 370 | default "6" if MK7 || MK8 || MPENTIUMM |
373 | 371 | ||
374 | config RWSEM_GENERIC_SPINLOCK | 372 | config RWSEM_GENERIC_SPINLOCK |
@@ -387,7 +385,7 @@ config GENERIC_CALIBRATE_DELAY | |||
387 | 385 | ||
388 | config X86_PPRO_FENCE | 386 | config X86_PPRO_FENCE |
389 | bool | 387 | bool |
390 | depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODE | 388 | depends on M686 || M586MMX || M586TSC || M586 || M486 || M386 || MGEODEGX1 |
391 | default y | 389 | default y |
392 | 390 | ||
393 | config X86_F00F_BUG | 391 | config X86_F00F_BUG |
@@ -417,7 +415,7 @@ config X86_POPAD_OK | |||
417 | 415 | ||
418 | config X86_ALIGNMENT_16 | 416 | config X86_ALIGNMENT_16 |
419 | bool | 417 | bool |
420 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODE | 418 | depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1 |
421 | default y | 419 | default y |
422 | 420 | ||
423 | config X86_GOOD_APIC | 421 | config X86_GOOD_APIC |
@@ -442,7 +440,7 @@ config X86_USE_3DNOW | |||
442 | 440 | ||
443 | config X86_OOSTORE | 441 | config X86_OOSTORE |
444 | bool | 442 | bool |
445 | depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MGEODE) && MTRR | 443 | depends on (MWINCHIP3D || MWINCHIP2 || MWINCHIPC6) && MTRR |
446 | default y | 444 | default y |
447 | 445 | ||
448 | config HPET_TIMER | 446 | config HPET_TIMER |
@@ -578,7 +576,7 @@ config X86_VISWS_APIC | |||
578 | 576 | ||
579 | config X86_TSC | 577 | config X86_TSC |
580 | bool | 578 | bool |
581 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODE) && !X86_NUMAQ | 579 | depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ |
582 | default y | 580 | default y |
583 | 581 | ||
584 | config X86_MCE | 582 | config X86_MCE |
diff --git a/arch/i386/Makefile b/arch/i386/Makefile index 04783ceb050c..1c36ca332a96 100644 --- a/arch/i386/Makefile +++ b/arch/i386/Makefile | |||
@@ -14,7 +14,7 @@ | |||
14 | # 19990713 Artur Skawina <skawina@geocities.com> | 14 | # 19990713 Artur Skawina <skawina@geocities.com> |
15 | # Added '-march' and '-mpreferred-stack-boundary' support | 15 | # Added '-march' and '-mpreferred-stack-boundary' support |
16 | # | 16 | # |
17 | # Kianusch Sayah Karadji <kianusch@sk-tech.net> | 17 | # 20050320 Kianusch Sayah Karadji <kianusch@sk-tech.net> |
18 | # Added support for GEODE CPU | 18 | # Added support for GEODE CPU |
19 | 19 | ||
20 | LDFLAGS := -m elf_i386 | 20 | LDFLAGS := -m elf_i386 |
@@ -54,8 +54,8 @@ cflags-$(CONFIG_MVIAC3_2) += $(call cc-option,-march=c3-2,-march=i686) | |||
54 | # AMD Elan support | 54 | # AMD Elan support |
55 | cflags-$(CONFIG_X86_ELAN) += -march=i486 | 55 | cflags-$(CONFIG_X86_ELAN) += -march=i486 |
56 | 56 | ||
57 | # MediaGX aka Geode support | 57 | # Geode GX1 support |
58 | cflags-$(CONFIG_MGEODE) += $(call cc-option,-march=pentium-mmx,-march=i586) | 58 | cflags-$(CONFIG_MGEODEGX1) += $(call cc-option,-march=pentium-mmx,-march=i486) |
59 | 59 | ||
60 | # -mregparm=3 works ok on gcc-3.0 and later | 60 | # -mregparm=3 works ok on gcc-3.0 and later |
61 | # | 61 | # |
diff --git a/arch/i386/boot/bootsect.S b/arch/i386/boot/bootsect.S index ba9fe14db6a9..011b7a4993d4 100644 --- a/arch/i386/boot/bootsect.S +++ b/arch/i386/boot/bootsect.S | |||
@@ -83,7 +83,7 @@ bugger_off_msg: | |||
83 | .ascii "\n" | 83 | .ascii "\n" |
84 | .ascii "Remove disk and press any key to reboot . . .\r\n" | 84 | .ascii "Remove disk and press any key to reboot . . .\r\n" |
85 | .byte 0 | 85 | .byte 0 |
86 | 86 | ||
87 | 87 | ||
88 | # Kernel attributes; used by setup | 88 | # Kernel attributes; used by setup |
89 | 89 | ||
diff --git a/arch/i386/boot/video.S b/arch/i386/boot/video.S index 925d3f5a3824..0587477c99f2 100644 --- a/arch/i386/boot/video.S +++ b/arch/i386/boot/video.S | |||
@@ -1924,36 +1924,36 @@ skip10: movb %ah, %al | |||
1924 | ret | 1924 | ret |
1925 | 1925 | ||
1926 | store_edid: | 1926 | store_edid: |
1927 | pushw %es # just save all registers | 1927 | pushw %es # just save all registers |
1928 | pushw %ax | 1928 | pushw %ax |
1929 | pushw %bx | 1929 | pushw %bx |
1930 | pushw %cx | 1930 | pushw %cx |
1931 | pushw %dx | 1931 | pushw %dx |
1932 | pushw %di | 1932 | pushw %di |
1933 | 1933 | ||
1934 | pushw %fs | 1934 | pushw %fs |
1935 | popw %es | 1935 | popw %es |
1936 | 1936 | ||
1937 | movl $0x13131313, %eax # memset block with 0x13 | 1937 | movl $0x13131313, %eax # memset block with 0x13 |
1938 | movw $32, %cx | 1938 | movw $32, %cx |
1939 | movw $0x140, %di | 1939 | movw $0x140, %di |
1940 | cld | 1940 | cld |
1941 | rep | 1941 | rep |
1942 | stosl | 1942 | stosl |
1943 | 1943 | ||
1944 | movw $0x4f15, %ax # do VBE/DDC | 1944 | movw $0x4f15, %ax # do VBE/DDC |
1945 | movw $0x01, %bx | 1945 | movw $0x01, %bx |
1946 | movw $0x00, %cx | 1946 | movw $0x00, %cx |
1947 | movw $0x01, %dx | 1947 | movw $0x01, %dx |
1948 | movw $0x140, %di | 1948 | movw $0x140, %di |
1949 | int $0x10 | 1949 | int $0x10 |
1950 | 1950 | ||
1951 | popw %di # restore all registers | 1951 | popw %di # restore all registers |
1952 | popw %dx | 1952 | popw %dx |
1953 | popw %cx | 1953 | popw %cx |
1954 | popw %bx | 1954 | popw %bx |
1955 | popw %ax | 1955 | popw %ax |
1956 | popw %es | 1956 | popw %es |
1957 | ret | 1957 | ret |
1958 | 1958 | ||
1959 | # VIDEO_SELECT-only variables | 1959 | # VIDEO_SELECT-only variables |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 53eb5cfd5b63..848bb97af7ca 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -650,7 +650,7 @@ acpi_find_rsdp (void) | |||
650 | */ | 650 | */ |
651 | rsdp_phys = acpi_scan_rsdp (0, 0x400); | 651 | rsdp_phys = acpi_scan_rsdp (0, 0x400); |
652 | if (!rsdp_phys) | 652 | if (!rsdp_phys) |
653 | rsdp_phys = acpi_scan_rsdp (0xE0000, 0xFFFFF); | 653 | rsdp_phys = acpi_scan_rsdp (0xE0000, 0x20000); |
654 | 654 | ||
655 | return rsdp_phys; | 655 | return rsdp_phys; |
656 | } | 656 | } |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 16dbc4151be4..73aeaf5a9d4e 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -24,9 +24,6 @@ __asm__(".align 4\nvide: ret"); | |||
24 | 24 | ||
25 | static void __init init_amd(struct cpuinfo_x86 *c) | 25 | static void __init init_amd(struct cpuinfo_x86 *c) |
26 | { | 26 | { |
27 | #ifdef CONFIG_X86_SMP | ||
28 | int cpu = c == &boot_cpu_data ? 0 : c - cpu_data; | ||
29 | #endif | ||
30 | u32 l, h; | 27 | u32 l, h; |
31 | int mbytes = num_physpages >> (20-PAGE_SHIFT); | 28 | int mbytes = num_physpages >> (20-PAGE_SHIFT); |
32 | int r; | 29 | int r; |
@@ -198,14 +195,19 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
198 | c->x86_num_cores = 1; | 195 | c->x86_num_cores = 1; |
199 | } | 196 | } |
200 | 197 | ||
201 | #ifdef CONFIG_X86_SMP | 198 | #ifdef CONFIG_X86_HT |
202 | /* | 199 | /* |
203 | * On a AMD dual core setup the lower bits of the APIC id | 200 | * On a AMD dual core setup the lower bits of the APIC id |
204 | * distingush the cores. Assumes number of cores is a power | 201 | * distingush the cores. Assumes number of cores is a power |
205 | * of two. | 202 | * of two. |
206 | */ | 203 | */ |
207 | if (c->x86_num_cores > 1) { | 204 | if (c->x86_num_cores > 1) { |
208 | cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); | 205 | int cpu = smp_processor_id(); |
206 | unsigned bits = 0; | ||
207 | while ((1 << bits) < c->x86_num_cores) | ||
208 | bits++; | ||
209 | cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1); | ||
210 | phys_proc_id[cpu] >>= bits; | ||
209 | printk(KERN_INFO "CPU %d(%d) -> Core %d\n", | 211 | printk(KERN_INFO "CPU %d(%d) -> Core %d\n", |
210 | cpu, c->x86_num_cores, cpu_core_id[cpu]); | 212 | cpu, c->x86_num_cores, cpu_core_id[cpu]); |
211 | } | 213 | } |
diff --git a/arch/i386/kernel/cpu/common.c b/arch/i386/kernel/cpu/common.c index 6be0310e3cd3..d199e525680a 100644 --- a/arch/i386/kernel/cpu/common.c +++ b/arch/i386/kernel/cpu/common.c | |||
@@ -243,6 +243,10 @@ static void __init early_cpu_detect(void) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | early_intel_workaround(c); | 245 | early_intel_workaround(c); |
246 | |||
247 | #ifdef CONFIG_X86_HT | ||
248 | phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; | ||
249 | #endif | ||
246 | } | 250 | } |
247 | 251 | ||
248 | void __init generic_identify(struct cpuinfo_x86 * c) | 252 | void __init generic_identify(struct cpuinfo_x86 * c) |
diff --git a/arch/i386/kernel/cpu/mtrr/cyrix.c b/arch/i386/kernel/cpu/mtrr/cyrix.c index 933b0dd62f48..9027a987006b 100644 --- a/arch/i386/kernel/cpu/mtrr/cyrix.c +++ b/arch/i386/kernel/cpu/mtrr/cyrix.c | |||
@@ -218,12 +218,12 @@ typedef struct { | |||
218 | mtrr_type type; | 218 | mtrr_type type; |
219 | } arr_state_t; | 219 | } arr_state_t; |
220 | 220 | ||
221 | static arr_state_t arr_state[8] __initdata = { | 221 | static arr_state_t arr_state[8] __devinitdata = { |
222 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, | 222 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, |
223 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} | 223 | {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL}, {0UL, 0UL, 0UL} |
224 | }; | 224 | }; |
225 | 225 | ||
226 | static unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 }; | 226 | static unsigned char ccr_state[7] __devinitdata = { 0, 0, 0, 0, 0, 0, 0 }; |
227 | 227 | ||
228 | static void cyrix_set_all(void) | 228 | static void cyrix_set_all(void) |
229 | { | 229 | { |
diff --git a/arch/i386/kernel/i386_ksyms.c b/arch/i386/kernel/i386_ksyms.c index 14ec354bec92..903190a4b3ff 100644 --- a/arch/i386/kernel/i386_ksyms.c +++ b/arch/i386/kernel/i386_ksyms.c | |||
@@ -169,10 +169,6 @@ EXPORT_SYMBOL(rtc_lock); | |||
169 | EXPORT_SYMBOL_GPL(set_nmi_callback); | 169 | EXPORT_SYMBOL_GPL(set_nmi_callback); |
170 | EXPORT_SYMBOL_GPL(unset_nmi_callback); | 170 | EXPORT_SYMBOL_GPL(unset_nmi_callback); |
171 | 171 | ||
172 | #undef memcmp | ||
173 | extern int memcmp(const void *,const void *,__kernel_size_t); | ||
174 | EXPORT_SYMBOL(memcmp); | ||
175 | |||
176 | EXPORT_SYMBOL(register_die_notifier); | 172 | EXPORT_SYMBOL(register_die_notifier); |
177 | #ifdef CONFIG_HAVE_DEC_LOCK | 173 | #ifdef CONFIG_HAVE_DEC_LOCK |
178 | EXPORT_SYMBOL(_atomic_dec_and_lock); | 174 | EXPORT_SYMBOL(_atomic_dec_and_lock); |
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index 671681659243..59ff9b455069 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -217,6 +217,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
217 | *tos &= ~(TF_MASK | IF_MASK); | 217 | *tos &= ~(TF_MASK | IF_MASK); |
218 | *tos |= kprobe_old_eflags; | 218 | *tos |= kprobe_old_eflags; |
219 | break; | 219 | break; |
220 | case 0xc3: /* ret/lret */ | ||
221 | case 0xcb: | ||
222 | case 0xc2: | ||
223 | case 0xca: | ||
224 | regs->eflags &= ~TF_MASK; | ||
225 | /* eip is already adjusted, no more changes required*/ | ||
226 | return; | ||
220 | case 0xe8: /* call relative - Fix return addr */ | 227 | case 0xe8: /* call relative - Fix return addr */ |
221 | *tos = orig_eip + (*tos - copy_eip); | 228 | *tos = orig_eip + (*tos - copy_eip); |
222 | break; | 229 | break; |
diff --git a/arch/i386/kernel/process.c b/arch/i386/kernel/process.c index 85bd56d44314..96e3ea6b17c7 100644 --- a/arch/i386/kernel/process.c +++ b/arch/i386/kernel/process.c | |||
@@ -400,11 +400,6 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, | |||
400 | int err; | 400 | int err; |
401 | 401 | ||
402 | childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; | 402 | childregs = ((struct pt_regs *) (THREAD_SIZE + (unsigned long) p->thread_info)) - 1; |
403 | *childregs = *regs; | ||
404 | childregs->eax = 0; | ||
405 | childregs->esp = esp; | ||
406 | |||
407 | p->thread.esp = (unsigned long) childregs; | ||
408 | /* | 403 | /* |
409 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. | 404 | * The below -8 is to reserve 8 bytes on top of the ring0 stack. |
410 | * This is necessary to guarantee that the entire "struct pt_regs" | 405 | * This is necessary to guarantee that the entire "struct pt_regs" |
@@ -415,7 +410,13 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long esp, | |||
415 | * "struct pt_regs" is possible, but they may contain the | 410 | * "struct pt_regs" is possible, but they may contain the |
416 | * completely wrong values. | 411 | * completely wrong values. |
417 | */ | 412 | */ |
418 | p->thread.esp0 = (unsigned long) (childregs+1) - 8; | 413 | childregs = (struct pt_regs *) ((unsigned long) childregs - 8); |
414 | *childregs = *regs; | ||
415 | childregs->eax = 0; | ||
416 | childregs->esp = esp; | ||
417 | |||
418 | p->thread.esp = (unsigned long) childregs; | ||
419 | p->thread.esp0 = (unsigned long) (childregs+1); | ||
419 | 420 | ||
420 | p->thread.eip = (unsigned long) ret_from_fork; | 421 | p->thread.eip = (unsigned long) ret_from_fork; |
421 | 422 | ||
diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index cbea7ac582e5..35bfe138cb1a 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c | |||
@@ -888,6 +888,7 @@ void *xquad_portio; | |||
888 | 888 | ||
889 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 889 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; |
890 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | 890 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; |
891 | EXPORT_SYMBOL(cpu_core_map); | ||
891 | 892 | ||
892 | static void __init smp_boot_cpus(unsigned int max_cpus) | 893 | static void __init smp_boot_cpus(unsigned int max_cpus) |
893 | { | 894 | { |
diff --git a/arch/i386/mm/ioremap.c b/arch/i386/mm/ioremap.c index db06f7399913..ab542792b27b 100644 --- a/arch/i386/mm/ioremap.c +++ b/arch/i386/mm/ioremap.c | |||
@@ -238,19 +238,21 @@ void iounmap(volatile void __iomem *addr) | |||
238 | addr < phys_to_virt(ISA_END_ADDRESS)) | 238 | addr < phys_to_virt(ISA_END_ADDRESS)) |
239 | return; | 239 | return; |
240 | 240 | ||
241 | p = remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | 241 | write_lock(&vmlist_lock); |
242 | p = __remove_vm_area((void *) (PAGE_MASK & (unsigned long __force) addr)); | ||
242 | if (!p) { | 243 | if (!p) { |
243 | printk("__iounmap: bad address %p\n", addr); | 244 | printk("iounmap: bad address %p\n", addr); |
244 | return; | 245 | goto out_unlock; |
245 | } | 246 | } |
246 | 247 | ||
247 | if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { | 248 | if ((p->flags >> 20) && p->phys_addr < virt_to_phys(high_memory) - 1) { |
248 | /* p->size includes the guard page, but cpa doesn't like that */ | ||
249 | change_page_attr(virt_to_page(__va(p->phys_addr)), | 249 | change_page_attr(virt_to_page(__va(p->phys_addr)), |
250 | p->size >> PAGE_SHIFT, | 250 | p->size >> PAGE_SHIFT, |
251 | PAGE_KERNEL); | 251 | PAGE_KERNEL); |
252 | global_flush_tlb(); | 252 | global_flush_tlb(); |
253 | } | 253 | } |
254 | out_unlock: | ||
255 | write_unlock(&vmlist_lock); | ||
254 | kfree(p); | 256 | kfree(p); |
255 | } | 257 | } |
256 | 258 | ||
diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index be52c5ac4e05..8e8e895e1b5a 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c | |||
@@ -253,7 +253,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci | |||
253 | #define MAX_PCIEROOT 6 | 253 | #define MAX_PCIEROOT 6 |
254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; | 254 | static int quirk_aspm_offset[MAX_PCIEROOT << 3]; |
255 | 255 | ||
256 | #define GET_INDEX(a, b) (((a - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + b) | 256 | #define GET_INDEX(a, b) ((((a) - PCI_DEVICE_ID_INTEL_MCH_PA) << 3) + ((b) & 7)) |
257 | 257 | ||
258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) | 258 | static int quirk_pcie_aspm_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *value) |
259 | { | 259 | { |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index ce13ad689d19..3ad2c4af099c 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -46,6 +46,10 @@ config GENERIC_IOMAP | |||
46 | bool | 46 | bool |
47 | default y | 47 | default y |
48 | 48 | ||
49 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
50 | bool | ||
51 | default y | ||
52 | |||
49 | choice | 53 | choice |
50 | prompt "System type" | 54 | prompt "System type" |
51 | default IA64_GENERIC | 55 | default IA64_GENERIC |
diff --git a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c index 9845dabe2613..164b211f4174 100644 --- a/arch/ia64/ia32/ia32_ioctl.c +++ b/arch/ia64/ia32/ia32_ioctl.c | |||
@@ -13,7 +13,6 @@ | |||
13 | 13 | ||
14 | #define INCLUDES | 14 | #define INCLUDES |
15 | #include "compat_ioctl.c" | 15 | #include "compat_ioctl.c" |
16 | #include <asm/ioctl32.h> | ||
17 | 16 | ||
18 | #define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 17 | #define IOCTL_NR(a) ((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
19 | 18 | ||
diff --git a/arch/mips/vr41xx/common/pmu.c b/arch/mips/vr41xx/common/pmu.c index c5f1043de938..53166f3598b2 100644 --- a/arch/mips/vr41xx/common/pmu.c +++ b/arch/mips/vr41xx/common/pmu.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * pmu.c, Power Management Unit routines for NEC VR4100 series. | 2 | * pmu.c, Power Management Unit routines for NEC VR4100 series. |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> | 4 | * Copyright (C) 2003-2005 Yoichi Yuasa <yuasa@hh.iij4u.or.jp> |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -17,7 +17,9 @@ | |||
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ | 19 | */ |
20 | #include <linux/errno.h> | ||
20 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/ioport.h> | ||
21 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
22 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
23 | #include <linux/types.h> | 25 | #include <linux/types.h> |
@@ -27,20 +29,31 @@ | |||
27 | #include <asm/reboot.h> | 29 | #include <asm/reboot.h> |
28 | #include <asm/system.h> | 30 | #include <asm/system.h> |
29 | 31 | ||
30 | #define PMUCNT2REG KSEG1ADDR(0x0f0000c6) | 32 | #define PMU_TYPE1_BASE 0x0b0000a0UL |
33 | #define PMU_TYPE1_SIZE 0x0eUL | ||
34 | |||
35 | #define PMU_TYPE2_BASE 0x0f0000c0UL | ||
36 | #define PMU_TYPE2_SIZE 0x10UL | ||
37 | |||
38 | #define PMUCNT2REG 0x06 | ||
31 | #define SOFTRST 0x0010 | 39 | #define SOFTRST 0x0010 |
32 | 40 | ||
41 | static void __iomem *pmu_base; | ||
42 | |||
43 | #define pmu_read(offset) readw(pmu_base + (offset)) | ||
44 | #define pmu_write(offset, value) writew((value), pmu_base + (offset)) | ||
45 | |||
33 | static inline void software_reset(void) | 46 | static inline void software_reset(void) |
34 | { | 47 | { |
35 | uint16_t val; | 48 | uint16_t pmucnt2; |
36 | 49 | ||
37 | switch (current_cpu_data.cputype) { | 50 | switch (current_cpu_data.cputype) { |
38 | case CPU_VR4122: | 51 | case CPU_VR4122: |
39 | case CPU_VR4131: | 52 | case CPU_VR4131: |
40 | case CPU_VR4133: | 53 | case CPU_VR4133: |
41 | val = readw(PMUCNT2REG); | 54 | pmucnt2 = pmu_read(PMUCNT2REG); |
42 | val |= SOFTRST; | 55 | pmucnt2 |= SOFTRST; |
43 | writew(val, PMUCNT2REG); | 56 | pmu_write(PMUCNT2REG, pmucnt2); |
44 | break; | 57 | break; |
45 | default: | 58 | default: |
46 | break; | 59 | break; |
@@ -71,6 +84,34 @@ static void vr41xx_power_off(void) | |||
71 | 84 | ||
72 | static int __init vr41xx_pmu_init(void) | 85 | static int __init vr41xx_pmu_init(void) |
73 | { | 86 | { |
87 | unsigned long start, size; | ||
88 | |||
89 | switch (current_cpu_data.cputype) { | ||
90 | case CPU_VR4111: | ||
91 | case CPU_VR4121: | ||
92 | start = PMU_TYPE1_BASE; | ||
93 | size = PMU_TYPE1_SIZE; | ||
94 | break; | ||
95 | case CPU_VR4122: | ||
96 | case CPU_VR4131: | ||
97 | case CPU_VR4133: | ||
98 | start = PMU_TYPE2_BASE; | ||
99 | size = PMU_TYPE2_SIZE; | ||
100 | break; | ||
101 | default: | ||
102 | printk("Unexpected CPU of NEC VR4100 series\n"); | ||
103 | return -ENODEV; | ||
104 | } | ||
105 | |||
106 | if (request_mem_region(start, size, "PMU") == NULL) | ||
107 | return -EBUSY; | ||
108 | |||
109 | pmu_base = ioremap(start, size); | ||
110 | if (pmu_base == NULL) { | ||
111 | release_mem_region(start, size); | ||
112 | return -EBUSY; | ||
113 | } | ||
114 | |||
74 | _machine_restart = vr41xx_restart; | 115 | _machine_restart = vr41xx_restart; |
75 | _machine_halt = vr41xx_halt; | 116 | _machine_halt = vr41xx_halt; |
76 | _machine_power_off = vr41xx_power_off; | 117 | _machine_power_off = vr41xx_power_off; |
@@ -78,4 +119,4 @@ static int __init vr41xx_pmu_init(void) | |||
78 | return 0; | 119 | return 0; |
79 | } | 120 | } |
80 | 121 | ||
81 | early_initcall(vr41xx_pmu_init); | 122 | core_initcall(vr41xx_pmu_init); |
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index ff04dcd30200..600f23d7fd33 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -43,6 +43,10 @@ config GENERIC_NVRAM | |||
43 | bool | 43 | bool |
44 | default y | 44 | default y |
45 | 45 | ||
46 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
47 | bool | ||
48 | default y | ||
49 | |||
46 | source "init/Kconfig" | 50 | source "init/Kconfig" |
47 | 51 | ||
48 | menu "Processor" | 52 | menu "Processor" |
@@ -73,9 +77,11 @@ config 44x | |||
73 | bool "44x" | 77 | bool "44x" |
74 | 78 | ||
75 | config POWER3 | 79 | config POWER3 |
80 | select PPC_FPU | ||
76 | bool "POWER3" | 81 | bool "POWER3" |
77 | 82 | ||
78 | config POWER4 | 83 | config POWER4 |
84 | select PPC_FPU | ||
79 | bool "POWER4 and 970 (G5)" | 85 | bool "POWER4 and 970 (G5)" |
80 | 86 | ||
81 | config 8xx | 87 | config 8xx |
diff --git a/arch/ppc/kernel/head_44x.S b/arch/ppc/kernel/head_44x.S index 9b6a8e513657..6c7ae6052464 100644 --- a/arch/ppc/kernel/head_44x.S +++ b/arch/ppc/kernel/head_44x.S | |||
@@ -330,8 +330,9 @@ interrupt_base: | |||
330 | /* If we are faulting a kernel address, we have to use the | 330 | /* If we are faulting a kernel address, we have to use the |
331 | * kernel page tables. | 331 | * kernel page tables. |
332 | */ | 332 | */ |
333 | andis. r11, r10, 0x8000 | 333 | lis r11, TASK_SIZE@h |
334 | beq 3f | 334 | cmplw r10, r11 |
335 | blt+ 3f | ||
335 | lis r11, swapper_pg_dir@h | 336 | lis r11, swapper_pg_dir@h |
336 | ori r11, r11, swapper_pg_dir@l | 337 | ori r11, r11, swapper_pg_dir@l |
337 | 338 | ||
@@ -464,8 +465,9 @@ interrupt_base: | |||
464 | /* If we are faulting a kernel address, we have to use the | 465 | /* If we are faulting a kernel address, we have to use the |
465 | * kernel page tables. | 466 | * kernel page tables. |
466 | */ | 467 | */ |
467 | andis. r11, r10, 0x8000 | 468 | lis r11, TASK_SIZE@h |
468 | beq 3f | 469 | cmplw r10, r11 |
470 | blt+ 3f | ||
469 | lis r11, swapper_pg_dir@h | 471 | lis r11, swapper_pg_dir@h |
470 | ori r11, r11, swapper_pg_dir@l | 472 | ori r11, r11, swapper_pg_dir@l |
471 | 473 | ||
@@ -533,8 +535,9 @@ interrupt_base: | |||
533 | /* If we are faulting a kernel address, we have to use the | 535 | /* If we are faulting a kernel address, we have to use the |
534 | * kernel page tables. | 536 | * kernel page tables. |
535 | */ | 537 | */ |
536 | andis. r11, r10, 0x8000 | 538 | lis r11, TASK_SIZE@h |
537 | beq 3f | 539 | cmplw r10, r11 |
540 | blt+ 3f | ||
538 | lis r11, swapper_pg_dir@h | 541 | lis r11, swapper_pg_dir@h |
539 | ori r11, r11, swapper_pg_dir@l | 542 | ori r11, r11, swapper_pg_dir@l |
540 | 543 | ||
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index e97ce635b99e..5c20266e3b1f 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c | |||
@@ -221,27 +221,26 @@ int show_cpuinfo(struct seq_file *m, void *v) | |||
221 | return err; | 221 | return err; |
222 | } | 222 | } |
223 | 223 | ||
224 | switch (PVR_VER(pvr)) { | 224 | /* If we are a Freescale core do a simple check so |
225 | case 0x0020: /* 403 family */ | 225 | * we dont have to keep adding cases in the future */ |
226 | maj = PVR_MAJ(pvr) + 1; | 226 | if ((PVR_VER(pvr) & 0x8000) == 0x8000) { |
227 | min = PVR_MIN(pvr); | ||
228 | break; | ||
229 | case 0x1008: /* 740P/750P ?? */ | ||
230 | maj = ((pvr >> 8) & 0xFF) - 1; | ||
231 | min = pvr & 0xFF; | ||
232 | break; | ||
233 | case 0x8083: /* e300 */ | ||
234 | maj = PVR_MAJ(pvr); | ||
235 | min = PVR_MIN(pvr); | ||
236 | break; | ||
237 | case 0x8020: /* e500 */ | ||
238 | maj = PVR_MAJ(pvr); | 227 | maj = PVR_MAJ(pvr); |
239 | min = PVR_MIN(pvr); | 228 | min = PVR_MIN(pvr); |
240 | break; | 229 | } else { |
241 | default: | 230 | switch (PVR_VER(pvr)) { |
242 | maj = (pvr >> 8) & 0xFF; | 231 | case 0x0020: /* 403 family */ |
243 | min = pvr & 0xFF; | 232 | maj = PVR_MAJ(pvr) + 1; |
244 | break; | 233 | min = PVR_MIN(pvr); |
234 | break; | ||
235 | case 0x1008: /* 740P/750P ?? */ | ||
236 | maj = ((pvr >> 8) & 0xFF) - 1; | ||
237 | min = pvr & 0xFF; | ||
238 | break; | ||
239 | default: | ||
240 | maj = (pvr >> 8) & 0xFF; | ||
241 | min = pvr & 0xFF; | ||
242 | break; | ||
243 | } | ||
245 | } | 244 | } |
246 | 245 | ||
247 | seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", | 246 | seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", |
@@ -500,7 +499,7 @@ static int __init set_preferred_console(void) | |||
500 | { | 499 | { |
501 | struct device_node *prom_stdout; | 500 | struct device_node *prom_stdout; |
502 | char *name; | 501 | char *name; |
503 | int offset; | 502 | int offset = 0; |
504 | 503 | ||
505 | if (of_stdout_device == NULL) | 504 | if (of_stdout_device == NULL) |
506 | return -ENODEV; | 505 | return -ENODEV; |
@@ -754,6 +753,8 @@ void __init setup_arch(char **cmdline_p) | |||
754 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | 753 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); |
755 | *cmdline_p = cmd_line; | 754 | *cmdline_p = cmd_line; |
756 | 755 | ||
756 | parse_early_param(); | ||
757 | |||
757 | /* set up the bootmem stuff with available memory */ | 758 | /* set up the bootmem stuff with available memory */ |
758 | do_init_bootmem(); | 759 | do_init_bootmem(); |
759 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); | 760 | if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); |
diff --git a/arch/ppc/kernel/vmlinux.lds.S b/arch/ppc/kernel/vmlinux.lds.S index 0c0e714b84de..9353584fb710 100644 --- a/arch/ppc/kernel/vmlinux.lds.S +++ b/arch/ppc/kernel/vmlinux.lds.S | |||
@@ -145,6 +145,7 @@ SECTIONS | |||
145 | __init_end = .; | 145 | __init_end = .; |
146 | 146 | ||
147 | . = ALIGN(4096); | 147 | . = ALIGN(4096); |
148 | _sextratext = .; | ||
148 | __pmac_begin = .; | 149 | __pmac_begin = .; |
149 | .pmac.text : { *(.pmac.text) } | 150 | .pmac.text : { *(.pmac.text) } |
150 | .pmac.data : { *(.pmac.data) } | 151 | .pmac.data : { *(.pmac.data) } |
@@ -171,6 +172,7 @@ SECTIONS | |||
171 | .openfirmware.data : { *(.openfirmware.data) } | 172 | .openfirmware.data : { *(.openfirmware.data) } |
172 | . = ALIGN(4096); | 173 | . = ALIGN(4096); |
173 | __openfirmware_end = .; | 174 | __openfirmware_end = .; |
175 | _eextratext = .; | ||
174 | 176 | ||
175 | __bss_start = .; | 177 | __bss_start = .; |
176 | .bss : | 178 | .bss : |
diff --git a/arch/ppc/lib/string.S b/arch/ppc/lib/string.S index 8d08a2eb225e..36c9b97fd92a 100644 --- a/arch/ppc/lib/string.S +++ b/arch/ppc/lib/string.S | |||
@@ -446,6 +446,7 @@ _GLOBAL(__copy_tofrom_user) | |||
446 | #ifdef CONFIG_8xx | 446 | #ifdef CONFIG_8xx |
447 | /* Don't use prefetch on 8xx */ | 447 | /* Don't use prefetch on 8xx */ |
448 | mtctr r0 | 448 | mtctr r0 |
449 | li r0,0 | ||
449 | 53: COPY_16_BYTES_WITHEX(0) | 450 | 53: COPY_16_BYTES_WITHEX(0) |
450 | bdnz 53b | 451 | bdnz 53b |
451 | 452 | ||
@@ -564,7 +565,9 @@ _GLOBAL(__copy_tofrom_user) | |||
564 | /* or write fault in cacheline loop */ | 565 | /* or write fault in cacheline loop */ |
565 | 105: li r9,1 | 566 | 105: li r9,1 |
566 | 92: li r3,LG_CACHELINE_BYTES | 567 | 92: li r3,LG_CACHELINE_BYTES |
567 | b 99f | 568 | mfctr r8 |
569 | add r0,r0,r8 | ||
570 | b 106f | ||
568 | /* read fault in final word loop */ | 571 | /* read fault in final word loop */ |
569 | 108: li r9,0 | 572 | 108: li r9,0 |
570 | b 93f | 573 | b 93f |
@@ -585,7 +588,7 @@ _GLOBAL(__copy_tofrom_user) | |||
585 | * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. | 588 | * r5 + (ctr << r3), and r9 is 0 for read or 1 for write. |
586 | */ | 589 | */ |
587 | 99: mfctr r0 | 590 | 99: mfctr r0 |
588 | slw r3,r0,r3 | 591 | 106: slw r3,r0,r3 |
589 | add. r3,r3,r5 | 592 | add. r3,r3,r5 |
590 | beq 120f /* shouldn't happen */ | 593 | beq 120f /* shouldn't happen */ |
591 | cmpwi 0,r9,0 | 594 | cmpwi 0,r9,0 |
diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index be02a7fec2b7..363c157e3617 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c | |||
@@ -179,6 +179,7 @@ void free_initmem(void) | |||
179 | if (!have_of) | 179 | if (!have_of) |
180 | FREESEC(openfirmware); | 180 | FREESEC(openfirmware); |
181 | printk("\n"); | 181 | printk("\n"); |
182 | ppc_md.progress = NULL; | ||
182 | #undef FREESEC | 183 | #undef FREESEC |
183 | } | 184 | } |
184 | 185 | ||
diff --git a/arch/ppc/syslib/mpc83xx_devices.c b/arch/ppc/syslib/mpc83xx_devices.c index 5c1a919eaabf..75c8e9834ae7 100644 --- a/arch/ppc/syslib/mpc83xx_devices.c +++ b/arch/ppc/syslib/mpc83xx_devices.c | |||
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
61 | .iotype = UPIO_MEM, | 61 | .iotype = UPIO_MEM, |
62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, | 62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST, |
63 | }, | 63 | }, |
64 | { }, | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct platform_device ppc_sys_platform_devices[] = { | 67 | struct platform_device ppc_sys_platform_devices[] = { |
diff --git a/arch/ppc/syslib/mpc85xx_devices.c b/arch/ppc/syslib/mpc85xx_devices.c index a231795ee26f..1e658ef57e75 100644 --- a/arch/ppc/syslib/mpc85xx_devices.c +++ b/arch/ppc/syslib/mpc85xx_devices.c | |||
@@ -61,6 +61,7 @@ static struct plat_serial8250_port serial_platform_data[] = { | |||
61 | .iotype = UPIO_MEM, | 61 | .iotype = UPIO_MEM, |
62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, | 62 | .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ, |
63 | }, | 63 | }, |
64 | { }, | ||
64 | }; | 65 | }; |
65 | 66 | ||
66 | struct platform_device ppc_sys_platform_devices[] = { | 67 | struct platform_device ppc_sys_platform_devices[] = { |
diff --git a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c index 7619e16fccae..9d4ed68b5804 100644 --- a/arch/ppc/syslib/open_pic.c +++ b/arch/ppc/syslib/open_pic.c | |||
@@ -557,12 +557,10 @@ static void __init openpic_initipi(u_int ipi, u_int pri, u_int vec) | |||
557 | */ | 557 | */ |
558 | void openpic_cause_IPI(u_int ipi, cpumask_t cpumask) | 558 | void openpic_cause_IPI(u_int ipi, cpumask_t cpumask) |
559 | { | 559 | { |
560 | cpumask_t phys; | ||
561 | DECL_THIS_CPU; | 560 | DECL_THIS_CPU; |
562 | 561 | ||
563 | CHECK_THIS_CPU; | 562 | CHECK_THIS_CPU; |
564 | check_arg_ipi(ipi); | 563 | check_arg_ipi(ipi); |
565 | phys = physmask(cpumask); | ||
566 | openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), | 564 | openpic_write(&OpenPIC->THIS_CPU.IPI_Dispatch(ipi), |
567 | cpus_addr(physmask(cpumask))[0]); | 565 | cpus_addr(physmask(cpumask))[0]); |
568 | } | 566 | } |
diff --git a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig index f5508abf1188..5cb343883e4d 100644 --- a/arch/ppc64/Kconfig +++ b/arch/ppc64/Kconfig | |||
@@ -40,6 +40,10 @@ config COMPAT | |||
40 | bool | 40 | bool |
41 | default y | 41 | default y |
42 | 42 | ||
43 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
44 | bool | ||
45 | default y | ||
46 | |||
43 | # We optimistically allocate largepages from the VM, so make the limit | 47 | # We optimistically allocate largepages from the VM, so make the limit |
44 | # large enough (16MB). This badly named config option is actually | 48 | # large enough (16MB). This badly named config option is actually |
45 | # max order + 1 | 49 | # max order + 1 |
@@ -258,6 +262,7 @@ config PPC_RTAS | |||
258 | config RTAS_PROC | 262 | config RTAS_PROC |
259 | bool "Proc interface to RTAS" | 263 | bool "Proc interface to RTAS" |
260 | depends on PPC_RTAS | 264 | depends on PPC_RTAS |
265 | default y | ||
261 | 266 | ||
262 | config RTAS_FLASH | 267 | config RTAS_FLASH |
263 | tristate "Firmware flash interface" | 268 | tristate "Firmware flash interface" |
diff --git a/arch/ppc64/Kconfig.debug b/arch/ppc64/Kconfig.debug index e341a129da80..46b1ce58da3b 100644 --- a/arch/ppc64/Kconfig.debug +++ b/arch/ppc64/Kconfig.debug | |||
@@ -5,6 +5,9 @@ source "lib/Kconfig.debug" | |||
5 | config DEBUG_STACKOVERFLOW | 5 | config DEBUG_STACKOVERFLOW |
6 | bool "Check for stack overflows" | 6 | bool "Check for stack overflows" |
7 | depends on DEBUG_KERNEL | 7 | depends on DEBUG_KERNEL |
8 | help | ||
9 | This option will cause messages to be printed if free stack space | ||
10 | drops below a certain limit. | ||
8 | 11 | ||
9 | config KPROBES | 12 | config KPROBES |
10 | bool "Kprobes" | 13 | bool "Kprobes" |
diff --git a/arch/ppc64/boot/main.c b/arch/ppc64/boot/main.c index b0fa86ad8b1b..da12ea2ca464 100644 --- a/arch/ppc64/boot/main.c +++ b/arch/ppc64/boot/main.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
15 | #include <asm/processor.h> | 15 | #include <asm/processor.h> |
16 | #include <asm/page.h> | 16 | #include <asm/page.h> |
17 | #include <asm/bootinfo.h> | ||
18 | 17 | ||
19 | extern void *finddevice(const char *); | 18 | extern void *finddevice(const char *); |
20 | extern int getprop(void *, const char *, void *, int); | 19 | extern int getprop(void *, const char *, void *, int); |
diff --git a/arch/ppc64/boot/start.c b/arch/ppc64/boot/start.c deleted file mode 100644 index ea247e79b55e..000000000000 --- a/arch/ppc64/boot/start.c +++ /dev/null | |||
@@ -1,654 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) Paul Mackerras 1997. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version | ||
7 | * 2 of the License, or (at your option) any later version. | ||
8 | */ | ||
9 | #include <stdarg.h> | ||
10 | #include <linux/types.h> | ||
11 | #include <linux/string.h> | ||
12 | #include <linux/ctype.h> | ||
13 | |||
14 | #include <asm/div64.h> | ||
15 | |||
16 | int (*prom)(void *); | ||
17 | |||
18 | void *chosen_handle; | ||
19 | void *stdin; | ||
20 | void *stdout; | ||
21 | void *stderr; | ||
22 | |||
23 | void exit(void); | ||
24 | void *finddevice(const char *name); | ||
25 | int getprop(void *phandle, const char *name, void *buf, int buflen); | ||
26 | void chrpboot(int a1, int a2, void *prom); /* in main.c */ | ||
27 | |||
28 | void printk(char *fmt, ...); | ||
29 | |||
30 | void | ||
31 | start(int a1, int a2, void *promptr) | ||
32 | { | ||
33 | prom = (int (*)(void *)) promptr; | ||
34 | chosen_handle = finddevice("/chosen"); | ||
35 | if (chosen_handle == (void *) -1) | ||
36 | exit(); | ||
37 | if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4) | ||
38 | exit(); | ||
39 | stderr = stdout; | ||
40 | if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4) | ||
41 | exit(); | ||
42 | |||
43 | chrpboot(a1, a2, promptr); | ||
44 | for (;;) | ||
45 | exit(); | ||
46 | } | ||
47 | |||
48 | int | ||
49 | write(void *handle, void *ptr, int nb) | ||
50 | { | ||
51 | struct prom_args { | ||
52 | char *service; | ||
53 | int nargs; | ||
54 | int nret; | ||
55 | void *ihandle; | ||
56 | void *addr; | ||
57 | int len; | ||
58 | int actual; | ||
59 | } args; | ||
60 | |||
61 | args.service = "write"; | ||
62 | args.nargs = 3; | ||
63 | args.nret = 1; | ||
64 | args.ihandle = handle; | ||
65 | args.addr = ptr; | ||
66 | args.len = nb; | ||
67 | args.actual = -1; | ||
68 | (*prom)(&args); | ||
69 | return args.actual; | ||
70 | } | ||
71 | |||
72 | int | ||
73 | read(void *handle, void *ptr, int nb) | ||
74 | { | ||
75 | struct prom_args { | ||
76 | char *service; | ||
77 | int nargs; | ||
78 | int nret; | ||
79 | void *ihandle; | ||
80 | void *addr; | ||
81 | int len; | ||
82 | int actual; | ||
83 | } args; | ||
84 | |||
85 | args.service = "read"; | ||
86 | args.nargs = 3; | ||
87 | args.nret = 1; | ||
88 | args.ihandle = handle; | ||
89 | args.addr = ptr; | ||
90 | args.len = nb; | ||
91 | args.actual = -1; | ||
92 | (*prom)(&args); | ||
93 | return args.actual; | ||
94 | } | ||
95 | |||
96 | void | ||
97 | exit() | ||
98 | { | ||
99 | struct prom_args { | ||
100 | char *service; | ||
101 | } args; | ||
102 | |||
103 | for (;;) { | ||
104 | args.service = "exit"; | ||
105 | (*prom)(&args); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | void | ||
110 | pause(void) | ||
111 | { | ||
112 | struct prom_args { | ||
113 | char *service; | ||
114 | } args; | ||
115 | |||
116 | args.service = "enter"; | ||
117 | (*prom)(&args); | ||
118 | } | ||
119 | |||
120 | void * | ||
121 | finddevice(const char *name) | ||
122 | { | ||
123 | struct prom_args { | ||
124 | char *service; | ||
125 | int nargs; | ||
126 | int nret; | ||
127 | const char *devspec; | ||
128 | void *phandle; | ||
129 | } args; | ||
130 | |||
131 | args.service = "finddevice"; | ||
132 | args.nargs = 1; | ||
133 | args.nret = 1; | ||
134 | args.devspec = name; | ||
135 | args.phandle = (void *) -1; | ||
136 | (*prom)(&args); | ||
137 | return args.phandle; | ||
138 | } | ||
139 | |||
140 | void * | ||
141 | claim(unsigned long virt, unsigned long size, unsigned long align) | ||
142 | { | ||
143 | struct prom_args { | ||
144 | char *service; | ||
145 | int nargs; | ||
146 | int nret; | ||
147 | unsigned int virt; | ||
148 | unsigned int size; | ||
149 | unsigned int align; | ||
150 | void *ret; | ||
151 | } args; | ||
152 | |||
153 | args.service = "claim"; | ||
154 | args.nargs = 3; | ||
155 | args.nret = 1; | ||
156 | args.virt = virt; | ||
157 | args.size = size; | ||
158 | args.align = align; | ||
159 | (*prom)(&args); | ||
160 | return args.ret; | ||
161 | } | ||
162 | |||
163 | int | ||
164 | getprop(void *phandle, const char *name, void *buf, int buflen) | ||
165 | { | ||
166 | struct prom_args { | ||
167 | char *service; | ||
168 | int nargs; | ||
169 | int nret; | ||
170 | void *phandle; | ||
171 | const char *name; | ||
172 | void *buf; | ||
173 | int buflen; | ||
174 | int size; | ||
175 | } args; | ||
176 | |||
177 | args.service = "getprop"; | ||
178 | args.nargs = 4; | ||
179 | args.nret = 1; | ||
180 | args.phandle = phandle; | ||
181 | args.name = name; | ||
182 | args.buf = buf; | ||
183 | args.buflen = buflen; | ||
184 | args.size = -1; | ||
185 | (*prom)(&args); | ||
186 | return args.size; | ||
187 | } | ||
188 | |||
189 | int | ||
190 | putc(int c, void *f) | ||
191 | { | ||
192 | char ch = c; | ||
193 | |||
194 | if (c == '\n') | ||
195 | putc('\r', f); | ||
196 | return write(f, &ch, 1) == 1? c: -1; | ||
197 | } | ||
198 | |||
199 | int | ||
200 | putchar(int c) | ||
201 | { | ||
202 | return putc(c, stdout); | ||
203 | } | ||
204 | |||
205 | int | ||
206 | fputs(char *str, void *f) | ||
207 | { | ||
208 | int n = strlen(str); | ||
209 | |||
210 | return write(f, str, n) == n? 0: -1; | ||
211 | } | ||
212 | |||
213 | int | ||
214 | readchar(void) | ||
215 | { | ||
216 | char ch; | ||
217 | |||
218 | for (;;) { | ||
219 | switch (read(stdin, &ch, 1)) { | ||
220 | case 1: | ||
221 | return ch; | ||
222 | case -1: | ||
223 | printk("read(stdin) returned -1\r\n"); | ||
224 | return -1; | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | |||
229 | static char line[256]; | ||
230 | static char *lineptr; | ||
231 | static int lineleft; | ||
232 | |||
233 | int | ||
234 | getchar(void) | ||
235 | { | ||
236 | int c; | ||
237 | |||
238 | if (lineleft == 0) { | ||
239 | lineptr = line; | ||
240 | for (;;) { | ||
241 | c = readchar(); | ||
242 | if (c == -1 || c == 4) | ||
243 | break; | ||
244 | if (c == '\r' || c == '\n') { | ||
245 | *lineptr++ = '\n'; | ||
246 | putchar('\n'); | ||
247 | break; | ||
248 | } | ||
249 | switch (c) { | ||
250 | case 0177: | ||
251 | case '\b': | ||
252 | if (lineptr > line) { | ||
253 | putchar('\b'); | ||
254 | putchar(' '); | ||
255 | putchar('\b'); | ||
256 | --lineptr; | ||
257 | } | ||
258 | break; | ||
259 | case 'U' & 0x1F: | ||
260 | while (lineptr > line) { | ||
261 | putchar('\b'); | ||
262 | putchar(' '); | ||
263 | putchar('\b'); | ||
264 | --lineptr; | ||
265 | } | ||
266 | break; | ||
267 | default: | ||
268 | if (lineptr >= &line[sizeof(line) - 1]) | ||
269 | putchar('\a'); | ||
270 | else { | ||
271 | putchar(c); | ||
272 | *lineptr++ = c; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | lineleft = lineptr - line; | ||
277 | lineptr = line; | ||
278 | } | ||
279 | if (lineleft == 0) | ||
280 | return -1; | ||
281 | --lineleft; | ||
282 | return *lineptr++; | ||
283 | } | ||
284 | |||
285 | |||
286 | |||
287 | /* String functions lifted from lib/vsprintf.c and lib/ctype.c */ | ||
288 | unsigned char _ctype[] = { | ||
289 | _C,_C,_C,_C,_C,_C,_C,_C, /* 0-7 */ | ||
290 | _C,_C|_S,_C|_S,_C|_S,_C|_S,_C|_S,_C,_C, /* 8-15 */ | ||
291 | _C,_C,_C,_C,_C,_C,_C,_C, /* 16-23 */ | ||
292 | _C,_C,_C,_C,_C,_C,_C,_C, /* 24-31 */ | ||
293 | _S|_SP,_P,_P,_P,_P,_P,_P,_P, /* 32-39 */ | ||
294 | _P,_P,_P,_P,_P,_P,_P,_P, /* 40-47 */ | ||
295 | _D,_D,_D,_D,_D,_D,_D,_D, /* 48-55 */ | ||
296 | _D,_D,_P,_P,_P,_P,_P,_P, /* 56-63 */ | ||
297 | _P,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U|_X,_U, /* 64-71 */ | ||
298 | _U,_U,_U,_U,_U,_U,_U,_U, /* 72-79 */ | ||
299 | _U,_U,_U,_U,_U,_U,_U,_U, /* 80-87 */ | ||
300 | _U,_U,_U,_P,_P,_P,_P,_P, /* 88-95 */ | ||
301 | _P,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L|_X,_L, /* 96-103 */ | ||
302 | _L,_L,_L,_L,_L,_L,_L,_L, /* 104-111 */ | ||
303 | _L,_L,_L,_L,_L,_L,_L,_L, /* 112-119 */ | ||
304 | _L,_L,_L,_P,_P,_P,_P,_C, /* 120-127 */ | ||
305 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 128-143 */ | ||
306 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 144-159 */ | ||
307 | _S|_SP,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 160-175 */ | ||
308 | _P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P,_P, /* 176-191 */ | ||
309 | _U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U,_U, /* 192-207 */ | ||
310 | _U,_U,_U,_U,_U,_U,_U,_P,_U,_U,_U,_U,_U,_U,_U,_L, /* 208-223 */ | ||
311 | _L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L,_L, /* 224-239 */ | ||
312 | _L,_L,_L,_L,_L,_L,_L,_P,_L,_L,_L,_L,_L,_L,_L,_L}; /* 240-255 */ | ||
313 | |||
314 | size_t strnlen(const char * s, size_t count) | ||
315 | { | ||
316 | const char *sc; | ||
317 | |||
318 | for (sc = s; count-- && *sc != '\0'; ++sc) | ||
319 | /* nothing */; | ||
320 | return sc - s; | ||
321 | } | ||
322 | |||
323 | unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base) | ||
324 | { | ||
325 | unsigned long result = 0,value; | ||
326 | |||
327 | if (!base) { | ||
328 | base = 10; | ||
329 | if (*cp == '0') { | ||
330 | base = 8; | ||
331 | cp++; | ||
332 | if ((*cp == 'x') && isxdigit(cp[1])) { | ||
333 | cp++; | ||
334 | base = 16; | ||
335 | } | ||
336 | } | ||
337 | } | ||
338 | while (isxdigit(*cp) && | ||
339 | (value = isdigit(*cp) ? *cp-'0' : toupper(*cp)-'A'+10) < base) { | ||
340 | result = result*base + value; | ||
341 | cp++; | ||
342 | } | ||
343 | if (endp) | ||
344 | *endp = (char *)cp; | ||
345 | return result; | ||
346 | } | ||
347 | |||
348 | long simple_strtol(const char *cp,char **endp,unsigned int base) | ||
349 | { | ||
350 | if(*cp=='-') | ||
351 | return -simple_strtoul(cp+1,endp,base); | ||
352 | return simple_strtoul(cp,endp,base); | ||
353 | } | ||
354 | |||
355 | static int skip_atoi(const char **s) | ||
356 | { | ||
357 | int i=0; | ||
358 | |||
359 | while (isdigit(**s)) | ||
360 | i = i*10 + *((*s)++) - '0'; | ||
361 | return i; | ||
362 | } | ||
363 | |||
364 | #define ZEROPAD 1 /* pad with zero */ | ||
365 | #define SIGN 2 /* unsigned/signed long */ | ||
366 | #define PLUS 4 /* show plus */ | ||
367 | #define SPACE 8 /* space if plus */ | ||
368 | #define LEFT 16 /* left justified */ | ||
369 | #define SPECIAL 32 /* 0x */ | ||
370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | ||
371 | |||
372 | static char * number(char * str, long long num, int base, int size, int precision, int type) | ||
373 | { | ||
374 | char c,sign,tmp[66]; | ||
375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | ||
376 | int i; | ||
377 | |||
378 | if (type & LARGE) | ||
379 | digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; | ||
380 | if (type & LEFT) | ||
381 | type &= ~ZEROPAD; | ||
382 | if (base < 2 || base > 36) | ||
383 | return 0; | ||
384 | c = (type & ZEROPAD) ? '0' : ' '; | ||
385 | sign = 0; | ||
386 | if (type & SIGN) { | ||
387 | if (num < 0) { | ||
388 | sign = '-'; | ||
389 | num = -num; | ||
390 | size--; | ||
391 | } else if (type & PLUS) { | ||
392 | sign = '+'; | ||
393 | size--; | ||
394 | } else if (type & SPACE) { | ||
395 | sign = ' '; | ||
396 | size--; | ||
397 | } | ||
398 | } | ||
399 | if (type & SPECIAL) { | ||
400 | if (base == 16) | ||
401 | size -= 2; | ||
402 | else if (base == 8) | ||
403 | size--; | ||
404 | } | ||
405 | i = 0; | ||
406 | if (num == 0) | ||
407 | tmp[i++]='0'; | ||
408 | else while (num != 0) | ||
409 | tmp[i++] = digits[do_div(num,base)]; | ||
410 | if (i > precision) | ||
411 | precision = i; | ||
412 | size -= precision; | ||
413 | if (!(type&(ZEROPAD+LEFT))) | ||
414 | while(size-->0) | ||
415 | *str++ = ' '; | ||
416 | if (sign) | ||
417 | *str++ = sign; | ||
418 | if (type & SPECIAL) { | ||
419 | if (base==8) | ||
420 | *str++ = '0'; | ||
421 | else if (base==16) { | ||
422 | *str++ = '0'; | ||
423 | *str++ = digits[33]; | ||
424 | } | ||
425 | } | ||
426 | if (!(type & LEFT)) | ||
427 | while (size-- > 0) | ||
428 | *str++ = c; | ||
429 | while (i < precision--) | ||
430 | *str++ = '0'; | ||
431 | while (i-- > 0) | ||
432 | *str++ = tmp[i]; | ||
433 | while (size-- > 0) | ||
434 | *str++ = ' '; | ||
435 | return str; | ||
436 | } | ||
437 | |||
438 | /* Forward decl. needed for IP address printing stuff... */ | ||
439 | int sprintf(char * buf, const char *fmt, ...); | ||
440 | |||
441 | int vsprintf(char *buf, const char *fmt, va_list args) | ||
442 | { | ||
443 | int len; | ||
444 | unsigned long long num; | ||
445 | int i, base; | ||
446 | char * str; | ||
447 | const char *s; | ||
448 | |||
449 | int flags; /* flags to number() */ | ||
450 | |||
451 | int field_width; /* width of output field */ | ||
452 | int precision; /* min. # of digits for integers; max | ||
453 | number of chars for from string */ | ||
454 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | ||
455 | /* 'z' support added 23/7/1999 S.H. */ | ||
456 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | ||
457 | |||
458 | |||
459 | for (str=buf ; *fmt ; ++fmt) { | ||
460 | if (*fmt != '%') { | ||
461 | *str++ = *fmt; | ||
462 | continue; | ||
463 | } | ||
464 | |||
465 | /* process flags */ | ||
466 | flags = 0; | ||
467 | repeat: | ||
468 | ++fmt; /* this also skips first '%' */ | ||
469 | switch (*fmt) { | ||
470 | case '-': flags |= LEFT; goto repeat; | ||
471 | case '+': flags |= PLUS; goto repeat; | ||
472 | case ' ': flags |= SPACE; goto repeat; | ||
473 | case '#': flags |= SPECIAL; goto repeat; | ||
474 | case '0': flags |= ZEROPAD; goto repeat; | ||
475 | } | ||
476 | |||
477 | /* get field width */ | ||
478 | field_width = -1; | ||
479 | if (isdigit(*fmt)) | ||
480 | field_width = skip_atoi(&fmt); | ||
481 | else if (*fmt == '*') { | ||
482 | ++fmt; | ||
483 | /* it's the next argument */ | ||
484 | field_width = va_arg(args, int); | ||
485 | if (field_width < 0) { | ||
486 | field_width = -field_width; | ||
487 | flags |= LEFT; | ||
488 | } | ||
489 | } | ||
490 | |||
491 | /* get the precision */ | ||
492 | precision = -1; | ||
493 | if (*fmt == '.') { | ||
494 | ++fmt; | ||
495 | if (isdigit(*fmt)) | ||
496 | precision = skip_atoi(&fmt); | ||
497 | else if (*fmt == '*') { | ||
498 | ++fmt; | ||
499 | /* it's the next argument */ | ||
500 | precision = va_arg(args, int); | ||
501 | } | ||
502 | if (precision < 0) | ||
503 | precision = 0; | ||
504 | } | ||
505 | |||
506 | /* get the conversion qualifier */ | ||
507 | qualifier = -1; | ||
508 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt =='Z') { | ||
509 | qualifier = *fmt; | ||
510 | ++fmt; | ||
511 | } | ||
512 | |||
513 | /* default base */ | ||
514 | base = 10; | ||
515 | |||
516 | switch (*fmt) { | ||
517 | case 'c': | ||
518 | if (!(flags & LEFT)) | ||
519 | while (--field_width > 0) | ||
520 | *str++ = ' '; | ||
521 | *str++ = (unsigned char) va_arg(args, int); | ||
522 | while (--field_width > 0) | ||
523 | *str++ = ' '; | ||
524 | continue; | ||
525 | |||
526 | case 's': | ||
527 | s = va_arg(args, char *); | ||
528 | if (!s) | ||
529 | s = "<NULL>"; | ||
530 | |||
531 | len = strnlen(s, precision); | ||
532 | |||
533 | if (!(flags & LEFT)) | ||
534 | while (len < field_width--) | ||
535 | *str++ = ' '; | ||
536 | for (i = 0; i < len; ++i) | ||
537 | *str++ = *s++; | ||
538 | while (len < field_width--) | ||
539 | *str++ = ' '; | ||
540 | continue; | ||
541 | |||
542 | case 'p': | ||
543 | if (field_width == -1) { | ||
544 | field_width = 2*sizeof(void *); | ||
545 | flags |= ZEROPAD; | ||
546 | } | ||
547 | str = number(str, | ||
548 | (unsigned long) va_arg(args, void *), 16, | ||
549 | field_width, precision, flags); | ||
550 | continue; | ||
551 | |||
552 | |||
553 | case 'n': | ||
554 | if (qualifier == 'l') { | ||
555 | long * ip = va_arg(args, long *); | ||
556 | *ip = (str - buf); | ||
557 | } else if (qualifier == 'Z') { | ||
558 | size_t * ip = va_arg(args, size_t *); | ||
559 | *ip = (str - buf); | ||
560 | } else { | ||
561 | int * ip = va_arg(args, int *); | ||
562 | *ip = (str - buf); | ||
563 | } | ||
564 | continue; | ||
565 | |||
566 | case '%': | ||
567 | *str++ = '%'; | ||
568 | continue; | ||
569 | |||
570 | /* integer number formats - set up the flags and "break" */ | ||
571 | case 'o': | ||
572 | base = 8; | ||
573 | break; | ||
574 | |||
575 | case 'X': | ||
576 | flags |= LARGE; | ||
577 | case 'x': | ||
578 | base = 16; | ||
579 | break; | ||
580 | |||
581 | case 'd': | ||
582 | case 'i': | ||
583 | flags |= SIGN; | ||
584 | case 'u': | ||
585 | break; | ||
586 | |||
587 | default: | ||
588 | *str++ = '%'; | ||
589 | if (*fmt) | ||
590 | *str++ = *fmt; | ||
591 | else | ||
592 | --fmt; | ||
593 | continue; | ||
594 | } | ||
595 | if (qualifier == 'L') | ||
596 | num = va_arg(args, long long); | ||
597 | else if (qualifier == 'l') { | ||
598 | num = va_arg(args, unsigned long); | ||
599 | if (flags & SIGN) | ||
600 | num = (signed long) num; | ||
601 | } else if (qualifier == 'Z') { | ||
602 | num = va_arg(args, size_t); | ||
603 | } else if (qualifier == 'h') { | ||
604 | num = (unsigned short) va_arg(args, int); | ||
605 | if (flags & SIGN) | ||
606 | num = (signed short) num; | ||
607 | } else { | ||
608 | num = va_arg(args, unsigned int); | ||
609 | if (flags & SIGN) | ||
610 | num = (signed int) num; | ||
611 | } | ||
612 | str = number(str, num, base, field_width, precision, flags); | ||
613 | } | ||
614 | *str = '\0'; | ||
615 | return str-buf; | ||
616 | } | ||
617 | |||
618 | int sprintf(char * buf, const char *fmt, ...) | ||
619 | { | ||
620 | va_list args; | ||
621 | int i; | ||
622 | |||
623 | va_start(args, fmt); | ||
624 | i=vsprintf(buf,fmt,args); | ||
625 | va_end(args); | ||
626 | return i; | ||
627 | } | ||
628 | |||
629 | static char sprint_buf[1024]; | ||
630 | |||
631 | void | ||
632 | printk(char *fmt, ...) | ||
633 | { | ||
634 | va_list args; | ||
635 | int n; | ||
636 | |||
637 | va_start(args, fmt); | ||
638 | n = vsprintf(sprint_buf, fmt, args); | ||
639 | va_end(args); | ||
640 | write(stdout, sprint_buf, n); | ||
641 | } | ||
642 | |||
643 | int | ||
644 | printf(char *fmt, ...) | ||
645 | { | ||
646 | va_list args; | ||
647 | int n; | ||
648 | |||
649 | va_start(args, fmt); | ||
650 | n = vsprintf(sprint_buf, fmt, args); | ||
651 | va_end(args); | ||
652 | write(stdout, sprint_buf, n); | ||
653 | return n; | ||
654 | } | ||
diff --git a/arch/ppc64/kernel/misc.S b/arch/ppc64/kernel/misc.S index 90b41f48d21c..b944717c1dbd 100644 --- a/arch/ppc64/kernel/misc.S +++ b/arch/ppc64/kernel/misc.S | |||
@@ -32,7 +32,7 @@ | |||
32 | .text | 32 | .text |
33 | 33 | ||
34 | /* | 34 | /* |
35 | * Returns (address we're running at) - (address we were linked at) | 35 | * Returns (address we were linked at) - (address we are running at) |
36 | * for use before the text and data are mapped to KERNELBASE. | 36 | * for use before the text and data are mapped to KERNELBASE. |
37 | */ | 37 | */ |
38 | 38 | ||
diff --git a/arch/ppc64/kernel/pSeries_smp.c b/arch/ppc64/kernel/pSeries_smp.c index c60d8cb2b84d..fbad349ec58c 100644 --- a/arch/ppc64/kernel/pSeries_smp.c +++ b/arch/ppc64/kernel/pSeries_smp.c | |||
@@ -326,13 +326,6 @@ static void __devinit smp_xics_setup_cpu(int cpu) | |||
326 | 326 | ||
327 | cpu_clear(cpu, of_spin_map); | 327 | cpu_clear(cpu, of_spin_map); |
328 | 328 | ||
329 | /* | ||
330 | * Put the calling processor into the GIQ. This is really only | ||
331 | * necessary from a secondary thread as the OF start-cpu interface | ||
332 | * performs this function for us on primary threads. | ||
333 | */ | ||
334 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
335 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
336 | } | 329 | } |
337 | 330 | ||
338 | static DEFINE_SPINLOCK(timebase_lock); | 331 | static DEFINE_SPINLOCK(timebase_lock); |
diff --git a/arch/ppc64/kernel/pci.c b/arch/ppc64/kernel/pci.c index be3cc387c1ec..d786d4b6af0b 100644 --- a/arch/ppc64/kernel/pci.c +++ b/arch/ppc64/kernel/pci.c | |||
@@ -438,7 +438,7 @@ pgprot_t pci_phys_mem_access_prot(struct file *file, | |||
438 | int i; | 438 | int i; |
439 | 439 | ||
440 | if (page_is_ram(offset >> PAGE_SHIFT)) | 440 | if (page_is_ram(offset >> PAGE_SHIFT)) |
441 | return prot; | 441 | return __pgprot(prot); |
442 | 442 | ||
443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; | 443 | prot |= _PAGE_NO_CACHE | _PAGE_GUARDED; |
444 | 444 | ||
diff --git a/arch/ppc64/kernel/prom.c b/arch/ppc64/kernel/prom.c index fe2946c58314..eb6538b58008 100644 --- a/arch/ppc64/kernel/prom.c +++ b/arch/ppc64/kernel/prom.c | |||
@@ -834,7 +834,7 @@ void __init unflatten_device_tree(void) | |||
834 | { | 834 | { |
835 | unsigned long start, mem, size; | 835 | unsigned long start, mem, size; |
836 | struct device_node **allnextp = &allnodes; | 836 | struct device_node **allnextp = &allnodes; |
837 | char *p; | 837 | char *p = NULL; |
838 | int l = 0; | 838 | int l = 0; |
839 | 839 | ||
840 | DBG(" -> unflatten_device_tree()\n"); | 840 | DBG(" -> unflatten_device_tree()\n"); |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index a95a2b49a1d5..bf782276984c 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
@@ -42,11 +42,7 @@ | |||
42 | 42 | ||
43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | 43 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) |
44 | 44 | ||
45 | #ifndef MIN | 45 | #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs)) |
46 | #define MIN(a,b) (((a) < (b)) ? (a) : (b)) | ||
47 | #endif | ||
48 | |||
49 | #define GP_REGS_SIZE MIN(sizeof(elf_gregset_t), sizeof(struct pt_regs)) | ||
50 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) | 46 | #define FP_REGS_SIZE sizeof(elf_fpregset_t) |
51 | 47 | ||
52 | #define TRAMP_TRACEBACK 3 | 48 | #define TRAMP_TRACEBACK 3 |
diff --git a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c index eedd1d3c2a10..879f39b90a33 100644 --- a/arch/ppc64/kernel/xics.c +++ b/arch/ppc64/kernel/xics.c | |||
@@ -432,6 +432,7 @@ void xics_cause_IPI(int cpu) | |||
432 | { | 432 | { |
433 | ops->qirr_info(cpu, IPI_PRIORITY); | 433 | ops->qirr_info(cpu, IPI_PRIORITY); |
434 | } | 434 | } |
435 | #endif /* CONFIG_SMP */ | ||
435 | 436 | ||
436 | void xics_setup_cpu(void) | 437 | void xics_setup_cpu(void) |
437 | { | 438 | { |
@@ -439,9 +440,17 @@ void xics_setup_cpu(void) | |||
439 | 440 | ||
440 | ops->cppr_info(cpu, 0xff); | 441 | ops->cppr_info(cpu, 0xff); |
441 | iosync(); | 442 | iosync(); |
442 | } | ||
443 | 443 | ||
444 | #endif /* CONFIG_SMP */ | 444 | /* |
445 | * Put the calling processor into the GIQ. This is really only | ||
446 | * necessary from a secondary thread as the OF start-cpu interface | ||
447 | * performs this function for us on primary threads. | ||
448 | * | ||
449 | * XXX: undo of teardown on kexec needs this too, as may hotplug | ||
450 | */ | ||
451 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | ||
452 | (1UL << interrupt_server_size) - 1 - default_distrib_server, 1); | ||
453 | } | ||
445 | 454 | ||
446 | void xics_init_IRQ(void) | 455 | void xics_init_IRQ(void) |
447 | { | 456 | { |
@@ -563,8 +572,7 @@ nextnode: | |||
563 | for (; i < NR_IRQS; ++i) | 572 | for (; i < NR_IRQS; ++i) |
564 | get_irq_desc(i)->handler = &xics_pic; | 573 | get_irq_desc(i)->handler = &xics_pic; |
565 | 574 | ||
566 | ops->cppr_info(boot_cpuid, 0xff); | 575 | xics_setup_cpu(); |
567 | iosync(); | ||
568 | 576 | ||
569 | ppc64_boot_msg(0x21, "XICS Done"); | 577 | ppc64_boot_msg(0x21, "XICS Done"); |
570 | } | 578 | } |
diff --git a/arch/ppc64/mm/hash_native.c b/arch/ppc64/mm/hash_native.c index 144657e0c3d5..52b6b9305341 100644 --- a/arch/ppc64/mm/hash_native.c +++ b/arch/ppc64/mm/hash_native.c | |||
@@ -320,8 +320,7 @@ static void native_flush_hash_range(unsigned long context, | |||
320 | 320 | ||
321 | j = 0; | 321 | j = 0; |
322 | for (i = 0; i < number; i++) { | 322 | for (i = 0; i < number; i++) { |
323 | if ((batch->addr[i] >= USER_START) && | 323 | if (batch->addr[i] < KERNELBASE) |
324 | (batch->addr[i] <= USER_END)) | ||
325 | vsid = get_vsid(context, batch->addr[i]); | 324 | vsid = get_vsid(context, batch->addr[i]); |
326 | else | 325 | else |
327 | vsid = get_kernel_vsid(batch->addr[i]); | 326 | vsid = get_kernel_vsid(batch->addr[i]); |
diff --git a/arch/ppc64/mm/hash_utils.c b/arch/ppc64/mm/hash_utils.c index e48be12f518c..0a0f97008d02 100644 --- a/arch/ppc64/mm/hash_utils.c +++ b/arch/ppc64/mm/hash_utils.c | |||
@@ -298,24 +298,23 @@ int hash_page(unsigned long ea, unsigned long access, unsigned long trap) | |||
298 | int local = 0; | 298 | int local = 0; |
299 | cpumask_t tmp; | 299 | cpumask_t tmp; |
300 | 300 | ||
301 | if ((ea & ~REGION_MASK) > EADDR_MASK) | ||
302 | return 1; | ||
303 | |||
301 | switch (REGION_ID(ea)) { | 304 | switch (REGION_ID(ea)) { |
302 | case USER_REGION_ID: | 305 | case USER_REGION_ID: |
303 | user_region = 1; | 306 | user_region = 1; |
304 | mm = current->mm; | 307 | mm = current->mm; |
305 | if ((ea > USER_END) || (! mm)) | 308 | if (! mm) |
306 | return 1; | 309 | return 1; |
307 | 310 | ||
308 | vsid = get_vsid(mm->context.id, ea); | 311 | vsid = get_vsid(mm->context.id, ea); |
309 | break; | 312 | break; |
310 | case IO_REGION_ID: | 313 | case IO_REGION_ID: |
311 | if (ea > IMALLOC_END) | ||
312 | return 1; | ||
313 | mm = &ioremap_mm; | 314 | mm = &ioremap_mm; |
314 | vsid = get_kernel_vsid(ea); | 315 | vsid = get_kernel_vsid(ea); |
315 | break; | 316 | break; |
316 | case VMALLOC_REGION_ID: | 317 | case VMALLOC_REGION_ID: |
317 | if (ea > VMALLOC_END) | ||
318 | return 1; | ||
319 | mm = &init_mm; | 318 | mm = &init_mm; |
320 | vsid = get_kernel_vsid(ea); | 319 | vsid = get_kernel_vsid(ea); |
321 | break; | 320 | break; |
@@ -362,7 +361,7 @@ void flush_hash_page(unsigned long context, unsigned long ea, pte_t pte, | |||
362 | unsigned long vsid, vpn, va, hash, secondary, slot; | 361 | unsigned long vsid, vpn, va, hash, secondary, slot; |
363 | unsigned long huge = pte_huge(pte); | 362 | unsigned long huge = pte_huge(pte); |
364 | 363 | ||
365 | if ((ea >= USER_START) && (ea <= USER_END)) | 364 | if (ea < KERNELBASE) |
366 | vsid = get_vsid(context, ea); | 365 | vsid = get_vsid(context, ea); |
367 | else | 366 | else |
368 | vsid = get_kernel_vsid(ea); | 367 | vsid = get_kernel_vsid(ea); |
diff --git a/arch/ppc64/mm/imalloc.c b/arch/ppc64/mm/imalloc.c index 9d92b0d9cde5..cb8727f3267a 100644 --- a/arch/ppc64/mm/imalloc.c +++ b/arch/ppc64/mm/imalloc.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/pgalloc.h> | 14 | #include <asm/pgalloc.h> |
15 | #include <asm/pgtable.h> | 15 | #include <asm/pgtable.h> |
16 | #include <asm/semaphore.h> | 16 | #include <asm/semaphore.h> |
17 | #include <asm/imalloc.h> | ||
17 | 18 | ||
18 | static DECLARE_MUTEX(imlist_sem); | 19 | static DECLARE_MUTEX(imlist_sem); |
19 | struct vm_struct * imlist = NULL; | 20 | struct vm_struct * imlist = NULL; |
@@ -23,11 +24,11 @@ static int get_free_im_addr(unsigned long size, unsigned long *im_addr) | |||
23 | unsigned long addr; | 24 | unsigned long addr; |
24 | struct vm_struct **p, *tmp; | 25 | struct vm_struct **p, *tmp; |
25 | 26 | ||
26 | addr = IMALLOC_START; | 27 | addr = ioremap_bot; |
27 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { | 28 | for (p = &imlist; (tmp = *p) ; p = &tmp->next) { |
28 | if (size + addr < (unsigned long) tmp->addr) | 29 | if (size + addr < (unsigned long) tmp->addr) |
29 | break; | 30 | break; |
30 | if ((unsigned long)tmp->addr >= IMALLOC_START) | 31 | if ((unsigned long)tmp->addr >= ioremap_bot) |
31 | addr = tmp->size + (unsigned long) tmp->addr; | 32 | addr = tmp->size + (unsigned long) tmp->addr; |
32 | if (addr > IMALLOC_END-size) | 33 | if (addr > IMALLOC_END-size) |
33 | return 1; | 34 | return 1; |
diff --git a/arch/ppc64/mm/init.c b/arch/ppc64/mm/init.c index cf33d7ec2e29..4b42aff74d73 100644 --- a/arch/ppc64/mm/init.c +++ b/arch/ppc64/mm/init.c | |||
@@ -64,6 +64,7 @@ | |||
64 | #include <asm/iommu.h> | 64 | #include <asm/iommu.h> |
65 | #include <asm/abs_addr.h> | 65 | #include <asm/abs_addr.h> |
66 | #include <asm/vdso.h> | 66 | #include <asm/vdso.h> |
67 | #include <asm/imalloc.h> | ||
67 | 68 | ||
68 | int mem_init_done; | 69 | int mem_init_done; |
69 | unsigned long ioremap_bot = IMALLOC_BASE; | 70 | unsigned long ioremap_bot = IMALLOC_BASE; |
@@ -668,7 +669,7 @@ void __init paging_init(void) | |||
668 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; | 669 | zones_size[ZONE_DMA] = top_of_ram >> PAGE_SHIFT; |
669 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; | 670 | zholes_size[ZONE_DMA] = (top_of_ram - total_ram) >> PAGE_SHIFT; |
670 | 671 | ||
671 | free_area_init_node(0, &contig_page_data, zones_size, | 672 | free_area_init_node(0, NODE_DATA(0), zones_size, |
672 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); | 673 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, zholes_size); |
673 | } | 674 | } |
674 | #endif /* CONFIG_DISCONTIGMEM */ | 675 | #endif /* CONFIG_DISCONTIGMEM */ |
diff --git a/arch/ppc64/mm/stab.c b/arch/ppc64/mm/stab.c index 31491131d5e4..df4bbe14153c 100644 --- a/arch/ppc64/mm/stab.c +++ b/arch/ppc64/mm/stab.c | |||
@@ -19,6 +19,11 @@ | |||
19 | #include <asm/paca.h> | 19 | #include <asm/paca.h> |
20 | #include <asm/cputable.h> | 20 | #include <asm/cputable.h> |
21 | 21 | ||
22 | struct stab_entry { | ||
23 | unsigned long esid_data; | ||
24 | unsigned long vsid_data; | ||
25 | }; | ||
26 | |||
22 | /* Both the segment table and SLB code uses the following cache */ | 27 | /* Both the segment table and SLB code uses the following cache */ |
23 | #define NR_STAB_CACHE_ENTRIES 8 | 28 | #define NR_STAB_CACHE_ENTRIES 8 |
24 | DEFINE_PER_CPU(long, stab_cache_ptr); | 29 | DEFINE_PER_CPU(long, stab_cache_ptr); |
diff --git a/arch/sparc/kernel/process.c b/arch/sparc/kernel/process.c index 066e253f9c12..2c216ffeea90 100644 --- a/arch/sparc/kernel/process.c +++ b/arch/sparc/kernel/process.c | |||
@@ -83,9 +83,6 @@ void default_idle(void) | |||
83 | */ | 83 | */ |
84 | void cpu_idle(void) | 84 | void cpu_idle(void) |
85 | { | 85 | { |
86 | if (current->pid != 0) | ||
87 | goto out; | ||
88 | |||
89 | /* endless idle loop with no priority at all */ | 86 | /* endless idle loop with no priority at all */ |
90 | for (;;) { | 87 | for (;;) { |
91 | if (ARCH_SUN4C_SUN4) { | 88 | if (ARCH_SUN4C_SUN4) { |
@@ -126,8 +123,6 @@ void cpu_idle(void) | |||
126 | schedule(); | 123 | schedule(); |
127 | check_pgt_cache(); | 124 | check_pgt_cache(); |
128 | } | 125 | } |
129 | out: | ||
130 | return; | ||
131 | } | 126 | } |
132 | 127 | ||
133 | #else | 128 | #else |
diff --git a/arch/sparc64/kernel/pci_iommu.c b/arch/sparc64/kernel/pci_iommu.c index 292983413ae2..33ca56c90da2 100644 --- a/arch/sparc64/kernel/pci_iommu.c +++ b/arch/sparc64/kernel/pci_iommu.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
10 | #include <linux/mm.h> | 10 | #include <linux/mm.h> |
11 | #include <linux/delay.h> | ||
11 | 12 | ||
12 | #include <asm/pbm.h> | 13 | #include <asm/pbm.h> |
13 | 14 | ||
@@ -379,6 +380,56 @@ bad: | |||
379 | return PCI_DMA_ERROR_CODE; | 380 | return PCI_DMA_ERROR_CODE; |
380 | } | 381 | } |
381 | 382 | ||
383 | static void pci_strbuf_flush(struct pci_strbuf *strbuf, struct pci_iommu *iommu, u32 vaddr, unsigned long ctx, unsigned long npages) | ||
384 | { | ||
385 | int limit; | ||
386 | |||
387 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
388 | if (strbuf->strbuf_ctxflush && | ||
389 | iommu->iommu_ctxflush) { | ||
390 | unsigned long matchreg, flushreg; | ||
391 | |||
392 | flushreg = strbuf->strbuf_ctxflush; | ||
393 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
394 | |||
395 | limit = 100000; | ||
396 | pci_iommu_write(flushreg, ctx); | ||
397 | for(;;) { | ||
398 | if (((long)pci_iommu_read(matchreg)) >= 0L) | ||
399 | break; | ||
400 | limit--; | ||
401 | if (!limit) | ||
402 | break; | ||
403 | udelay(1); | ||
404 | } | ||
405 | if (!limit) | ||
406 | printk(KERN_WARNING "pci_strbuf_flush: ctx flush " | ||
407 | "timeout vaddr[%08x] ctx[%lx]\n", | ||
408 | vaddr, ctx); | ||
409 | } else { | ||
410 | unsigned long i; | ||
411 | |||
412 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
413 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
414 | } | ||
415 | |||
416 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
417 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
418 | |||
419 | limit = 100000; | ||
420 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) { | ||
421 | limit--; | ||
422 | if (!limit) | ||
423 | break; | ||
424 | udelay(1); | ||
425 | membar("#LoadLoad"); | ||
426 | } | ||
427 | if (!limit) | ||
428 | printk(KERN_WARNING "pci_strbuf_flush: flushflag timeout " | ||
429 | "vaddr[%08x] ctx[%lx] npages[%ld]\n", | ||
430 | vaddr, ctx, npages); | ||
431 | } | ||
432 | |||
382 | /* Unmap a single streaming mode DMA translation. */ | 433 | /* Unmap a single streaming mode DMA translation. */ |
383 | void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) | 434 | void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int direction) |
384 | { | 435 | { |
@@ -386,7 +437,7 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
386 | struct pci_iommu *iommu; | 437 | struct pci_iommu *iommu; |
387 | struct pci_strbuf *strbuf; | 438 | struct pci_strbuf *strbuf; |
388 | iopte_t *base; | 439 | iopte_t *base; |
389 | unsigned long flags, npages, i, ctx; | 440 | unsigned long flags, npages, ctx; |
390 | 441 | ||
391 | if (direction == PCI_DMA_NONE) | 442 | if (direction == PCI_DMA_NONE) |
392 | BUG(); | 443 | BUG(); |
@@ -414,29 +465,8 @@ void pci_unmap_single(struct pci_dev *pdev, dma_addr_t bus_addr, size_t sz, int | |||
414 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | 465 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; |
415 | 466 | ||
416 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 467 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
417 | if (strbuf->strbuf_enabled) { | 468 | if (strbuf->strbuf_enabled) |
418 | u32 vaddr = bus_addr; | 469 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); |
419 | |||
420 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
421 | if (strbuf->strbuf_ctxflush && | ||
422 | iommu->iommu_ctxflush) { | ||
423 | unsigned long matchreg, flushreg; | ||
424 | |||
425 | flushreg = strbuf->strbuf_ctxflush; | ||
426 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
427 | do { | ||
428 | pci_iommu_write(flushreg, ctx); | ||
429 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
430 | } else { | ||
431 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
432 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
433 | } | ||
434 | |||
435 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
436 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
437 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
438 | membar("#LoadLoad"); | ||
439 | } | ||
440 | 470 | ||
441 | /* Step 2: Clear out first TSB entry. */ | 471 | /* Step 2: Clear out first TSB entry. */ |
442 | iopte_make_dummy(iommu, base); | 472 | iopte_make_dummy(iommu, base); |
@@ -647,29 +677,8 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems, | |||
647 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; | 677 | ctx = (iopte_val(*base) & IOPTE_CONTEXT) >> 47UL; |
648 | 678 | ||
649 | /* Step 1: Kick data out of streaming buffers if necessary. */ | 679 | /* Step 1: Kick data out of streaming buffers if necessary. */ |
650 | if (strbuf->strbuf_enabled) { | 680 | if (strbuf->strbuf_enabled) |
651 | u32 vaddr = (u32) bus_addr; | 681 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); |
652 | |||
653 | PCI_STC_FLUSHFLAG_INIT(strbuf); | ||
654 | if (strbuf->strbuf_ctxflush && | ||
655 | iommu->iommu_ctxflush) { | ||
656 | unsigned long matchreg, flushreg; | ||
657 | |||
658 | flushreg = strbuf->strbuf_ctxflush; | ||
659 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
660 | do { | ||
661 | pci_iommu_write(flushreg, ctx); | ||
662 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
663 | } else { | ||
664 | for (i = 0; i < npages; i++, vaddr += IO_PAGE_SIZE) | ||
665 | pci_iommu_write(strbuf->strbuf_pflush, vaddr); | ||
666 | } | ||
667 | |||
668 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
669 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
670 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
671 | membar("#LoadLoad"); | ||
672 | } | ||
673 | 682 | ||
674 | /* Step 2: Clear out first TSB entry. */ | 683 | /* Step 2: Clear out first TSB entry. */ |
675 | iopte_make_dummy(iommu, base); | 684 | iopte_make_dummy(iommu, base); |
@@ -715,28 +724,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *pdev, dma_addr_t bus_addr, size | |||
715 | } | 724 | } |
716 | 725 | ||
717 | /* Step 2: Kick data out of streaming buffers. */ | 726 | /* Step 2: Kick data out of streaming buffers. */ |
718 | PCI_STC_FLUSHFLAG_INIT(strbuf); | 727 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); |
719 | if (iommu->iommu_ctxflush && | ||
720 | strbuf->strbuf_ctxflush) { | ||
721 | unsigned long matchreg, flushreg; | ||
722 | |||
723 | flushreg = strbuf->strbuf_ctxflush; | ||
724 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | ||
725 | do { | ||
726 | pci_iommu_write(flushreg, ctx); | ||
727 | } while(((long)pci_iommu_read(matchreg)) < 0L); | ||
728 | } else { | ||
729 | unsigned long i; | ||
730 | |||
731 | for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE) | ||
732 | pci_iommu_write(strbuf->strbuf_pflush, bus_addr); | ||
733 | } | ||
734 | |||
735 | /* Step 3: Perform flush synchronization sequence. */ | ||
736 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
737 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
738 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
739 | membar("#LoadLoad"); | ||
740 | 728 | ||
741 | spin_unlock_irqrestore(&iommu->lock, flags); | 729 | spin_unlock_irqrestore(&iommu->lock, flags); |
742 | } | 730 | } |
@@ -749,7 +737,8 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
749 | struct pcidev_cookie *pcp; | 737 | struct pcidev_cookie *pcp; |
750 | struct pci_iommu *iommu; | 738 | struct pci_iommu *iommu; |
751 | struct pci_strbuf *strbuf; | 739 | struct pci_strbuf *strbuf; |
752 | unsigned long flags, ctx; | 740 | unsigned long flags, ctx, npages, i; |
741 | u32 bus_addr; | ||
753 | 742 | ||
754 | pcp = pdev->sysdata; | 743 | pcp = pdev->sysdata; |
755 | iommu = pcp->pbm->iommu; | 744 | iommu = pcp->pbm->iommu; |
@@ -772,36 +761,14 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *pdev, struct scatterlist *sglist, i | |||
772 | } | 761 | } |
773 | 762 | ||
774 | /* Step 2: Kick data out of streaming buffers. */ | 763 | /* Step 2: Kick data out of streaming buffers. */ |
775 | PCI_STC_FLUSHFLAG_INIT(strbuf); | 764 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; |
776 | if (iommu->iommu_ctxflush && | 765 | for(i = 1; i < nelems; i++) |
777 | strbuf->strbuf_ctxflush) { | 766 | if (!sglist[i].dma_length) |
778 | unsigned long matchreg, flushreg; | 767 | break; |
779 | 768 | i--; | |
780 | flushreg = strbuf->strbuf_ctxflush; | 769 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) |
781 | matchreg = PCI_STC_CTXMATCH_ADDR(strbuf, ctx); | 770 | - bus_addr) >> IO_PAGE_SHIFT; |
782 | do { | 771 | pci_strbuf_flush(strbuf, iommu, bus_addr, ctx, npages); |
783 | pci_iommu_write(flushreg, ctx); | ||
784 | } while (((long)pci_iommu_read(matchreg)) < 0L); | ||
785 | } else { | ||
786 | unsigned long i, npages; | ||
787 | u32 bus_addr; | ||
788 | |||
789 | bus_addr = sglist[0].dma_address & IO_PAGE_MASK; | ||
790 | |||
791 | for(i = 1; i < nelems; i++) | ||
792 | if (!sglist[i].dma_length) | ||
793 | break; | ||
794 | i--; | ||
795 | npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - bus_addr) >> IO_PAGE_SHIFT; | ||
796 | for (i = 0; i < npages; i++, bus_addr += IO_PAGE_SIZE) | ||
797 | pci_iommu_write(strbuf->strbuf_pflush, bus_addr); | ||
798 | } | ||
799 | |||
800 | /* Step 3: Perform flush synchronization sequence. */ | ||
801 | pci_iommu_write(strbuf->strbuf_fsync, strbuf->strbuf_flushflag_pa); | ||
802 | (void) pci_iommu_read(iommu->write_complete_reg); | ||
803 | while (!PCI_STC_FLUSHFLAG_SET(strbuf)) | ||
804 | membar("#LoadLoad"); | ||
805 | 772 | ||
806 | spin_unlock_irqrestore(&iommu->lock, flags); | 773 | spin_unlock_irqrestore(&iommu->lock, flags); |
807 | } | 774 | } |
diff --git a/arch/sparc64/kernel/process.c b/arch/sparc64/kernel/process.c index 26d3ec41da1c..a0cd2b2494d6 100644 --- a/arch/sparc64/kernel/process.c +++ b/arch/sparc64/kernel/process.c | |||
@@ -62,9 +62,6 @@ void default_idle(void) | |||
62 | */ | 62 | */ |
63 | void cpu_idle(void) | 63 | void cpu_idle(void) |
64 | { | 64 | { |
65 | if (current->pid != 0) | ||
66 | return; | ||
67 | |||
68 | /* endless idle loop with no priority at all */ | 65 | /* endless idle loop with no priority at all */ |
69 | for (;;) { | 66 | for (;;) { |
70 | /* If current->work.need_resched is zero we should really | 67 | /* If current->work.need_resched is zero we should really |
@@ -80,7 +77,6 @@ void cpu_idle(void) | |||
80 | schedule(); | 77 | schedule(); |
81 | check_pgt_cache(); | 78 | check_pgt_cache(); |
82 | } | 79 | } |
83 | return; | ||
84 | } | 80 | } |
85 | 81 | ||
86 | #else | 82 | #else |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 14d9c3a21b9a..76ea6455433f 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages | |||
117 | 117 | ||
118 | #define STRBUF_TAG_VALID 0x02UL | 118 | #define STRBUF_TAG_VALID 0x02UL |
119 | 119 | ||
120 | static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) | 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) |
121 | { | 121 | { |
122 | unsigned long n; | ||
123 | int limit; | ||
124 | |||
122 | iommu->strbuf_flushflag = 0UL; | 125 | iommu->strbuf_flushflag = 0UL; |
123 | while (npages--) | 126 | n = npages; |
124 | upa_writeq(base + (npages << IO_PAGE_SHIFT), | 127 | while (n--) |
128 | upa_writeq(base + (n << IO_PAGE_SHIFT), | ||
125 | iommu->strbuf_regs + STRBUF_PFLUSH); | 129 | iommu->strbuf_regs + STRBUF_PFLUSH); |
126 | 130 | ||
127 | /* Whoopee cushion! */ | 131 | /* Whoopee cushion! */ |
128 | upa_writeq(__pa(&iommu->strbuf_flushflag), | 132 | upa_writeq(__pa(&iommu->strbuf_flushflag), |
129 | iommu->strbuf_regs + STRBUF_FSYNC); | 133 | iommu->strbuf_regs + STRBUF_FSYNC); |
130 | upa_readq(iommu->sbus_control_reg); | 134 | upa_readq(iommu->sbus_control_reg); |
131 | while (iommu->strbuf_flushflag == 0UL) | 135 | |
136 | limit = 100000; | ||
137 | while (iommu->strbuf_flushflag == 0UL) { | ||
138 | limit--; | ||
139 | if (!limit) | ||
140 | break; | ||
141 | udelay(1); | ||
132 | membar("#LoadLoad"); | 142 | membar("#LoadLoad"); |
143 | } | ||
144 | if (!limit) | ||
145 | printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout " | ||
146 | "vaddr[%08x] npages[%ld]\n", | ||
147 | base, npages); | ||
133 | } | 148 | } |
134 | 149 | ||
135 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) | 150 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) |
@@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, | |||
406 | 421 | ||
407 | spin_lock_irqsave(&iommu->lock, flags); | 422 | spin_lock_irqsave(&iommu->lock, flags); |
408 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); | 423 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
409 | strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); | 424 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); |
410 | spin_unlock_irqrestore(&iommu->lock, flags); | 425 | spin_unlock_irqrestore(&iommu->lock, flags); |
411 | } | 426 | } |
412 | 427 | ||
@@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int | |||
569 | iommu = sdev->bus->iommu; | 584 | iommu = sdev->bus->iommu; |
570 | spin_lock_irqsave(&iommu->lock, flags); | 585 | spin_lock_irqsave(&iommu->lock, flags); |
571 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 586 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
572 | strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 587 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
573 | spin_unlock_irqrestore(&iommu->lock, flags); | 588 | spin_unlock_irqrestore(&iommu->lock, flags); |
574 | } | 589 | } |
575 | 590 | ||
@@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t | |||
581 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); | 596 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
582 | 597 | ||
583 | spin_lock_irqsave(&iommu->lock, flags); | 598 | spin_lock_irqsave(&iommu->lock, flags); |
584 | strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); | 599 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); |
585 | spin_unlock_irqrestore(&iommu->lock, flags); | 600 | spin_unlock_irqrestore(&iommu->lock, flags); |
586 | } | 601 | } |
587 | 602 | ||
@@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int | |||
605 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; | 620 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
606 | 621 | ||
607 | spin_lock_irqsave(&iommu->lock, flags); | 622 | spin_lock_irqsave(&iommu->lock, flags); |
608 | strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); | 623 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); |
609 | spin_unlock_irqrestore(&iommu->lock, flags); | 624 | spin_unlock_irqrestore(&iommu->lock, flags); |
610 | } | 625 | } |
611 | 626 | ||
diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index cad5a1122800..e78cc53594fa 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c | |||
@@ -278,7 +278,7 @@ EXPORT_SYMBOL(verify_compat_iovec); | |||
278 | 278 | ||
279 | EXPORT_SYMBOL(dump_thread); | 279 | EXPORT_SYMBOL(dump_thread); |
280 | EXPORT_SYMBOL(dump_fpu); | 280 | EXPORT_SYMBOL(dump_fpu); |
281 | EXPORT_SYMBOL(__pte_alloc_one_kernel); | 281 | EXPORT_SYMBOL(pte_alloc_one_kernel); |
282 | #ifndef CONFIG_SMP | 282 | #ifndef CONFIG_SMP |
283 | EXPORT_SYMBOL(pgt_quicklists); | 283 | EXPORT_SYMBOL(pgt_quicklists); |
284 | #endif | 284 | #endif |
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c index db6fa77b4dab..9c5222075da9 100644 --- a/arch/sparc64/mm/init.c +++ b/arch/sparc64/mm/init.c | |||
@@ -1114,7 +1114,7 @@ struct pgtable_cache_struct pgt_quicklists; | |||
1114 | #else | 1114 | #else |
1115 | #define DC_ALIAS_SHIFT 0 | 1115 | #define DC_ALIAS_SHIFT 0 |
1116 | #endif | 1116 | #endif |
1117 | pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | 1117 | pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) |
1118 | { | 1118 | { |
1119 | struct page *page; | 1119 | struct page *page; |
1120 | unsigned long color; | 1120 | unsigned long color; |
diff --git a/arch/um/Kconfig_x86_64 b/arch/um/Kconfig_x86_64 index fd8d7e8982b1..f162f50f0b17 100644 --- a/arch/um/Kconfig_x86_64 +++ b/arch/um/Kconfig_x86_64 | |||
@@ -6,6 +6,10 @@ config 64BIT | |||
6 | bool | 6 | bool |
7 | default y | 7 | default y |
8 | 8 | ||
9 | config TOP_ADDR | ||
10 | hex | ||
11 | default 0x80000000 | ||
12 | |||
9 | config 3_LEVEL_PGTABLES | 13 | config 3_LEVEL_PGTABLES |
10 | bool | 14 | bool |
11 | default y | 15 | default y |
diff --git a/arch/um/Makefile b/arch/um/Makefile index 97bca6b5ca95..f2a0c40a9204 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile | |||
@@ -17,7 +17,7 @@ core-y += $(ARCH_DIR)/kernel/ \ | |||
17 | 17 | ||
18 | # Have to precede the include because the included Makefiles reference them. | 18 | # Have to precede the include because the included Makefiles reference them. |
19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ | 19 | SYMLINK_HEADERS := archparam.h system.h sigcontext.h processor.h ptrace.h \ |
20 | arch-signal.h module.h vm-flags.h | 20 | module.h vm-flags.h elf.h |
21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) | 21 | SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) |
22 | 22 | ||
23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes | 23 | # XXX: The "os" symlink is only used by arch/um/include/os.h, which includes |
@@ -44,6 +44,11 @@ ifneq ($(MAKEFILES-INCL),) | |||
44 | endif | 44 | endif |
45 | 45 | ||
46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include | 46 | ARCH_INCLUDE := -I$(ARCH_DIR)/include |
47 | ifneq ($(KBUILD_SRC),) | ||
48 | ARCH_INCLUDE += -I$(ARCH_DIR)/include2 | ||
49 | ARCH_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include | ||
50 | MRPROPER_DIRS += $(ARCH_DIR)/include2 | ||
51 | endif | ||
47 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) | 52 | SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH) |
48 | 53 | ||
49 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) | 54 | include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH) |
@@ -94,17 +99,18 @@ define archhelp | |||
94 | echo ' find in the kernel root.' | 99 | echo ' find in the kernel root.' |
95 | endef | 100 | endef |
96 | 101 | ||
102 | ifneq ($(KBUILD_SRC),) | ||
103 | $(shell mkdir -p $(ARCH_DIR) && ln -fsn $(srctree)/$(ARCH_DIR)/Kconfig_$(SUBARCH) $(ARCH_DIR)/Kconfig_arch) | ||
104 | CLEAN_FILES += $(ARCH_DIR)/Kconfig_arch | ||
105 | else | ||
97 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) | 106 | $(shell cd $(ARCH_DIR) && ln -sf Kconfig_$(SUBARCH) Kconfig_arch) |
107 | endif | ||
98 | 108 | ||
99 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) \ | 109 | prepare: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) |
100 | $(ARCH_DIR)/kernel/vmlinux.lds.S | ||
101 | 110 | ||
102 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static | 111 | LINK-$(CONFIG_LD_SCRIPT_STATIC) += -static |
103 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib | 112 | LINK-$(CONFIG_LD_SCRIPT_DYN) += -Wl,-rpath,/lib |
104 | 113 | ||
105 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_STATIC) := uml.lds.S | ||
106 | LD_SCRIPT-$(CONFIG_LD_SCRIPT_DYN) := dyn.lds.S | ||
107 | |||
108 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT | 114 | CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT |
109 | CONFIG_KERNEL_STACK_ORDER ?= 2 | 115 | CONFIG_KERNEL_STACK_ORDER ?= 2 |
110 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) | 116 | STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) |
@@ -126,7 +132,7 @@ define cmd_vmlinux__ | |||
126 | $(CC) $(CFLAGS_vmlinux) -o $@ \ | 132 | $(CC) $(CFLAGS_vmlinux) -o $@ \ |
127 | -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ | 133 | -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ |
128 | -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ | 134 | -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ |
129 | -L/usr/lib -lutil \ | 135 | -lutil \ |
130 | $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ | 136 | $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) \ |
131 | FORCE ,$^) ; rm -f linux | 137 | FORCE ,$^) ; rm -f linux |
132 | endef | 138 | endef |
@@ -145,31 +151,42 @@ archclean: | |||
145 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ | 151 | @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ |
146 | -o -name '*.gcov' \) -type f -print | xargs rm -f | 152 | -o -name '*.gcov' \) -type f -print | xargs rm -f |
147 | 153 | ||
148 | #We need to re-preprocess this when the symlink dest changes. | ||
149 | #So we touch it when needed. | ||
150 | $(ARCH_DIR)/kernel/vmlinux.lds.S: FORCE | ||
151 | $(Q)if [ "$(shell readlink $@)" != "$(LD_SCRIPT-y)" ]; then \ | ||
152 | echo ' SYMLINK $@'; \ | ||
153 | ln -sf $(LD_SCRIPT-y) $@; \ | ||
154 | touch $@; \ | ||
155 | fi; | ||
156 | |||
157 | $(SYMLINK_HEADERS): | 154 | $(SYMLINK_HEADERS): |
158 | @echo ' SYMLINK $@' | 155 | @echo ' SYMLINK $@' |
156 | ifneq ($(KBUILD_SRC),) | ||
157 | ln -fsn $(srctree)/include/asm-um/$(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $@ | ||
158 | else | ||
159 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ | 159 | $(Q)cd $(TOPDIR)/$(dir $@) ; \ |
160 | ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) | 160 | ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) |
161 | endif | ||
161 | 162 | ||
162 | include/asm-um/arch: | 163 | include/asm-um/arch: |
163 | @echo ' SYMLINK $@' | 164 | @echo ' SYMLINK $@' |
165 | ifneq ($(KBUILD_SRC),) | ||
166 | $(Q)mkdir -p include/asm-um | ||
167 | $(Q)ln -fsn $(srctree)/include/asm-$(SUBARCH) include/asm-um/arch | ||
168 | else | ||
164 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch | 169 | $(Q)cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch |
170 | endif | ||
165 | 171 | ||
166 | $(ARCH_DIR)/include/sysdep: | 172 | $(ARCH_DIR)/include/sysdep: |
167 | @echo ' SYMLINK $@' | 173 | @echo ' SYMLINK $@' |
174 | ifneq ($(KBUILD_SRC),) | ||
175 | $(Q)mkdir -p $(ARCH_DIR)/include | ||
176 | $(Q)mkdir -p $(ARCH_DIR)/include2 | ||
177 | $(Q)ln -fsn sysdep-$(SUBARCH) $(ARCH_DIR)/include/sysdep | ||
178 | $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/include/sysdep-$(SUBARCH) $(ARCH_DIR)/include2/sysdep | ||
179 | else | ||
168 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep | 180 | $(Q)cd $(ARCH_DIR)/include && ln -sf sysdep-$(SUBARCH) sysdep |
181 | endif | ||
169 | 182 | ||
170 | $(ARCH_DIR)/os: | 183 | $(ARCH_DIR)/os: |
171 | @echo ' SYMLINK $@' | 184 | @echo ' SYMLINK $@' |
185 | ifneq ($(KBUILD_SRC),) | ||
186 | $(Q)ln -fsn $(srctree)/$(ARCH_DIR)/os-$(OS) $(ARCH_DIR)/os | ||
187 | else | ||
172 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os | 188 | $(Q)cd $(ARCH_DIR) && ln -sf os-$(OS) os |
189 | endif | ||
173 | 190 | ||
174 | # Generated files | 191 | # Generated files |
175 | define filechk_umlconfig | 192 | define filechk_umlconfig |
@@ -179,10 +196,31 @@ endef | |||
179 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h | 196 | $(ARCH_DIR)/include/uml-config.h : include/linux/autoconf.h |
180 | $(call filechk,umlconfig) | 197 | $(call filechk,umlconfig) |
181 | 198 | ||
199 | $(ARCH_DIR)/user-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/user-offsets.c | ||
200 | $(CC) $(USER_CFLAGS) -S -o $@ $< | ||
201 | |||
202 | $(ARCH_DIR)/user-offsets.h: $(ARCH_DIR)/user-offsets.s | ||
203 | $(call filechk,gen-asm-offsets) | ||
204 | |||
205 | CLEAN_FILES += $(ARCH_DIR)/user-offsets.s $(ARCH_DIR)/user-offsets.h | ||
206 | |||
207 | $(ARCH_DIR)/kernel-offsets.s: $(ARCH_DIR)/sys-$(SUBARCH)/kernel-offsets.c \ | ||
208 | $(ARCH_SYMLINKS) \ | ||
209 | $(SYS_DIR)/sc.h \ | ||
210 | include/asm include/linux/version.h \ | ||
211 | include/config/MARKER \ | ||
212 | $(ARCH_DIR)/include/user_constants.h | ||
213 | $(CC) $(CFLAGS) $(NOSTDINC_FLAGS) $(CPPFLAGS) -S -o $@ $< | ||
214 | |||
215 | $(ARCH_DIR)/kernel-offsets.h: $(ARCH_DIR)/kernel-offsets.s | ||
216 | $(call filechk,gen-asm-offsets) | ||
217 | |||
218 | CLEAN_FILES += $(ARCH_DIR)/kernel-offsets.s $(ARCH_DIR)/kernel-offsets.h | ||
219 | |||
182 | $(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task | 220 | $(ARCH_DIR)/include/task.h: $(ARCH_DIR)/util/mk_task |
183 | $(call filechk,gen_header) | 221 | $(call filechk,gen_header) |
184 | 222 | ||
185 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os/util/mk_user_constants | 223 | $(ARCH_DIR)/include/user_constants.h: $(ARCH_DIR)/os-$(OS)/util/mk_user_constants |
186 | $(call filechk,gen_header) | 224 | $(call filechk,gen_header) |
187 | 225 | ||
188 | $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants | 226 | $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants |
@@ -191,20 +229,20 @@ $(ARCH_DIR)/include/kern_constants.h: $(ARCH_DIR)/util/mk_constants | |||
191 | $(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs | 229 | $(ARCH_DIR)/include/skas_ptregs.h: $(ARCH_DIR)/kernel/skas/util/mk_ptregs |
192 | $(call filechk,gen_header) | 230 | $(call filechk,gen_header) |
193 | 231 | ||
194 | $(ARCH_DIR)/os/util/mk_user_constants: $(ARCH_DIR)/os/util FORCE ; | 232 | $(ARCH_DIR)/os-$(OS)/util/mk_user_constants: $(ARCH_DIR)/os-$(OS)/util FORCE ; |
195 | 233 | ||
196 | $(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ | 234 | $(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants: $(ARCH_DIR)/include/user_constants.h $(ARCH_DIR)/util \ |
197 | FORCE ; | 235 | FORCE ; |
198 | 236 | ||
199 | $(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; | 237 | $(ARCH_DIR)/kernel/skas/util/mk_ptregs: $(ARCH_DIR)/kernel/skas/util FORCE ; |
200 | 238 | ||
201 | $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h FORCE | 239 | $(ARCH_DIR)/util: scripts_basic $(SYS_DIR)/sc.h $(ARCH_DIR)/kernel-offsets.h FORCE |
202 | $(Q)$(MAKE) $(build)=$@ | 240 | $(Q)$(MAKE) $(build)=$@ |
203 | 241 | ||
204 | $(ARCH_DIR)/kernel/skas/util: scripts_basic FORCE | 242 | $(ARCH_DIR)/kernel/skas/util: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
205 | $(Q)$(MAKE) $(build)=$@ | 243 | $(Q)$(MAKE) $(build)=$@ |
206 | 244 | ||
207 | $(ARCH_DIR)/os/util: scripts_basic FORCE | 245 | $(ARCH_DIR)/os-$(OS)/util: scripts_basic FORCE |
208 | $(Q)$(MAKE) $(build)=$@ | 246 | $(Q)$(MAKE) $(build)=$@ |
209 | 247 | ||
210 | export SUBARCH USER_CFLAGS OS | 248 | export SUBARCH USER_CFLAGS OS |
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386 index f9e3c0f06541..29e182d5a83a 100644 --- a/arch/um/Makefile-i386 +++ b/arch/um/Makefile-i386 | |||
@@ -32,10 +32,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc | |||
32 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread | 32 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread |
33 | $(call filechk,gen_header) | 33 | $(call filechk,gen_header) |
34 | 34 | ||
35 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE | 35 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
36 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 36 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
37 | 37 | ||
38 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE | 38 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_DIR)/kernel-offsets.h FORCE |
39 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 39 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
40 | 40 | ||
41 | $(SYS_UTIL_DIR): scripts_basic include/asm FORCE | 41 | $(SYS_UTIL_DIR): scripts_basic include/asm FORCE |
diff --git a/arch/um/Makefile-x86_64 b/arch/um/Makefile-x86_64 index a77971133e91..32144562c279 100644 --- a/arch/um/Makefile-x86_64 +++ b/arch/um/Makefile-x86_64 | |||
@@ -23,10 +23,10 @@ $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc | |||
23 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread | 23 | $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread |
24 | $(call filechk,gen_header) | 24 | $(call filechk,gen_header) |
25 | 25 | ||
26 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic FORCE | 26 | $(SYS_UTIL_DIR)/mk_sc: scripts_basic $(ARCH_DIR)/user-offsets.h FORCE |
27 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 27 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
28 | 28 | ||
29 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE | 29 | $(SYS_UTIL_DIR)/mk_thread: scripts_basic $(GEN_HEADERS) $(ARCH_DIR)/kernel-offsets.h FORCE |
30 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ | 30 | $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@ |
31 | 31 | ||
32 | CLEAN_FILES += $(SYS_HEADERS) | 32 | CLEAN_FILES += $(SYS_HEADERS) |
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c index 0150038af795..14a12d6b3df6 100644 --- a/arch/um/drivers/chan_kern.c +++ b/arch/um/drivers/chan_kern.c | |||
@@ -20,9 +20,17 @@ | |||
20 | #include "os.h" | 20 | #include "os.h" |
21 | 21 | ||
22 | #ifdef CONFIG_NOCONFIG_CHAN | 22 | #ifdef CONFIG_NOCONFIG_CHAN |
23 | |||
24 | /* The printk's here are wrong because we are complaining that there is no | ||
25 | * output device, but printk is printing to that output device. The user will | ||
26 | * never see the error. printf would be better, except it can't run on a | ||
27 | * kernel stack because it will overflow it. | ||
28 | * Use printk for now since that will avoid crashing. | ||
29 | */ | ||
30 | |||
23 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) | 31 | static void *not_configged_init(char *str, int device, struct chan_opts *opts) |
24 | { | 32 | { |
25 | printf(KERN_ERR "Using a channel type which is configured out of " | 33 | printk(KERN_ERR "Using a channel type which is configured out of " |
26 | "UML\n"); | 34 | "UML\n"); |
27 | return(NULL); | 35 | return(NULL); |
28 | } | 36 | } |
@@ -30,27 +38,27 @@ static void *not_configged_init(char *str, int device, struct chan_opts *opts) | |||
30 | static int not_configged_open(int input, int output, int primary, void *data, | 38 | static int not_configged_open(int input, int output, int primary, void *data, |
31 | char **dev_out) | 39 | char **dev_out) |
32 | { | 40 | { |
33 | printf(KERN_ERR "Using a channel type which is configured out of " | 41 | printk(KERN_ERR "Using a channel type which is configured out of " |
34 | "UML\n"); | 42 | "UML\n"); |
35 | return(-ENODEV); | 43 | return(-ENODEV); |
36 | } | 44 | } |
37 | 45 | ||
38 | static void not_configged_close(int fd, void *data) | 46 | static void not_configged_close(int fd, void *data) |
39 | { | 47 | { |
40 | printf(KERN_ERR "Using a channel type which is configured out of " | 48 | printk(KERN_ERR "Using a channel type which is configured out of " |
41 | "UML\n"); | 49 | "UML\n"); |
42 | } | 50 | } |
43 | 51 | ||
44 | static int not_configged_read(int fd, char *c_out, void *data) | 52 | static int not_configged_read(int fd, char *c_out, void *data) |
45 | { | 53 | { |
46 | printf(KERN_ERR "Using a channel type which is configured out of " | 54 | printk(KERN_ERR "Using a channel type which is configured out of " |
47 | "UML\n"); | 55 | "UML\n"); |
48 | return(-EIO); | 56 | return(-EIO); |
49 | } | 57 | } |
50 | 58 | ||
51 | static int not_configged_write(int fd, const char *buf, int len, void *data) | 59 | static int not_configged_write(int fd, const char *buf, int len, void *data) |
52 | { | 60 | { |
53 | printf(KERN_ERR "Using a channel type which is configured out of " | 61 | printk(KERN_ERR "Using a channel type which is configured out of " |
54 | "UML\n"); | 62 | "UML\n"); |
55 | return(-EIO); | 63 | return(-EIO); |
56 | } | 64 | } |
@@ -58,7 +66,7 @@ static int not_configged_write(int fd, const char *buf, int len, void *data) | |||
58 | static int not_configged_console_write(int fd, const char *buf, int len, | 66 | static int not_configged_console_write(int fd, const char *buf, int len, |
59 | void *data) | 67 | void *data) |
60 | { | 68 | { |
61 | printf(KERN_ERR "Using a channel type which is configured out of " | 69 | printk(KERN_ERR "Using a channel type which is configured out of " |
62 | "UML\n"); | 70 | "UML\n"); |
63 | return(-EIO); | 71 | return(-EIO); |
64 | } | 72 | } |
@@ -66,7 +74,7 @@ static int not_configged_console_write(int fd, const char *buf, int len, | |||
66 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, | 74 | static int not_configged_window_size(int fd, void *data, unsigned short *rows, |
67 | unsigned short *cols) | 75 | unsigned short *cols) |
68 | { | 76 | { |
69 | printf(KERN_ERR "Using a channel type which is configured out of " | 77 | printk(KERN_ERR "Using a channel type which is configured out of " |
70 | "UML\n"); | 78 | "UML\n"); |
71 | return(-ENODEV); | 79 | return(-ENODEV); |
72 | } | 80 | } |
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c index d0f97127adf6..025d3be8aca4 100644 --- a/arch/um/drivers/line.c +++ b/arch/um/drivers/line.c | |||
@@ -462,12 +462,15 @@ out: | |||
462 | return err; | 462 | return err; |
463 | } | 463 | } |
464 | 464 | ||
465 | static void unregister_winch(struct tty_struct *tty); | ||
466 | |||
465 | void line_close(struct tty_struct *tty, struct file * filp) | 467 | void line_close(struct tty_struct *tty, struct file * filp) |
466 | { | 468 | { |
467 | struct line *line = tty->driver_data; | 469 | struct line *line = tty->driver_data; |
468 | 470 | ||
469 | /* XXX: I assume this should be called in process context, not with interrupt | 471 | /* XXX: I assume this should be called in process context, not with |
470 | * disabled!*/ | 472 | * interrupts disabled! |
473 | */ | ||
471 | spin_lock_irq(&line->lock); | 474 | spin_lock_irq(&line->lock); |
472 | 475 | ||
473 | /* We ignore the error anyway! */ | 476 | /* We ignore the error anyway! */ |
@@ -478,6 +481,12 @@ void line_close(struct tty_struct *tty, struct file * filp) | |||
478 | line_disable(tty, -1); | 481 | line_disable(tty, -1); |
479 | tty->driver_data = NULL; | 482 | tty->driver_data = NULL; |
480 | } | 483 | } |
484 | |||
485 | if((line->count == 0) && line->sigio){ | ||
486 | unregister_winch(tty); | ||
487 | line->sigio = 0; | ||
488 | } | ||
489 | |||
481 | spin_unlock_irq(&line->lock); | 490 | spin_unlock_irq(&line->lock); |
482 | } | 491 | } |
483 | 492 | ||
@@ -729,6 +738,34 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty) | |||
729 | up(&winch_handler_sem); | 738 | up(&winch_handler_sem); |
730 | } | 739 | } |
731 | 740 | ||
741 | static void unregister_winch(struct tty_struct *tty) | ||
742 | { | ||
743 | struct list_head *ele; | ||
744 | struct winch *winch, *found = NULL; | ||
745 | |||
746 | down(&winch_handler_sem); | ||
747 | list_for_each(ele, &winch_handlers){ | ||
748 | winch = list_entry(ele, struct winch, list); | ||
749 | if(winch->tty == tty){ | ||
750 | found = winch; | ||
751 | break; | ||
752 | } | ||
753 | } | ||
754 | |||
755 | if(found == NULL) | ||
756 | goto out; | ||
757 | |||
758 | if(winch->pid != -1) | ||
759 | os_kill_process(winch->pid, 1); | ||
760 | |||
761 | free_irq_by_irq_and_dev(WINCH_IRQ, winch); | ||
762 | free_irq(WINCH_IRQ, winch); | ||
763 | list_del(&winch->list); | ||
764 | kfree(winch); | ||
765 | out: | ||
766 | up(&winch_handler_sem); | ||
767 | } | ||
768 | |||
732 | static void winch_cleanup(void) | 769 | static void winch_cleanup(void) |
733 | { | 770 | { |
734 | struct list_head *ele; | 771 | struct list_head *ele; |
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c index faf714e87b5b..217438cdef33 100644 --- a/arch/um/drivers/mcast_kern.c +++ b/arch/um/drivers/mcast_kern.c | |||
@@ -73,7 +73,6 @@ int mcast_setup(char *str, char **mac_out, void *data) | |||
73 | struct mcast_init *init = data; | 73 | struct mcast_init *init = data; |
74 | char *port_str = NULL, *ttl_str = NULL, *remain; | 74 | char *port_str = NULL, *ttl_str = NULL, *remain; |
75 | char *last; | 75 | char *last; |
76 | int n; | ||
77 | 76 | ||
78 | *init = ((struct mcast_init) | 77 | *init = ((struct mcast_init) |
79 | { .addr = "239.192.168.1", | 78 | { .addr = "239.192.168.1", |
@@ -89,13 +88,12 @@ int mcast_setup(char *str, char **mac_out, void *data) | |||
89 | } | 88 | } |
90 | 89 | ||
91 | if(port_str != NULL){ | 90 | if(port_str != NULL){ |
92 | n = simple_strtoul(port_str, &last, 10); | 91 | init->port = simple_strtoul(port_str, &last, 10); |
93 | if((*last != '\0') || (last == port_str)){ | 92 | if((*last != '\0') || (last == port_str)){ |
94 | printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", | 93 | printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", |
95 | port_str); | 94 | port_str); |
96 | return(0); | 95 | return(0); |
97 | } | 96 | } |
98 | init->port = htons(n); | ||
99 | } | 97 | } |
100 | 98 | ||
101 | if(ttl_str != NULL){ | 99 | if(ttl_str != NULL){ |
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c index 0fe1d9fa9139..7a0d115b29d0 100644 --- a/arch/um/drivers/mcast_user.c +++ b/arch/um/drivers/mcast_user.c | |||
@@ -38,7 +38,7 @@ static struct sockaddr_in *new_addr(char *addr, unsigned short port) | |||
38 | } | 38 | } |
39 | sin->sin_family = AF_INET; | 39 | sin->sin_family = AF_INET; |
40 | sin->sin_addr.s_addr = in_aton(addr); | 40 | sin->sin_addr.s_addr = in_aton(addr); |
41 | sin->sin_port = port; | 41 | sin->sin_port = htons(port); |
42 | return(sin); | 42 | return(sin); |
43 | } | 43 | } |
44 | 44 | ||
@@ -55,28 +55,25 @@ static int mcast_open(void *data) | |||
55 | struct mcast_data *pri = data; | 55 | struct mcast_data *pri = data; |
56 | struct sockaddr_in *sin = pri->mcast_addr; | 56 | struct sockaddr_in *sin = pri->mcast_addr; |
57 | struct ip_mreq mreq; | 57 | struct ip_mreq mreq; |
58 | int fd, yes = 1; | 58 | int fd = -EINVAL, yes = 1, err = -EINVAL;; |
59 | 59 | ||
60 | 60 | ||
61 | if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) { | 61 | if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) |
62 | fd = -EINVAL; | ||
63 | goto out; | 62 | goto out; |
64 | } | ||
65 | 63 | ||
66 | fd = socket(AF_INET, SOCK_DGRAM, 0); | 64 | fd = socket(AF_INET, SOCK_DGRAM, 0); |
65 | |||
67 | if (fd < 0){ | 66 | if (fd < 0){ |
68 | printk("mcast_open : data socket failed, errno = %d\n", | 67 | printk("mcast_open : data socket failed, errno = %d\n", |
69 | errno); | 68 | errno); |
70 | fd = -ENOMEM; | 69 | fd = -errno; |
71 | goto out; | 70 | goto out; |
72 | } | 71 | } |
73 | 72 | ||
74 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { | 73 | if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { |
75 | printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", | 74 | printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", |
76 | errno); | 75 | errno); |
77 | os_close_file(fd); | 76 | goto out_close; |
78 | fd = -EINVAL; | ||
79 | goto out; | ||
80 | } | 77 | } |
81 | 78 | ||
82 | /* set ttl according to config */ | 79 | /* set ttl according to config */ |
@@ -84,26 +81,20 @@ static int mcast_open(void *data) | |||
84 | sizeof(pri->ttl)) < 0) { | 81 | sizeof(pri->ttl)) < 0) { |
85 | printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", | 82 | printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", |
86 | errno); | 83 | errno); |
87 | os_close_file(fd); | 84 | goto out_close; |
88 | fd = -EINVAL; | ||
89 | goto out; | ||
90 | } | 85 | } |
91 | 86 | ||
92 | /* set LOOP, so data does get fed back to local sockets */ | 87 | /* set LOOP, so data does get fed back to local sockets */ |
93 | if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { | 88 | if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { |
94 | printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", | 89 | printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", |
95 | errno); | 90 | errno); |
96 | os_close_file(fd); | 91 | goto out_close; |
97 | fd = -EINVAL; | ||
98 | goto out; | ||
99 | } | 92 | } |
100 | 93 | ||
101 | /* bind socket to mcast address */ | 94 | /* bind socket to mcast address */ |
102 | if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { | 95 | if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { |
103 | printk("mcast_open : data bind failed, errno = %d\n", errno); | 96 | printk("mcast_open : data bind failed, errno = %d\n", errno); |
104 | os_close_file(fd); | 97 | goto out_close; |
105 | fd = -EINVAL; | ||
106 | goto out; | ||
107 | } | 98 | } |
108 | 99 | ||
109 | /* subscribe to the multicast group */ | 100 | /* subscribe to the multicast group */ |
@@ -117,12 +108,15 @@ static int mcast_open(void *data) | |||
117 | "interface on the host.\n"); | 108 | "interface on the host.\n"); |
118 | printk("eth0 should be configured in order to use the " | 109 | printk("eth0 should be configured in order to use the " |
119 | "multicast transport.\n"); | 110 | "multicast transport.\n"); |
120 | os_close_file(fd); | 111 | goto out_close; |
121 | fd = -EINVAL; | ||
122 | } | 112 | } |
123 | 113 | ||
124 | out: | 114 | out: |
125 | return(fd); | 115 | return fd; |
116 | |||
117 | out_close: | ||
118 | os_close_file(fd); | ||
119 | return err; | ||
126 | } | 120 | } |
127 | 121 | ||
128 | static void mcast_close(int fd, void *data) | 122 | static void mcast_close(int fd, void *data) |
@@ -164,14 +158,3 @@ struct net_user_info mcast_user_info = { | |||
164 | .delete_address = NULL, | 158 | .delete_address = NULL, |
165 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER | 159 | .max_packet = MAX_PACKET - ETH_HEADER_OTHER |
166 | }; | 160 | }; |
167 | |||
168 | /* | ||
169 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
170 | * Emacs will notice this stuff at the end of the file and automatically | ||
171 | * adjust the settings for this buffer only. This must remain at the end | ||
172 | * of the file. | ||
173 | * --------------------------------------------------------------------------- | ||
174 | * Local variables: | ||
175 | * c-file-style: "linux" | ||
176 | * End: | ||
177 | */ | ||
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c index 9a56ff94308d..88f956c34fed 100644 --- a/arch/um/drivers/ubd_kern.c +++ b/arch/um/drivers/ubd_kern.c | |||
@@ -55,7 +55,7 @@ | |||
55 | #include "mem_kern.h" | 55 | #include "mem_kern.h" |
56 | #include "cow.h" | 56 | #include "cow.h" |
57 | 57 | ||
58 | enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP }; | 58 | enum ubd_req { UBD_READ, UBD_WRITE }; |
59 | 59 | ||
60 | struct io_thread_req { | 60 | struct io_thread_req { |
61 | enum ubd_req op; | 61 | enum ubd_req op; |
@@ -68,8 +68,6 @@ struct io_thread_req { | |||
68 | unsigned long sector_mask; | 68 | unsigned long sector_mask; |
69 | unsigned long long cow_offset; | 69 | unsigned long long cow_offset; |
70 | unsigned long bitmap_words[2]; | 70 | unsigned long bitmap_words[2]; |
71 | int map_fd; | ||
72 | unsigned long long map_offset; | ||
73 | int error; | 71 | int error; |
74 | }; | 72 | }; |
75 | 73 | ||
@@ -122,10 +120,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
122 | 120 | ||
123 | #define MAX_DEV (8) | 121 | #define MAX_DEV (8) |
124 | 122 | ||
125 | /* Changed in early boot */ | ||
126 | static int ubd_do_mmap = 0; | ||
127 | #define UBD_MMAP_BLOCK_SIZE PAGE_SIZE | ||
128 | |||
129 | static struct block_device_operations ubd_blops = { | 123 | static struct block_device_operations ubd_blops = { |
130 | .owner = THIS_MODULE, | 124 | .owner = THIS_MODULE, |
131 | .open = ubd_open, | 125 | .open = ubd_open, |
@@ -175,12 +169,6 @@ struct ubd { | |||
175 | int no_cow; | 169 | int no_cow; |
176 | struct cow cow; | 170 | struct cow cow; |
177 | struct platform_device pdev; | 171 | struct platform_device pdev; |
178 | |||
179 | int map_writes; | ||
180 | int map_reads; | ||
181 | int nomap_writes; | ||
182 | int nomap_reads; | ||
183 | int write_maps; | ||
184 | }; | 172 | }; |
185 | 173 | ||
186 | #define DEFAULT_COW { \ | 174 | #define DEFAULT_COW { \ |
@@ -200,11 +188,6 @@ struct ubd { | |||
200 | .openflags = OPEN_FLAGS, \ | 188 | .openflags = OPEN_FLAGS, \ |
201 | .no_cow = 0, \ | 189 | .no_cow = 0, \ |
202 | .cow = DEFAULT_COW, \ | 190 | .cow = DEFAULT_COW, \ |
203 | .map_writes = 0, \ | ||
204 | .map_reads = 0, \ | ||
205 | .nomap_writes = 0, \ | ||
206 | .nomap_reads = 0, \ | ||
207 | .write_maps = 0, \ | ||
208 | } | 191 | } |
209 | 192 | ||
210 | struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; | 193 | struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; |
@@ -314,13 +297,6 @@ static int ubd_setup_common(char *str, int *index_out) | |||
314 | int major; | 297 | int major; |
315 | 298 | ||
316 | str++; | 299 | str++; |
317 | if(!strcmp(str, "mmap")){ | ||
318 | CHOOSE_MODE(printk("mmap not supported by the ubd " | ||
319 | "driver in tt mode\n"), | ||
320 | ubd_do_mmap = 1); | ||
321 | return(0); | ||
322 | } | ||
323 | |||
324 | if(!strcmp(str, "sync")){ | 300 | if(!strcmp(str, "sync")){ |
325 | global_openflags = of_sync(global_openflags); | 301 | global_openflags = of_sync(global_openflags); |
326 | return(0); | 302 | return(0); |
@@ -524,7 +500,7 @@ static void ubd_handler(void) | |||
524 | { | 500 | { |
525 | struct io_thread_req req; | 501 | struct io_thread_req req; |
526 | struct request *rq = elv_next_request(ubd_queue); | 502 | struct request *rq = elv_next_request(ubd_queue); |
527 | int n, err; | 503 | int n; |
528 | 504 | ||
529 | do_ubd = NULL; | 505 | do_ubd = NULL; |
530 | intr_count++; | 506 | intr_count++; |
@@ -538,19 +514,6 @@ static void ubd_handler(void) | |||
538 | return; | 514 | return; |
539 | } | 515 | } |
540 | 516 | ||
541 | if((req.op != UBD_MMAP) && | ||
542 | ((req.offset != ((__u64) (rq->sector)) << 9) || | ||
543 | (req.length != (rq->current_nr_sectors) << 9))) | ||
544 | panic("I/O op mismatch"); | ||
545 | |||
546 | if(req.map_fd != -1){ | ||
547 | err = physmem_subst_mapping(req.buffer, req.map_fd, | ||
548 | req.map_offset, 1); | ||
549 | if(err) | ||
550 | printk("ubd_handler - physmem_subst_mapping failed, " | ||
551 | "err = %d\n", -err); | ||
552 | } | ||
553 | |||
554 | ubd_finish(rq, req.error); | 517 | ubd_finish(rq, req.error); |
555 | reactivate_fd(thread_fd, UBD_IRQ); | 518 | reactivate_fd(thread_fd, UBD_IRQ); |
556 | do_ubd_request(ubd_queue); | 519 | do_ubd_request(ubd_queue); |
@@ -583,14 +546,10 @@ static int ubd_file_size(struct ubd *dev, __u64 *size_out) | |||
583 | 546 | ||
584 | static void ubd_close(struct ubd *dev) | 547 | static void ubd_close(struct ubd *dev) |
585 | { | 548 | { |
586 | if(ubd_do_mmap) | ||
587 | physmem_forget_descriptor(dev->fd); | ||
588 | os_close_file(dev->fd); | 549 | os_close_file(dev->fd); |
589 | if(dev->cow.file == NULL) | 550 | if(dev->cow.file == NULL) |
590 | return; | 551 | return; |
591 | 552 | ||
592 | if(ubd_do_mmap) | ||
593 | physmem_forget_descriptor(dev->cow.fd); | ||
594 | os_close_file(dev->cow.fd); | 553 | os_close_file(dev->cow.fd); |
595 | vfree(dev->cow.bitmap); | 554 | vfree(dev->cow.bitmap); |
596 | dev->cow.bitmap = NULL; | 555 | dev->cow.bitmap = NULL; |
@@ -1010,94 +969,13 @@ static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, | |||
1010 | req->bitmap_words, bitmap_len); | 969 | req->bitmap_words, bitmap_len); |
1011 | } | 970 | } |
1012 | 971 | ||
1013 | static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset) | ||
1014 | { | ||
1015 | __u64 sector; | ||
1016 | unsigned char *bitmap; | ||
1017 | int bit, i; | ||
1018 | |||
1019 | /* mmap must have been requested on the command line */ | ||
1020 | if(!ubd_do_mmap) | ||
1021 | return(-1); | ||
1022 | |||
1023 | /* The buffer must be page aligned */ | ||
1024 | if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0) | ||
1025 | return(-1); | ||
1026 | |||
1027 | /* The request must be a page long */ | ||
1028 | if((req->current_nr_sectors << 9) != PAGE_SIZE) | ||
1029 | return(-1); | ||
1030 | |||
1031 | if(dev->cow.file == NULL) | ||
1032 | return(dev->fd); | ||
1033 | |||
1034 | sector = offset >> 9; | ||
1035 | bitmap = (unsigned char *) dev->cow.bitmap; | ||
1036 | bit = ubd_test_bit(sector, bitmap); | ||
1037 | |||
1038 | for(i = 1; i < req->current_nr_sectors; i++){ | ||
1039 | if(ubd_test_bit(sector + i, bitmap) != bit) | ||
1040 | return(-1); | ||
1041 | } | ||
1042 | |||
1043 | if(bit || (rq_data_dir(req) == WRITE)) | ||
1044 | offset += dev->cow.data_offset; | ||
1045 | |||
1046 | /* The data on disk must be page aligned */ | ||
1047 | if((offset % UBD_MMAP_BLOCK_SIZE) != 0) | ||
1048 | return(-1); | ||
1049 | |||
1050 | return(bit ? dev->fd : dev->cow.fd); | ||
1051 | } | ||
1052 | |||
1053 | static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, | ||
1054 | struct request *req, | ||
1055 | struct io_thread_req *io_req) | ||
1056 | { | ||
1057 | int err; | ||
1058 | |||
1059 | if(rq_data_dir(req) == WRITE){ | ||
1060 | /* Writes are almost no-ops since the new data is already in the | ||
1061 | * host page cache | ||
1062 | */ | ||
1063 | dev->map_writes++; | ||
1064 | if(dev->cow.file != NULL) | ||
1065 | cowify_bitmap(io_req->offset, io_req->length, | ||
1066 | &io_req->sector_mask, &io_req->cow_offset, | ||
1067 | dev->cow.bitmap, dev->cow.bitmap_offset, | ||
1068 | io_req->bitmap_words, | ||
1069 | dev->cow.bitmap_len); | ||
1070 | } | ||
1071 | else { | ||
1072 | int w; | ||
1073 | |||
1074 | if((dev->cow.file != NULL) && (fd == dev->cow.fd)) | ||
1075 | w = 0; | ||
1076 | else w = dev->openflags.w; | ||
1077 | |||
1078 | if((dev->cow.file != NULL) && (fd == dev->fd)) | ||
1079 | offset += dev->cow.data_offset; | ||
1080 | |||
1081 | err = physmem_subst_mapping(req->buffer, fd, offset, w); | ||
1082 | if(err){ | ||
1083 | printk("physmem_subst_mapping failed, err = %d\n", | ||
1084 | -err); | ||
1085 | return(1); | ||
1086 | } | ||
1087 | dev->map_reads++; | ||
1088 | } | ||
1089 | io_req->op = UBD_MMAP; | ||
1090 | io_req->buffer = req->buffer; | ||
1091 | return(0); | ||
1092 | } | ||
1093 | |||
1094 | /* Called with ubd_io_lock held */ | 972 | /* Called with ubd_io_lock held */ |
1095 | static int prepare_request(struct request *req, struct io_thread_req *io_req) | 973 | static int prepare_request(struct request *req, struct io_thread_req *io_req) |
1096 | { | 974 | { |
1097 | struct gendisk *disk = req->rq_disk; | 975 | struct gendisk *disk = req->rq_disk; |
1098 | struct ubd *dev = disk->private_data; | 976 | struct ubd *dev = disk->private_data; |
1099 | __u64 offset; | 977 | __u64 offset; |
1100 | int len, fd; | 978 | int len; |
1101 | 979 | ||
1102 | if(req->rq_status == RQ_INACTIVE) return(1); | 980 | if(req->rq_status == RQ_INACTIVE) return(1); |
1103 | 981 | ||
@@ -1114,34 +992,12 @@ static int prepare_request(struct request *req, struct io_thread_req *io_req) | |||
1114 | 992 | ||
1115 | io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; | 993 | io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; |
1116 | io_req->fds[1] = dev->fd; | 994 | io_req->fds[1] = dev->fd; |
1117 | io_req->map_fd = -1; | ||
1118 | io_req->cow_offset = -1; | 995 | io_req->cow_offset = -1; |
1119 | io_req->offset = offset; | 996 | io_req->offset = offset; |
1120 | io_req->length = len; | 997 | io_req->length = len; |
1121 | io_req->error = 0; | 998 | io_req->error = 0; |
1122 | io_req->sector_mask = 0; | 999 | io_req->sector_mask = 0; |
1123 | 1000 | ||
1124 | fd = mmap_fd(req, dev, io_req->offset); | ||
1125 | if(fd > 0){ | ||
1126 | /* If mmapping is otherwise OK, but the first access to the | ||
1127 | * page is a write, then it's not mapped in yet. So we have | ||
1128 | * to write the data to disk first, then we can map the disk | ||
1129 | * page in and continue normally from there. | ||
1130 | */ | ||
1131 | if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){ | ||
1132 | io_req->map_fd = dev->fd; | ||
1133 | io_req->map_offset = io_req->offset + | ||
1134 | dev->cow.data_offset; | ||
1135 | dev->write_maps++; | ||
1136 | } | ||
1137 | else return(prepare_mmap_request(dev, fd, io_req->offset, req, | ||
1138 | io_req)); | ||
1139 | } | ||
1140 | |||
1141 | if(rq_data_dir(req) == READ) | ||
1142 | dev->nomap_reads++; | ||
1143 | else dev->nomap_writes++; | ||
1144 | |||
1145 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; | 1001 | io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE; |
1146 | io_req->offsets[0] = 0; | 1002 | io_req->offsets[0] = 0; |
1147 | io_req->offsets[1] = dev->cow.data_offset; | 1003 | io_req->offsets[1] = dev->cow.data_offset; |
@@ -1229,143 +1085,6 @@ static int ubd_ioctl(struct inode * inode, struct file * file, | |||
1229 | return(-EINVAL); | 1085 | return(-EINVAL); |
1230 | } | 1086 | } |
1231 | 1087 | ||
1232 | static int ubd_check_remapped(int fd, unsigned long address, int is_write, | ||
1233 | __u64 offset) | ||
1234 | { | ||
1235 | __u64 bitmap_offset; | ||
1236 | unsigned long new_bitmap[2]; | ||
1237 | int i, err, n; | ||
1238 | |||
1239 | /* If it's not a write access, we can't do anything about it */ | ||
1240 | if(!is_write) | ||
1241 | return(0); | ||
1242 | |||
1243 | /* We have a write */ | ||
1244 | for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){ | ||
1245 | struct ubd *dev = &ubd_dev[i]; | ||
1246 | |||
1247 | if((dev->fd != fd) && (dev->cow.fd != fd)) | ||
1248 | continue; | ||
1249 | |||
1250 | /* It's a write to a ubd device */ | ||
1251 | |||
1252 | /* This should be impossible now */ | ||
1253 | if(!dev->openflags.w){ | ||
1254 | /* It's a write access on a read-only device - probably | ||
1255 | * shouldn't happen. If the kernel is trying to change | ||
1256 | * something with no intention of writing it back out, | ||
1257 | * then this message will clue us in that this needs | ||
1258 | * fixing | ||
1259 | */ | ||
1260 | printk("Write access to mapped page from readonly ubd " | ||
1261 | "device %d\n", i); | ||
1262 | return(0); | ||
1263 | } | ||
1264 | |||
1265 | /* It's a write to a writeable ubd device - it must be COWed | ||
1266 | * because, otherwise, the page would have been mapped in | ||
1267 | * writeable | ||
1268 | */ | ||
1269 | |||
1270 | if(!dev->cow.file) | ||
1271 | panic("Write fault on writeable non-COW ubd device %d", | ||
1272 | i); | ||
1273 | |||
1274 | /* It should also be an access to the backing file since the | ||
1275 | * COW pages should be mapped in read-write | ||
1276 | */ | ||
1277 | |||
1278 | if(fd == dev->fd) | ||
1279 | panic("Write fault on a backing page of ubd " | ||
1280 | "device %d\n", i); | ||
1281 | |||
1282 | /* So, we do the write, copying the backing data to the COW | ||
1283 | * file... | ||
1284 | */ | ||
1285 | |||
1286 | err = os_seek_file(dev->fd, offset + dev->cow.data_offset); | ||
1287 | if(err < 0) | ||
1288 | panic("Couldn't seek to %lld in COW file of ubd " | ||
1289 | "device %d, err = %d", | ||
1290 | offset + dev->cow.data_offset, i, -err); | ||
1291 | |||
1292 | n = os_write_file(dev->fd, (void *) address, PAGE_SIZE); | ||
1293 | if(n != PAGE_SIZE) | ||
1294 | panic("Couldn't copy data to COW file of ubd " | ||
1295 | "device %d, err = %d", i, -n); | ||
1296 | |||
1297 | /* ... updating the COW bitmap... */ | ||
1298 | |||
1299 | cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, | ||
1300 | dev->cow.bitmap, dev->cow.bitmap_offset, | ||
1301 | new_bitmap, dev->cow.bitmap_len); | ||
1302 | |||
1303 | err = os_seek_file(dev->fd, bitmap_offset); | ||
1304 | if(err < 0) | ||
1305 | panic("Couldn't seek to %lld in COW file of ubd " | ||
1306 | "device %d, err = %d", bitmap_offset, i, -err); | ||
1307 | |||
1308 | n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap)); | ||
1309 | if(n != sizeof(new_bitmap)) | ||
1310 | panic("Couldn't update bitmap of ubd device %d, " | ||
1311 | "err = %d", i, -n); | ||
1312 | |||
1313 | /* Maybe we can map the COW page in, and maybe we can't. If | ||
1314 | * it is a pre-V3 COW file, we can't, since the alignment will | ||
1315 | * be wrong. If it is a V3 or later COW file which has been | ||
1316 | * moved to a system with a larger page size, then maybe we | ||
1317 | * can't, depending on the exact location of the page. | ||
1318 | */ | ||
1319 | |||
1320 | offset += dev->cow.data_offset; | ||
1321 | |||
1322 | /* Remove the remapping, putting the original anonymous page | ||
1323 | * back. If the COW file can be mapped in, that is done. | ||
1324 | * Otherwise, the COW page is read in. | ||
1325 | */ | ||
1326 | |||
1327 | if(!physmem_remove_mapping((void *) address)) | ||
1328 | panic("Address 0x%lx not remapped by ubd device %d", | ||
1329 | address, i); | ||
1330 | if((offset % UBD_MMAP_BLOCK_SIZE) == 0) | ||
1331 | physmem_subst_mapping((void *) address, dev->fd, | ||
1332 | offset, 1); | ||
1333 | else { | ||
1334 | err = os_seek_file(dev->fd, offset); | ||
1335 | if(err < 0) | ||
1336 | panic("Couldn't seek to %lld in COW file of " | ||
1337 | "ubd device %d, err = %d", offset, i, | ||
1338 | -err); | ||
1339 | |||
1340 | n = os_read_file(dev->fd, (void *) address, PAGE_SIZE); | ||
1341 | if(n != PAGE_SIZE) | ||
1342 | panic("Failed to read page from offset %llx of " | ||
1343 | "COW file of ubd device %d, err = %d", | ||
1344 | offset, i, -n); | ||
1345 | } | ||
1346 | |||
1347 | return(1); | ||
1348 | } | ||
1349 | |||
1350 | /* It's not a write on a ubd device */ | ||
1351 | return(0); | ||
1352 | } | ||
1353 | |||
1354 | static struct remapper ubd_remapper = { | ||
1355 | .list = LIST_HEAD_INIT(ubd_remapper.list), | ||
1356 | .proc = ubd_check_remapped, | ||
1357 | }; | ||
1358 | |||
1359 | static int ubd_remapper_setup(void) | ||
1360 | { | ||
1361 | if(ubd_do_mmap) | ||
1362 | register_remapper(&ubd_remapper); | ||
1363 | |||
1364 | return(0); | ||
1365 | } | ||
1366 | |||
1367 | __initcall(ubd_remapper_setup); | ||
1368 | |||
1369 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) | 1088 | static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) |
1370 | { | 1089 | { |
1371 | struct uml_stat buf1, buf2; | 1090 | struct uml_stat buf1, buf2; |
@@ -1568,15 +1287,6 @@ void do_io(struct io_thread_req *req) | |||
1568 | int err; | 1287 | int err; |
1569 | __u64 off; | 1288 | __u64 off; |
1570 | 1289 | ||
1571 | if(req->op == UBD_MMAP){ | ||
1572 | /* Touch the page to force the host to do any necessary IO to | ||
1573 | * get it into memory | ||
1574 | */ | ||
1575 | n = *((volatile int *) req->buffer); | ||
1576 | req->error = update_bitmap(req); | ||
1577 | return; | ||
1578 | } | ||
1579 | |||
1580 | nsectors = req->length / req->sectorsize; | 1290 | nsectors = req->length / req->sectorsize; |
1581 | start = 0; | 1291 | start = 0; |
1582 | do { | 1292 | do { |
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c index 7917b9d1cec8..a4fdf3584ad2 100644 --- a/arch/um/drivers/xterm_kern.c +++ b/arch/um/drivers/xterm_kern.c | |||
@@ -7,7 +7,6 @@ | |||
7 | #include "linux/slab.h" | 7 | #include "linux/slab.h" |
8 | #include "linux/signal.h" | 8 | #include "linux/signal.h" |
9 | #include "linux/interrupt.h" | 9 | #include "linux/interrupt.h" |
10 | #include "asm/semaphore.h" | ||
11 | #include "asm/irq.h" | 10 | #include "asm/irq.h" |
12 | #include "irq_user.h" | 11 | #include "irq_user.h" |
13 | #include "irq_kern.h" | 12 | #include "irq_kern.h" |
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h new file mode 100644 index 000000000000..d705daa2d854 --- /dev/null +++ b/arch/um/include/common-offsets.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* for use by sys-$SUBARCH/kernel-offsets.c */ | ||
2 | |||
3 | OFFSET(TASK_REGS, task_struct, thread.regs); | ||
4 | OFFSET(TASK_PID, task_struct, pid); | ||
5 | DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); | ||
6 | DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); | ||
7 | DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); | ||
8 | DEFINE_STR(UM_KERN_ALERT, KERN_ALERT); | ||
9 | DEFINE_STR(UM_KERN_CRIT, KERN_CRIT); | ||
10 | DEFINE_STR(UM_KERN_ERR, KERN_ERR); | ||
11 | DEFINE_STR(UM_KERN_WARNING, KERN_WARNING); | ||
12 | DEFINE_STR(UM_KERN_NOTICE, KERN_NOTICE); | ||
13 | DEFINE_STR(UM_KERN_INFO, KERN_INFO); | ||
14 | DEFINE_STR(UM_KERN_DEBUG, KERN_DEBUG); | ||
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h index 15389c886b41..e5fec5570199 100644 --- a/arch/um/include/kern_util.h +++ b/arch/um/include/kern_util.h | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include "linux/threads.h" | 9 | #include "linux/threads.h" |
10 | #include "sysdep/ptrace.h" | 10 | #include "sysdep/ptrace.h" |
11 | #include "sysdep/faultinfo.h" | ||
11 | 12 | ||
12 | extern int ncpus; | 13 | extern int ncpus; |
13 | extern char *linux_prog; | 14 | extern char *linux_prog; |
@@ -31,8 +32,8 @@ extern int current_pid(void); | |||
31 | extern unsigned long alloc_stack(int order, int atomic); | 32 | extern unsigned long alloc_stack(int order, int atomic); |
32 | extern int do_signal(void); | 33 | extern int do_signal(void); |
33 | extern int is_stack_fault(unsigned long sp); | 34 | extern int is_stack_fault(unsigned long sp); |
34 | extern unsigned long segv(unsigned long address, unsigned long ip, | 35 | extern unsigned long segv(struct faultinfo fi, unsigned long ip, |
35 | int is_write, int is_user, void *sc); | 36 | int is_user, void *sc); |
36 | extern int handle_page_fault(unsigned long address, unsigned long ip, | 37 | extern int handle_page_fault(unsigned long address, unsigned long ip, |
37 | int is_write, int is_user, int *code_out); | 38 | int is_write, int is_user, int *code_out); |
38 | extern void syscall_ready(void); | 39 | extern void syscall_ready(void); |
@@ -82,7 +83,7 @@ extern void timer_irq(union uml_pt_regs *regs); | |||
82 | extern void unprotect_stack(unsigned long stack); | 83 | extern void unprotect_stack(unsigned long stack); |
83 | extern void do_uml_exitcalls(void); | 84 | extern void do_uml_exitcalls(void); |
84 | extern int attach_debugger(int idle_pid, int pid, int stop); | 85 | extern int attach_debugger(int idle_pid, int pid, int stop); |
85 | extern void bad_segv(unsigned long address, unsigned long ip, int is_write); | 86 | extern void bad_segv(struct faultinfo fi, unsigned long ip); |
86 | extern int config_gdb(char *str); | 87 | extern int config_gdb(char *str); |
87 | extern int remove_gdb(void); | 88 | extern int remove_gdb(void); |
88 | extern char *uml_strdup(char *string); | 89 | extern char *uml_strdup(char *string); |
diff --git a/arch/um/include/os.h b/arch/um/include/os.h index 07340c8cf203..d246d5a24609 100644 --- a/arch/um/include/os.h +++ b/arch/um/include/os.h | |||
@@ -160,6 +160,7 @@ extern void os_kill_process(int pid, int reap_child); | |||
160 | extern void os_kill_ptraced_process(int pid, int reap_child); | 160 | extern void os_kill_ptraced_process(int pid, int reap_child); |
161 | extern void os_usr1_process(int pid); | 161 | extern void os_usr1_process(int pid); |
162 | extern int os_getpid(void); | 162 | extern int os_getpid(void); |
163 | extern int os_getpgrp(void); | ||
163 | 164 | ||
164 | extern int os_map_memory(void *virt, int fd, unsigned long long off, | 165 | extern int os_map_memory(void *virt, int fd, unsigned long long off, |
165 | unsigned long len, int r, int w, int x); | 166 | unsigned long len, int r, int w, int x); |
diff --git a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h index cfb5fb4f5b91..cd2327d09c8d 100644 --- a/arch/um/include/skas_ptrace.h +++ b/arch/um/include/skas_ptrace.h | |||
@@ -6,22 +6,11 @@ | |||
6 | #ifndef __SKAS_PTRACE_H | 6 | #ifndef __SKAS_PTRACE_H |
7 | #define __SKAS_PTRACE_H | 7 | #define __SKAS_PTRACE_H |
8 | 8 | ||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_FAULTINFO 52 | 9 | #define PTRACE_FAULTINFO 52 |
21 | #define PTRACE_SIGPENDING 53 | ||
22 | #define PTRACE_LDT 54 | ||
23 | #define PTRACE_SWITCH_MM 55 | 10 | #define PTRACE_SWITCH_MM 55 |
24 | 11 | ||
12 | #include "sysdep/skas_ptrace.h" | ||
13 | |||
25 | #endif | 14 | #endif |
26 | 15 | ||
27 | /* | 16 | /* |
diff --git a/arch/um/include/sysdep-i386/checksum.h b/arch/um/include/sysdep-i386/checksum.h index 3a2a45811aa3..764ba4db4788 100644 --- a/arch/um/include/sysdep-i386/checksum.h +++ b/arch/um/include/sysdep-i386/checksum.h | |||
@@ -24,19 +24,6 @@ unsigned int csum_partial(const unsigned char * buff, int len, | |||
24 | unsigned int sum); | 24 | unsigned int sum); |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * the same as csum_partial, but copies from src while it | ||
28 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
29 | * | ||
30 | * here even more important to align src and dst on a 32-bit (or even | ||
31 | * better 64-bit) boundary | ||
32 | */ | ||
33 | |||
34 | unsigned int csum_partial_copy_to(const unsigned char *src, unsigned char *dst, | ||
35 | int len, int sum, int *err_ptr); | ||
36 | unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, | ||
37 | int len, int sum, int *err_ptr); | ||
38 | |||
39 | /* | ||
40 | * Note: when you get a NULL pointer exception here this means someone | 27 | * Note: when you get a NULL pointer exception here this means someone |
41 | * passed in an incorrect kernel address to one of these functions. | 28 | * passed in an incorrect kernel address to one of these functions. |
42 | * | 29 | * |
@@ -52,11 +39,24 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
52 | return(csum_partial(dst, len, sum)); | 39 | return(csum_partial(dst, len, sum)); |
53 | } | 40 | } |
54 | 41 | ||
42 | /* | ||
43 | * the same as csum_partial, but copies from src while it | ||
44 | * checksums, and handles user-space pointer exceptions correctly, when needed. | ||
45 | * | ||
46 | * here even more important to align src and dst on a 32-bit (or even | ||
47 | * better 64-bit) boundary | ||
48 | */ | ||
49 | |||
55 | static __inline__ | 50 | static __inline__ |
56 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 51 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, |
57 | int len, int sum, int *err_ptr) | 52 | int len, int sum, int *err_ptr) |
58 | { | 53 | { |
59 | return csum_partial_copy_from(src, dst, len, sum, err_ptr); | 54 | if(copy_from_user(dst, src, len)){ |
55 | *err_ptr = -EFAULT; | ||
56 | return(-1); | ||
57 | } | ||
58 | |||
59 | return csum_partial(dst, len, sum); | ||
60 | } | 60 | } |
61 | 61 | ||
62 | /* | 62 | /* |
@@ -67,7 +67,6 @@ unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char | |||
67 | */ | 67 | */ |
68 | 68 | ||
69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user | 69 | #define csum_partial_copy_fromuser csum_partial_copy_from_user |
70 | unsigned int csum_partial_copy(const unsigned char *src, unsigned char *dst, int len, int sum); | ||
71 | 70 | ||
72 | /* | 71 | /* |
73 | * This is a version of ip_compute_csum() optimized for IP headers, | 72 | * This is a version of ip_compute_csum() optimized for IP headers, |
@@ -196,8 +195,14 @@ static __inline__ unsigned int csum_and_copy_to_user(const unsigned char *src, | |||
196 | unsigned char *dst, | 195 | unsigned char *dst, |
197 | int len, int sum, int *err_ptr) | 196 | int len, int sum, int *err_ptr) |
198 | { | 197 | { |
199 | if (access_ok(VERIFY_WRITE, dst, len)) | 198 | if (access_ok(VERIFY_WRITE, dst, len)){ |
200 | return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); | 199 | if(copy_to_user(dst, src, len)){ |
200 | *err_ptr = -EFAULT; | ||
201 | return(-1); | ||
202 | } | ||
203 | |||
204 | return csum_partial(src, len, sum); | ||
205 | } | ||
201 | 206 | ||
202 | if (len) | 207 | if (len) |
203 | *err_ptr = -EFAULT; | 208 | *err_ptr = -EFAULT; |
diff --git a/arch/um/include/sysdep-i386/faultinfo.h b/arch/um/include/sysdep-i386/faultinfo.h new file mode 100644 index 000000000000..db437cc373bc --- /dev/null +++ b/arch/um/include/sysdep-i386/faultinfo.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Fujitsu Siemens Computers GmbH | ||
3 | * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #ifndef __FAULTINFO_I386_H | ||
8 | #define __FAULTINFO_I386_H | ||
9 | |||
10 | /* this structure contains the full arch-specific faultinfo | ||
11 | * from the traps. | ||
12 | * On i386, ptrace_faultinfo unfortunately doesn't provide | ||
13 | * all the info, since trap_no is missing. | ||
14 | * All common elements are defined at the same position in | ||
15 | * both structures, thus making it easy to copy the | ||
16 | * contents without knowledge about the structure elements. | ||
17 | */ | ||
18 | struct faultinfo { | ||
19 | int error_code; /* in ptrace_faultinfo misleadingly called is_write */ | ||
20 | unsigned long cr2; /* in ptrace_faultinfo called addr */ | ||
21 | int trap_no; /* missing in ptrace_faultinfo */ | ||
22 | }; | ||
23 | |||
24 | #define FAULT_WRITE(fi) ((fi).error_code & 2) | ||
25 | #define FAULT_ADDRESS(fi) ((fi).cr2) | ||
26 | |||
27 | #define PTRACE_FULL_FAULTINFO 0 | ||
28 | |||
29 | #endif | ||
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h index 661d495e2044..6eaeb9919983 100644 --- a/arch/um/include/sysdep-i386/ptrace.h +++ b/arch/um/include/sysdep-i386/ptrace.h | |||
@@ -53,17 +53,12 @@ extern int sysemu_supported; | |||
53 | 53 | ||
54 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) | 54 | #define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) |
55 | 55 | ||
56 | #define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) | ||
57 | |||
58 | #define REGS_FAULT_ADDR(r) ((r)->fault_addr) | ||
59 | |||
60 | #define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) | ||
61 | |||
62 | #endif | 56 | #endif |
63 | #ifndef PTRACE_SYSEMU_SINGLESTEP | 57 | #ifndef PTRACE_SYSEMU_SINGLESTEP |
64 | #define PTRACE_SYSEMU_SINGLESTEP 32 | 58 | #define PTRACE_SYSEMU_SINGLESTEP 32 |
65 | #endif | 59 | #endif |
66 | 60 | ||
61 | #include "sysdep/faultinfo.h" | ||
67 | #include "choose-mode.h" | 62 | #include "choose-mode.h" |
68 | 63 | ||
69 | union uml_pt_regs { | 64 | union uml_pt_regs { |
@@ -71,6 +66,7 @@ union uml_pt_regs { | |||
71 | struct tt_regs { | 66 | struct tt_regs { |
72 | long syscall; | 67 | long syscall; |
73 | void *sc; | 68 | void *sc; |
69 | struct faultinfo faultinfo; | ||
74 | } tt; | 70 | } tt; |
75 | #endif | 71 | #endif |
76 | #ifdef UML_CONFIG_MODE_SKAS | 72 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -78,9 +74,7 @@ union uml_pt_regs { | |||
78 | unsigned long regs[HOST_FRAME_SIZE]; | 74 | unsigned long regs[HOST_FRAME_SIZE]; |
79 | unsigned long fp[HOST_FP_SIZE]; | 75 | unsigned long fp[HOST_FP_SIZE]; |
80 | unsigned long xfp[HOST_XFP_SIZE]; | 76 | unsigned long xfp[HOST_XFP_SIZE]; |
81 | unsigned long fault_addr; | 77 | struct faultinfo faultinfo; |
82 | unsigned long fault_type; | ||
83 | unsigned long trap_type; | ||
84 | long syscall; | 78 | long syscall; |
85 | int is_user; | 79 | int is_user; |
86 | } skas; | 80 | } skas; |
@@ -217,15 +211,8 @@ struct syscall_args { | |||
217 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) | 211 | #define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) |
218 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) | 212 | #define UPT_SYSCALL_RET(r) UPT_EAX(r) |
219 | 213 | ||
220 | #define UPT_SEGV_IS_FIXABLE(r) \ | 214 | #define UPT_FAULTINFO(r) \ |
221 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ | 215 | CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) |
222 | REGS_SEGV_IS_FIXABLE(&r->skas)) | ||
223 | |||
224 | #define UPT_FAULT_ADDR(r) \ | ||
225 | __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) | ||
226 | |||
227 | #define UPT_FAULT_WRITE(r) \ | ||
228 | CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) | ||
229 | 216 | ||
230 | #endif | 217 | #endif |
231 | 218 | ||
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h index dfee589de360..1fe729265167 100644 --- a/arch/um/include/sysdep-i386/sigcontext.h +++ b/arch/um/include/sysdep-i386/sigcontext.h | |||
@@ -13,15 +13,12 @@ | |||
13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) | 13 | #define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) |
14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) | 14 | #define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) |
15 | 15 | ||
16 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) | 16 | #define GET_FAULTINFO_FROM_SC(fi,sc) \ |
17 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) | 17 | { \ |
18 | 18 | (fi).cr2 = SC_CR2(sc); \ | |
19 | #define FAULT_WRITE(err) (err & 2) | 19 | (fi).error_code = SC_ERR(sc); \ |
20 | #define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) | 20 | (fi).trap_no = SC_TRAPNO(sc); \ |
21 | 21 | } | |
22 | #define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc))) | ||
23 | |||
24 | #define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) | ||
25 | 22 | ||
26 | /* ptrace expects that, at the start of a system call, %eax contains | 23 | /* ptrace expects that, at the start of a system call, %eax contains |
27 | * -ENOSYS, so this makes it so. | 24 | * -ENOSYS, so this makes it so. |
@@ -29,9 +26,7 @@ | |||
29 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) | 26 | #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) |
30 | 27 | ||
31 | /* This is Page Fault */ | 28 | /* This is Page Fault */ |
32 | #define SEGV_IS_FIXABLE(trap) (trap == 14) | 29 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
33 | |||
34 | #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) | ||
35 | 30 | ||
36 | extern unsigned long *sc_sigmask(void *sc_ptr); | 31 | extern unsigned long *sc_sigmask(void *sc_ptr); |
37 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); | 32 | extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); |
diff --git a/arch/um/include/sysdep-i386/signal.h b/arch/um/include/sysdep-i386/signal.h index b1e1f7a77499..07518b162136 100644 --- a/arch/um/include/sysdep-i386/signal.h +++ b/arch/um/include/sysdep-i386/signal.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include <signal.h> | 9 | #include <signal.h> |
10 | 10 | ||
11 | #define ARCH_SIGHDLR_PARAM int sig | ||
12 | |||
11 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ | 13 | #define ARCH_GET_SIGCONTEXT(sc, sig) \ |
12 | do sc = (struct sigcontext *) (&sig + 1); while(0) | 14 | do sc = (struct sigcontext *) (&sig + 1); while(0) |
13 | 15 | ||
diff --git a/arch/um/include/sysdep-i386/skas_ptrace.h b/arch/um/include/sysdep-i386/skas_ptrace.h new file mode 100644 index 000000000000..e27b8a791773 --- /dev/null +++ b/arch/um/include/sysdep-i386/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_I386_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_I386_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-ia64/skas_ptrace.h b/arch/um/include/sysdep-ia64/skas_ptrace.h new file mode 100644 index 000000000000..25a38e715702 --- /dev/null +++ b/arch/um/include/sysdep-ia64/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_IA64_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_IA64_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-ppc/skas_ptrace.h b/arch/um/include/sysdep-ppc/skas_ptrace.h new file mode 100644 index 000000000000..d9fbbac10de0 --- /dev/null +++ b/arch/um/include/sysdep-ppc/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_PPC_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_PPC_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/checksum.h b/arch/um/include/sysdep-x86_64/checksum.h index 572c6c19be33..ea97005af694 100644 --- a/arch/um/include/sysdep-x86_64/checksum.h +++ b/arch/um/include/sysdep-x86_64/checksum.h | |||
@@ -9,8 +9,6 @@ | |||
9 | #include "linux/in6.h" | 9 | #include "linux/in6.h" |
10 | #include "asm/uaccess.h" | 10 | #include "asm/uaccess.h" |
11 | 11 | ||
12 | extern unsigned int csum_partial_copy_from(const unsigned char *src, unsigned char *dst, int len, | ||
13 | int sum, int *err_ptr); | ||
14 | extern unsigned csum_partial(const unsigned char *buff, unsigned len, | 12 | extern unsigned csum_partial(const unsigned char *buff, unsigned len, |
15 | unsigned sum); | 13 | unsigned sum); |
16 | 14 | ||
@@ -31,10 +29,15 @@ unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char * | |||
31 | } | 29 | } |
32 | 30 | ||
33 | static __inline__ | 31 | static __inline__ |
34 | unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, | 32 | unsigned int csum_partial_copy_from_user(const unsigned char *src, |
35 | int len, int sum, int *err_ptr) | 33 | unsigned char *dst, int len, int sum, |
34 | int *err_ptr) | ||
36 | { | 35 | { |
37 | return csum_partial_copy_from(src, dst, len, sum, err_ptr); | 36 | if(copy_from_user(dst, src, len)){ |
37 | *err_ptr = -EFAULT; | ||
38 | return(-1); | ||
39 | } | ||
40 | return csum_partial(dst, len, sum); | ||
38 | } | 41 | } |
39 | 42 | ||
40 | /** | 43 | /** |
@@ -137,15 +140,6 @@ static inline unsigned add32_with_carry(unsigned a, unsigned b) | |||
137 | return a; | 140 | return a; |
138 | } | 141 | } |
139 | 142 | ||
140 | #endif | 143 | extern unsigned short ip_compute_csum(unsigned char * buff, int len); |
141 | 144 | ||
142 | /* | 145 | #endif |
143 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
144 | * Emacs will notice this stuff at the end of the file and automatically | ||
145 | * adjust the settings for this buffer only. This must remain at the end | ||
146 | * of the file. | ||
147 | * --------------------------------------------------------------------------- | ||
148 | * Local variables: | ||
149 | * c-file-style: "linux" | ||
150 | * End: | ||
151 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/faultinfo.h b/arch/um/include/sysdep-x86_64/faultinfo.h new file mode 100644 index 000000000000..cb917b0d5660 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/faultinfo.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Fujitsu Siemens Computers GmbH | ||
3 | * Author: Bodo Stroesser <bstroesser@fujitsu-siemens.com> | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | |||
7 | #ifndef __FAULTINFO_X86_64_H | ||
8 | #define __FAULTINFO_X86_64_H | ||
9 | |||
10 | /* this structure contains the full arch-specific faultinfo | ||
11 | * from the traps. | ||
12 | * On i386, ptrace_faultinfo unfortunately doesn't provide | ||
13 | * all the info, since trap_no is missing. | ||
14 | * All common elements are defined at the same position in | ||
15 | * both structures, thus making it easy to copy the | ||
16 | * contents without knowledge about the structure elements. | ||
17 | */ | ||
18 | struct faultinfo { | ||
19 | int error_code; /* in ptrace_faultinfo misleadingly called is_write */ | ||
20 | unsigned long cr2; /* in ptrace_faultinfo called addr */ | ||
21 | int trap_no; /* missing in ptrace_faultinfo */ | ||
22 | }; | ||
23 | |||
24 | #define FAULT_WRITE(fi) ((fi).error_code & 2) | ||
25 | #define FAULT_ADDRESS(fi) ((fi).cr2) | ||
26 | |||
27 | #define PTRACE_FULL_FAULTINFO 1 | ||
28 | |||
29 | #endif | ||
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h index 915c82daffbd..be8acd5efd97 100644 --- a/arch/um/include/sysdep-x86_64/ptrace.h +++ b/arch/um/include/sysdep-x86_64/ptrace.h | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include "uml-config.h" | 10 | #include "uml-config.h" |
11 | #include "user_constants.h" | 11 | #include "user_constants.h" |
12 | #include "sysdep/faultinfo.h" | ||
12 | 13 | ||
13 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) | 14 | #define MAX_REG_OFFSET (UM_FRAME_SIZE) |
14 | #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) | 15 | #define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) |
@@ -83,6 +84,7 @@ union uml_pt_regs { | |||
83 | long syscall; | 84 | long syscall; |
84 | unsigned long orig_rax; | 85 | unsigned long orig_rax; |
85 | void *sc; | 86 | void *sc; |
87 | struct faultinfo faultinfo; | ||
86 | } tt; | 88 | } tt; |
87 | #endif | 89 | #endif |
88 | #ifdef UML_CONFIG_MODE_SKAS | 90 | #ifdef UML_CONFIG_MODE_SKAS |
@@ -90,9 +92,7 @@ union uml_pt_regs { | |||
90 | /* XXX */ | 92 | /* XXX */ |
91 | unsigned long regs[27]; | 93 | unsigned long regs[27]; |
92 | unsigned long fp[65]; | 94 | unsigned long fp[65]; |
93 | unsigned long fault_addr; | 95 | struct faultinfo faultinfo; |
94 | unsigned long fault_type; | ||
95 | unsigned long trap_type; | ||
96 | long syscall; | 96 | long syscall; |
97 | int is_user; | 97 | int is_user; |
98 | } skas; | 98 | } skas; |
@@ -135,6 +135,7 @@ extern int mode_tt; | |||
135 | __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) | 135 | __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) |
136 | #define UPT_SC(r) ((r)->tt.sc) | 136 | #define UPT_SC(r) ((r)->tt.sc) |
137 | #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) | 137 | #define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) |
138 | #define UPT_SYSCALL_RET(r) UPT_RAX(r) | ||
138 | 139 | ||
139 | extern int user_context(unsigned long sp); | 140 | extern int user_context(unsigned long sp); |
140 | 141 | ||
@@ -196,32 +197,32 @@ struct syscall_args { | |||
196 | 197 | ||
197 | 198 | ||
198 | #define UPT_SET(regs, reg, val) \ | 199 | #define UPT_SET(regs, reg, val) \ |
199 | ({ unsigned long val; \ | 200 | ({ unsigned long __upt_val = val; \ |
200 | switch(reg){ \ | 201 | switch(reg){ \ |
201 | case R8: UPT_R8(regs) = val; break; \ | 202 | case R8: UPT_R8(regs) = __upt_val; break; \ |
202 | case R9: UPT_R9(regs) = val; break; \ | 203 | case R9: UPT_R9(regs) = __upt_val; break; \ |
203 | case R10: UPT_R10(regs) = val; break; \ | 204 | case R10: UPT_R10(regs) = __upt_val; break; \ |
204 | case R11: UPT_R11(regs) = val; break; \ | 205 | case R11: UPT_R11(regs) = __upt_val; break; \ |
205 | case R12: UPT_R12(regs) = val; break; \ | 206 | case R12: UPT_R12(regs) = __upt_val; break; \ |
206 | case R13: UPT_R13(regs) = val; break; \ | 207 | case R13: UPT_R13(regs) = __upt_val; break; \ |
207 | case R14: UPT_R14(regs) = val; break; \ | 208 | case R14: UPT_R14(regs) = __upt_val; break; \ |
208 | case R15: UPT_R15(regs) = val; break; \ | 209 | case R15: UPT_R15(regs) = __upt_val; break; \ |
209 | case RIP: UPT_IP(regs) = val; break; \ | 210 | case RIP: UPT_IP(regs) = __upt_val; break; \ |
210 | case RSP: UPT_SP(regs) = val; break; \ | 211 | case RSP: UPT_SP(regs) = __upt_val; break; \ |
211 | case RAX: UPT_RAX(regs) = val; break; \ | 212 | case RAX: UPT_RAX(regs) = __upt_val; break; \ |
212 | case RBX: UPT_RBX(regs) = val; break; \ | 213 | case RBX: UPT_RBX(regs) = __upt_val; break; \ |
213 | case RCX: UPT_RCX(regs) = val; break; \ | 214 | case RCX: UPT_RCX(regs) = __upt_val; break; \ |
214 | case RDX: UPT_RDX(regs) = val; break; \ | 215 | case RDX: UPT_RDX(regs) = __upt_val; break; \ |
215 | case RSI: UPT_RSI(regs) = val; break; \ | 216 | case RSI: UPT_RSI(regs) = __upt_val; break; \ |
216 | case RDI: UPT_RDI(regs) = val; break; \ | 217 | case RDI: UPT_RDI(regs) = __upt_val; break; \ |
217 | case RBP: UPT_RBP(regs) = val; break; \ | 218 | case RBP: UPT_RBP(regs) = __upt_val; break; \ |
218 | case ORIG_RAX: UPT_ORIG_RAX(regs) = val; break; \ | 219 | case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ |
219 | case CS: UPT_CS(regs) = val; break; \ | 220 | case CS: UPT_CS(regs) = __upt_val; break; \ |
220 | case DS: UPT_DS(regs) = val; break; \ | 221 | case DS: UPT_DS(regs) = __upt_val; break; \ |
221 | case ES: UPT_ES(regs) = val; break; \ | 222 | case ES: UPT_ES(regs) = __upt_val; break; \ |
222 | case FS: UPT_FS(regs) = val; break; \ | 223 | case FS: UPT_FS(regs) = __upt_val; break; \ |
223 | case GS: UPT_GS(regs) = val; break; \ | 224 | case GS: UPT_GS(regs) = __upt_val; break; \ |
224 | case EFLAGS: UPT_EFLAGS(regs) = val; break; \ | 225 | case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ |
225 | default : \ | 226 | default : \ |
226 | panic("Bad register in UPT_SET : %d\n", reg); \ | 227 | panic("Bad register in UPT_SET : %d\n", reg); \ |
227 | break; \ | 228 | break; \ |
@@ -241,24 +242,7 @@ struct syscall_args { | |||
241 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ | 242 | CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ |
242 | REGS_SEGV_IS_FIXABLE(&r->skas)) | 243 | REGS_SEGV_IS_FIXABLE(&r->skas)) |
243 | 244 | ||
244 | #define UPT_FAULT_ADDR(r) \ | 245 | #define UPT_FAULTINFO(r) \ |
245 | __CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) | 246 | CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) |
246 | |||
247 | #define UPT_FAULT_WRITE(r) \ | ||
248 | CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) | ||
249 | |||
250 | #define UPT_TRAP(r) __CHOOSE_MODE(SC_TRAP_TYPE(UPT_SC(r)), REGS_TRAP(&r->skas)) | ||
251 | #define UPT_ERR(r) __CHOOSE_MODE(SC_FAULT_TYPE(UPT_SC(r)), REGS_ERR(&r->skas)) | ||
252 | 247 | ||
253 | #endif | 248 | #endif |
254 | |||
255 | /* | ||
256 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
257 | * Emacs will notice this stuff at the end of the file and automatically | ||
258 | * adjust the settings for this buffer only. This must remain at the end | ||
259 | * of the file. | ||
260 | * --------------------------------------------------------------------------- | ||
261 | * Local variables: | ||
262 | * c-file-style: "linux" | ||
263 | * End: | ||
264 | */ | ||
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h index 1e38a54ff4cf..2a78260d15a0 100644 --- a/arch/um/include/sysdep-x86_64/sigcontext.h +++ b/arch/um/include/sysdep-x86_64/sigcontext.h | |||
@@ -17,11 +17,12 @@ | |||
17 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) | 17 | #define SC_FAULT_ADDR(sc) SC_CR2(sc) |
18 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) | 18 | #define SC_FAULT_TYPE(sc) SC_ERR(sc) |
19 | 19 | ||
20 | #define FAULT_WRITE(err) ((err) & 2) | 20 | #define GET_FAULTINFO_FROM_SC(fi,sc) \ |
21 | 21 | { \ | |
22 | #define SC_FAULT_WRITE(sc) FAULT_WRITE(SC_FAULT_TYPE(sc)) | 22 | (fi).cr2 = SC_CR2(sc); \ |
23 | 23 | (fi).error_code = SC_ERR(sc); \ | |
24 | #define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) | 24 | (fi).trap_no = SC_TRAPNO(sc); \ |
25 | } | ||
25 | 26 | ||
26 | /* ptrace expects that, at the start of a system call, %eax contains | 27 | /* ptrace expects that, at the start of a system call, %eax contains |
27 | * -ENOSYS, so this makes it so. | 28 | * -ENOSYS, so this makes it so. |
@@ -29,8 +30,8 @@ | |||
29 | 30 | ||
30 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) | 31 | #define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0) |
31 | 32 | ||
32 | #define SEGV_IS_FIXABLE(trap) ((trap) == 14) | 33 | /* This is Page Fault */ |
33 | #define SC_SEGV_IS_FIXABLE(sc) SEGV_IS_FIXABLE(SC_TRAP_TYPE(sc)) | 34 | #define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) |
34 | 35 | ||
35 | extern unsigned long *sc_sigmask(void *sc_ptr); | 36 | extern unsigned long *sc_sigmask(void *sc_ptr); |
36 | 37 | ||
diff --git a/arch/um/include/sysdep-x86_64/signal.h b/arch/um/include/sysdep-x86_64/signal.h index e5e52756fab4..6142897af3d1 100644 --- a/arch/um/include/sysdep-x86_64/signal.h +++ b/arch/um/include/sysdep-x86_64/signal.h | |||
@@ -6,6 +6,8 @@ | |||
6 | #ifndef __X86_64_SIGNAL_H_ | 6 | #ifndef __X86_64_SIGNAL_H_ |
7 | #define __X86_64_SIGNAL_H_ | 7 | #define __X86_64_SIGNAL_H_ |
8 | 8 | ||
9 | #define ARCH_SIGHDLR_PARAM int sig | ||
10 | |||
9 | #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ | 11 | #define ARCH_GET_SIGCONTEXT(sc, sig_addr) \ |
10 | do { \ | 12 | do { \ |
11 | struct ucontext *__uc; \ | 13 | struct ucontext *__uc; \ |
diff --git a/arch/um/include/sysdep-x86_64/skas_ptrace.h b/arch/um/include/sysdep-x86_64/skas_ptrace.h new file mode 100644 index 000000000000..95db4be786e4 --- /dev/null +++ b/arch/um/include/sysdep-x86_64/skas_ptrace.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __SYSDEP_X86_64_SKAS_PTRACE_H | ||
7 | #define __SYSDEP_X86_64_SKAS_PTRACE_H | ||
8 | |||
9 | struct ptrace_faultinfo { | ||
10 | int is_write; | ||
11 | unsigned long addr; | ||
12 | }; | ||
13 | |||
14 | struct ptrace_ldt { | ||
15 | int func; | ||
16 | void *ptr; | ||
17 | unsigned long bytecount; | ||
18 | }; | ||
19 | |||
20 | #define PTRACE_LDT 54 | ||
21 | |||
22 | #endif | ||
diff --git a/arch/um/include/user_util.h b/arch/um/include/user_util.h index 103cd320386c..b8c5b8a95250 100644 --- a/arch/um/include/user_util.h +++ b/arch/um/include/user_util.h | |||
@@ -67,7 +67,6 @@ extern void *um_kmalloc(int size); | |||
67 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); | 67 | extern int switcheroo(int fd, int prot, void *from, void *to, int size); |
68 | extern void setup_machinename(char *machine_out); | 68 | extern void setup_machinename(char *machine_out); |
69 | extern void setup_hostinfo(void); | 69 | extern void setup_hostinfo(void); |
70 | extern void add_arg(char *arg); | ||
71 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); | 70 | extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); |
72 | extern void init_new_thread_signals(int altstack); | 71 | extern void init_new_thread_signals(int altstack); |
73 | extern void do_exec(int old_pid, int new_pid); | 72 | extern void do_exec(int old_pid, int new_pid); |
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index 246f0e7fb4cc..a8918e80df96 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile | |||
@@ -4,9 +4,9 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | extra-y := vmlinux.lds | 6 | extra-y := vmlinux.lds |
7 | clean-files := vmlinux.lds.S config.tmp | 7 | clean-files := |
8 | 8 | ||
9 | obj-y = checksum.o config.o exec_kern.o exitcode.o \ | 9 | obj-y = config.o exec_kern.o exitcode.o \ |
10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ | 10 | helper.o init_task.o irq.o irq_user.o ksyms.o main.o mem.o mem_user.o \ |
11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ | 11 | physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ |
12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ | 12 | sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ |
@@ -14,7 +14,7 @@ obj-y = checksum.o config.o exec_kern.o exitcode.o \ | |||
14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ | 14 | tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o umid.o \ |
15 | user_util.o | 15 | user_util.o |
16 | 16 | ||
17 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o | 17 | obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o |
18 | obj-$(CONFIG_GPROF) += gprof_syms.o | 18 | obj-$(CONFIG_GPROF) += gprof_syms.o |
19 | obj-$(CONFIG_GCOV) += gmon_syms.o | 19 | obj-$(CONFIG_GCOV) += gmon_syms.o |
20 | obj-$(CONFIG_TTY_LOG) += tty_log.o | 20 | obj-$(CONFIG_TTY_LOG) += tty_log.o |
@@ -23,18 +23,14 @@ obj-$(CONFIG_SYSCALL_DEBUG) += syscall_user.o | |||
23 | obj-$(CONFIG_MODE_TT) += tt/ | 23 | obj-$(CONFIG_MODE_TT) += tt/ |
24 | obj-$(CONFIG_MODE_SKAS) += skas/ | 24 | obj-$(CONFIG_MODE_SKAS) += skas/ |
25 | 25 | ||
26 | # This needs be compiled with frame pointers regardless of how the rest of the | ||
27 | # kernel is built. | ||
28 | CFLAGS_frame.o := -fno-omit-frame-pointer | ||
29 | |||
30 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o | 26 | user-objs-$(CONFIG_TTY_LOG) += tty_log.o |
31 | 27 | ||
32 | USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ | 28 | USER_OBJS := $(user-objs-y) config.o helper.o main.o process.o tempfile.o \ |
33 | time.o tty_log.o umid.o user_util.o frame.o | 29 | time.o tty_log.o umid.o user_util.o |
34 | 30 | ||
35 | include arch/um/scripts/Makefile.rules | 31 | include arch/um/scripts/Makefile.rules |
36 | 32 | ||
37 | targets += config.c | 33 | targets := config.c config.tmp |
38 | 34 | ||
39 | # Be careful with the below Sed code - sed is pitfall-rich! | 35 | # Be careful with the below Sed code - sed is pitfall-rich! |
40 | # We use sed to lower build requirements, for "embedded" builders for instance. | 36 | # We use sed to lower build requirements, for "embedded" builders for instance. |
diff --git a/arch/um/kernel/checksum.c b/arch/um/kernel/checksum.c deleted file mode 100644 index e69b2be951d1..000000000000 --- a/arch/um/kernel/checksum.c +++ /dev/null | |||
@@ -1,36 +0,0 @@ | |||
1 | #include "asm/uaccess.h" | ||
2 | #include "linux/errno.h" | ||
3 | #include "linux/module.h" | ||
4 | |||
5 | unsigned int arch_csum_partial(const unsigned char *buff, int len, int sum); | ||
6 | |||
7 | unsigned int csum_partial(unsigned char *buff, int len, int sum) | ||
8 | { | ||
9 | return arch_csum_partial(buff, len, sum); | ||
10 | } | ||
11 | |||
12 | EXPORT_SYMBOL(csum_partial); | ||
13 | |||
14 | unsigned int csum_partial_copy_to(const unsigned char *src, | ||
15 | unsigned char __user *dst, int len, int sum, | ||
16 | int *err_ptr) | ||
17 | { | ||
18 | if(copy_to_user(dst, src, len)){ | ||
19 | *err_ptr = -EFAULT; | ||
20 | return(-1); | ||
21 | } | ||
22 | |||
23 | return(arch_csum_partial(src, len, sum)); | ||
24 | } | ||
25 | |||
26 | unsigned int csum_partial_copy_from(const unsigned char __user *src, | ||
27 | unsigned char *dst, int len, int sum, | ||
28 | int *err_ptr) | ||
29 | { | ||
30 | if(copy_from_user(dst, src, len)){ | ||
31 | *err_ptr = -EFAULT; | ||
32 | return(-1); | ||
33 | } | ||
34 | |||
35 | return arch_csum_partial(dst, len, sum); | ||
36 | } | ||
diff --git a/arch/um/kernel/initrd.c b/arch/um/kernel/initrd.c new file mode 100644 index 000000000000..82ecf904b09c --- /dev/null +++ b/arch/um/kernel/initrd.c | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #include "linux/init.h" | ||
7 | #include "linux/bootmem.h" | ||
8 | #include "linux/initrd.h" | ||
9 | #include "asm/types.h" | ||
10 | #include "user_util.h" | ||
11 | #include "kern_util.h" | ||
12 | #include "initrd.h" | ||
13 | #include "init.h" | ||
14 | #include "os.h" | ||
15 | |||
16 | /* Changed by uml_initrd_setup, which is a setup */ | ||
17 | static char *initrd __initdata = NULL; | ||
18 | |||
19 | static int __init read_initrd(void) | ||
20 | { | ||
21 | void *area; | ||
22 | long long size; | ||
23 | int err; | ||
24 | |||
25 | if(initrd == NULL) return 0; | ||
26 | err = os_file_size(initrd, &size); | ||
27 | if(err) return 0; | ||
28 | area = alloc_bootmem(size); | ||
29 | if(area == NULL) return 0; | ||
30 | if(load_initrd(initrd, area, size) == -1) return 0; | ||
31 | initrd_start = (unsigned long) area; | ||
32 | initrd_end = initrd_start + size; | ||
33 | return 0; | ||
34 | } | ||
35 | |||
36 | __uml_postsetup(read_initrd); | ||
37 | |||
38 | static int __init uml_initrd_setup(char *line, int *add) | ||
39 | { | ||
40 | initrd = line; | ||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | __uml_setup("initrd=", uml_initrd_setup, | ||
45 | "initrd=<initrd image>\n" | ||
46 | " This is used to boot UML from an initrd image. The argument is the\n" | ||
47 | " name of the file containing the image.\n\n" | ||
48 | ); | ||
49 | |||
50 | int load_initrd(char *filename, void *buf, int size) | ||
51 | { | ||
52 | int fd, n; | ||
53 | |||
54 | fd = os_open_file(filename, of_read(OPENFLAGS()), 0); | ||
55 | if(fd < 0){ | ||
56 | printk("Opening '%s' failed - err = %d\n", filename, -fd); | ||
57 | return(-1); | ||
58 | } | ||
59 | n = os_read_file(fd, buf, size); | ||
60 | if(n != size){ | ||
61 | printk("Read of %d bytes from '%s' failed, err = %d\n", size, | ||
62 | filename, -n); | ||
63 | return(-1); | ||
64 | } | ||
65 | |||
66 | os_close_file(fd); | ||
67 | return(0); | ||
68 | } | ||
69 | /* | ||
70 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
71 | * Emacs will notice this stuff at the end of the file and automatically | ||
72 | * adjust the settings for this buffer only. This must remain at the end | ||
73 | * of the file. | ||
74 | * --------------------------------------------------------------------------- | ||
75 | * Local variables: | ||
76 | * c-file-style: "linux" | ||
77 | * End: | ||
78 | */ | ||
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c index d71e8f00810f..d44fb5282547 100644 --- a/arch/um/kernel/irq.c +++ b/arch/um/kernel/irq.c | |||
@@ -163,7 +163,6 @@ void __init init_IRQ(void) | |||
163 | irq_desc[i].handler = &SIGIO_irq_type; | 163 | irq_desc[i].handler = &SIGIO_irq_type; |
164 | enable_irq(i); | 164 | enable_irq(i); |
165 | } | 165 | } |
166 | init_irq_signals(0); | ||
167 | } | 166 | } |
168 | 167 | ||
169 | /* | 168 | /* |
diff --git a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c index 6d6f9484b884..b3074cbaa479 100644 --- a/arch/um/kernel/irq_user.c +++ b/arch/um/kernel/irq_user.c | |||
@@ -236,9 +236,15 @@ static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) | |||
236 | (*prev)->fd, pollfds[i].fd); | 236 | (*prev)->fd, pollfds[i].fd); |
237 | goto out; | 237 | goto out; |
238 | } | 238 | } |
239 | memcpy(&pollfds[i], &pollfds[i + 1], | 239 | |
240 | (pollfds_num - i - 1) * sizeof(pollfds[0])); | ||
241 | pollfds_num--; | 240 | pollfds_num--; |
241 | |||
242 | /* This moves the *whole* array after pollfds[i] (though | ||
243 | * it doesn't spot as such)! */ | ||
244 | |||
245 | memmove(&pollfds[i], &pollfds[i + 1], | ||
246 | (pollfds_num - i) * sizeof(pollfds[0])); | ||
247 | |||
242 | if(last_irq_ptr == &old_fd->next) | 248 | if(last_irq_ptr == &old_fd->next) |
243 | last_irq_ptr = prev; | 249 | last_irq_ptr = prev; |
244 | *prev = (*prev)->next; | 250 | *prev = (*prev)->next; |
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c index b41d3397d07b..99439fa15ef4 100644 --- a/arch/um/kernel/ksyms.c +++ b/arch/um/kernel/ksyms.c | |||
@@ -10,7 +10,6 @@ | |||
10 | #include "linux/spinlock.h" | 10 | #include "linux/spinlock.h" |
11 | #include "linux/highmem.h" | 11 | #include "linux/highmem.h" |
12 | #include "asm/current.h" | 12 | #include "asm/current.h" |
13 | #include "asm/delay.h" | ||
14 | #include "asm/processor.h" | 13 | #include "asm/processor.h" |
15 | #include "asm/unistd.h" | 14 | #include "asm/unistd.h" |
16 | #include "asm/pgalloc.h" | 15 | #include "asm/pgalloc.h" |
@@ -28,8 +27,6 @@ EXPORT_SYMBOL(uml_physmem); | |||
28 | EXPORT_SYMBOL(set_signals); | 27 | EXPORT_SYMBOL(set_signals); |
29 | EXPORT_SYMBOL(get_signals); | 28 | EXPORT_SYMBOL(get_signals); |
30 | EXPORT_SYMBOL(kernel_thread); | 29 | EXPORT_SYMBOL(kernel_thread); |
31 | EXPORT_SYMBOL(__const_udelay); | ||
32 | EXPORT_SYMBOL(__udelay); | ||
33 | EXPORT_SYMBOL(sys_waitpid); | 30 | EXPORT_SYMBOL(sys_waitpid); |
34 | EXPORT_SYMBOL(task_size); | 31 | EXPORT_SYMBOL(task_size); |
35 | EXPORT_SYMBOL(flush_tlb_range); | 32 | EXPORT_SYMBOL(flush_tlb_range); |
@@ -60,6 +57,7 @@ EXPORT_SYMBOL(copy_to_user_tt); | |||
60 | EXPORT_SYMBOL(strncpy_from_user_skas); | 57 | EXPORT_SYMBOL(strncpy_from_user_skas); |
61 | EXPORT_SYMBOL(copy_to_user_skas); | 58 | EXPORT_SYMBOL(copy_to_user_skas); |
62 | EXPORT_SYMBOL(copy_from_user_skas); | 59 | EXPORT_SYMBOL(copy_from_user_skas); |
60 | EXPORT_SYMBOL(clear_user_skas); | ||
63 | #endif | 61 | #endif |
64 | EXPORT_SYMBOL(uml_strdup); | 62 | EXPORT_SYMBOL(uml_strdup); |
65 | 63 | ||
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index f156661781cb..c22825f13e40 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c | |||
@@ -100,12 +100,37 @@ void mem_init(void) | |||
100 | #endif | 100 | #endif |
101 | } | 101 | } |
102 | 102 | ||
103 | /* | ||
104 | * Create a page table and place a pointer to it in a middle page | ||
105 | * directory entry. | ||
106 | */ | ||
107 | static void __init one_page_table_init(pmd_t *pmd) | ||
108 | { | ||
109 | if (pmd_none(*pmd)) { | ||
110 | pte_t *pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
111 | set_pmd(pmd, __pmd(_KERNPG_TABLE + | ||
112 | (unsigned long) __pa(pte))); | ||
113 | if (pte != pte_offset_kernel(pmd, 0)) | ||
114 | BUG(); | ||
115 | } | ||
116 | } | ||
117 | |||
118 | static void __init one_md_table_init(pud_t *pud) | ||
119 | { | ||
120 | #ifdef CONFIG_3_LEVEL_PGTABLES | ||
121 | pmd_t *pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
122 | set_pud(pud, __pud(_KERNPG_TABLE + (unsigned long) __pa(pmd_table))); | ||
123 | if (pmd_table != pmd_offset(pud, 0)) | ||
124 | BUG(); | ||
125 | #endif | ||
126 | } | ||
127 | |||
103 | static void __init fixrange_init(unsigned long start, unsigned long end, | 128 | static void __init fixrange_init(unsigned long start, unsigned long end, |
104 | pgd_t *pgd_base) | 129 | pgd_t *pgd_base) |
105 | { | 130 | { |
106 | pgd_t *pgd; | 131 | pgd_t *pgd; |
132 | pud_t *pud; | ||
107 | pmd_t *pmd; | 133 | pmd_t *pmd; |
108 | pte_t *pte; | ||
109 | int i, j; | 134 | int i, j; |
110 | unsigned long vaddr; | 135 | unsigned long vaddr; |
111 | 136 | ||
@@ -115,15 +140,12 @@ static void __init fixrange_init(unsigned long start, unsigned long end, | |||
115 | pgd = pgd_base + i; | 140 | pgd = pgd_base + i; |
116 | 141 | ||
117 | for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { | 142 | for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { |
118 | pmd = (pmd_t *)pgd; | 143 | pud = pud_offset(pgd, vaddr); |
144 | if (pud_none(*pud)) | ||
145 | one_md_table_init(pud); | ||
146 | pmd = pmd_offset(pud, vaddr); | ||
119 | for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { | 147 | for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { |
120 | if (pmd_none(*pmd)) { | 148 | one_page_table_init(pmd); |
121 | pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); | ||
122 | set_pmd(pmd, __pmd(_KERNPG_TABLE + | ||
123 | (unsigned long) __pa(pte))); | ||
124 | if (pte != pte_offset_kernel(pmd, 0)) | ||
125 | BUG(); | ||
126 | } | ||
127 | vaddr += PMD_SIZE; | 149 | vaddr += PMD_SIZE; |
128 | } | 150 | } |
129 | j = 0; | 151 | j = 0; |
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index f76a2692adca..51f8e5a8ac6a 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c | |||
@@ -65,8 +65,6 @@ void init_new_thread_signals(int altstack) | |||
65 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 65 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
66 | set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, | 66 | set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, |
67 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 67 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
68 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, | ||
69 | SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | ||
70 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, | 68 | set_handler(SIGUSR2, (__sighandler_t) sig_handler, |
71 | flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); | 69 | flags, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); |
72 | signal(SIGHUP, SIG_IGN); | 70 | signal(SIGHUP, SIG_IGN); |
diff --git a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c index 7a943696f950..c1adf7ba3fd1 100644 --- a/arch/um/kernel/process_kern.c +++ b/arch/um/kernel/process_kern.c | |||
@@ -115,16 +115,6 @@ int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) | |||
115 | return(pid); | 115 | return(pid); |
116 | } | 116 | } |
117 | 117 | ||
118 | void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
119 | struct task_struct *tsk) | ||
120 | { | ||
121 | int cpu = smp_processor_id(); | ||
122 | |||
123 | if (prev != next) | ||
124 | cpu_clear(cpu, prev->cpu_vm_mask); | ||
125 | cpu_set(cpu, next->cpu_vm_mask); | ||
126 | } | ||
127 | |||
128 | void set_current(void *t) | 118 | void set_current(void *t) |
129 | { | 119 | { |
130 | struct task_struct *task = t; | 120 | struct task_struct *task = t; |
@@ -152,7 +142,6 @@ void release_thread(struct task_struct *task) | |||
152 | 142 | ||
153 | void exit_thread(void) | 143 | void exit_thread(void) |
154 | { | 144 | { |
155 | CHOOSE_MODE(exit_thread_tt(), exit_thread_skas()); | ||
156 | unprotect_stack((unsigned long) current_thread); | 145 | unprotect_stack((unsigned long) current_thread); |
157 | } | 146 | } |
158 | 147 | ||
@@ -476,12 +465,21 @@ int singlestepping(void * t) | |||
476 | return 2; | 465 | return 2; |
477 | } | 466 | } |
478 | 467 | ||
468 | /* | ||
469 | * Only x86 and x86_64 have an arch_align_stack(). | ||
470 | * All other arches have "#define arch_align_stack(x) (x)" | ||
471 | * in their asm/system.h | ||
472 | * As this is included in UML from asm-um/system-generic.h, | ||
473 | * we can use it to behave as the subarch does. | ||
474 | */ | ||
475 | #ifndef arch_align_stack | ||
479 | unsigned long arch_align_stack(unsigned long sp) | 476 | unsigned long arch_align_stack(unsigned long sp) |
480 | { | 477 | { |
481 | if (randomize_va_space) | 478 | if (randomize_va_space) |
482 | sp -= get_random_int() % 8192; | 479 | sp -= get_random_int() % 8192; |
483 | return sp & ~0xf; | 480 | return sp & ~0xf; |
484 | } | 481 | } |
482 | #endif | ||
485 | 483 | ||
486 | 484 | ||
487 | /* | 485 | /* |
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c index 959b2d2490df..2925e15324de 100644 --- a/arch/um/kernel/ptrace.c +++ b/arch/um/kernel/ptrace.c | |||
@@ -19,15 +19,30 @@ | |||
19 | #include "skas_ptrace.h" | 19 | #include "skas_ptrace.h" |
20 | #include "sysdep/ptrace.h" | 20 | #include "sysdep/ptrace.h" |
21 | 21 | ||
22 | static inline void set_singlestepping(struct task_struct *child, int on) | ||
23 | { | ||
24 | if (on) | ||
25 | child->ptrace |= PT_DTRACE; | ||
26 | else | ||
27 | child->ptrace &= ~PT_DTRACE; | ||
28 | child->thread.singlestep_syscall = 0; | ||
29 | |||
30 | #ifdef SUBARCH_SET_SINGLESTEPPING | ||
31 | SUBARCH_SET_SINGLESTEPPING(child, on); | ||
32 | #endif | ||
33 | } | ||
34 | |||
22 | /* | 35 | /* |
23 | * Called by kernel/ptrace.c when detaching.. | 36 | * Called by kernel/ptrace.c when detaching.. |
24 | */ | 37 | */ |
25 | void ptrace_disable(struct task_struct *child) | 38 | void ptrace_disable(struct task_struct *child) |
26 | { | 39 | { |
27 | child->ptrace &= ~PT_DTRACE; | 40 | set_singlestepping(child,0); |
28 | child->thread.singlestep_syscall = 0; | ||
29 | } | 41 | } |
30 | 42 | ||
43 | extern int peek_user(struct task_struct * child, long addr, long data); | ||
44 | extern int poke_user(struct task_struct * child, long addr, long data); | ||
45 | |||
31 | long sys_ptrace(long request, long pid, long addr, long data) | 46 | long sys_ptrace(long request, long pid, long addr, long data) |
32 | { | 47 | { |
33 | struct task_struct *child; | 48 | struct task_struct *child; |
@@ -67,6 +82,10 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
67 | goto out_tsk; | 82 | goto out_tsk; |
68 | } | 83 | } |
69 | 84 | ||
85 | #ifdef SUBACH_PTRACE_SPECIAL | ||
86 | SUBARCH_PTRACE_SPECIAL(child,request,addr,data); | ||
87 | #endif | ||
88 | |||
70 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 89 | ret = ptrace_check_attach(child, request == PTRACE_KILL); |
71 | if (ret < 0) | 90 | if (ret < 0) |
72 | goto out_tsk; | 91 | goto out_tsk; |
@@ -87,26 +106,9 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
87 | } | 106 | } |
88 | 107 | ||
89 | /* read the word at location addr in the USER area. */ | 108 | /* read the word at location addr in the USER area. */ |
90 | case PTRACE_PEEKUSR: { | 109 | case PTRACE_PEEKUSR: |
91 | unsigned long tmp; | 110 | ret = peek_user(child, addr, data); |
92 | 111 | break; | |
93 | ret = -EIO; | ||
94 | if ((addr & 3) || addr < 0) | ||
95 | break; | ||
96 | |||
97 | tmp = 0; /* Default return condition */ | ||
98 | if(addr < MAX_REG_OFFSET){ | ||
99 | tmp = getreg(child, addr); | ||
100 | } | ||
101 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
102 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
103 | addr -= offsetof(struct user, u_debugreg[0]); | ||
104 | addr = addr >> 2; | ||
105 | tmp = child->thread.arch.debugregs[addr]; | ||
106 | } | ||
107 | ret = put_user(tmp, (unsigned long __user *) data); | ||
108 | break; | ||
109 | } | ||
110 | 112 | ||
111 | /* when I and D space are separate, this will have to be fixed. */ | 113 | /* when I and D space are separate, this will have to be fixed. */ |
112 | case PTRACE_POKETEXT: /* write the word at location addr. */ | 114 | case PTRACE_POKETEXT: /* write the word at location addr. */ |
@@ -119,26 +121,8 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
119 | break; | 121 | break; |
120 | 122 | ||
121 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ | 123 | case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ |
122 | ret = -EIO; | 124 | ret = poke_user(child, addr, data); |
123 | if ((addr & 3) || addr < 0) | 125 | break; |
124 | break; | ||
125 | |||
126 | if (addr < MAX_REG_OFFSET) { | ||
127 | ret = putreg(child, addr, data); | ||
128 | break; | ||
129 | } | ||
130 | #if 0 /* XXX x86_64 */ | ||
131 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
132 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
133 | addr -= offsetof(struct user, u_debugreg[0]); | ||
134 | addr = addr >> 2; | ||
135 | if((addr == 4) || (addr == 5)) break; | ||
136 | child->thread.arch.debugregs[addr] = data; | ||
137 | ret = 0; | ||
138 | } | ||
139 | #endif | ||
140 | |||
141 | break; | ||
142 | 126 | ||
143 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ | 127 | case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ |
144 | case PTRACE_CONT: { /* restart after signal. */ | 128 | case PTRACE_CONT: { /* restart after signal. */ |
@@ -146,8 +130,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
146 | if (!valid_signal(data)) | 130 | if (!valid_signal(data)) |
147 | break; | 131 | break; |
148 | 132 | ||
149 | child->ptrace &= ~PT_DTRACE; | 133 | set_singlestepping(child, 0); |
150 | child->thread.singlestep_syscall = 0; | ||
151 | if (request == PTRACE_SYSCALL) { | 134 | if (request == PTRACE_SYSCALL) { |
152 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 135 | set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
153 | } | 136 | } |
@@ -170,8 +153,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
170 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ | 153 | if (child->exit_state == EXIT_ZOMBIE) /* already dead */ |
171 | break; | 154 | break; |
172 | 155 | ||
173 | child->ptrace &= ~PT_DTRACE; | 156 | set_singlestepping(child, 0); |
174 | child->thread.singlestep_syscall = 0; | ||
175 | child->exit_code = SIGKILL; | 157 | child->exit_code = SIGKILL; |
176 | wake_up_process(child); | 158 | wake_up_process(child); |
177 | break; | 159 | break; |
@@ -182,8 +164,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
182 | if (!valid_signal(data)) | 164 | if (!valid_signal(data)) |
183 | break; | 165 | break; |
184 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); | 166 | clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); |
185 | child->ptrace |= PT_DTRACE; | 167 | set_singlestepping(child, 1); |
186 | child->thread.singlestep_syscall = 0; | ||
187 | child->exit_code = data; | 168 | child->exit_code = data; |
188 | /* give it a chance to run. */ | 169 | /* give it a chance to run. */ |
189 | wake_up_process(child); | 170 | wake_up_process(child); |
@@ -250,23 +231,19 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
250 | break; | 231 | break; |
251 | #endif | 232 | #endif |
252 | case PTRACE_FAULTINFO: { | 233 | case PTRACE_FAULTINFO: { |
253 | struct ptrace_faultinfo fault; | 234 | /* Take the info from thread->arch->faultinfo, |
254 | 235 | * but transfer max. sizeof(struct ptrace_faultinfo). | |
255 | fault = ((struct ptrace_faultinfo) | 236 | * On i386, ptrace_faultinfo is smaller! |
256 | { .is_write = child->thread.err, | 237 | */ |
257 | .addr = child->thread.cr2 }); | 238 | ret = copy_to_user((unsigned long __user *) data, |
258 | ret = copy_to_user((unsigned long __user *) data, &fault, | 239 | &child->thread.arch.faultinfo, |
259 | sizeof(fault)); | 240 | sizeof(struct ptrace_faultinfo)); |
260 | if(ret) | 241 | if(ret) |
261 | break; | 242 | break; |
262 | break; | 243 | break; |
263 | } | 244 | } |
264 | case PTRACE_SIGPENDING: | ||
265 | ret = copy_to_user((unsigned long __user *) data, | ||
266 | &child->pending.signal, | ||
267 | sizeof(child->pending.signal)); | ||
268 | break; | ||
269 | 245 | ||
246 | #ifdef PTRACE_LDT | ||
270 | case PTRACE_LDT: { | 247 | case PTRACE_LDT: { |
271 | struct ptrace_ldt ldt; | 248 | struct ptrace_ldt ldt; |
272 | 249 | ||
@@ -282,6 +259,7 @@ long sys_ptrace(long request, long pid, long addr, long data) | |||
282 | ret = -EIO; | 259 | ret = -EIO; |
283 | break; | 260 | break; |
284 | } | 261 | } |
262 | #endif | ||
285 | #ifdef CONFIG_PROC_MM | 263 | #ifdef CONFIG_PROC_MM |
286 | case PTRACE_SWITCH_MM: { | 264 | case PTRACE_SWITCH_MM: { |
287 | struct mm_struct *old = child->mm; | 265 | struct mm_struct *old = child->mm; |
diff --git a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c index 668df13d8c9d..e89218958f38 100644 --- a/arch/um/kernel/sigio_user.c +++ b/arch/um/kernel/sigio_user.c | |||
@@ -182,6 +182,7 @@ static int write_sigio_thread(void *unused) | |||
182 | int i, n, respond_fd; | 182 | int i, n, respond_fd; |
183 | char c; | 183 | char c; |
184 | 184 | ||
185 | signal(SIGWINCH, SIG_IGN); | ||
185 | fds = ¤t_poll; | 186 | fds = ¤t_poll; |
186 | while(1){ | 187 | while(1){ |
187 | n = poll(fds->poll, fds->used, -1); | 188 | n = poll(fds->poll, fds->used, -1); |
diff --git a/arch/um/kernel/skas/include/mode_kern-skas.h b/arch/um/kernel/skas/include/mode_kern-skas.h index 94c564962378..e48490028111 100644 --- a/arch/um/kernel/skas/include/mode_kern-skas.h +++ b/arch/um/kernel/skas/include/mode_kern-skas.h | |||
@@ -18,7 +18,6 @@ extern int copy_thread_skas(int nr, unsigned long clone_flags, | |||
18 | unsigned long sp, unsigned long stack_top, | 18 | unsigned long sp, unsigned long stack_top, |
19 | struct task_struct *p, struct pt_regs *regs); | 19 | struct task_struct *p, struct pt_regs *regs); |
20 | extern void release_thread_skas(struct task_struct *task); | 20 | extern void release_thread_skas(struct task_struct *task); |
21 | extern void exit_thread_skas(void); | ||
22 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); | 21 | extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); |
23 | extern void init_idle_skas(void); | 22 | extern void init_idle_skas(void); |
24 | extern void flush_tlb_kernel_range_skas(unsigned long start, | 23 | extern void flush_tlb_kernel_range_skas(unsigned long start, |
diff --git a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h index f0702c2c7204..96b51dba3471 100644 --- a/arch/um/kernel/skas/include/skas.h +++ b/arch/um/kernel/skas/include/skas.h | |||
@@ -27,9 +27,10 @@ extern void map(int fd, unsigned long virt, unsigned long len, int r, int w, | |||
27 | extern int unmap(int fd, void *addr, unsigned long len); | 27 | extern int unmap(int fd, void *addr, unsigned long len); |
28 | extern int protect(int fd, unsigned long addr, unsigned long len, | 28 | extern int protect(int fd, unsigned long addr, unsigned long len, |
29 | int r, int w, int x); | 29 | int r, int w, int x); |
30 | extern void user_signal(int sig, union uml_pt_regs *regs); | 30 | extern void user_signal(int sig, union uml_pt_regs *regs, int pid); |
31 | extern int new_mm(int from); | 31 | extern int new_mm(int from); |
32 | extern void start_userspace(int cpu); | 32 | extern void start_userspace(int cpu); |
33 | extern void get_skas_faultinfo(int pid, struct faultinfo * fi); | ||
33 | extern long execute_syscall_skas(void *r); | 34 | extern long execute_syscall_skas(void *r); |
34 | 35 | ||
35 | #endif | 36 | #endif |
diff --git a/arch/um/kernel/skas/include/uaccess-skas.h b/arch/um/kernel/skas/include/uaccess-skas.h index c35620385da0..cd6c280482cb 100644 --- a/arch/um/kernel/skas/include/uaccess-skas.h +++ b/arch/um/kernel/skas/include/uaccess-skas.h | |||
@@ -18,8 +18,8 @@ | |||
18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ | 18 | ((unsigned long) (addr) + (size) <= FIXADDR_USER_END) && \ |
19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) | 19 | ((unsigned long) (addr) + (size) >= (unsigned long)(addr)))) |
20 | 20 | ||
21 | static inline int __deprecated verify_area_skas(int type, const void * addr, | 21 | static inline int verify_area_skas(int type, const void * addr, |
22 | unsigned long size) | 22 | unsigned long size) |
23 | { | 23 | { |
24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); | 24 | return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); |
25 | } | 25 | } |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index b4ffaaa81241..773cd2b525fc 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -4,6 +4,7 @@ | |||
4 | */ | 4 | */ |
5 | 5 | ||
6 | #include <stdlib.h> | 6 | #include <stdlib.h> |
7 | #include <string.h> | ||
7 | #include <unistd.h> | 8 | #include <unistd.h> |
8 | #include <errno.h> | 9 | #include <errno.h> |
9 | #include <signal.h> | 10 | #include <signal.h> |
@@ -27,27 +28,37 @@ | |||
27 | #include "chan_user.h" | 28 | #include "chan_user.h" |
28 | #include "signal_user.h" | 29 | #include "signal_user.h" |
29 | #include "registers.h" | 30 | #include "registers.h" |
31 | #include "process.h" | ||
30 | 32 | ||
31 | int is_skas_winch(int pid, int fd, void *data) | 33 | int is_skas_winch(int pid, int fd, void *data) |
32 | { | 34 | { |
33 | if(pid != os_getpid()) | 35 | if(pid != os_getpgrp()) |
34 | return(0); | 36 | return(0); |
35 | 37 | ||
36 | register_winch_irq(-1, fd, -1, data); | 38 | register_winch_irq(-1, fd, -1, data); |
37 | return(1); | 39 | return(1); |
38 | } | 40 | } |
39 | 41 | ||
40 | static void handle_segv(int pid) | 42 | void get_skas_faultinfo(int pid, struct faultinfo * fi) |
41 | { | 43 | { |
42 | struct ptrace_faultinfo fault; | ||
43 | int err; | 44 | int err; |
44 | 45 | ||
45 | err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); | 46 | err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); |
46 | if(err) | 47 | if(err) |
47 | panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", | 48 | panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " |
48 | errno); | 49 | "errno = %d\n", errno); |
50 | |||
51 | /* Special handling for i386, which has different structs */ | ||
52 | if (sizeof(struct ptrace_faultinfo) < sizeof(struct faultinfo)) | ||
53 | memset((char *)fi + sizeof(struct ptrace_faultinfo), 0, | ||
54 | sizeof(struct faultinfo) - | ||
55 | sizeof(struct ptrace_faultinfo)); | ||
56 | } | ||
49 | 57 | ||
50 | segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); | 58 | static void handle_segv(int pid, union uml_pt_regs * regs) |
59 | { | ||
60 | get_skas_faultinfo(pid, ®s->skas.faultinfo); | ||
61 | segv(regs->skas.faultinfo, 0, 1, NULL); | ||
51 | } | 62 | } |
52 | 63 | ||
53 | /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ | 64 | /*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ |
@@ -163,7 +174,7 @@ void userspace(union uml_pt_regs *regs) | |||
163 | if(WIFSTOPPED(status)){ | 174 | if(WIFSTOPPED(status)){ |
164 | switch(WSTOPSIG(status)){ | 175 | switch(WSTOPSIG(status)){ |
165 | case SIGSEGV: | 176 | case SIGSEGV: |
166 | handle_segv(pid); | 177 | handle_segv(pid, regs); |
167 | break; | 178 | break; |
168 | case SIGTRAP + 0x80: | 179 | case SIGTRAP + 0x80: |
169 | handle_trap(pid, regs, local_using_sysemu); | 180 | handle_trap(pid, regs, local_using_sysemu); |
@@ -177,7 +188,7 @@ void userspace(union uml_pt_regs *regs) | |||
177 | case SIGBUS: | 188 | case SIGBUS: |
178 | case SIGFPE: | 189 | case SIGFPE: |
179 | case SIGWINCH: | 190 | case SIGWINCH: |
180 | user_signal(WSTOPSIG(status), regs); | 191 | user_signal(WSTOPSIG(status), regs, pid); |
181 | break; | 192 | break; |
182 | default: | 193 | default: |
183 | printk("userspace - child stopped with signal " | 194 | printk("userspace - child stopped with signal " |
@@ -190,6 +201,11 @@ void userspace(union uml_pt_regs *regs) | |||
190 | } | 201 | } |
191 | } | 202 | } |
192 | } | 203 | } |
204 | #define INIT_JMP_NEW_THREAD 0 | ||
205 | #define INIT_JMP_REMOVE_SIGSTACK 1 | ||
206 | #define INIT_JMP_CALLBACK 2 | ||
207 | #define INIT_JMP_HALT 3 | ||
208 | #define INIT_JMP_REBOOT 4 | ||
193 | 209 | ||
194 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | 210 | void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, |
195 | void (*handler)(int)) | 211 | void (*handler)(int)) |
@@ -225,7 +241,7 @@ void thread_wait(void *sw, void *fb) | |||
225 | *switch_buf = &buf; | 241 | *switch_buf = &buf; |
226 | fork_buf = fb; | 242 | fork_buf = fb; |
227 | if(sigsetjmp(buf, 1) == 0) | 243 | if(sigsetjmp(buf, 1) == 0) |
228 | siglongjmp(*fork_buf, 1); | 244 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
229 | } | 245 | } |
230 | 246 | ||
231 | void switch_threads(void *me, void *next) | 247 | void switch_threads(void *me, void *next) |
@@ -249,23 +265,31 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
249 | sigjmp_buf **switch_buf = switch_buf_ptr; | 265 | sigjmp_buf **switch_buf = switch_buf_ptr; |
250 | int n; | 266 | int n; |
251 | 267 | ||
268 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | ||
269 | SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, | ||
270 | SIGVTALRM, -1); | ||
271 | |||
252 | *fork_buf_ptr = &initial_jmpbuf; | 272 | *fork_buf_ptr = &initial_jmpbuf; |
253 | n = sigsetjmp(initial_jmpbuf, 1); | 273 | n = sigsetjmp(initial_jmpbuf, 1); |
254 | if(n == 0) | 274 | switch(n){ |
255 | new_thread_proc((void *) stack, new_thread_handler); | 275 | case INIT_JMP_NEW_THREAD: |
256 | else if(n == 1) | 276 | new_thread_proc((void *) stack, new_thread_handler); |
257 | remove_sigstack(); | 277 | break; |
258 | else if(n == 2){ | 278 | case INIT_JMP_REMOVE_SIGSTACK: |
279 | remove_sigstack(); | ||
280 | break; | ||
281 | case INIT_JMP_CALLBACK: | ||
259 | (*cb_proc)(cb_arg); | 282 | (*cb_proc)(cb_arg); |
260 | siglongjmp(*cb_back, 1); | 283 | siglongjmp(*cb_back, 1); |
261 | } | 284 | break; |
262 | else if(n == 3){ | 285 | case INIT_JMP_HALT: |
263 | kmalloc_ok = 0; | 286 | kmalloc_ok = 0; |
264 | return(0); | 287 | return(0); |
265 | } | 288 | case INIT_JMP_REBOOT: |
266 | else if(n == 4){ | ||
267 | kmalloc_ok = 0; | 289 | kmalloc_ok = 0; |
268 | return(1); | 290 | return(1); |
291 | default: | ||
292 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | ||
269 | } | 293 | } |
270 | siglongjmp(**switch_buf, 1); | 294 | siglongjmp(**switch_buf, 1); |
271 | } | 295 | } |
@@ -290,7 +314,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
290 | 314 | ||
291 | block_signals(); | 315 | block_signals(); |
292 | if(sigsetjmp(here, 1) == 0) | 316 | if(sigsetjmp(here, 1) == 0) |
293 | siglongjmp(initial_jmpbuf, 2); | 317 | siglongjmp(initial_jmpbuf, INIT_JMP_CALLBACK); |
294 | unblock_signals(); | 318 | unblock_signals(); |
295 | 319 | ||
296 | cb_proc = NULL; | 320 | cb_proc = NULL; |
@@ -301,13 +325,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
301 | void halt_skas(void) | 325 | void halt_skas(void) |
302 | { | 326 | { |
303 | block_signals(); | 327 | block_signals(); |
304 | siglongjmp(initial_jmpbuf, 3); | 328 | siglongjmp(initial_jmpbuf, INIT_JMP_HALT); |
305 | } | 329 | } |
306 | 330 | ||
307 | void reboot_skas(void) | 331 | void reboot_skas(void) |
308 | { | 332 | { |
309 | block_signals(); | 333 | block_signals(); |
310 | siglongjmp(initial_jmpbuf, 4); | 334 | siglongjmp(initial_jmpbuf, INIT_JMP_REBOOT); |
311 | } | 335 | } |
312 | 336 | ||
313 | void switch_mm_skas(int mm_fd) | 337 | void switch_mm_skas(int mm_fd) |
diff --git a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c index 5d096ea63b97..ab5d3271da0b 100644 --- a/arch/um/kernel/skas/process_kern.c +++ b/arch/um/kernel/skas/process_kern.c | |||
@@ -83,10 +83,6 @@ void release_thread_skas(struct task_struct *task) | |||
83 | { | 83 | { |
84 | } | 84 | } |
85 | 85 | ||
86 | void exit_thread_skas(void) | ||
87 | { | ||
88 | } | ||
89 | |||
90 | void fork_handler(int sig) | 86 | void fork_handler(int sig) |
91 | { | 87 | { |
92 | change_sig(SIGUSR1, 1); | 88 | change_sig(SIGUSR1, 1); |
diff --git a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c index 8e9b46d4702e..0dee1d95c806 100644 --- a/arch/um/kernel/skas/trap_user.c +++ b/arch/um/kernel/skas/trap_user.c | |||
@@ -5,12 +5,15 @@ | |||
5 | 5 | ||
6 | #include <signal.h> | 6 | #include <signal.h> |
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include "sysdep/ptrace.h" | ||
9 | #include "signal_user.h" | 8 | #include "signal_user.h" |
10 | #include "user_util.h" | 9 | #include "user_util.h" |
11 | #include "kern_util.h" | 10 | #include "kern_util.h" |
12 | #include "task.h" | 11 | #include "task.h" |
13 | #include "sigcontext.h" | 12 | #include "sigcontext.h" |
13 | #include "skas.h" | ||
14 | #include "ptrace_user.h" | ||
15 | #include "sysdep/ptrace.h" | ||
16 | #include "sysdep/ptrace_user.h" | ||
14 | 17 | ||
15 | void sig_handler_common_skas(int sig, void *sc_ptr) | 18 | void sig_handler_common_skas(int sig, void *sc_ptr) |
16 | { | 19 | { |
@@ -31,9 +34,11 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
31 | r = &TASK_REGS(get_current())->skas; | 34 | r = &TASK_REGS(get_current())->skas; |
32 | save_user = r->is_user; | 35 | save_user = r->is_user; |
33 | r->is_user = 0; | 36 | r->is_user = 0; |
34 | r->fault_addr = SC_FAULT_ADDR(sc); | 37 | if ( sig == SIGFPE || sig == SIGSEGV || |
35 | r->fault_type = SC_FAULT_TYPE(sc); | 38 | sig == SIGBUS || sig == SIGILL || |
36 | r->trap_type = SC_TRAP_TYPE(sc); | 39 | sig == SIGTRAP ) { |
40 | GET_FAULTINFO_FROM_SC(r->faultinfo, sc); | ||
41 | } | ||
37 | 42 | ||
38 | change_sig(SIGUSR1, 1); | 43 | change_sig(SIGUSR1, 1); |
39 | info = &sig_info[sig]; | 44 | info = &sig_info[sig]; |
@@ -45,14 +50,17 @@ void sig_handler_common_skas(int sig, void *sc_ptr) | |||
45 | r->is_user = save_user; | 50 | r->is_user = save_user; |
46 | } | 51 | } |
47 | 52 | ||
48 | void user_signal(int sig, union uml_pt_regs *regs) | 53 | extern int ptrace_faultinfo; |
54 | |||
55 | void user_signal(int sig, union uml_pt_regs *regs, int pid) | ||
49 | { | 56 | { |
50 | struct signal_info *info; | 57 | struct signal_info *info; |
58 | int segv = ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) || | ||
59 | (sig == SIGILL) || (sig == SIGTRAP)); | ||
51 | 60 | ||
52 | regs->skas.is_user = 1; | 61 | regs->skas.is_user = 1; |
53 | regs->skas.fault_addr = 0; | 62 | if (segv) |
54 | regs->skas.fault_type = 0; | 63 | get_skas_faultinfo(pid, ®s->skas.faultinfo); |
55 | regs->skas.trap_type = 0; | ||
56 | info = &sig_info[sig]; | 64 | info = &sig_info[sig]; |
57 | (*info->handler)(sig, regs); | 65 | (*info->handler)(sig, regs); |
58 | 66 | ||
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index f7da9d027672..75195281081e 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c | |||
@@ -29,9 +29,12 @@ static unsigned long maybe_map(unsigned long virt, int is_write) | |||
29 | if(IS_ERR(phys) || (is_write && !pte_write(pte))){ | 29 | if(IS_ERR(phys) || (is_write && !pte_write(pte))){ |
30 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); | 30 | err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); |
31 | if(err) | 31 | if(err) |
32 | return(0); | 32 | return(-1UL); |
33 | phys = um_virt_to_phys(current, virt, NULL); | 33 | phys = um_virt_to_phys(current, virt, NULL); |
34 | } | 34 | } |
35 | if(IS_ERR(phys)) | ||
36 | phys = (void *) -1; | ||
37 | |||
35 | return((unsigned long) phys); | 38 | return((unsigned long) phys); |
36 | } | 39 | } |
37 | 40 | ||
@@ -42,7 +45,7 @@ static int do_op(unsigned long addr, int len, int is_write, | |||
42 | int n; | 45 | int n; |
43 | 46 | ||
44 | addr = maybe_map(addr, is_write); | 47 | addr = maybe_map(addr, is_write); |
45 | if(addr == -1) | 48 | if(addr == -1UL) |
46 | return(-1); | 49 | return(-1); |
47 | 50 | ||
48 | page = phys_to_page(addr); | 51 | page = phys_to_page(addr); |
diff --git a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile index 17f5909d60f7..f7b7eba83340 100644 --- a/arch/um/kernel/skas/util/Makefile +++ b/arch/um/kernel/skas/util/Makefile | |||
@@ -2,3 +2,4 @@ hostprogs-y := mk_ptregs | |||
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o | 4 | mk_ptregs-objs := mk_ptregs-$(SUBARCH).o |
5 | HOSTCFLAGS_mk_ptregs-$(SUBARCH).o := -I$(objtree)/arch/um | ||
diff --git a/arch/um/kernel/skas/util/mk_ptregs-i386.c b/arch/um/kernel/skas/util/mk_ptregs-i386.c index 0788dd05bcac..1f96e1eeb8a7 100644 --- a/arch/um/kernel/skas/util/mk_ptregs-i386.c +++ b/arch/um/kernel/skas/util/mk_ptregs-i386.c | |||
@@ -1,8 +1,7 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <asm/ptrace.h> | 2 | #include <user-offsets.h> |
3 | #include <asm/user.h> | ||
4 | 3 | ||
5 | #define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val)) | 4 | #define SHOW(name) printf("#define %s %d\n", #name, name) |
6 | 5 | ||
7 | int main(int argc, char **argv) | 6 | int main(int argc, char **argv) |
8 | { | 7 | { |
@@ -12,28 +11,27 @@ int main(int argc, char **argv) | |||
12 | printf("#ifndef __SKAS_PT_REGS_\n"); | 11 | printf("#ifndef __SKAS_PT_REGS_\n"); |
13 | printf("#define __SKAS_PT_REGS_\n"); | 12 | printf("#define __SKAS_PT_REGS_\n"); |
14 | printf("\n"); | 13 | printf("\n"); |
15 | printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE); | 14 | SHOW(HOST_FRAME_SIZE); |
16 | printf("#define HOST_FP_SIZE %d\n", | 15 | SHOW(HOST_FP_SIZE); |
17 | sizeof(struct user_i387_struct) / sizeof(unsigned long)); | 16 | SHOW(HOST_XFP_SIZE); |
18 | printf("#define HOST_XFP_SIZE %d\n", | 17 | |
19 | sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); | 18 | SHOW(HOST_IP); |
19 | SHOW(HOST_SP); | ||
20 | SHOW(HOST_EFLAGS); | ||
21 | SHOW(HOST_EAX); | ||
22 | SHOW(HOST_EBX); | ||
23 | SHOW(HOST_ECX); | ||
24 | SHOW(HOST_EDX); | ||
25 | SHOW(HOST_ESI); | ||
26 | SHOW(HOST_EDI); | ||
27 | SHOW(HOST_EBP); | ||
28 | SHOW(HOST_CS); | ||
29 | SHOW(HOST_SS); | ||
30 | SHOW(HOST_DS); | ||
31 | SHOW(HOST_FS); | ||
32 | SHOW(HOST_ES); | ||
33 | SHOW(HOST_GS); | ||
20 | 34 | ||
21 | PRINT_REG("IP", EIP); | ||
22 | PRINT_REG("SP", UESP); | ||
23 | PRINT_REG("EFLAGS", EFL); | ||
24 | PRINT_REG("EAX", EAX); | ||
25 | PRINT_REG("EBX", EBX); | ||
26 | PRINT_REG("ECX", ECX); | ||
27 | PRINT_REG("EDX", EDX); | ||
28 | PRINT_REG("ESI", ESI); | ||
29 | PRINT_REG("EDI", EDI); | ||
30 | PRINT_REG("EBP", EBP); | ||
31 | PRINT_REG("CS", CS); | ||
32 | PRINT_REG("SS", SS); | ||
33 | PRINT_REG("DS", DS); | ||
34 | PRINT_REG("FS", FS); | ||
35 | PRINT_REG("ES", ES); | ||
36 | PRINT_REG("GS", GS); | ||
37 | printf("\n"); | 35 | printf("\n"); |
38 | printf("#endif\n"); | 36 | printf("#endif\n"); |
39 | return(0); | 37 | return(0); |
diff --git a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c index 67aee92a70ef..5fccbfe35f78 100644 --- a/arch/um/kernel/skas/util/mk_ptregs-x86_64.c +++ b/arch/um/kernel/skas/util/mk_ptregs-x86_64.c | |||
@@ -5,11 +5,10 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <stdio.h> | 7 | #include <stdio.h> |
8 | #define __FRAME_OFFSETS | 8 | #include <user-offsets.h> |
9 | #include <asm/ptrace.h> | ||
10 | 9 | ||
11 | #define PRINT_REG(name, val) \ | 10 | #define SHOW(name) \ |
12 | printf("#define HOST_%s (%d / sizeof(unsigned long))\n", (name), (val)) | 11 | printf("#define %s (%d / sizeof(unsigned long))\n", #name, name) |
13 | 12 | ||
14 | int main(int argc, char **argv) | 13 | int main(int argc, char **argv) |
15 | { | 14 | { |
@@ -18,36 +17,35 @@ int main(int argc, char **argv) | |||
18 | printf("\n"); | 17 | printf("\n"); |
19 | printf("#ifndef __SKAS_PT_REGS_\n"); | 18 | printf("#ifndef __SKAS_PT_REGS_\n"); |
20 | printf("#define __SKAS_PT_REGS_\n"); | 19 | printf("#define __SKAS_PT_REGS_\n"); |
21 | printf("#define HOST_FRAME_SIZE (%d / sizeof(unsigned long))\n", | 20 | SHOW(HOST_FRAME_SIZE); |
22 | FRAME_SIZE); | 21 | SHOW(HOST_RBX); |
23 | PRINT_REG("RBX", RBX); | 22 | SHOW(HOST_RCX); |
24 | PRINT_REG("RCX", RCX); | 23 | SHOW(HOST_RDI); |
25 | PRINT_REG("RDI", RDI); | 24 | SHOW(HOST_RSI); |
26 | PRINT_REG("RSI", RSI); | 25 | SHOW(HOST_RDX); |
27 | PRINT_REG("RDX", RDX); | 26 | SHOW(HOST_RBP); |
28 | PRINT_REG("RBP", RBP); | 27 | SHOW(HOST_RAX); |
29 | PRINT_REG("RAX", RAX); | 28 | SHOW(HOST_R8); |
30 | PRINT_REG("R8", R8); | 29 | SHOW(HOST_R9); |
31 | PRINT_REG("R9", R9); | 30 | SHOW(HOST_R10); |
32 | PRINT_REG("R10", R10); | 31 | SHOW(HOST_R11); |
33 | PRINT_REG("R11", R11); | 32 | SHOW(HOST_R12); |
34 | PRINT_REG("R12", R12); | 33 | SHOW(HOST_R13); |
35 | PRINT_REG("R13", R13); | 34 | SHOW(HOST_R14); |
36 | PRINT_REG("R14", R14); | 35 | SHOW(HOST_R15); |
37 | PRINT_REG("R15", R15); | 36 | SHOW(HOST_ORIG_RAX); |
38 | PRINT_REG("ORIG_RAX", ORIG_RAX); | 37 | SHOW(HOST_CS); |
39 | PRINT_REG("CS", CS); | 38 | SHOW(HOST_SS); |
40 | PRINT_REG("SS", SS); | 39 | SHOW(HOST_EFLAGS); |
41 | PRINT_REG("EFLAGS", EFLAGS); | ||
42 | #if 0 | 40 | #if 0 |
43 | PRINT_REG("FS", FS); | 41 | SHOW(HOST_FS); |
44 | PRINT_REG("GS", GS); | 42 | SHOW(HOST_GS); |
45 | PRINT_REG("DS", DS); | 43 | SHOW(HOST_DS); |
46 | PRINT_REG("ES", ES); | 44 | SHOW(HOST_ES); |
47 | #endif | 45 | #endif |
48 | 46 | ||
49 | PRINT_REG("IP", RIP); | 47 | SHOW(HOST_IP); |
50 | PRINT_REG("SP", RSP); | 48 | SHOW(HOST_SP); |
51 | printf("#define HOST_FP_SIZE 0\n"); | 49 | printf("#define HOST_FP_SIZE 0\n"); |
52 | printf("#define HOST_XFP_SIZE 0\n"); | 50 | printf("#define HOST_XFP_SIZE 0\n"); |
53 | printf("\n"); | 51 | printf("\n"); |
diff --git a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c index 42731e04f50f..b7a55251e897 100644 --- a/arch/um/kernel/syscall_kern.c +++ b/arch/um/kernel/syscall_kern.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "linux/utime.h" | 17 | #include "linux/utime.h" |
18 | #include "asm/mman.h" | 18 | #include "asm/mman.h" |
19 | #include "asm/uaccess.h" | 19 | #include "asm/uaccess.h" |
20 | #include "asm/ipc.h" | ||
21 | #include "kern_util.h" | 20 | #include "kern_util.h" |
22 | #include "user_util.h" | 21 | #include "user_util.h" |
23 | #include "sysdep/syscalls.h" | 22 | #include "sysdep/syscalls.h" |
diff --git a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c index 2461cd73ca87..6516fc52afe0 100644 --- a/arch/um/kernel/time_kern.c +++ b/arch/um/kernel/time_kern.c | |||
@@ -48,8 +48,6 @@ static unsigned long long prev_usecs; | |||
48 | static long long delta; /* Deviation per interval */ | 48 | static long long delta; /* Deviation per interval */ |
49 | #endif | 49 | #endif |
50 | 50 | ||
51 | #define MILLION 1000000 | ||
52 | |||
53 | void timer_irq(union uml_pt_regs *regs) | 51 | void timer_irq(union uml_pt_regs *regs) |
54 | { | 52 | { |
55 | unsigned long long ticks = 0; | 53 | unsigned long long ticks = 0; |
@@ -136,22 +134,6 @@ long um_stime(int __user *tptr) | |||
136 | return 0; | 134 | return 0; |
137 | } | 135 | } |
138 | 136 | ||
139 | void __udelay(unsigned long usecs) | ||
140 | { | ||
141 | int i, n; | ||
142 | |||
143 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
144 | for(i=0;i<n;i++) ; | ||
145 | } | ||
146 | |||
147 | void __const_udelay(unsigned long usecs) | ||
148 | { | ||
149 | int i, n; | ||
150 | |||
151 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
152 | for(i=0;i<n;i++) ; | ||
153 | } | ||
154 | |||
155 | void timer_handler(int sig, union uml_pt_regs *regs) | 137 | void timer_handler(int sig, union uml_pt_regs *regs) |
156 | { | 138 | { |
157 | local_irq_disable(); | 139 | local_irq_disable(); |
diff --git a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c index 47e766e6ba10..1de22d8a313a 100644 --- a/arch/um/kernel/trap_kern.c +++ b/arch/um/kernel/trap_kern.c | |||
@@ -48,7 +48,7 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
48 | goto good_area; | 48 | goto good_area; |
49 | else if(!(vma->vm_flags & VM_GROWSDOWN)) | 49 | else if(!(vma->vm_flags & VM_GROWSDOWN)) |
50 | goto out; | 50 | goto out; |
51 | else if(!ARCH_IS_STACKGROW(address)) | 51 | else if(is_user && !ARCH_IS_STACKGROW(address)) |
52 | goto out; | 52 | goto out; |
53 | else if(expand_stack(vma, address)) | 53 | else if(expand_stack(vma, address)) |
54 | goto out; | 54 | goto out; |
@@ -57,10 +57,11 @@ int handle_page_fault(unsigned long address, unsigned long ip, | |||
57 | *code_out = SEGV_ACCERR; | 57 | *code_out = SEGV_ACCERR; |
58 | if(is_write && !(vma->vm_flags & VM_WRITE)) | 58 | if(is_write && !(vma->vm_flags & VM_WRITE)) |
59 | goto out; | 59 | goto out; |
60 | |||
61 | if(!(vma->vm_flags & (VM_READ | VM_EXEC))) | ||
62 | goto out; | ||
63 | |||
60 | page = address & PAGE_MASK; | 64 | page = address & PAGE_MASK; |
61 | pgd = pgd_offset(mm, page); | ||
62 | pud = pud_offset(pgd, page); | ||
63 | pmd = pmd_offset(pud, page); | ||
64 | do { | 65 | do { |
65 | survive: | 66 | survive: |
66 | switch (handle_mm_fault(mm, vma, address, is_write)){ | 67 | switch (handle_mm_fault(mm, vma, address, is_write)){ |
@@ -106,46 +107,24 @@ out_of_memory: | |||
106 | goto out; | 107 | goto out; |
107 | } | 108 | } |
108 | 109 | ||
109 | LIST_HEAD(physmem_remappers); | 110 | /* |
110 | 111 | * We give a *copy* of the faultinfo in the regs to segv. | |
111 | void register_remapper(struct remapper *info) | 112 | * This must be done, since nesting SEGVs could overwrite |
112 | { | 113 | * the info in the regs. A pointer to the info then would |
113 | list_add(&info->list, &physmem_remappers); | 114 | * give us bad data! |
114 | } | 115 | */ |
115 | 116 | unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, void *sc) | |
116 | static int check_remapped_addr(unsigned long address, int is_write) | ||
117 | { | ||
118 | struct remapper *remapper; | ||
119 | struct list_head *ele; | ||
120 | __u64 offset; | ||
121 | int fd; | ||
122 | |||
123 | fd = phys_mapping(__pa(address), &offset); | ||
124 | if(fd == -1) | ||
125 | return(0); | ||
126 | |||
127 | list_for_each(ele, &physmem_remappers){ | ||
128 | remapper = list_entry(ele, struct remapper, list); | ||
129 | if((*remapper->proc)(fd, address, is_write, offset)) | ||
130 | return(1); | ||
131 | } | ||
132 | |||
133 | return(0); | ||
134 | } | ||
135 | |||
136 | unsigned long segv(unsigned long address, unsigned long ip, int is_write, | ||
137 | int is_user, void *sc) | ||
138 | { | 117 | { |
139 | struct siginfo si; | 118 | struct siginfo si; |
140 | void *catcher; | 119 | void *catcher; |
141 | int err; | 120 | int err; |
121 | int is_write = FAULT_WRITE(fi); | ||
122 | unsigned long address = FAULT_ADDRESS(fi); | ||
142 | 123 | ||
143 | if(!is_user && (address >= start_vm) && (address < end_vm)){ | 124 | if(!is_user && (address >= start_vm) && (address < end_vm)){ |
144 | flush_tlb_kernel_vm(); | 125 | flush_tlb_kernel_vm(); |
145 | return(0); | 126 | return(0); |
146 | } | 127 | } |
147 | else if(check_remapped_addr(address & PAGE_MASK, is_write)) | ||
148 | return(0); | ||
149 | else if(current->mm == NULL) | 128 | else if(current->mm == NULL) |
150 | panic("Segfault with no mm"); | 129 | panic("Segfault with no mm"); |
151 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); | 130 | err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); |
@@ -159,7 +138,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
159 | } | 138 | } |
160 | else if(current->thread.fault_addr != NULL) | 139 | else if(current->thread.fault_addr != NULL) |
161 | panic("fault_addr set but no fault catcher"); | 140 | panic("fault_addr set but no fault catcher"); |
162 | else if(arch_fixup(ip, sc)) | 141 | else if(!is_user && arch_fixup(ip, sc)) |
163 | return(0); | 142 | return(0); |
164 | 143 | ||
165 | if(!is_user) | 144 | if(!is_user) |
@@ -171,6 +150,7 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
171 | si.si_errno = 0; | 150 | si.si_errno = 0; |
172 | si.si_code = BUS_ADRERR; | 151 | si.si_code = BUS_ADRERR; |
173 | si.si_addr = (void *)address; | 152 | si.si_addr = (void *)address; |
153 | current->thread.arch.faultinfo = fi; | ||
174 | force_sig_info(SIGBUS, &si, current); | 154 | force_sig_info(SIGBUS, &si, current); |
175 | } | 155 | } |
176 | else if(err == -ENOMEM){ | 156 | else if(err == -ENOMEM){ |
@@ -180,22 +160,20 @@ unsigned long segv(unsigned long address, unsigned long ip, int is_write, | |||
180 | else { | 160 | else { |
181 | si.si_signo = SIGSEGV; | 161 | si.si_signo = SIGSEGV; |
182 | si.si_addr = (void *) address; | 162 | si.si_addr = (void *) address; |
183 | current->thread.cr2 = address; | 163 | current->thread.arch.faultinfo = fi; |
184 | current->thread.err = is_write; | ||
185 | force_sig_info(SIGSEGV, &si, current); | 164 | force_sig_info(SIGSEGV, &si, current); |
186 | } | 165 | } |
187 | return(0); | 166 | return(0); |
188 | } | 167 | } |
189 | 168 | ||
190 | void bad_segv(unsigned long address, unsigned long ip, int is_write) | 169 | void bad_segv(struct faultinfo fi, unsigned long ip) |
191 | { | 170 | { |
192 | struct siginfo si; | 171 | struct siginfo si; |
193 | 172 | ||
194 | si.si_signo = SIGSEGV; | 173 | si.si_signo = SIGSEGV; |
195 | si.si_code = SEGV_ACCERR; | 174 | si.si_code = SEGV_ACCERR; |
196 | si.si_addr = (void *) address; | 175 | si.si_addr = (void *) FAULT_ADDRESS(fi); |
197 | current->thread.cr2 = address; | 176 | current->thread.arch.faultinfo = fi; |
198 | current->thread.err = is_write; | ||
199 | force_sig_info(SIGSEGV, &si, current); | 177 | force_sig_info(SIGSEGV, &si, current); |
200 | } | 178 | } |
201 | 179 | ||
@@ -204,6 +182,7 @@ void relay_signal(int sig, union uml_pt_regs *regs) | |||
204 | if(arch_handle_signal(sig, regs)) return; | 182 | if(arch_handle_signal(sig, regs)) return; |
205 | if(!UPT_IS_USER(regs)) | 183 | if(!UPT_IS_USER(regs)) |
206 | panic("Kernel mode signal %d", sig); | 184 | panic("Kernel mode signal %d", sig); |
185 | current->thread.arch.faultinfo = *UPT_FAULTINFO(regs); | ||
207 | force_sig(sig, current); | 186 | force_sig(sig, current); |
208 | } | 187 | } |
209 | 188 | ||
diff --git a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c index 50a4042a509f..f825a6eda3f5 100644 --- a/arch/um/kernel/trap_user.c +++ b/arch/um/kernel/trap_user.c | |||
@@ -54,23 +54,22 @@ struct { | |||
54 | void segv_handler(int sig, union uml_pt_regs *regs) | 54 | void segv_handler(int sig, union uml_pt_regs *regs) |
55 | { | 55 | { |
56 | int index, max; | 56 | int index, max; |
57 | struct faultinfo * fi = UPT_FAULTINFO(regs); | ||
57 | 58 | ||
58 | if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ | 59 | if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ |
59 | bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), | 60 | bad_segv(*fi, UPT_IP(regs)); |
60 | UPT_FAULT_WRITE(regs)); | ||
61 | return; | 61 | return; |
62 | } | 62 | } |
63 | max = sizeof(segfault_record)/sizeof(segfault_record[0]); | 63 | max = sizeof(segfault_record)/sizeof(segfault_record[0]); |
64 | index = next_trap_index(max); | 64 | index = next_trap_index(max); |
65 | 65 | ||
66 | nsegfaults++; | 66 | nsegfaults++; |
67 | segfault_record[index].address = UPT_FAULT_ADDR(regs); | 67 | segfault_record[index].address = FAULT_ADDRESS(*fi); |
68 | segfault_record[index].pid = os_getpid(); | 68 | segfault_record[index].pid = os_getpid(); |
69 | segfault_record[index].is_write = UPT_FAULT_WRITE(regs); | 69 | segfault_record[index].is_write = FAULT_WRITE(*fi); |
70 | segfault_record[index].sp = UPT_SP(regs); | 70 | segfault_record[index].sp = UPT_SP(regs); |
71 | segfault_record[index].is_user = UPT_IS_USER(regs); | 71 | segfault_record[index].is_user = UPT_IS_USER(regs); |
72 | segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), | 72 | segv(*fi, UPT_IP(regs), UPT_IS_USER(regs), regs); |
73 | UPT_IS_USER(regs), regs); | ||
74 | } | 73 | } |
75 | 74 | ||
76 | void usr2_handler(int sig, union uml_pt_regs *regs) | 75 | void usr2_handler(int sig, union uml_pt_regs *regs) |
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile index 3d5177df3504..c3faea21a996 100644 --- a/arch/um/kernel/tt/Makefile +++ b/arch/um/kernel/tt/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # | 4 | # |
5 | 5 | ||
6 | extra-y := unmap_fin.o | 6 | extra-y := unmap_fin.o |
7 | targets := unmap.o | ||
7 | clean-files := unmap_tmp.o | 8 | clean-files := unmap_tmp.o |
8 | 9 | ||
9 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ | 10 | obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ |
diff --git a/arch/um/kernel/tt/include/mode_kern-tt.h b/arch/um/kernel/tt/include/mode_kern-tt.h index 28aaab3448fa..e0ca0e0b2516 100644 --- a/arch/um/kernel/tt/include/mode_kern-tt.h +++ b/arch/um/kernel/tt/include/mode_kern-tt.h | |||
@@ -19,7 +19,6 @@ extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, | |||
19 | unsigned long stack_top, struct task_struct *p, | 19 | unsigned long stack_top, struct task_struct *p, |
20 | struct pt_regs *regs); | 20 | struct pt_regs *regs); |
21 | extern void release_thread_tt(struct task_struct *task); | 21 | extern void release_thread_tt(struct task_struct *task); |
22 | extern void exit_thread_tt(void); | ||
23 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); | 22 | extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); |
24 | extern void init_idle_tt(void); | 23 | extern void init_idle_tt(void); |
25 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); | 24 | extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end); |
diff --git a/arch/um/kernel/tt/include/uaccess-tt.h b/arch/um/kernel/tt/include/uaccess-tt.h index bb69d6b7d022..3fbb5fe26f49 100644 --- a/arch/um/kernel/tt/include/uaccess-tt.h +++ b/arch/um/kernel/tt/include/uaccess-tt.h | |||
@@ -33,8 +33,8 @@ extern unsigned long uml_physmem; | |||
33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ | 33 | (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ |
34 | (under_task_size(addr, size) || is_stack(addr, size)))) | 34 | (under_task_size(addr, size) || is_stack(addr, size)))) |
35 | 35 | ||
36 | static inline int __deprecated verify_area_tt(int type, const void * addr, | 36 | static inline int verify_area_tt(int type, const void * addr, |
37 | unsigned long size) | 37 | unsigned long size) |
38 | { | 38 | { |
39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); | 39 | return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); |
40 | } | 40 | } |
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c index 92ec85d67c7c..84a9385a8fef 100644 --- a/arch/um/kernel/tt/ksyms.c +++ b/arch/um/kernel/tt/ksyms.c | |||
@@ -12,6 +12,7 @@ EXPORT_SYMBOL(__do_copy_to_user); | |||
12 | EXPORT_SYMBOL(__do_strncpy_from_user); | 12 | EXPORT_SYMBOL(__do_strncpy_from_user); |
13 | EXPORT_SYMBOL(__do_strnlen_user); | 13 | EXPORT_SYMBOL(__do_strnlen_user); |
14 | EXPORT_SYMBOL(__do_clear_user); | 14 | EXPORT_SYMBOL(__do_clear_user); |
15 | EXPORT_SYMBOL(clear_user_tt); | ||
15 | 16 | ||
16 | EXPORT_SYMBOL(tracing_pid); | 17 | EXPORT_SYMBOL(tracing_pid); |
17 | EXPORT_SYMBOL(honeypot); | 18 | EXPORT_SYMBOL(honeypot); |
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c index 74346a04a2b2..bcb8796c3cb1 100644 --- a/arch/um/kernel/tt/mem.c +++ b/arch/um/kernel/tt/mem.c | |||
@@ -21,14 +21,8 @@ void before_mem_tt(unsigned long brk_start) | |||
21 | remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); | 21 | remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); |
22 | } | 22 | } |
23 | 23 | ||
24 | #ifdef CONFIG_HOST_2G_2G | ||
25 | #define TOP 0x80000000 | ||
26 | #else | ||
27 | #define TOP 0xc0000000 | ||
28 | #endif | ||
29 | |||
30 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) | 24 | #define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) |
31 | #define START (TOP - SIZE) | 25 | #define START (CONFIG_TOP_ADDR - SIZE) |
32 | 26 | ||
33 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, | 27 | unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, |
34 | unsigned long *task_size_out) | 28 | unsigned long *task_size_out) |
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c index f19f7c18febe..df810ca8fc12 100644 --- a/arch/um/kernel/tt/process_kern.c +++ b/arch/um/kernel/tt/process_kern.c | |||
@@ -65,8 +65,7 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
65 | panic("write of switch_pipe failed, err = %d", -err); | 65 | panic("write of switch_pipe failed, err = %d", -err); |
66 | 66 | ||
67 | reading = 1; | 67 | reading = 1; |
68 | if((from->exit_state == EXIT_ZOMBIE) || | 68 | if(from->thread.mode.tt.switch_pipe[0] == -1) |
69 | (from->exit_state == EXIT_DEAD)) | ||
70 | os_kill_process(os_getpid(), 0); | 69 | os_kill_process(os_getpid(), 0); |
71 | 70 | ||
72 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); | 71 | err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); |
@@ -81,8 +80,7 @@ void *switch_to_tt(void *prev, void *next, void *last) | |||
81 | * in case it has not already killed itself. | 80 | * in case it has not already killed itself. |
82 | */ | 81 | */ |
83 | prev_sched = current->thread.prev_sched; | 82 | prev_sched = current->thread.prev_sched; |
84 | if((prev_sched->exit_state == EXIT_ZOMBIE) || | 83 | if(prev_sched->thread.mode.tt.switch_pipe[0] == -1) |
85 | (prev_sched->exit_state == EXIT_DEAD)) | ||
86 | os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); | 84 | os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1); |
87 | 85 | ||
88 | change_sig(SIGVTALRM, vtalrm); | 86 | change_sig(SIGVTALRM, vtalrm); |
@@ -101,14 +99,18 @@ void release_thread_tt(struct task_struct *task) | |||
101 | { | 99 | { |
102 | int pid = task->thread.mode.tt.extern_pid; | 100 | int pid = task->thread.mode.tt.extern_pid; |
103 | 101 | ||
102 | /* | ||
103 | * We first have to kill the other process, before | ||
104 | * closing its switch_pipe. Else it might wake up | ||
105 | * and receive "EOF" before we could kill it. | ||
106 | */ | ||
104 | if(os_getpid() != pid) | 107 | if(os_getpid() != pid) |
105 | os_kill_process(pid, 0); | 108 | os_kill_process(pid, 0); |
106 | } | ||
107 | 109 | ||
108 | void exit_thread_tt(void) | 110 | os_close_file(task->thread.mode.tt.switch_pipe[0]); |
109 | { | 111 | os_close_file(task->thread.mode.tt.switch_pipe[1]); |
110 | os_close_file(current->thread.mode.tt.switch_pipe[0]); | 112 | /* use switch_pipe as flag: thread is released */ |
111 | os_close_file(current->thread.mode.tt.switch_pipe[1]); | 113 | task->thread.mode.tt.switch_pipe[0] = -1; |
112 | } | 114 | } |
113 | 115 | ||
114 | void suspend_new_thread(int fd) | 116 | void suspend_new_thread(int fd) |
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c index e4e7e9c2224c..b218316cfdb2 100644 --- a/arch/um/kernel/tt/syscall_user.c +++ b/arch/um/kernel/tt/syscall_user.c | |||
@@ -63,6 +63,10 @@ void do_syscall(void *task, int pid, int local_using_sysemu) | |||
63 | 63 | ||
64 | UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); | 64 | UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs); |
65 | 65 | ||
66 | #ifdef UPT_ORIGGPR2 | ||
67 | UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs); | ||
68 | #endif | ||
69 | |||
66 | if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && | 70 | if(((unsigned long *) PT_IP(proc_regs) >= &_stext) && |
67 | ((unsigned long *) PT_IP(proc_regs) <= &_etext)) | 71 | ((unsigned long *) PT_IP(proc_regs) <= &_etext)) |
68 | tracer_panic("I'm tracing myself and I can't get out"); | 72 | tracer_panic("I'm tracing myself and I can't get out"); |
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c index 7b5d937e5955..d11e7399d7a1 100644 --- a/arch/um/kernel/tt/tracer.c +++ b/arch/um/kernel/tt/tracer.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "kern_util.h" | 26 | #include "kern_util.h" |
27 | #include "chan_user.h" | 27 | #include "chan_user.h" |
28 | #include "ptrace_user.h" | 28 | #include "ptrace_user.h" |
29 | #include "irq_user.h" | ||
29 | #include "mode.h" | 30 | #include "mode.h" |
30 | #include "tt.h" | 31 | #include "tt.h" |
31 | 32 | ||
@@ -33,7 +34,7 @@ static int tracer_winch[2]; | |||
33 | 34 | ||
34 | int is_tracer_winch(int pid, int fd, void *data) | 35 | int is_tracer_winch(int pid, int fd, void *data) |
35 | { | 36 | { |
36 | if(pid != tracing_pid) | 37 | if(pid != os_getpgrp()) |
37 | return(0); | 38 | return(0); |
38 | 39 | ||
39 | register_winch_irq(tracer_winch[0], fd, -1, data); | 40 | register_winch_irq(tracer_winch[0], fd, -1, data); |
@@ -89,8 +90,10 @@ void tracer_panic(char *format, ...) | |||
89 | 90 | ||
90 | static void tracer_segv(int sig, struct sigcontext sc) | 91 | static void tracer_segv(int sig, struct sigcontext sc) |
91 | { | 92 | { |
93 | struct faultinfo fi; | ||
94 | GET_FAULTINFO_FROM_SC(fi, &sc); | ||
92 | printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", | 95 | printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", |
93 | SC_FAULT_ADDR(&sc), SC_IP(&sc)); | 96 | FAULT_ADDRESS(fi), SC_IP(&sc)); |
94 | while(1) | 97 | while(1) |
95 | pause(); | 98 | pause(); |
96 | } | 99 | } |
@@ -117,6 +120,7 @@ static int signal_tramp(void *arg) | |||
117 | signal(SIGSEGV, (__sighandler_t) sig_handler); | 120 | signal(SIGSEGV, (__sighandler_t) sig_handler); |
118 | set_cmdline("(idle thread)"); | 121 | set_cmdline("(idle thread)"); |
119 | set_init_pid(os_getpid()); | 122 | set_init_pid(os_getpid()); |
123 | init_irq_signals(0); | ||
120 | proc = arg; | 124 | proc = arg; |
121 | return((*proc)(NULL)); | 125 | return((*proc)(NULL)); |
122 | } | 126 | } |
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c index 92a3820ca543..fc108615beaf 100644 --- a/arch/um/kernel/tt/trap_user.c +++ b/arch/um/kernel/tt/trap_user.c | |||
@@ -7,6 +7,7 @@ | |||
7 | #include <errno.h> | 7 | #include <errno.h> |
8 | #include <signal.h> | 8 | #include <signal.h> |
9 | #include "sysdep/ptrace.h" | 9 | #include "sysdep/ptrace.h" |
10 | #include "sysdep/sigcontext.h" | ||
10 | #include "signal_user.h" | 11 | #include "signal_user.h" |
11 | #include "user_util.h" | 12 | #include "user_util.h" |
12 | #include "kern_util.h" | 13 | #include "kern_util.h" |
@@ -28,6 +29,11 @@ void sig_handler_common_tt(int sig, void *sc_ptr) | |||
28 | change_sig(SIGSEGV, 1); | 29 | change_sig(SIGSEGV, 1); |
29 | 30 | ||
30 | r = &TASK_REGS(get_current())->tt; | 31 | r = &TASK_REGS(get_current())->tt; |
32 | if ( sig == SIGFPE || sig == SIGSEGV || | ||
33 | sig == SIGBUS || sig == SIGILL || | ||
34 | sig == SIGTRAP ) { | ||
35 | GET_FAULTINFO_FROM_SC(r->faultinfo, sc); | ||
36 | } | ||
31 | save_regs = *r; | 37 | save_regs = *r; |
32 | is_user = user_context(SC_SP(sc)); | 38 | is_user = user_context(SC_SP(sc)); |
33 | r->sc = sc; | 39 | r->sc = sc; |
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 5c49d88eed3d..4d10ec372a67 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include "asm/ptrace.h" | 23 | #include "asm/ptrace.h" |
24 | #include "asm/elf.h" | 24 | #include "asm/elf.h" |
25 | #include "asm/user.h" | 25 | #include "asm/user.h" |
26 | #include "asm/setup.h" | ||
26 | #include "ubd_user.h" | 27 | #include "ubd_user.h" |
27 | #include "asm/current.h" | 28 | #include "asm/current.h" |
28 | #include "asm/setup.h" | 29 | #include "asm/setup.h" |
@@ -42,9 +43,9 @@ | |||
42 | #define DEFAULT_COMMAND_LINE "root=98:0" | 43 | #define DEFAULT_COMMAND_LINE "root=98:0" |
43 | 44 | ||
44 | /* Changed in linux_main and setup_arch, which run before SMP is started */ | 45 | /* Changed in linux_main and setup_arch, which run before SMP is started */ |
45 | char command_line[COMMAND_LINE_SIZE] = { 0 }; | 46 | static char command_line[COMMAND_LINE_SIZE] = { 0 }; |
46 | 47 | ||
47 | void add_arg(char *arg) | 48 | static void add_arg(char *arg) |
48 | { | 49 | { |
49 | if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { | 50 | if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { |
50 | printf("add_arg: Too many command line arguments!\n"); | 51 | printf("add_arg: Too many command line arguments!\n"); |
@@ -449,7 +450,7 @@ void __init setup_arch(char **cmdline_p) | |||
449 | { | 450 | { |
450 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); | 451 | notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); |
451 | paging_init(); | 452 | paging_init(); |
452 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); | 453 | strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); |
453 | *cmdline_p = command_line; | 454 | *cmdline_p = command_line; |
454 | setup_hostinfo(); | 455 | setup_hostinfo(); |
455 | } | 456 | } |
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 76eadb309189..dd5355500bdc 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S | |||
@@ -73,6 +73,8 @@ SECTIONS | |||
73 | 73 | ||
74 | .got : { *(.got.plt) *(.got) } | 74 | .got : { *(.got.plt) *(.got) } |
75 | .dynamic : { *(.dynamic) } | 75 | .dynamic : { *(.dynamic) } |
76 | .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } | ||
77 | .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } | ||
76 | /* We want the small data sections together, so single-instruction offsets | 78 | /* We want the small data sections together, so single-instruction offsets |
77 | can access them all, and initialized data all before uninitialized, so | 79 | can access them all, and initialized data all before uninitialized, so |
78 | we can shorten the on-disk segment size. */ | 80 | we can shorten the on-disk segment size. */ |
diff --git a/arch/um/kernel/vmlinux.lds.S b/arch/um/kernel/vmlinux.lds.S new file mode 100644 index 000000000000..1660a769674b --- /dev/null +++ b/arch/um/kernel/vmlinux.lds.S | |||
@@ -0,0 +1,6 @@ | |||
1 | #include <linux/config.h> | ||
2 | #ifdef CONFIG_LD_SCRIPT_STATIC | ||
3 | #include "uml.lds.S" | ||
4 | #else | ||
5 | #include "dyn.lds.S" | ||
6 | #endif | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index ba9ca1cc790a..1e126bfd31a7 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -123,6 +123,11 @@ int os_getpid(void) | |||
123 | return(getpid()); | 123 | return(getpid()); |
124 | } | 124 | } |
125 | 125 | ||
126 | int os_getpgrp(void) | ||
127 | { | ||
128 | return getpgrp(); | ||
129 | } | ||
130 | |||
126 | int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, | 131 | int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, |
127 | int r, int w, int x) | 132 | int r, int w, int x) |
128 | { | 133 | { |
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 7eac1baf5975..c7bfd5ee3925 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c | |||
@@ -8,7 +8,7 @@ | |||
8 | #include "mode.h" | 8 | #include "mode.h" |
9 | #include "sysdep/signal.h" | 9 | #include "sysdep/signal.h" |
10 | 10 | ||
11 | void sig_handler(int sig) | 11 | void sig_handler(ARCH_SIGHDLR_PARAM) |
12 | { | 12 | { |
13 | struct sigcontext *sc; | 13 | struct sigcontext *sc; |
14 | 14 | ||
@@ -19,7 +19,7 @@ void sig_handler(int sig) | |||
19 | 19 | ||
20 | extern int timer_irq_inited; | 20 | extern int timer_irq_inited; |
21 | 21 | ||
22 | void alarm_handler(int sig) | 22 | void alarm_handler(ARCH_SIGHDLR_PARAM) |
23 | { | 23 | { |
24 | struct sigcontext *sc; | 24 | struct sigcontext *sc; |
25 | 25 | ||
diff --git a/arch/um/os-Linux/util/Makefile b/arch/um/os-Linux/util/Makefile index fb00ddf969bd..9778aed0c314 100644 --- a/arch/um/os-Linux/util/Makefile +++ b/arch/um/os-Linux/util/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | hostprogs-y := mk_user_constants | 1 | hostprogs-y := mk_user_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_user_constants-objs := mk_user_constants.o | 4 | HOSTCFLAGS_mk_user_constants.o := -I$(objtree)/arch/um |
diff --git a/arch/um/os-Linux/util/mk_user_constants.c b/arch/um/os-Linux/util/mk_user_constants.c index 0933518aa8bd..4838f30eecf0 100644 --- a/arch/um/os-Linux/util/mk_user_constants.c +++ b/arch/um/os-Linux/util/mk_user_constants.c | |||
@@ -1,11 +1,5 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <asm/types.h> | 2 | #include <user-offsets.h> |
3 | /* For some reason, x86_64 nowhere defines u64 and u32, even though they're | ||
4 | * used throughout the headers. | ||
5 | */ | ||
6 | typedef __u64 u64; | ||
7 | typedef __u32 u32; | ||
8 | #include <asm/user.h> | ||
9 | 3 | ||
10 | int main(int argc, char **argv) | 4 | int main(int argc, char **argv) |
11 | { | 5 | { |
@@ -20,7 +14,7 @@ int main(int argc, char **argv) | |||
20 | * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on | 14 | * x86_64 (216 vs 168 bytes). user_regs_struct is the correct size on |
21 | * both x86_64 and i386. | 15 | * both x86_64 and i386. |
22 | */ | 16 | */ |
23 | printf("#define UM_FRAME_SIZE %d\n", (int) sizeof(struct user_regs_struct)); | 17 | printf("#define UM_FRAME_SIZE %d\n", __UM_FRAME_SIZE); |
24 | 18 | ||
25 | printf("\n"); | 19 | printf("\n"); |
26 | printf("#endif\n"); | 20 | printf("#endif\n"); |
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules index 143f6fea0763..0b2491883d9c 100644 --- a/arch/um/scripts/Makefile.rules +++ b/arch/um/scripts/Makefile.rules | |||
@@ -2,12 +2,27 @@ | |||
2 | # arch/um: Generic definitions | 2 | # arch/um: Generic definitions |
3 | # =========================================================================== | 3 | # =========================================================================== |
4 | 4 | ||
5 | USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) | 5 | USER_SINGLE_OBJS := \ |
6 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | 6 | $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) |
7 | 7 | USER_OBJS += $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) | |
8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) | 8 | USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file)) |
9 | 9 | ||
10 | $(USER_OBJS): c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) $(CFLAGS_$(notdir $@)) | 10 | $(USER_OBJS) : c_flags = -Wp,-MD,$(depfile) $(USER_CFLAGS) \ |
11 | $(CFLAGS_$(notdir $@)) | ||
11 | 12 | ||
12 | quiet_cmd_make_link = SYMLINK $@ | 13 | quiet_cmd_make_link = SYMLINK $@ |
13 | cmd_make_link = rm -f $@; ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ | 14 | cmd_make_link = ln -sf $(srctree)/arch/$(SUBARCH)/$($(notdir $@)-dir)/$(notdir $@) $@ |
15 | |||
16 | # this needs to be before the foreach, because targets does not accept | ||
17 | # complete paths like $(obj)/$(f). To make sure this works, use a := assignment, | ||
18 | # or we will get $(obj)/$(f) in the "targets" value. | ||
19 | # Also, this forces you to use the := syntax when assigning to targets. | ||
20 | # Otherwise the line below will cause an infinite loop (if you don't know why, | ||
21 | # just do it). | ||
22 | |||
23 | targets := $(targets) $(SYMLINKS) | ||
24 | |||
25 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$(f)) | ||
26 | |||
27 | $(SYMLINKS): FORCE | ||
28 | $(call if_changed,make_link) | ||
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile index 950781e354de..4351e5605506 100644 --- a/arch/um/sys-i386/Makefile +++ b/arch/um/sys-i386/Makefile | |||
@@ -7,24 +7,13 @@ obj-$(CONFIG_MODULES) += module.o | |||
7 | 7 | ||
8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o | 8 | USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o |
9 | 9 | ||
10 | include arch/um/scripts/Makefile.rules | ||
11 | |||
12 | SYMLINKS = bitops.c semaphore.c highmem.c module.c | 10 | SYMLINKS = bitops.c semaphore.c highmem.c module.c |
13 | 11 | ||
14 | # this needs to be before the foreach, because clean-files does not accept | 12 | include arch/um/scripts/Makefile.rules |
15 | # complete paths like $(src)/$f. | ||
16 | clean-files := $(SYMLINKS) | ||
17 | |||
18 | targets += $(SYMLINKS) | ||
19 | |||
20 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
21 | 13 | ||
22 | bitops.c-dir = lib | 14 | bitops.c-dir = lib |
23 | semaphore.c-dir = kernel | 15 | semaphore.c-dir = kernel |
24 | highmem.c-dir = mm | 16 | highmem.c-dir = mm |
25 | module.c-dir = kernel | 17 | module.c-dir = kernel |
26 | 18 | ||
27 | $(SYMLINKS): FORCE | ||
28 | $(call if_changed,make_link) | ||
29 | |||
30 | subdir- := util | 19 | subdir- := util |
diff --git a/arch/um/sys-i386/checksum.S b/arch/um/sys-i386/checksum.S index a11171fb6223..d98b2fff3d08 100644 --- a/arch/um/sys-i386/checksum.S +++ b/arch/um/sys-i386/checksum.S | |||
@@ -38,7 +38,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
38 | 38 | ||
39 | .text | 39 | .text |
40 | .align 4 | 40 | .align 4 |
41 | .globl arch_csum_partial | 41 | .globl csum_partial |
42 | 42 | ||
43 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM | 43 | #ifndef CONFIG_X86_USE_PPRO_CHECKSUM |
44 | 44 | ||
@@ -49,7 +49,7 @@ unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) | |||
49 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte | 49 | * Fortunately, it is easy to convert 2-byte alignment to 4-byte |
50 | * alignment for the unrolled loop. | 50 | * alignment for the unrolled loop. |
51 | */ | 51 | */ |
52 | arch_csum_partial: | 52 | csum_partial: |
53 | pushl %esi | 53 | pushl %esi |
54 | pushl %ebx | 54 | pushl %ebx |
55 | movl 20(%esp),%eax # Function arg: unsigned int sum | 55 | movl 20(%esp),%eax # Function arg: unsigned int sum |
@@ -119,7 +119,7 @@ arch_csum_partial: | |||
119 | 119 | ||
120 | /* Version for PentiumII/PPro */ | 120 | /* Version for PentiumII/PPro */ |
121 | 121 | ||
122 | arch_csum_partial: | 122 | csum_partial: |
123 | pushl %esi | 123 | pushl %esi |
124 | pushl %ebx | 124 | pushl %ebx |
125 | movl 20(%esp),%eax # Function arg: unsigned int sum | 125 | movl 20(%esp),%eax # Function arg: unsigned int sum |
diff --git a/arch/um/sys-i386/delay.c b/arch/um/sys-i386/delay.c index 20d37dbbaf08..2c11b9770e8b 100644 --- a/arch/um/sys-i386/delay.c +++ b/arch/um/sys-i386/delay.c | |||
@@ -1,3 +1,8 @@ | |||
1 | #include <linux/module.h> | ||
2 | #include <linux/kernel.h> | ||
3 | #include <linux/delay.h> | ||
4 | #include <asm/param.h> | ||
5 | |||
1 | void __delay(unsigned long time) | 6 | void __delay(unsigned long time) |
2 | { | 7 | { |
3 | /* Stolen from the i386 __loop_delay */ | 8 | /* Stolen from the i386 __loop_delay */ |
@@ -12,3 +17,24 @@ void __delay(unsigned long time) | |||
12 | :"0" (time)); | 17 | :"0" (time)); |
13 | } | 18 | } |
14 | 19 | ||
20 | void __udelay(unsigned long usecs) | ||
21 | { | ||
22 | int i, n; | ||
23 | |||
24 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
25 | for(i=0;i<n;i++) | ||
26 | cpu_relax(); | ||
27 | } | ||
28 | |||
29 | EXPORT_SYMBOL(__udelay); | ||
30 | |||
31 | void __const_udelay(unsigned long usecs) | ||
32 | { | ||
33 | int i, n; | ||
34 | |||
35 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
36 | for(i=0;i<n;i++) | ||
37 | cpu_relax(); | ||
38 | } | ||
39 | |||
40 | EXPORT_SYMBOL(__const_udelay); | ||
diff --git a/arch/um/sys-i386/kernel-offsets.c b/arch/um/sys-i386/kernel-offsets.c new file mode 100644 index 000000000000..9f8ecd1fdd96 --- /dev/null +++ b/arch/um/sys-i386/kernel-offsets.c | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/stddef.h> | ||
3 | #include <linux/sched.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <asm/page.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define STR(x) #x | ||
11 | #define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " STR(val) " " #val: : ) | ||
12 | |||
13 | #define BLANK() asm volatile("\n->" : : ) | ||
14 | |||
15 | #define OFFSET(sym, str, mem) \ | ||
16 | DEFINE(sym, offsetof(struct str, mem)); | ||
17 | |||
18 | void foo(void) | ||
19 | { | ||
20 | OFFSET(TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | ||
21 | #ifdef CONFIG_MODE_TT | ||
22 | OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
23 | #endif | ||
24 | #include <common-offsets.h> | ||
25 | } | ||
diff --git a/arch/um/sys-i386/ksyms.c b/arch/um/sys-i386/ksyms.c index 74f70a120458..db524ab3f743 100644 --- a/arch/um/sys-i386/ksyms.c +++ b/arch/um/sys-i386/ksyms.c | |||
@@ -2,6 +2,7 @@ | |||
2 | #include "linux/in6.h" | 2 | #include "linux/in6.h" |
3 | #include "linux/rwsem.h" | 3 | #include "linux/rwsem.h" |
4 | #include "asm/byteorder.h" | 4 | #include "asm/byteorder.h" |
5 | #include "asm/delay.h" | ||
5 | #include "asm/semaphore.h" | 6 | #include "asm/semaphore.h" |
6 | #include "asm/uaccess.h" | 7 | #include "asm/uaccess.h" |
7 | #include "asm/checksum.h" | 8 | #include "asm/checksum.h" |
@@ -13,5 +14,8 @@ EXPORT_SYMBOL(__down_failed_trylock); | |||
13 | EXPORT_SYMBOL(__up_wakeup); | 14 | EXPORT_SYMBOL(__up_wakeup); |
14 | 15 | ||
15 | /* Networking helper routines. */ | 16 | /* Networking helper routines. */ |
16 | EXPORT_SYMBOL(csum_partial_copy_from); | 17 | EXPORT_SYMBOL(csum_partial); |
17 | EXPORT_SYMBOL(csum_partial_copy_to); | 18 | |
19 | /* delay core functions */ | ||
20 | EXPORT_SYMBOL(__const_udelay); | ||
21 | EXPORT_SYMBOL(__udelay); | ||
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c index 31bcb2f997d4..dc755b0b9db8 100644 --- a/arch/um/sys-i386/ldt.c +++ b/arch/um/sys-i386/ldt.c | |||
@@ -25,7 +25,7 @@ int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount) | |||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_MODE_SKAS | 27 | #ifdef CONFIG_MODE_SKAS |
28 | extern int userspace_pid; | 28 | extern int userspace_pid[]; |
29 | 29 | ||
30 | #include "skas_ptrace.h" | 30 | #include "skas_ptrace.h" |
31 | 31 | ||
@@ -56,7 +56,8 @@ int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount) | |||
56 | ldt = ((struct ptrace_ldt) { .func = func, | 56 | ldt = ((struct ptrace_ldt) { .func = func, |
57 | .ptr = buf, | 57 | .ptr = buf, |
58 | .bytecount = bytecount }); | 58 | .bytecount = bytecount }); |
59 | res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); | 59 | #warning Need to look up userspace_pid by cpu |
60 | res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt); | ||
60 | if(res < 0) | 61 | if(res < 0) |
61 | goto out; | 62 | goto out; |
62 | 63 | ||
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c index e470d28cdf84..e839ce65ad28 100644 --- a/arch/um/sys-i386/ptrace.c +++ b/arch/um/sys-i386/ptrace.c | |||
@@ -73,6 +73,25 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
73 | return 0; | 73 | return 0; |
74 | } | 74 | } |
75 | 75 | ||
76 | int poke_user(struct task_struct *child, long addr, long data) | ||
77 | { | ||
78 | if ((addr & 3) || addr < 0) | ||
79 | return -EIO; | ||
80 | |||
81 | if (addr < MAX_REG_OFFSET) | ||
82 | return putreg(child, addr, data); | ||
83 | |||
84 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
85 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
86 | addr -= offsetof(struct user, u_debugreg[0]); | ||
87 | addr = addr >> 2; | ||
88 | if((addr == 4) || (addr == 5)) return -EIO; | ||
89 | child->thread.arch.debugregs[addr] = data; | ||
90 | return 0; | ||
91 | } | ||
92 | return -EIO; | ||
93 | } | ||
94 | |||
76 | unsigned long getreg(struct task_struct *child, int regno) | 95 | unsigned long getreg(struct task_struct *child, int regno) |
77 | { | 96 | { |
78 | unsigned long retval = ~0UL; | 97 | unsigned long retval = ~0UL; |
@@ -93,6 +112,27 @@ unsigned long getreg(struct task_struct *child, int regno) | |||
93 | return retval; | 112 | return retval; |
94 | } | 113 | } |
95 | 114 | ||
115 | int peek_user(struct task_struct *child, long addr, long data) | ||
116 | { | ||
117 | /* read the word at location addr in the USER area. */ | ||
118 | unsigned long tmp; | ||
119 | |||
120 | if ((addr & 3) || addr < 0) | ||
121 | return -EIO; | ||
122 | |||
123 | tmp = 0; /* Default return condition */ | ||
124 | if(addr < MAX_REG_OFFSET){ | ||
125 | tmp = getreg(child, addr); | ||
126 | } | ||
127 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
128 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
129 | addr -= offsetof(struct user, u_debugreg[0]); | ||
130 | addr = addr >> 2; | ||
131 | tmp = child->thread.arch.debugregs[addr]; | ||
132 | } | ||
133 | return put_user(tmp, (unsigned long *) data); | ||
134 | } | ||
135 | |||
96 | struct i387_fxsave_struct { | 136 | struct i387_fxsave_struct { |
97 | unsigned short cwd; | 137 | unsigned short cwd; |
98 | unsigned short swd; | 138 | unsigned short swd; |
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 76ba87254b25..03913ca5d256 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -47,9 +47,6 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
47 | REGS_CS(regs->regs.skas.regs) = sc.cs; | 47 | REGS_CS(regs->regs.skas.regs) = sc.cs; |
48 | REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; | 48 | REGS_EFLAGS(regs->regs.skas.regs) = sc.eflags; |
49 | REGS_SS(regs->regs.skas.regs) = sc.ss; | 49 | REGS_SS(regs->regs.skas.regs) = sc.ss; |
50 | regs->regs.skas.fault_addr = sc.cr2; | ||
51 | regs->regs.skas.fault_type = FAULT_WRITE(sc.err); | ||
52 | regs->regs.skas.trap_type = sc.trapno; | ||
53 | 50 | ||
54 | err = restore_fp_registers(userspace_pid[0], fpregs); | 51 | err = restore_fp_registers(userspace_pid[0], fpregs); |
55 | if(err < 0){ | 52 | if(err < 0){ |
@@ -62,11 +59,11 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
62 | } | 59 | } |
63 | 60 | ||
64 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 61 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, |
65 | struct pt_regs *regs, unsigned long fault_addr, | 62 | struct pt_regs *regs) |
66 | int fault_type) | ||
67 | { | 63 | { |
68 | struct sigcontext sc; | 64 | struct sigcontext sc; |
69 | unsigned long fpregs[HOST_FP_SIZE]; | 65 | unsigned long fpregs[HOST_FP_SIZE]; |
66 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; | ||
70 | int err; | 67 | int err; |
71 | 68 | ||
72 | sc.gs = REGS_GS(regs->regs.skas.regs); | 69 | sc.gs = REGS_GS(regs->regs.skas.regs); |
@@ -86,9 +83,9 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | |||
86 | sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); | 83 | sc.eflags = REGS_EFLAGS(regs->regs.skas.regs); |
87 | sc.esp_at_signal = regs->regs.skas.regs[UESP]; | 84 | sc.esp_at_signal = regs->regs.skas.regs[UESP]; |
88 | sc.ss = regs->regs.skas.regs[SS]; | 85 | sc.ss = regs->regs.skas.regs[SS]; |
89 | sc.cr2 = fault_addr; | 86 | sc.cr2 = fi->cr2; |
90 | sc.err = TO_SC_ERR(fault_type); | 87 | sc.err = fi->error_code; |
91 | sc.trapno = regs->regs.skas.trap_type; | 88 | sc.trapno = fi->trap_no; |
92 | 89 | ||
93 | err = save_fp_registers(userspace_pid[0], fpregs); | 90 | err = save_fp_registers(userspace_pid[0], fpregs); |
94 | if(err < 0){ | 91 | if(err < 0){ |
@@ -167,9 +164,7 @@ static int copy_sc_to_user(struct sigcontext *to, struct _fpstate *fp, | |||
167 | { | 164 | { |
168 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 165 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), |
169 | sizeof(*fp)), | 166 | sizeof(*fp)), |
170 | copy_sc_to_user_skas(to, fp, from, | 167 | copy_sc_to_user_skas(to, fp, from))); |
171 | current->thread.cr2, | ||
172 | current->thread.err))); | ||
173 | } | 168 | } |
174 | 169 | ||
175 | static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, | 170 | static int copy_ucontext_to_user(struct ucontext *uc, struct _fpstate *fp, |
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c new file mode 100644 index 000000000000..3ceaabceb3d7 --- /dev/null +++ b/arch/um/sys-i386/user-offsets.c | |||
@@ -0,0 +1,69 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <signal.h> | ||
3 | #include <asm/ptrace.h> | ||
4 | #include <asm/user.h> | ||
5 | #include <linux/stddef.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define OFFSET(sym, str, mem) \ | ||
11 | DEFINE(sym, offsetof(struct str, mem)); | ||
12 | |||
13 | void foo(void) | ||
14 | { | ||
15 | OFFSET(SC_IP, sigcontext, eip); | ||
16 | OFFSET(SC_SP, sigcontext, esp); | ||
17 | OFFSET(SC_FS, sigcontext, fs); | ||
18 | OFFSET(SC_GS, sigcontext, gs); | ||
19 | OFFSET(SC_DS, sigcontext, ds); | ||
20 | OFFSET(SC_ES, sigcontext, es); | ||
21 | OFFSET(SC_SS, sigcontext, ss); | ||
22 | OFFSET(SC_CS, sigcontext, cs); | ||
23 | OFFSET(SC_EFLAGS, sigcontext, eflags); | ||
24 | OFFSET(SC_EAX, sigcontext, eax); | ||
25 | OFFSET(SC_EBX, sigcontext, ebx); | ||
26 | OFFSET(SC_ECX, sigcontext, ecx); | ||
27 | OFFSET(SC_EDX, sigcontext, edx); | ||
28 | OFFSET(SC_EDI, sigcontext, edi); | ||
29 | OFFSET(SC_ESI, sigcontext, esi); | ||
30 | OFFSET(SC_EBP, sigcontext, ebp); | ||
31 | OFFSET(SC_TRAPNO, sigcontext, trapno); | ||
32 | OFFSET(SC_ERR, sigcontext, err); | ||
33 | OFFSET(SC_CR2, sigcontext, cr2); | ||
34 | OFFSET(SC_FPSTATE, sigcontext, fpstate); | ||
35 | OFFSET(SC_SIGMASK, sigcontext, oldmask); | ||
36 | OFFSET(SC_FP_CW, _fpstate, cw); | ||
37 | OFFSET(SC_FP_SW, _fpstate, sw); | ||
38 | OFFSET(SC_FP_TAG, _fpstate, tag); | ||
39 | OFFSET(SC_FP_IPOFF, _fpstate, ipoff); | ||
40 | OFFSET(SC_FP_CSSEL, _fpstate, cssel); | ||
41 | OFFSET(SC_FP_DATAOFF, _fpstate, dataoff); | ||
42 | OFFSET(SC_FP_DATASEL, _fpstate, datasel); | ||
43 | OFFSET(SC_FP_ST, _fpstate, _st); | ||
44 | OFFSET(SC_FXSR_ENV, _fpstate, _fxsr_env); | ||
45 | |||
46 | DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); | ||
47 | DEFINE(HOST_FP_SIZE, | ||
48 | sizeof(struct user_i387_struct) / sizeof(unsigned long)); | ||
49 | DEFINE(HOST_XFP_SIZE, | ||
50 | sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); | ||
51 | |||
52 | DEFINE(HOST_IP, EIP); | ||
53 | DEFINE(HOST_SP, UESP); | ||
54 | DEFINE(HOST_EFLAGS, EFL); | ||
55 | DEFINE(HOST_EAX, EAX); | ||
56 | DEFINE(HOST_EBX, EBX); | ||
57 | DEFINE(HOST_ECX, ECX); | ||
58 | DEFINE(HOST_EDX, EDX); | ||
59 | DEFINE(HOST_ESI, ESI); | ||
60 | DEFINE(HOST_EDI, EDI); | ||
61 | DEFINE(HOST_EBP, EBP); | ||
62 | DEFINE(HOST_CS, CS); | ||
63 | DEFINE(HOST_SS, SS); | ||
64 | DEFINE(HOST_DS, DS); | ||
65 | DEFINE(HOST_FS, FS); | ||
66 | DEFINE(HOST_ES, ES); | ||
67 | DEFINE(HOST_GS, GS); | ||
68 | DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); | ||
69 | } | ||
diff --git a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile index 34860f9ca7b0..bf61afd0b045 100644 --- a/arch/um/sys-i386/util/Makefile +++ b/arch/um/sys-i386/util/Makefile | |||
@@ -1,8 +1,5 @@ | |||
1 | |||
2 | hostprogs-y := mk_sc mk_thread | 1 | hostprogs-y := mk_sc mk_thread |
3 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
4 | 3 | ||
5 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 4 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
6 | 5 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
7 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS) | ||
diff --git a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c index 85cbd30396f7..04c0d73433aa 100644 --- a/arch/um/sys-i386/util/mk_sc.c +++ b/arch/um/sys-i386/util/mk_sc.c | |||
@@ -1,52 +1,51 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <signal.h> | 2 | #include <user-offsets.h> |
3 | #include <linux/stddef.h> | ||
4 | 3 | ||
5 | #define SC_OFFSET(name, field) \ | 4 | #define SC_OFFSET(name, field) \ |
6 | printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ | 5 | printf("#define " #name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ |
7 | offsetof(struct sigcontext, field)) | 6 | name) |
8 | 7 | ||
9 | #define SC_FP_OFFSET(name, field) \ | 8 | #define SC_FP_OFFSET(name, field) \ |
10 | printf("#define " name \ | 9 | printf("#define " #name \ |
11 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | 10 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ |
12 | offsetof(struct _fpstate, field)) | 11 | name) |
13 | 12 | ||
14 | #define SC_FP_OFFSET_PTR(name, field, type) \ | 13 | #define SC_FP_OFFSET_PTR(name, field, type) \ |
15 | printf("#define " name \ | 14 | printf("#define " #name \ |
16 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | 15 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ |
17 | offsetof(struct _fpstate, field)) | 16 | name) |
18 | 17 | ||
19 | int main(int argc, char **argv) | 18 | int main(int argc, char **argv) |
20 | { | 19 | { |
21 | SC_OFFSET("SC_IP", eip); | 20 | SC_OFFSET(SC_IP, eip); |
22 | SC_OFFSET("SC_SP", esp); | 21 | SC_OFFSET(SC_SP, esp); |
23 | SC_OFFSET("SC_FS", fs); | 22 | SC_OFFSET(SC_FS, fs); |
24 | SC_OFFSET("SC_GS", gs); | 23 | SC_OFFSET(SC_GS, gs); |
25 | SC_OFFSET("SC_DS", ds); | 24 | SC_OFFSET(SC_DS, ds); |
26 | SC_OFFSET("SC_ES", es); | 25 | SC_OFFSET(SC_ES, es); |
27 | SC_OFFSET("SC_SS", ss); | 26 | SC_OFFSET(SC_SS, ss); |
28 | SC_OFFSET("SC_CS", cs); | 27 | SC_OFFSET(SC_CS, cs); |
29 | SC_OFFSET("SC_EFLAGS", eflags); | 28 | SC_OFFSET(SC_EFLAGS, eflags); |
30 | SC_OFFSET("SC_EAX", eax); | 29 | SC_OFFSET(SC_EAX, eax); |
31 | SC_OFFSET("SC_EBX", ebx); | 30 | SC_OFFSET(SC_EBX, ebx); |
32 | SC_OFFSET("SC_ECX", ecx); | 31 | SC_OFFSET(SC_ECX, ecx); |
33 | SC_OFFSET("SC_EDX", edx); | 32 | SC_OFFSET(SC_EDX, edx); |
34 | SC_OFFSET("SC_EDI", edi); | 33 | SC_OFFSET(SC_EDI, edi); |
35 | SC_OFFSET("SC_ESI", esi); | 34 | SC_OFFSET(SC_ESI, esi); |
36 | SC_OFFSET("SC_EBP", ebp); | 35 | SC_OFFSET(SC_EBP, ebp); |
37 | SC_OFFSET("SC_TRAPNO", trapno); | 36 | SC_OFFSET(SC_TRAPNO, trapno); |
38 | SC_OFFSET("SC_ERR", err); | 37 | SC_OFFSET(SC_ERR, err); |
39 | SC_OFFSET("SC_CR2", cr2); | 38 | SC_OFFSET(SC_CR2, cr2); |
40 | SC_OFFSET("SC_FPSTATE", fpstate); | 39 | SC_OFFSET(SC_FPSTATE, fpstate); |
41 | SC_OFFSET("SC_SIGMASK", oldmask); | 40 | SC_OFFSET(SC_SIGMASK, oldmask); |
42 | SC_FP_OFFSET("SC_FP_CW", cw); | 41 | SC_FP_OFFSET(SC_FP_CW, cw); |
43 | SC_FP_OFFSET("SC_FP_SW", sw); | 42 | SC_FP_OFFSET(SC_FP_SW, sw); |
44 | SC_FP_OFFSET("SC_FP_TAG", tag); | 43 | SC_FP_OFFSET(SC_FP_TAG, tag); |
45 | SC_FP_OFFSET("SC_FP_IPOFF", ipoff); | 44 | SC_FP_OFFSET(SC_FP_IPOFF, ipoff); |
46 | SC_FP_OFFSET("SC_FP_CSSEL", cssel); | 45 | SC_FP_OFFSET(SC_FP_CSSEL, cssel); |
47 | SC_FP_OFFSET("SC_FP_DATAOFF", dataoff); | 46 | SC_FP_OFFSET(SC_FP_DATAOFF, dataoff); |
48 | SC_FP_OFFSET("SC_FP_DATASEL", datasel); | 47 | SC_FP_OFFSET(SC_FP_DATASEL, datasel); |
49 | SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate"); | 48 | SC_FP_OFFSET_PTR(SC_FP_ST, _st, "struct _fpstate"); |
50 | SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void"); | 49 | SC_FP_OFFSET_PTR(SC_FXSR_ENV, _fxsr_env, "void"); |
51 | return(0); | 50 | return(0); |
52 | } | 51 | } |
diff --git a/arch/um/sys-i386/util/mk_thread.c b/arch/um/sys-i386/util/mk_thread.c new file mode 100644 index 000000000000..7470d0dda67e --- /dev/null +++ b/arch/um/sys-i386/util/mk_thread.c | |||
@@ -0,0 +1,22 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | int main(int argc, char **argv) | ||
5 | { | ||
6 | printf("/*\n"); | ||
7 | printf(" * Generated by mk_thread\n"); | ||
8 | printf(" */\n"); | ||
9 | printf("\n"); | ||
10 | printf("#ifndef __UM_THREAD_H\n"); | ||
11 | printf("#define __UM_THREAD_H\n"); | ||
12 | printf("\n"); | ||
13 | printf("#define TASK_DEBUGREGS(task) ((unsigned long *) " | ||
14 | "&(((char *) (task))[%d]))\n", TASK_DEBUGREGS); | ||
15 | #ifdef TASK_EXTERN_PID | ||
16 | printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", | ||
17 | TASK_EXTERN_PID); | ||
18 | #endif | ||
19 | printf("\n"); | ||
20 | printf("#endif\n"); | ||
21 | return(0); | ||
22 | } | ||
diff --git a/arch/um/sys-i386/util/mk_thread_kern.c b/arch/um/sys-i386/util/mk_thread_kern.c deleted file mode 100644 index 948b1ce85230..000000000000 --- a/arch/um/sys-i386/util/mk_thread_kern.c +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #include "linux/config.h" | ||
2 | #include "linux/stddef.h" | ||
3 | #include "linux/sched.h" | ||
4 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int main(int argc, char **argv) | ||
13 | { | ||
14 | print_head(); | ||
15 | print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs)); | ||
16 | #ifdef CONFIG_MODE_TT | ||
17 | print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); | ||
18 | #endif | ||
19 | print_tail(); | ||
20 | return(0); | ||
21 | } | ||
22 | |||
diff --git a/arch/um/sys-i386/util/mk_thread_user.c b/arch/um/sys-i386/util/mk_thread_user.c deleted file mode 100644 index 2620cd6aa1f1..000000000000 --- a/arch/um/sys-i386/util/mk_thread_user.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_thread\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_THREAD_H\n"); | ||
10 | printf("#define __UM_THREAD_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void print_constant(char *name, char *type, int value) | ||
21 | { | ||
22 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | ||
23 | value); | ||
24 | } | ||
25 | |||
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | ||
29 | printf("#endif\n"); | ||
30 | } | ||
diff --git a/arch/um/sys-ppc/ptrace.c b/arch/um/sys-ppc/ptrace.c index a971366d3277..8e71b47f2b8e 100644 --- a/arch/um/sys-ppc/ptrace.c +++ b/arch/um/sys-ppc/ptrace.c | |||
@@ -8,6 +8,25 @@ int putreg(struct task_struct *child, unsigned long regno, | |||
8 | return 0; | 8 | return 0; |
9 | } | 9 | } |
10 | 10 | ||
11 | int poke_user(struct task_struct *child, long addr, long data) | ||
12 | { | ||
13 | if ((addr & 3) || addr < 0) | ||
14 | return -EIO; | ||
15 | |||
16 | if (addr < MAX_REG_OFFSET) | ||
17 | return putreg(child, addr, data); | ||
18 | |||
19 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
20 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
21 | addr -= offsetof(struct user, u_debugreg[0]); | ||
22 | addr = addr >> 2; | ||
23 | if((addr == 4) || (addr == 5)) return -EIO; | ||
24 | child->thread.arch.debugregs[addr] = data; | ||
25 | return 0; | ||
26 | } | ||
27 | return -EIO; | ||
28 | } | ||
29 | |||
11 | unsigned long getreg(struct task_struct *child, unsigned long regno) | 30 | unsigned long getreg(struct task_struct *child, unsigned long regno) |
12 | { | 31 | { |
13 | unsigned long retval = ~0UL; | 32 | unsigned long retval = ~0UL; |
@@ -16,6 +35,27 @@ unsigned long getreg(struct task_struct *child, unsigned long regno) | |||
16 | return retval; | 35 | return retval; |
17 | } | 36 | } |
18 | 37 | ||
38 | int peek_user(struct task_struct *child, long addr, long data) | ||
39 | { | ||
40 | /* read the word at location addr in the USER area. */ | ||
41 | unsigned long tmp; | ||
42 | |||
43 | if ((addr & 3) || addr < 0) | ||
44 | return -EIO; | ||
45 | |||
46 | tmp = 0; /* Default return condition */ | ||
47 | if(addr < MAX_REG_OFFSET){ | ||
48 | tmp = getreg(child, addr); | ||
49 | } | ||
50 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
51 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
52 | addr -= offsetof(struct user, u_debugreg[0]); | ||
53 | addr = addr >> 2; | ||
54 | tmp = child->thread.arch.debugregs[addr]; | ||
55 | } | ||
56 | return put_user(tmp, (unsigned long *) data); | ||
57 | } | ||
58 | |||
19 | /* | 59 | /* |
20 | * Overrides for Emacs so that we follow Linus's tabbing style. | 60 | * Overrides for Emacs so that we follow Linus's tabbing style. |
21 | * Emacs will notice this stuff at the end of the file and automatically | 61 | * Emacs will notice this stuff at the end of the file and automatically |
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile index d7ed2f7908df..608466ad6b22 100644 --- a/arch/um/sys-x86_64/Makefile +++ b/arch/um/sys-x86_64/Makefile | |||
@@ -4,24 +4,20 @@ | |||
4 | # Licensed under the GPL | 4 | # Licensed under the GPL |
5 | # | 5 | # |
6 | 6 | ||
7 | #XXX: why into lib-y? | ||
7 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ | 8 | lib-y = bitops.o bugs.o csum-partial.o delay.o fault.o mem.o memcpy.o \ |
8 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ | 9 | ptrace.o ptrace_user.o semaphore.o sigcontext.o signal.o \ |
9 | syscalls.o sysrq.o thunk.o syscall_table.o | 10 | syscalls.o sysrq.o thunk.o syscall_table.o |
10 | 11 | ||
11 | USER_OBJS := ptrace_user.o sigcontext.o | 12 | obj-y := ksyms.o |
13 | obj-$(CONFIG_MODULES) += module.o um_module.o | ||
12 | 14 | ||
13 | include arch/um/scripts/Makefile.rules | 15 | USER_OBJS := ptrace_user.o sigcontext.o |
14 | 16 | ||
15 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ | 17 | SYMLINKS = bitops.c csum-copy.S csum-partial.c csum-wrappers.c memcpy.S \ |
16 | semaphore.c thunk.S | 18 | semaphore.c thunk.S module.c |
17 | |||
18 | # this needs to be before the foreach, because clean-files does not accept | ||
19 | # complete paths like $(src)/$f. | ||
20 | clean-files := $(SYMLINKS) | ||
21 | 19 | ||
22 | targets += $(SYMLINKS) | 20 | include arch/um/scripts/Makefile.rules |
23 | |||
24 | SYMLINKS := $(foreach f,$(SYMLINKS),$(obj)/$f) | ||
25 | 21 | ||
26 | bitops.c-dir = lib | 22 | bitops.c-dir = lib |
27 | csum-copy.S-dir = lib | 23 | csum-copy.S-dir = lib |
@@ -30,8 +26,6 @@ csum-wrappers.c-dir = lib | |||
30 | memcpy.S-dir = lib | 26 | memcpy.S-dir = lib |
31 | semaphore.c-dir = kernel | 27 | semaphore.c-dir = kernel |
32 | thunk.S-dir = lib | 28 | thunk.S-dir = lib |
29 | module.c-dir = kernel | ||
33 | 30 | ||
34 | $(SYMLINKS): FORCE | 31 | subdir- := util |
35 | $(call if_changed,make_link) | ||
36 | |||
37 | CFLAGS_csum-partial.o := -Dcsum_partial=arch_csum_partial | ||
diff --git a/arch/um/sys-x86_64/delay.c b/arch/um/sys-x86_64/delay.c index f3b5187942b4..137f4446b439 100644 --- a/arch/um/sys-x86_64/delay.c +++ b/arch/um/sys-x86_64/delay.c | |||
@@ -5,22 +5,37 @@ | |||
5 | * Licensed under the GPL | 5 | * Licensed under the GPL |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include "asm/processor.h" | 8 | #include <linux/module.h> |
9 | #include <linux/delay.h> | ||
10 | #include <asm/processor.h> | ||
11 | #include <asm/param.h> | ||
9 | 12 | ||
10 | void __delay(unsigned long loops) | 13 | void __delay(unsigned long loops) |
11 | { | 14 | { |
12 | unsigned long i; | 15 | unsigned long i; |
13 | 16 | ||
14 | for(i = 0; i < loops; i++) ; | 17 | for(i = 0; i < loops; i++) |
18 | cpu_relax(); | ||
15 | } | 19 | } |
16 | 20 | ||
17 | /* | 21 | void __udelay(unsigned long usecs) |
18 | * Overrides for Emacs so that we follow Linus's tabbing style. | 22 | { |
19 | * Emacs will notice this stuff at the end of the file and automatically | 23 | unsigned long i, n; |
20 | * adjust the settings for this buffer only. This must remain at the end | 24 | |
21 | * of the file. | 25 | n = (loops_per_jiffy * HZ * usecs) / MILLION; |
22 | * --------------------------------------------------------------------------- | 26 | for(i=0;i<n;i++) |
23 | * Local variables: | 27 | cpu_relax(); |
24 | * c-file-style: "linux" | 28 | } |
25 | * End: | 29 | |
26 | */ | 30 | EXPORT_SYMBOL(__udelay); |
31 | |||
32 | void __const_udelay(unsigned long usecs) | ||
33 | { | ||
34 | unsigned long i, n; | ||
35 | |||
36 | n = (loops_per_jiffy * HZ * usecs) / MILLION; | ||
37 | for(i=0;i<n;i++) | ||
38 | cpu_relax(); | ||
39 | } | ||
40 | |||
41 | EXPORT_SYMBOL(__const_udelay); | ||
diff --git a/arch/um/sys-x86_64/kernel-offsets.c b/arch/um/sys-x86_64/kernel-offsets.c new file mode 100644 index 000000000000..220e875cbe29 --- /dev/null +++ b/arch/um/sys-x86_64/kernel-offsets.c | |||
@@ -0,0 +1,24 @@ | |||
1 | #include <linux/config.h> | ||
2 | #include <linux/stddef.h> | ||
3 | #include <linux/sched.h> | ||
4 | #include <linux/time.h> | ||
5 | #include <asm/page.h> | ||
6 | |||
7 | #define DEFINE(sym, val) \ | ||
8 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
9 | |||
10 | #define DEFINE_STR1(x) #x | ||
11 | #define DEFINE_STR(sym, val) asm volatile("\n->" #sym " " DEFINE_STR1(val) " " #val: : ) | ||
12 | |||
13 | #define BLANK() asm volatile("\n->" : : ) | ||
14 | |||
15 | #define OFFSET(sym, str, mem) \ | ||
16 | DEFINE(sym, offsetof(struct str, mem)); | ||
17 | |||
18 | void foo(void) | ||
19 | { | ||
20 | #ifdef CONFIG_MODE_TT | ||
21 | OFFSET(TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | ||
22 | #endif | ||
23 | #include <common-offsets.h> | ||
24 | } | ||
diff --git a/arch/um/sys-x86_64/ksyms.c b/arch/um/sys-x86_64/ksyms.c new file mode 100644 index 000000000000..859273808203 --- /dev/null +++ b/arch/um/sys-x86_64/ksyms.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include "linux/module.h" | ||
2 | #include "linux/in6.h" | ||
3 | #include "linux/rwsem.h" | ||
4 | #include "asm/byteorder.h" | ||
5 | #include "asm/semaphore.h" | ||
6 | #include "asm/uaccess.h" | ||
7 | #include "asm/checksum.h" | ||
8 | #include "asm/errno.h" | ||
9 | |||
10 | EXPORT_SYMBOL(__down_failed); | ||
11 | EXPORT_SYMBOL(__down_failed_interruptible); | ||
12 | EXPORT_SYMBOL(__down_failed_trylock); | ||
13 | EXPORT_SYMBOL(__up_wakeup); | ||
14 | |||
15 | /*XXX: we need them because they would be exported by x86_64 */ | ||
16 | EXPORT_SYMBOL(__memcpy); | ||
17 | |||
18 | /* Networking helper routines. */ | ||
19 | EXPORT_SYMBOL(ip_compute_csum); | ||
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c index 8c146b2a1e00..74eee5c7c6dd 100644 --- a/arch/um/sys-x86_64/ptrace.c +++ b/arch/um/sys-x86_64/ptrace.c | |||
@@ -5,10 +5,11 @@ | |||
5 | */ | 5 | */ |
6 | 6 | ||
7 | #define __FRAME_OFFSETS | 7 | #define __FRAME_OFFSETS |
8 | #include "asm/ptrace.h" | 8 | #include <asm/ptrace.h> |
9 | #include "linux/sched.h" | 9 | #include <linux/sched.h> |
10 | #include "linux/errno.h" | 10 | #include <linux/errno.h> |
11 | #include "asm/elf.h" | 11 | #include <asm/uaccess.h> |
12 | #include <asm/elf.h> | ||
12 | 13 | ||
13 | /* XXX x86_64 */ | 14 | /* XXX x86_64 */ |
14 | unsigned long not_ss; | 15 | unsigned long not_ss; |
@@ -62,6 +63,27 @@ int putreg(struct task_struct *child, int regno, unsigned long value) | |||
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | 65 | ||
66 | int poke_user(struct task_struct *child, long addr, long data) | ||
67 | { | ||
68 | if ((addr & 3) || addr < 0) | ||
69 | return -EIO; | ||
70 | |||
71 | if (addr < MAX_REG_OFFSET) | ||
72 | return putreg(child, addr, data); | ||
73 | |||
74 | #if 0 /* Need x86_64 debugregs handling */ | ||
75 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
76 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
77 | addr -= offsetof(struct user, u_debugreg[0]); | ||
78 | addr = addr >> 2; | ||
79 | if((addr == 4) || (addr == 5)) return -EIO; | ||
80 | child->thread.arch.debugregs[addr] = data; | ||
81 | return 0; | ||
82 | } | ||
83 | #endif | ||
84 | return -EIO; | ||
85 | } | ||
86 | |||
65 | unsigned long getreg(struct task_struct *child, int regno) | 87 | unsigned long getreg(struct task_struct *child, int regno) |
66 | { | 88 | { |
67 | unsigned long retval = ~0UL; | 89 | unsigned long retval = ~0UL; |
@@ -84,6 +106,29 @@ unsigned long getreg(struct task_struct *child, int regno) | |||
84 | return retval; | 106 | return retval; |
85 | } | 107 | } |
86 | 108 | ||
109 | int peek_user(struct task_struct *child, long addr, long data) | ||
110 | { | ||
111 | /* read the word at location addr in the USER area. */ | ||
112 | unsigned long tmp; | ||
113 | |||
114 | if ((addr & 3) || addr < 0) | ||
115 | return -EIO; | ||
116 | |||
117 | tmp = 0; /* Default return condition */ | ||
118 | if(addr < MAX_REG_OFFSET){ | ||
119 | tmp = getreg(child, addr); | ||
120 | } | ||
121 | #if 0 /* Need x86_64 debugregs handling */ | ||
122 | else if((addr >= offsetof(struct user, u_debugreg[0])) && | ||
123 | (addr <= offsetof(struct user, u_debugreg[7]))){ | ||
124 | addr -= offsetof(struct user, u_debugreg[0]); | ||
125 | addr = addr >> 2; | ||
126 | tmp = child->thread.arch.debugregs[addr]; | ||
127 | } | ||
128 | #endif | ||
129 | return put_user(tmp, (unsigned long *) data); | ||
130 | } | ||
131 | |||
87 | void arch_switch(void) | 132 | void arch_switch(void) |
88 | { | 133 | { |
89 | /* XXX | 134 | /* XXX |
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c index 5bc5a0d796e5..73a7926f7370 100644 --- a/arch/um/sys-x86_64/signal.c +++ b/arch/um/sys-x86_64/signal.c | |||
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
57 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | 57 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, |
58 | struct pt_regs *regs, unsigned long mask) | 58 | struct pt_regs *regs, unsigned long mask) |
59 | { | 59 | { |
60 | unsigned long eflags; | 60 | struct faultinfo * fi = ¤t->thread.arch.faultinfo; |
61 | int err = 0; | 61 | int err = 0; |
62 | 62 | ||
63 | err |= __put_user(0, &to->gs); | 63 | err |= __put_user(0, &to->gs); |
@@ -84,14 +84,16 @@ int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate *to_fp, | |||
84 | err |= PUTREG(regs, R14, to, r14); | 84 | err |= PUTREG(regs, R14, to, r14); |
85 | err |= PUTREG(regs, R15, to, r15); | 85 | err |= PUTREG(regs, R15, to, r15); |
86 | err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ | 86 | err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ |
87 | err |= __put_user(current->thread.err, &to->err); | 87 | |
88 | err |= __put_user(current->thread.trap_no, &to->trapno); | 88 | err |= __put_user(fi->cr2, &to->cr2); |
89 | err |= __put_user(fi->error_code, &to->err); | ||
90 | err |= __put_user(fi->trap_no, &to->trapno); | ||
91 | |||
89 | err |= PUTREG(regs, RIP, to, rip); | 92 | err |= PUTREG(regs, RIP, to, rip); |
90 | err |= PUTREG(regs, EFLAGS, to, eflags); | 93 | err |= PUTREG(regs, EFLAGS, to, eflags); |
91 | #undef PUTREG | 94 | #undef PUTREG |
92 | 95 | ||
93 | err |= __put_user(mask, &to->oldmask); | 96 | err |= __put_user(mask, &to->oldmask); |
94 | err |= __put_user(current->thread.cr2, &to->cr2); | ||
95 | 97 | ||
96 | return(err); | 98 | return(err); |
97 | } | 99 | } |
@@ -166,7 +168,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig, | |||
166 | 168 | ||
167 | frame = (struct rt_sigframe __user *) | 169 | frame = (struct rt_sigframe __user *) |
168 | round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; | 170 | round_down(stack_top - sizeof(struct rt_sigframe), 16) - 8; |
169 | frame -= 128; | 171 | ((unsigned char *) frame) -= 128; |
170 | 172 | ||
171 | if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) | 173 | if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate))) |
172 | goto out; | 174 | goto out; |
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c index ab4b0abf8af3..d4a59657fb99 100644 --- a/arch/um/sys-x86_64/syscalls.c +++ b/arch/um/sys-x86_64/syscalls.c | |||
@@ -7,12 +7,15 @@ | |||
7 | #include "linux/linkage.h" | 7 | #include "linux/linkage.h" |
8 | #include "linux/slab.h" | 8 | #include "linux/slab.h" |
9 | #include "linux/shm.h" | 9 | #include "linux/shm.h" |
10 | #include "linux/utsname.h" | ||
11 | #include "linux/personality.h" | ||
10 | #include "asm/uaccess.h" | 12 | #include "asm/uaccess.h" |
11 | #define __FRAME_OFFSETS | 13 | #define __FRAME_OFFSETS |
12 | #include "asm/ptrace.h" | 14 | #include "asm/ptrace.h" |
13 | #include "asm/unistd.h" | 15 | #include "asm/unistd.h" |
14 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ | 16 | #include "asm/prctl.h" /* XXX This should get the constants from libc */ |
15 | #include "choose-mode.h" | 17 | #include "choose-mode.h" |
18 | #include "kern.h" | ||
16 | 19 | ||
17 | asmlinkage long sys_uname64(struct new_utsname __user * name) | 20 | asmlinkage long sys_uname64(struct new_utsname __user * name) |
18 | { | 21 | { |
@@ -42,6 +45,8 @@ long sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) | |||
42 | #ifdef CONFIG_MODE_SKAS | 45 | #ifdef CONFIG_MODE_SKAS |
43 | extern int userspace_pid[]; | 46 | extern int userspace_pid[]; |
44 | 47 | ||
48 | #include "skas_ptrace.h" | ||
49 | |||
45 | long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) | 50 | long sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) |
46 | { | 51 | { |
47 | struct ptrace_ldt ldt; | 52 | struct ptrace_ldt ldt; |
diff --git a/arch/um/sys-x86_64/um_module.c b/arch/um/sys-x86_64/um_module.c new file mode 100644 index 000000000000..8b8eff1bd977 --- /dev/null +++ b/arch/um/sys-x86_64/um_module.c | |||
@@ -0,0 +1,19 @@ | |||
1 | #include <linux/vmalloc.h> | ||
2 | #include <linux/moduleloader.h> | ||
3 | |||
4 | /*Copied from i386 arch/i386/kernel/module.c */ | ||
5 | void *module_alloc(unsigned long size) | ||
6 | { | ||
7 | if (size == 0) | ||
8 | return NULL; | ||
9 | return vmalloc_exec(size); | ||
10 | } | ||
11 | |||
12 | /* Free memory returned from module_alloc */ | ||
13 | void module_free(struct module *mod, void *module_region) | ||
14 | { | ||
15 | vfree(module_region); | ||
16 | /* FIXME: If module_region == mod->init_region, trim exception | ||
17 | table entries. */ | ||
18 | } | ||
19 | |||
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c new file mode 100644 index 000000000000..513d17ceafd4 --- /dev/null +++ b/arch/um/sys-x86_64/user-offsets.c | |||
@@ -0,0 +1,86 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <stddef.h> | ||
3 | #include <signal.h> | ||
4 | #define __FRAME_OFFSETS | ||
5 | #include <asm/ptrace.h> | ||
6 | #include <asm/types.h> | ||
7 | /* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I | ||
8 | * refuse to include here, even though they're used throughout the headers. | ||
9 | * These are used in asm/user.h, and that include can't be avoided because of | ||
10 | * the sizeof(struct user_regs_struct) below. | ||
11 | */ | ||
12 | typedef __u64 u64; | ||
13 | typedef __u32 u32; | ||
14 | #include <asm/user.h> | ||
15 | |||
16 | #define DEFINE(sym, val) \ | ||
17 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | ||
18 | |||
19 | #define OFFSET(sym, str, mem) \ | ||
20 | DEFINE(sym, offsetof(struct str, mem)); | ||
21 | |||
22 | void foo(void) | ||
23 | { | ||
24 | OFFSET(SC_RBX, sigcontext, rbx); | ||
25 | OFFSET(SC_RCX, sigcontext, rcx); | ||
26 | OFFSET(SC_RDX, sigcontext, rdx); | ||
27 | OFFSET(SC_RSI, sigcontext, rsi); | ||
28 | OFFSET(SC_RDI, sigcontext, rdi); | ||
29 | OFFSET(SC_RBP, sigcontext, rbp); | ||
30 | OFFSET(SC_RAX, sigcontext, rax); | ||
31 | OFFSET(SC_R8, sigcontext, r8); | ||
32 | OFFSET(SC_R9, sigcontext, r9); | ||
33 | OFFSET(SC_R10, sigcontext, r10); | ||
34 | OFFSET(SC_R11, sigcontext, r11); | ||
35 | OFFSET(SC_R12, sigcontext, r12); | ||
36 | OFFSET(SC_R13, sigcontext, r13); | ||
37 | OFFSET(SC_R14, sigcontext, r14); | ||
38 | OFFSET(SC_R15, sigcontext, r15); | ||
39 | OFFSET(SC_IP, sigcontext, rip); | ||
40 | OFFSET(SC_SP, sigcontext, rsp); | ||
41 | OFFSET(SC_CR2, sigcontext, cr2); | ||
42 | OFFSET(SC_ERR, sigcontext, err); | ||
43 | OFFSET(SC_TRAPNO, sigcontext, trapno); | ||
44 | OFFSET(SC_CS, sigcontext, cs); | ||
45 | OFFSET(SC_FS, sigcontext, fs); | ||
46 | OFFSET(SC_GS, sigcontext, gs); | ||
47 | OFFSET(SC_EFLAGS, sigcontext, eflags); | ||
48 | OFFSET(SC_SIGMASK, sigcontext, oldmask); | ||
49 | #if 0 | ||
50 | OFFSET(SC_ORIG_RAX, sigcontext, orig_rax); | ||
51 | OFFSET(SC_DS, sigcontext, ds); | ||
52 | OFFSET(SC_ES, sigcontext, es); | ||
53 | OFFSET(SC_SS, sigcontext, ss); | ||
54 | #endif | ||
55 | |||
56 | DEFINE(HOST_FRAME_SIZE, FRAME_SIZE); | ||
57 | DEFINE(HOST_RBX, RBX); | ||
58 | DEFINE(HOST_RCX, RCX); | ||
59 | DEFINE(HOST_RDI, RDI); | ||
60 | DEFINE(HOST_RSI, RSI); | ||
61 | DEFINE(HOST_RDX, RDX); | ||
62 | DEFINE(HOST_RBP, RBP); | ||
63 | DEFINE(HOST_RAX, RAX); | ||
64 | DEFINE(HOST_R8, R8); | ||
65 | DEFINE(HOST_R9, R9); | ||
66 | DEFINE(HOST_R10, R10); | ||
67 | DEFINE(HOST_R11, R11); | ||
68 | DEFINE(HOST_R12, R12); | ||
69 | DEFINE(HOST_R13, R13); | ||
70 | DEFINE(HOST_R14, R14); | ||
71 | DEFINE(HOST_R15, R15); | ||
72 | DEFINE(HOST_ORIG_RAX, ORIG_RAX); | ||
73 | DEFINE(HOST_CS, CS); | ||
74 | DEFINE(HOST_SS, SS); | ||
75 | DEFINE(HOST_EFLAGS, EFLAGS); | ||
76 | #if 0 | ||
77 | DEFINE(HOST_FS, FS); | ||
78 | DEFINE(HOST_GS, GS); | ||
79 | DEFINE(HOST_DS, DS); | ||
80 | DEFINE(HOST_ES, ES); | ||
81 | #endif | ||
82 | |||
83 | DEFINE(HOST_IP, RIP); | ||
84 | DEFINE(HOST_SP, RSP); | ||
85 | DEFINE(__UM_FRAME_SIZE, sizeof(struct user_regs_struct)); | ||
86 | } | ||
diff --git a/arch/um/sys-x86_64/util/Makefile b/arch/um/sys-x86_64/util/Makefile index 002607980864..75b052cfc206 100644 --- a/arch/um/sys-x86_64/util/Makefile +++ b/arch/um/sys-x86_64/util/Makefile | |||
@@ -4,7 +4,5 @@ | |||
4 | hostprogs-y := mk_sc mk_thread | 4 | hostprogs-y := mk_sc mk_thread |
5 | always := $(hostprogs-y) | 5 | always := $(hostprogs-y) |
6 | 6 | ||
7 | mk_thread-objs := mk_thread_kern.o mk_thread_user.o | 7 | HOSTCFLAGS_mk_sc.o := -I$(objtree)/arch/um |
8 | 8 | HOSTCFLAGS_mk_thread.o := -I$(objtree)/arch/um | |
9 | HOSTCFLAGS_mk_thread_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
10 | HOSTCFLAGS_mk_thread_user.o := $(USER_CFLAGS) | ||
diff --git a/arch/um/sys-x86_64/util/mk_sc.c b/arch/um/sys-x86_64/util/mk_sc.c index c236e213918d..7619bc377c1f 100644 --- a/arch/um/sys-x86_64/util/mk_sc.c +++ b/arch/um/sys-x86_64/util/mk_sc.c | |||
@@ -3,56 +3,45 @@ | |||
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <signal.h> | 6 | #include <user-offsets.h> |
7 | #include <linux/stddef.h> | ||
8 | 7 | ||
9 | #define SC_OFFSET(name, field) \ | 8 | #define SC_OFFSET(name) \ |
10 | printf("#define " name \ | 9 | printf("#define " #name \ |
11 | "(sc) *((unsigned long *) &(((char *) (sc))[%ld]))\n",\ | 10 | "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ |
12 | offsetof(struct sigcontext, field)) | 11 | name) |
13 | |||
14 | #define SC_FP_OFFSET(name, field) \ | ||
15 | printf("#define " name \ | ||
16 | "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%ld]))\n",\ | ||
17 | offsetof(struct _fpstate, field)) | ||
18 | |||
19 | #define SC_FP_OFFSET_PTR(name, field, type) \ | ||
20 | printf("#define " name \ | ||
21 | "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ | ||
22 | offsetof(struct _fpstate, field)) | ||
23 | 12 | ||
24 | int main(int argc, char **argv) | 13 | int main(int argc, char **argv) |
25 | { | 14 | { |
26 | SC_OFFSET("SC_RBX", rbx); | 15 | SC_OFFSET(SC_RBX); |
27 | SC_OFFSET("SC_RCX", rcx); | 16 | SC_OFFSET(SC_RCX); |
28 | SC_OFFSET("SC_RDX", rdx); | 17 | SC_OFFSET(SC_RDX); |
29 | SC_OFFSET("SC_RSI", rsi); | 18 | SC_OFFSET(SC_RSI); |
30 | SC_OFFSET("SC_RDI", rdi); | 19 | SC_OFFSET(SC_RDI); |
31 | SC_OFFSET("SC_RBP", rbp); | 20 | SC_OFFSET(SC_RBP); |
32 | SC_OFFSET("SC_RAX", rax); | 21 | SC_OFFSET(SC_RAX); |
33 | SC_OFFSET("SC_R8", r8); | 22 | SC_OFFSET(SC_R8); |
34 | SC_OFFSET("SC_R9", r9); | 23 | SC_OFFSET(SC_R9); |
35 | SC_OFFSET("SC_R10", r10); | 24 | SC_OFFSET(SC_R10); |
36 | SC_OFFSET("SC_R11", r11); | 25 | SC_OFFSET(SC_R11); |
37 | SC_OFFSET("SC_R12", r12); | 26 | SC_OFFSET(SC_R12); |
38 | SC_OFFSET("SC_R13", r13); | 27 | SC_OFFSET(SC_R13); |
39 | SC_OFFSET("SC_R14", r14); | 28 | SC_OFFSET(SC_R14); |
40 | SC_OFFSET("SC_R15", r15); | 29 | SC_OFFSET(SC_R15); |
41 | SC_OFFSET("SC_IP", rip); | 30 | SC_OFFSET(SC_IP); |
42 | SC_OFFSET("SC_SP", rsp); | 31 | SC_OFFSET(SC_SP); |
43 | SC_OFFSET("SC_CR2", cr2); | 32 | SC_OFFSET(SC_CR2); |
44 | SC_OFFSET("SC_ERR", err); | 33 | SC_OFFSET(SC_ERR); |
45 | SC_OFFSET("SC_TRAPNO", trapno); | 34 | SC_OFFSET(SC_TRAPNO); |
46 | SC_OFFSET("SC_CS", cs); | 35 | SC_OFFSET(SC_CS); |
47 | SC_OFFSET("SC_FS", fs); | 36 | SC_OFFSET(SC_FS); |
48 | SC_OFFSET("SC_GS", gs); | 37 | SC_OFFSET(SC_GS); |
49 | SC_OFFSET("SC_EFLAGS", eflags); | 38 | SC_OFFSET(SC_EFLAGS); |
50 | SC_OFFSET("SC_SIGMASK", oldmask); | 39 | SC_OFFSET(SC_SIGMASK); |
51 | #if 0 | 40 | #if 0 |
52 | SC_OFFSET("SC_ORIG_RAX", orig_rax); | 41 | SC_OFFSET(SC_ORIG_RAX); |
53 | SC_OFFSET("SC_DS", ds); | 42 | SC_OFFSET(SC_DS); |
54 | SC_OFFSET("SC_ES", es); | 43 | SC_OFFSET(SC_ES); |
55 | SC_OFFSET("SC_SS", ss); | 44 | SC_OFFSET(SC_SS); |
56 | #endif | 45 | #endif |
57 | return(0); | 46 | return(0); |
58 | } | 47 | } |
diff --git a/arch/um/sys-x86_64/util/mk_thread.c b/arch/um/sys-x86_64/util/mk_thread.c new file mode 100644 index 000000000000..15517396e9cf --- /dev/null +++ b/arch/um/sys-x86_64/util/mk_thread.c | |||
@@ -0,0 +1,20 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | int main(int argc, char **argv) | ||
5 | { | ||
6 | printf("/*\n"); | ||
7 | printf(" * Generated by mk_thread\n"); | ||
8 | printf(" */\n"); | ||
9 | printf("\n"); | ||
10 | printf("#ifndef __UM_THREAD_H\n"); | ||
11 | printf("#define __UM_THREAD_H\n"); | ||
12 | printf("\n"); | ||
13 | #ifdef TASK_EXTERN_PID | ||
14 | printf("#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[%d]))\n", | ||
15 | TASK_EXTERN_PID); | ||
16 | #endif | ||
17 | printf("\n"); | ||
18 | printf("#endif\n"); | ||
19 | return(0); | ||
20 | } | ||
diff --git a/arch/um/sys-x86_64/util/mk_thread_kern.c b/arch/um/sys-x86_64/util/mk_thread_kern.c deleted file mode 100644 index a281673f02b2..000000000000 --- a/arch/um/sys-x86_64/util/mk_thread_kern.c +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | #include "linux/config.h" | ||
2 | #include "linux/stddef.h" | ||
3 | #include "linux/sched.h" | ||
4 | |||
5 | extern void print_head(void); | ||
6 | extern void print_constant_ptr(char *name, int value); | ||
7 | extern void print_constant(char *name, char *type, int value); | ||
8 | extern void print_tail(void); | ||
9 | |||
10 | #define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) | ||
11 | |||
12 | int main(int argc, char **argv) | ||
13 | { | ||
14 | print_head(); | ||
15 | #ifdef CONFIG_MODE_TT | ||
16 | print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); | ||
17 | #endif | ||
18 | print_tail(); | ||
19 | return(0); | ||
20 | } | ||
21 | |||
diff --git a/arch/um/sys-x86_64/util/mk_thread_user.c b/arch/um/sys-x86_64/util/mk_thread_user.c deleted file mode 100644 index 7989725568b8..000000000000 --- a/arch/um/sys-x86_64/util/mk_thread_user.c +++ /dev/null | |||
@@ -1,30 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_thread\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_THREAD_H\n"); | ||
10 | printf("#define __UM_THREAD_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_ptr(char *name, int value) | ||
15 | { | ||
16 | printf("#define %s(task) ((unsigned long *) " | ||
17 | "&(((char *) (task))[%d]))\n", name, value); | ||
18 | } | ||
19 | |||
20 | void print_constant(char *name, char *type, int value) | ||
21 | { | ||
22 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | ||
23 | value); | ||
24 | } | ||
25 | |||
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | ||
29 | printf("#endif\n"); | ||
30 | } | ||
diff --git a/arch/um/util/Makefile b/arch/um/util/Makefile index e2ab71209f3f..4c7551c28033 100644 --- a/arch/um/util/Makefile +++ b/arch/um/util/Makefile | |||
@@ -1,8 +1,5 @@ | |||
1 | hostprogs-y := mk_task mk_constants | 1 | hostprogs-y := mk_task mk_constants |
2 | always := $(hostprogs-y) | 2 | always := $(hostprogs-y) |
3 | 3 | ||
4 | mk_task-objs := mk_task_user.o mk_task_kern.o | 4 | HOSTCFLAGS_mk_task.o := -I$(objtree)/arch/um |
5 | mk_constants-objs := mk_constants_user.o mk_constants_kern.o | 5 | HOSTCFLAGS_mk_constants.o := -I$(objtree)/arch/um |
6 | |||
7 | HOSTCFLAGS_mk_task_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
8 | HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS) $(CPPFLAGS) | ||
diff --git a/arch/um/util/mk_constants.c b/arch/um/util/mk_constants.c new file mode 100644 index 000000000000..ab217becc36a --- /dev/null +++ b/arch/um/util/mk_constants.c | |||
@@ -0,0 +1,32 @@ | |||
1 | #include <stdio.h> | ||
2 | #include <kernel-offsets.h> | ||
3 | |||
4 | #define SHOW_INT(sym) printf("#define %s %d\n", #sym, sym) | ||
5 | #define SHOW_STR(sym) printf("#define %s %s\n", #sym, sym) | ||
6 | |||
7 | int main(int argc, char **argv) | ||
8 | { | ||
9 | printf("/*\n"); | ||
10 | printf(" * Generated by mk_constants\n"); | ||
11 | printf(" */\n"); | ||
12 | printf("\n"); | ||
13 | printf("#ifndef __UM_CONSTANTS_H\n"); | ||
14 | printf("#define __UM_CONSTANTS_H\n"); | ||
15 | printf("\n"); | ||
16 | |||
17 | SHOW_INT(UM_KERN_PAGE_SIZE); | ||
18 | |||
19 | SHOW_STR(UM_KERN_EMERG); | ||
20 | SHOW_STR(UM_KERN_ALERT); | ||
21 | SHOW_STR(UM_KERN_CRIT); | ||
22 | SHOW_STR(UM_KERN_ERR); | ||
23 | SHOW_STR(UM_KERN_WARNING); | ||
24 | SHOW_STR(UM_KERN_NOTICE); | ||
25 | SHOW_STR(UM_KERN_INFO); | ||
26 | SHOW_STR(UM_KERN_DEBUG); | ||
27 | |||
28 | SHOW_INT(UM_NSEC_PER_SEC); | ||
29 | printf("\n"); | ||
30 | printf("#endif\n"); | ||
31 | return(0); | ||
32 | } | ||
diff --git a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c deleted file mode 100644 index cdcb1232a1ea..000000000000 --- a/arch/um/util/mk_constants_kern.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #include "linux/kernel.h" | ||
2 | #include "linux/stringify.h" | ||
3 | #include "linux/time.h" | ||
4 | #include "asm/page.h" | ||
5 | |||
6 | extern void print_head(void); | ||
7 | extern void print_constant_str(char *name, char *value); | ||
8 | extern void print_constant_int(char *name, int value); | ||
9 | extern void print_tail(void); | ||
10 | |||
11 | int main(int argc, char **argv) | ||
12 | { | ||
13 | print_head(); | ||
14 | print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE); | ||
15 | |||
16 | print_constant_str("UM_KERN_EMERG", KERN_EMERG); | ||
17 | print_constant_str("UM_KERN_ALERT", KERN_ALERT); | ||
18 | print_constant_str("UM_KERN_CRIT", KERN_CRIT); | ||
19 | print_constant_str("UM_KERN_ERR", KERN_ERR); | ||
20 | print_constant_str("UM_KERN_WARNING", KERN_WARNING); | ||
21 | print_constant_str("UM_KERN_NOTICE", KERN_NOTICE); | ||
22 | print_constant_str("UM_KERN_INFO", KERN_INFO); | ||
23 | print_constant_str("UM_KERN_DEBUG", KERN_DEBUG); | ||
24 | |||
25 | print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC); | ||
26 | print_tail(); | ||
27 | return(0); | ||
28 | } | ||
diff --git a/arch/um/util/mk_constants_user.c b/arch/um/util/mk_constants_user.c deleted file mode 100644 index 8f4d7e50be7c..000000000000 --- a/arch/um/util/mk_constants_user.c +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | #include <stdio.h> | ||
2 | |||
3 | void print_head(void) | ||
4 | { | ||
5 | printf("/*\n"); | ||
6 | printf(" * Generated by mk_constants\n"); | ||
7 | printf(" */\n"); | ||
8 | printf("\n"); | ||
9 | printf("#ifndef __UM_CONSTANTS_H\n"); | ||
10 | printf("#define __UM_CONSTANTS_H\n"); | ||
11 | printf("\n"); | ||
12 | } | ||
13 | |||
14 | void print_constant_str(char *name, char *value) | ||
15 | { | ||
16 | printf("#define %s \"%s\"\n", name, value); | ||
17 | } | ||
18 | |||
19 | void print_constant_int(char *name, int value) | ||
20 | { | ||
21 | printf("#define %s %d\n", name, value); | ||
22 | } | ||
23 | |||
24 | void print_tail(void) | ||
25 | { | ||
26 | printf("\n"); | ||
27 | printf("#endif\n"); | ||
28 | } | ||
diff --git a/arch/um/util/mk_task_user.c b/arch/um/util/mk_task.c index 9db849f3f3ac..36c9606505e2 100644 --- a/arch/um/util/mk_task_user.c +++ b/arch/um/util/mk_task.c | |||
@@ -1,18 +1,19 @@ | |||
1 | #include <stdio.h> | 1 | #include <stdio.h> |
2 | #include <kernel-offsets.h> | ||
2 | 3 | ||
3 | void print(char *name, char *type, int offset) | 4 | void print_ptr(char *name, char *type, int offset) |
4 | { | 5 | { |
5 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, | 6 | printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, |
6 | offset); | 7 | offset); |
7 | } | 8 | } |
8 | 9 | ||
9 | void print_ptr(char *name, char *type, int offset) | 10 | void print(char *name, char *type, int offset) |
10 | { | 11 | { |
11 | printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, | 12 | printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, |
12 | offset); | 13 | offset); |
13 | } | 14 | } |
14 | 15 | ||
15 | void print_head(void) | 16 | int main(int argc, char **argv) |
16 | { | 17 | { |
17 | printf("/*\n"); | 18 | printf("/*\n"); |
18 | printf(" * Generated by mk_task\n"); | 19 | printf(" * Generated by mk_task\n"); |
@@ -21,10 +22,9 @@ void print_head(void) | |||
21 | printf("#ifndef __TASK_H\n"); | 22 | printf("#ifndef __TASK_H\n"); |
22 | printf("#define __TASK_H\n"); | 23 | printf("#define __TASK_H\n"); |
23 | printf("\n"); | 24 | printf("\n"); |
24 | } | 25 | print_ptr("TASK_REGS", "union uml_pt_regs", TASK_REGS); |
25 | 26 | print("TASK_PID", "int", TASK_PID); | |
26 | void print_tail(void) | ||
27 | { | ||
28 | printf("\n"); | 27 | printf("\n"); |
29 | printf("#endif\n"); | 28 | printf("#endif\n"); |
29 | return(0); | ||
30 | } | 30 | } |
diff --git a/arch/um/util/mk_task_kern.c b/arch/um/util/mk_task_kern.c deleted file mode 100644 index c218103315ed..000000000000 --- a/arch/um/util/mk_task_kern.c +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | #include "linux/sched.h" | ||
2 | #include "linux/stddef.h" | ||
3 | |||
4 | extern void print(char *name, char *type, int offset); | ||
5 | extern void print_ptr(char *name, char *type, int offset); | ||
6 | extern void print_head(void); | ||
7 | extern void print_tail(void); | ||
8 | |||
9 | int main(int argc, char **argv) | ||
10 | { | ||
11 | print_head(); | ||
12 | print_ptr("TASK_REGS", "union uml_pt_regs", | ||
13 | offsetof(struct task_struct, thread.regs)); | ||
14 | print("TASK_PID", "int", offsetof(struct task_struct, pid)); | ||
15 | print_tail(); | ||
16 | return(0); | ||
17 | } | ||
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 44ee7f6acf7b..82cb2a3f127a 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig | |||
@@ -303,6 +303,20 @@ config HPET_TIMER | |||
303 | as it is off-chip. You can find the HPET spec at | 303 | as it is off-chip. You can find the HPET spec at |
304 | <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>. | 304 | <http://www.intel.com/labs/platcomp/hpet/hpetspec.htm>. |
305 | 305 | ||
306 | config X86_PM_TIMER | ||
307 | bool "PM timer" | ||
308 | default y | ||
309 | help | ||
310 | Support the ACPI PM timer for time keeping. This is slow, | ||
311 | but is useful on some chipsets without HPET on systems with more | ||
312 | than one CPU. On a single processor or single socket multi core | ||
313 | system it is normally not required. | ||
314 | When the PM timer is active 64bit vsyscalls are disabled | ||
315 | and should not be enabled (/proc/sys/kernel/vsyscall64 should | ||
316 | not be changed). | ||
317 | The kernel selects the PM timer only as a last resort, so it is | ||
318 | useful to enable just in case. | ||
319 | |||
306 | config HPET_EMULATE_RTC | 320 | config HPET_EMULATE_RTC |
307 | bool "Provide RTC interrupt" | 321 | bool "Provide RTC interrupt" |
308 | depends on HPET_TIMER && RTC=y | 322 | depends on HPET_TIMER && RTC=y |
diff --git a/arch/x86_64/boot/bootsect.S b/arch/x86_64/boot/bootsect.S index bb15d406ee95..011b7a4993d4 100644 --- a/arch/x86_64/boot/bootsect.S +++ b/arch/x86_64/boot/bootsect.S | |||
@@ -63,7 +63,7 @@ msg_loop: | |||
63 | jz die | 63 | jz die |
64 | movb $0xe, %ah | 64 | movb $0xe, %ah |
65 | movw $7, %bx | 65 | movw $7, %bx |
66 | int $0x10 | 66 | int $0x10 |
67 | jmp msg_loop | 67 | jmp msg_loop |
68 | 68 | ||
69 | die: | 69 | die: |
@@ -71,7 +71,7 @@ die: | |||
71 | xorw %ax, %ax | 71 | xorw %ax, %ax |
72 | int $0x16 | 72 | int $0x16 |
73 | int $0x19 | 73 | int $0x19 |
74 | 74 | ||
75 | # int 0x19 should never return. In case it does anyway, | 75 | # int 0x19 should never return. In case it does anyway, |
76 | # invoke the BIOS reset code... | 76 | # invoke the BIOS reset code... |
77 | ljmp $0xf000,$0xfff0 | 77 | ljmp $0xf000,$0xfff0 |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 9ce51dee30b3..569595b74c7c 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/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.11-bk7 | 3 | # Linux kernel version: 2.6.12-rc4 |
4 | # Sat Mar 12 23:43:44 2005 | 4 | # Fri May 13 06:39:11 2005 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -11,8 +11,6 @@ CONFIG_RWSEM_GENERIC_SPINLOCK=y | |||
11 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 11 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
12 | CONFIG_X86_CMPXCHG=y | 12 | CONFIG_X86_CMPXCHG=y |
13 | CONFIG_EARLY_PRINTK=y | 13 | CONFIG_EARLY_PRINTK=y |
14 | CONFIG_HPET_TIMER=y | ||
15 | CONFIG_HPET_EMULATE_RTC=y | ||
16 | CONFIG_GENERIC_ISA_DMA=y | 14 | CONFIG_GENERIC_ISA_DMA=y |
17 | CONFIG_GENERIC_IOMAP=y | 15 | CONFIG_GENERIC_IOMAP=y |
18 | 16 | ||
@@ -22,6 +20,7 @@ CONFIG_GENERIC_IOMAP=y | |||
22 | CONFIG_EXPERIMENTAL=y | 20 | CONFIG_EXPERIMENTAL=y |
23 | CONFIG_CLEAN_COMPILE=y | 21 | CONFIG_CLEAN_COMPILE=y |
24 | CONFIG_LOCK_KERNEL=y | 22 | CONFIG_LOCK_KERNEL=y |
23 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
25 | 24 | ||
26 | # | 25 | # |
27 | # General setup | 26 | # General setup |
@@ -33,7 +32,6 @@ CONFIG_POSIX_MQUEUE=y | |||
33 | # CONFIG_BSD_PROCESS_ACCT is not set | 32 | # CONFIG_BSD_PROCESS_ACCT is not set |
34 | CONFIG_SYSCTL=y | 33 | CONFIG_SYSCTL=y |
35 | # CONFIG_AUDIT is not set | 34 | # CONFIG_AUDIT is not set |
36 | CONFIG_LOG_BUF_SHIFT=18 | ||
37 | # CONFIG_HOTPLUG is not set | 35 | # CONFIG_HOTPLUG is not set |
38 | CONFIG_KOBJECT_UEVENT=y | 36 | CONFIG_KOBJECT_UEVENT=y |
39 | CONFIG_IKCONFIG=y | 37 | CONFIG_IKCONFIG=y |
@@ -43,10 +41,11 @@ CONFIG_IKCONFIG_PROC=y | |||
43 | CONFIG_KALLSYMS=y | 41 | CONFIG_KALLSYMS=y |
44 | CONFIG_KALLSYMS_ALL=y | 42 | CONFIG_KALLSYMS_ALL=y |
45 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 43 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
44 | CONFIG_PRINTK=y | ||
45 | CONFIG_BUG=y | ||
46 | CONFIG_BASE_FULL=y | 46 | CONFIG_BASE_FULL=y |
47 | CONFIG_FUTEX=y | 47 | CONFIG_FUTEX=y |
48 | CONFIG_EPOLL=y | 48 | CONFIG_EPOLL=y |
49 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
50 | CONFIG_SHMEM=y | 49 | CONFIG_SHMEM=y |
51 | CONFIG_CC_ALIGN_FUNCTIONS=0 | 50 | CONFIG_CC_ALIGN_FUNCTIONS=0 |
52 | CONFIG_CC_ALIGN_LABELS=0 | 51 | CONFIG_CC_ALIGN_LABELS=0 |
@@ -93,6 +92,9 @@ CONFIG_DISCONTIGMEM=y | |||
93 | CONFIG_NUMA=y | 92 | CONFIG_NUMA=y |
94 | CONFIG_HAVE_DEC_LOCK=y | 93 | CONFIG_HAVE_DEC_LOCK=y |
95 | CONFIG_NR_CPUS=8 | 94 | CONFIG_NR_CPUS=8 |
95 | CONFIG_HPET_TIMER=y | ||
96 | CONFIG_X86_PM_TIMER=y | ||
97 | CONFIG_HPET_EMULATE_RTC=y | ||
96 | CONFIG_GART_IOMMU=y | 98 | CONFIG_GART_IOMMU=y |
97 | CONFIG_SWIOTLB=y | 99 | CONFIG_SWIOTLB=y |
98 | CONFIG_X86_MCE=y | 100 | CONFIG_X86_MCE=y |
@@ -100,6 +102,7 @@ CONFIG_X86_MCE_INTEL=y | |||
100 | CONFIG_SECCOMP=y | 102 | CONFIG_SECCOMP=y |
101 | CONFIG_GENERIC_HARDIRQS=y | 103 | CONFIG_GENERIC_HARDIRQS=y |
102 | CONFIG_GENERIC_IRQ_PROBE=y | 104 | CONFIG_GENERIC_IRQ_PROBE=y |
105 | CONFIG_ISA_DMA_API=y | ||
103 | 106 | ||
104 | # | 107 | # |
105 | # Power management options | 108 | # Power management options |
@@ -129,7 +132,7 @@ CONFIG_ACPI_NUMA=y | |||
129 | # CONFIG_ACPI_IBM is not set | 132 | # CONFIG_ACPI_IBM is not set |
130 | CONFIG_ACPI_TOSHIBA=y | 133 | CONFIG_ACPI_TOSHIBA=y |
131 | CONFIG_ACPI_BLACKLIST_YEAR=2001 | 134 | CONFIG_ACPI_BLACKLIST_YEAR=2001 |
132 | CONFIG_ACPI_DEBUG=y | 135 | # CONFIG_ACPI_DEBUG is not set |
133 | CONFIG_ACPI_BUS=y | 136 | CONFIG_ACPI_BUS=y |
134 | CONFIG_ACPI_EC=y | 137 | CONFIG_ACPI_EC=y |
135 | CONFIG_ACPI_POWER=y | 138 | CONFIG_ACPI_POWER=y |
@@ -141,6 +144,7 @@ CONFIG_ACPI_SYSTEM=y | |||
141 | # CPU Frequency scaling | 144 | # CPU Frequency scaling |
142 | # | 145 | # |
143 | CONFIG_CPU_FREQ=y | 146 | CONFIG_CPU_FREQ=y |
147 | CONFIG_CPU_FREQ_TABLE=y | ||
144 | # CONFIG_CPU_FREQ_DEBUG is not set | 148 | # CONFIG_CPU_FREQ_DEBUG is not set |
145 | CONFIG_CPU_FREQ_STAT=y | 149 | CONFIG_CPU_FREQ_STAT=y |
146 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set | 150 | # CONFIG_CPU_FREQ_STAT_DETAILS is not set |
@@ -150,7 +154,6 @@ CONFIG_CPU_FREQ_GOV_PERFORMANCE=y | |||
150 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set | 154 | # CONFIG_CPU_FREQ_GOV_POWERSAVE is not set |
151 | CONFIG_CPU_FREQ_GOV_USERSPACE=y | 155 | CONFIG_CPU_FREQ_GOV_USERSPACE=y |
152 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y | 156 | CONFIG_CPU_FREQ_GOV_ONDEMAND=y |
153 | CONFIG_CPU_FREQ_TABLE=y | ||
154 | 157 | ||
155 | # | 158 | # |
156 | # CPUFreq processor drivers | 159 | # CPUFreq processor drivers |
@@ -164,6 +167,7 @@ CONFIG_X86_ACPI_CPUFREQ=y | |||
164 | # shared options | 167 | # shared options |
165 | # | 168 | # |
166 | CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y | 169 | CONFIG_X86_ACPI_CPUFREQ_PROC_INTF=y |
170 | # CONFIG_X86_SPEEDSTEP_LIB is not set | ||
167 | 171 | ||
168 | # | 172 | # |
169 | # Bus options (PCI etc.) | 173 | # Bus options (PCI etc.) |
@@ -172,9 +176,11 @@ CONFIG_PCI=y | |||
172 | CONFIG_PCI_DIRECT=y | 176 | CONFIG_PCI_DIRECT=y |
173 | CONFIG_PCI_MMCONFIG=y | 177 | CONFIG_PCI_MMCONFIG=y |
174 | CONFIG_UNORDERED_IO=y | 178 | CONFIG_UNORDERED_IO=y |
179 | # CONFIG_PCIEPORTBUS is not set | ||
175 | CONFIG_PCI_MSI=y | 180 | CONFIG_PCI_MSI=y |
176 | # CONFIG_PCI_LEGACY_PROC is not set | 181 | # CONFIG_PCI_LEGACY_PROC is not set |
177 | # CONFIG_PCI_NAMES is not set | 182 | # CONFIG_PCI_NAMES is not set |
183 | # CONFIG_PCI_DEBUG is not set | ||
178 | 184 | ||
179 | # | 185 | # |
180 | # PCCARD (PCMCIA/CardBus) support | 186 | # PCCARD (PCMCIA/CardBus) support |
@@ -182,10 +188,6 @@ CONFIG_PCI_MSI=y | |||
182 | # CONFIG_PCCARD is not set | 188 | # CONFIG_PCCARD is not set |
183 | 189 | ||
184 | # | 190 | # |
185 | # PC-card bridges | ||
186 | # | ||
187 | |||
188 | # | ||
189 | # PCI Hotplug Support | 191 | # PCI Hotplug Support |
190 | # | 192 | # |
191 | # CONFIG_HOTPLUG_PCI is not set | 193 | # CONFIG_HOTPLUG_PCI is not set |
@@ -254,7 +256,7 @@ CONFIG_LBD=y | |||
254 | # IO Schedulers | 256 | # IO Schedulers |
255 | # | 257 | # |
256 | CONFIG_IOSCHED_NOOP=y | 258 | CONFIG_IOSCHED_NOOP=y |
257 | CONFIG_IOSCHED_AS=y | 259 | # CONFIG_IOSCHED_AS is not set |
258 | CONFIG_IOSCHED_DEADLINE=y | 260 | CONFIG_IOSCHED_DEADLINE=y |
259 | CONFIG_IOSCHED_CFQ=y | 261 | CONFIG_IOSCHED_CFQ=y |
260 | # CONFIG_ATA_OVER_ETH is not set | 262 | # CONFIG_ATA_OVER_ETH is not set |
@@ -308,7 +310,8 @@ CONFIG_BLK_DEV_AMD74XX=y | |||
308 | CONFIG_BLK_DEV_PIIX=y | 310 | CONFIG_BLK_DEV_PIIX=y |
309 | # CONFIG_BLK_DEV_NS87415 is not set | 311 | # CONFIG_BLK_DEV_NS87415 is not set |
310 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | 312 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set |
311 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | 313 | CONFIG_BLK_DEV_PDC202XX_NEW=y |
314 | # CONFIG_PDC202XX_FORCE is not set | ||
312 | # CONFIG_BLK_DEV_SVWKS is not set | 315 | # CONFIG_BLK_DEV_SVWKS is not set |
313 | # CONFIG_BLK_DEV_SIIMAGE is not set | 316 | # CONFIG_BLK_DEV_SIIMAGE is not set |
314 | # CONFIG_BLK_DEV_SIS5513 is not set | 317 | # CONFIG_BLK_DEV_SIS5513 is not set |
@@ -353,7 +356,7 @@ CONFIG_BLK_DEV_SD=y | |||
353 | # | 356 | # |
354 | # SCSI low-level drivers | 357 | # SCSI low-level drivers |
355 | # | 358 | # |
356 | CONFIG_BLK_DEV_3W_XXXX_RAID=y | 359 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set |
357 | # CONFIG_SCSI_3W_9XXX is not set | 360 | # CONFIG_SCSI_3W_9XXX is not set |
358 | # CONFIG_SCSI_ACARD is not set | 361 | # CONFIG_SCSI_ACARD is not set |
359 | # CONFIG_SCSI_AACRAID is not set | 362 | # CONFIG_SCSI_AACRAID is not set |
@@ -384,7 +387,6 @@ CONFIG_SCSI_SATA_VIA=y | |||
384 | # CONFIG_SCSI_BUSLOGIC is not set | 387 | # CONFIG_SCSI_BUSLOGIC is not set |
385 | # CONFIG_SCSI_DMX3191D is not set | 388 | # CONFIG_SCSI_DMX3191D is not set |
386 | # CONFIG_SCSI_EATA is not set | 389 | # CONFIG_SCSI_EATA is not set |
387 | # CONFIG_SCSI_EATA_PIO is not set | ||
388 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | 390 | # CONFIG_SCSI_FUTURE_DOMAIN is not set |
389 | # CONFIG_SCSI_GDTH is not set | 391 | # CONFIG_SCSI_GDTH is not set |
390 | # CONFIG_SCSI_IPS is not set | 392 | # CONFIG_SCSI_IPS is not set |
@@ -392,7 +394,6 @@ CONFIG_SCSI_SATA_VIA=y | |||
392 | # CONFIG_SCSI_INIA100 is not set | 394 | # CONFIG_SCSI_INIA100 is not set |
393 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 395 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
394 | # CONFIG_SCSI_IPR is not set | 396 | # CONFIG_SCSI_IPR is not set |
395 | # CONFIG_SCSI_QLOGIC_ISP is not set | ||
396 | # CONFIG_SCSI_QLOGIC_FC is not set | 397 | # CONFIG_SCSI_QLOGIC_FC is not set |
397 | # CONFIG_SCSI_QLOGIC_1280 is not set | 398 | # CONFIG_SCSI_QLOGIC_1280 is not set |
398 | CONFIG_SCSI_QLA2XXX=y | 399 | CONFIG_SCSI_QLA2XXX=y |
@@ -401,6 +402,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
401 | # CONFIG_SCSI_QLA2300 is not set | 402 | # CONFIG_SCSI_QLA2300 is not set |
402 | # CONFIG_SCSI_QLA2322 is not set | 403 | # CONFIG_SCSI_QLA2322 is not set |
403 | # CONFIG_SCSI_QLA6312 is not set | 404 | # CONFIG_SCSI_QLA6312 is not set |
405 | # CONFIG_SCSI_LPFC is not set | ||
404 | # CONFIG_SCSI_DC395x is not set | 406 | # CONFIG_SCSI_DC395x is not set |
405 | # CONFIG_SCSI_DC390T is not set | 407 | # CONFIG_SCSI_DC390T is not set |
406 | # CONFIG_SCSI_DEBUG is not set | 408 | # CONFIG_SCSI_DEBUG is not set |
@@ -437,7 +439,6 @@ CONFIG_NET=y | |||
437 | # | 439 | # |
438 | CONFIG_PACKET=y | 440 | CONFIG_PACKET=y |
439 | # CONFIG_PACKET_MMAP is not set | 441 | # CONFIG_PACKET_MMAP is not set |
440 | # CONFIG_NETLINK_DEV is not set | ||
441 | CONFIG_UNIX=y | 442 | CONFIG_UNIX=y |
442 | # CONFIG_NET_KEY is not set | 443 | # CONFIG_NET_KEY is not set |
443 | CONFIG_INET=y | 444 | CONFIG_INET=y |
@@ -502,7 +503,7 @@ CONFIG_NETDEVICES=y | |||
502 | # CONFIG_DUMMY is not set | 503 | # CONFIG_DUMMY is not set |
503 | # CONFIG_BONDING is not set | 504 | # CONFIG_BONDING is not set |
504 | # CONFIG_EQUALIZER is not set | 505 | # CONFIG_EQUALIZER is not set |
505 | # CONFIG_TUN is not set | 506 | CONFIG_TUN=y |
506 | 507 | ||
507 | # | 508 | # |
508 | # ARCnet devices | 509 | # ARCnet devices |
@@ -525,8 +526,7 @@ CONFIG_MII=y | |||
525 | # CONFIG_HP100 is not set | 526 | # CONFIG_HP100 is not set |
526 | CONFIG_NET_PCI=y | 527 | CONFIG_NET_PCI=y |
527 | # CONFIG_PCNET32 is not set | 528 | # CONFIG_PCNET32 is not set |
528 | CONFIG_AMD8111_ETH=y | 529 | # CONFIG_AMD8111_ETH is not set |
529 | # CONFIG_AMD8111E_NAPI is not set | ||
530 | # CONFIG_ADAPTEC_STARFIRE is not set | 530 | # CONFIG_ADAPTEC_STARFIRE is not set |
531 | # CONFIG_B44 is not set | 531 | # CONFIG_B44 is not set |
532 | CONFIG_FORCEDETH=y | 532 | CONFIG_FORCEDETH=y |
@@ -536,7 +536,7 @@ CONFIG_FORCEDETH=y | |||
536 | # CONFIG_FEALNX is not set | 536 | # CONFIG_FEALNX is not set |
537 | # CONFIG_NATSEMI is not set | 537 | # CONFIG_NATSEMI is not set |
538 | # CONFIG_NE2K_PCI is not set | 538 | # CONFIG_NE2K_PCI is not set |
539 | CONFIG_8139CP=m | 539 | CONFIG_8139CP=y |
540 | CONFIG_8139TOO=y | 540 | CONFIG_8139TOO=y |
541 | # CONFIG_8139TOO_PIO is not set | 541 | # CONFIG_8139TOO_PIO is not set |
542 | # CONFIG_8139TOO_TUNE_TWISTER is not set | 542 | # CONFIG_8139TOO_TUNE_TWISTER is not set |
@@ -671,6 +671,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4 | |||
671 | # | 671 | # |
672 | CONFIG_SERIAL_CORE=y | 672 | CONFIG_SERIAL_CORE=y |
673 | CONFIG_SERIAL_CORE_CONSOLE=y | 673 | CONFIG_SERIAL_CORE_CONSOLE=y |
674 | # CONFIG_SERIAL_JSM is not set | ||
674 | CONFIG_UNIX98_PTYS=y | 675 | CONFIG_UNIX98_PTYS=y |
675 | CONFIG_LEGACY_PTYS=y | 676 | CONFIG_LEGACY_PTYS=y |
676 | CONFIG_LEGACY_PTY_COUNT=256 | 677 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -696,6 +697,7 @@ CONFIG_RTC=y | |||
696 | # | 697 | # |
697 | CONFIG_AGP=y | 698 | CONFIG_AGP=y |
698 | CONFIG_AGP_AMD64=y | 699 | CONFIG_AGP_AMD64=y |
700 | CONFIG_AGP_INTEL=y | ||
699 | # CONFIG_DRM is not set | 701 | # CONFIG_DRM is not set |
700 | # CONFIG_MWAVE is not set | 702 | # CONFIG_MWAVE is not set |
701 | CONFIG_RAW_DRIVER=y | 703 | CONFIG_RAW_DRIVER=y |
@@ -703,7 +705,7 @@ CONFIG_HPET=y | |||
703 | # CONFIG_HPET_RTC_IRQ is not set | 705 | # CONFIG_HPET_RTC_IRQ is not set |
704 | CONFIG_HPET_MMAP=y | 706 | CONFIG_HPET_MMAP=y |
705 | CONFIG_MAX_RAW_DEVS=256 | 707 | CONFIG_MAX_RAW_DEVS=256 |
706 | CONFIG_HANGCHECK_TIMER=y | 708 | # CONFIG_HANGCHECK_TIMER is not set |
707 | 709 | ||
708 | # | 710 | # |
709 | # TPM devices | 711 | # TPM devices |
@@ -786,6 +788,8 @@ CONFIG_SOUND_ICH=y | |||
786 | # | 788 | # |
787 | # USB support | 789 | # USB support |
788 | # | 790 | # |
791 | CONFIG_USB_ARCH_HAS_HCD=y | ||
792 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
789 | CONFIG_USB=y | 793 | CONFIG_USB=y |
790 | # CONFIG_USB_DEBUG is not set | 794 | # CONFIG_USB_DEBUG is not set |
791 | 795 | ||
@@ -797,8 +801,6 @@ CONFIG_USB_DEVICEFS=y | |||
797 | # CONFIG_USB_DYNAMIC_MINORS is not set | 801 | # CONFIG_USB_DYNAMIC_MINORS is not set |
798 | # CONFIG_USB_SUSPEND is not set | 802 | # CONFIG_USB_SUSPEND is not set |
799 | # CONFIG_USB_OTG is not set | 803 | # CONFIG_USB_OTG is not set |
800 | CONFIG_USB_ARCH_HAS_HCD=y | ||
801 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
802 | 804 | ||
803 | # | 805 | # |
804 | # USB Host Controller Drivers | 806 | # USB Host Controller Drivers |
@@ -826,7 +828,6 @@ CONFIG_USB_PRINTER=y | |||
826 | # | 828 | # |
827 | CONFIG_USB_STORAGE=y | 829 | CONFIG_USB_STORAGE=y |
828 | # CONFIG_USB_STORAGE_DEBUG is not set | 830 | # CONFIG_USB_STORAGE_DEBUG is not set |
829 | # CONFIG_USB_STORAGE_RW_DETECT is not set | ||
830 | # CONFIG_USB_STORAGE_DATAFAB is not set | 831 | # CONFIG_USB_STORAGE_DATAFAB is not set |
831 | # CONFIG_USB_STORAGE_FREECOM is not set | 832 | # CONFIG_USB_STORAGE_FREECOM is not set |
832 | # CONFIG_USB_STORAGE_ISD200 is not set | 833 | # CONFIG_USB_STORAGE_ISD200 is not set |
@@ -965,7 +966,7 @@ CONFIG_AUTOFS_FS=y | |||
965 | # CD-ROM/DVD Filesystems | 966 | # CD-ROM/DVD Filesystems |
966 | # | 967 | # |
967 | CONFIG_ISO9660_FS=y | 968 | CONFIG_ISO9660_FS=y |
968 | # CONFIG_JOLIET is not set | 969 | CONFIG_JOLIET=y |
969 | # CONFIG_ZISOFS is not set | 970 | # CONFIG_ZISOFS is not set |
970 | # CONFIG_UDF_FS is not set | 971 | # CONFIG_UDF_FS is not set |
971 | 972 | ||
@@ -1092,9 +1093,10 @@ CONFIG_OPROFILE=y | |||
1092 | # | 1093 | # |
1093 | # Kernel hacking | 1094 | # Kernel hacking |
1094 | # | 1095 | # |
1096 | # CONFIG_PRINTK_TIME is not set | ||
1095 | CONFIG_DEBUG_KERNEL=y | 1097 | CONFIG_DEBUG_KERNEL=y |
1096 | CONFIG_MAGIC_SYSRQ=y | 1098 | CONFIG_MAGIC_SYSRQ=y |
1097 | # CONFIG_PRINTK_TIME is not set | 1099 | CONFIG_LOG_BUF_SHIFT=18 |
1098 | # CONFIG_SCHEDSTATS is not set | 1100 | # CONFIG_SCHEDSTATS is not set |
1099 | # CONFIG_DEBUG_SLAB is not set | 1101 | # CONFIG_DEBUG_SLAB is not set |
1100 | # CONFIG_DEBUG_SPINLOCK is not set | 1102 | # CONFIG_DEBUG_SPINLOCK is not set |
diff --git a/arch/x86_64/kernel/Makefile b/arch/x86_64/kernel/Makefile index 0a3318e08ab6..5ca4a4598fda 100644 --- a/arch/x86_64/kernel/Makefile +++ b/arch/x86_64/kernel/Makefile | |||
@@ -28,6 +28,7 @@ obj-$(CONFIG_GART_IOMMU) += pci-gart.o aperture.o | |||
28 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o | 28 | obj-$(CONFIG_DUMMY_IOMMU) += pci-nommu.o pci-dma.o |
29 | obj-$(CONFIG_SWIOTLB) += swiotlb.o | 29 | obj-$(CONFIG_SWIOTLB) += swiotlb.o |
30 | obj-$(CONFIG_KPROBES) += kprobes.o | 30 | obj-$(CONFIG_KPROBES) += kprobes.o |
31 | obj-$(CONFIG_X86_PM_TIMER) += pmtimer.o | ||
31 | 32 | ||
32 | obj-$(CONFIG_MODULES) += module.o | 33 | obj-$(CONFIG_MODULES) += module.o |
33 | 34 | ||
diff --git a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c index 7e13545748e0..f8e6cc4fecd4 100644 --- a/arch/x86_64/kernel/apic.c +++ b/arch/x86_64/kernel/apic.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/mpspec.h> | 33 | #include <asm/mpspec.h> |
34 | #include <asm/pgalloc.h> | 34 | #include <asm/pgalloc.h> |
35 | #include <asm/mach_apic.h> | 35 | #include <asm/mach_apic.h> |
36 | #include <asm/nmi.h> | ||
36 | 37 | ||
37 | int apic_verbosity; | 38 | int apic_verbosity; |
38 | 39 | ||
@@ -925,7 +926,7 @@ __init int oem_force_hpet_timer(void) | |||
925 | unsigned id; | 926 | unsigned id; |
926 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); | 927 | DECLARE_BITMAP(clustermap, NUM_APIC_CLUSTERS); |
927 | 928 | ||
928 | bitmap_empty(clustermap, NUM_APIC_CLUSTERS); | 929 | bitmap_zero(clustermap, NUM_APIC_CLUSTERS); |
929 | 930 | ||
930 | for (i = 0; i < NR_CPUS; i++) { | 931 | for (i = 0; i < NR_CPUS; i++) { |
931 | id = bios_cpu_apicid[i]; | 932 | id = bios_cpu_apicid[i]; |
@@ -1056,7 +1057,7 @@ int __init APIC_init_uniprocessor (void) | |||
1056 | nr_ioapics = 0; | 1057 | nr_ioapics = 0; |
1057 | #endif | 1058 | #endif |
1058 | setup_boot_APIC_clock(); | 1059 | setup_boot_APIC_clock(); |
1059 | 1060 | check_nmi_watchdog(); | |
1060 | return 0; | 1061 | return 0; |
1061 | } | 1062 | } |
1062 | 1063 | ||
diff --git a/arch/x86_64/kernel/entry.S b/arch/x86_64/kernel/entry.S index 1086b5fcac21..28817490fdc6 100644 --- a/arch/x86_64/kernel/entry.S +++ b/arch/x86_64/kernel/entry.S | |||
@@ -220,13 +220,18 @@ sysret_careful: | |||
220 | jmp sysret_check | 220 | jmp sysret_check |
221 | 221 | ||
222 | /* Handle a signal */ | 222 | /* Handle a signal */ |
223 | /* edx: work flags (arg3) */ | ||
224 | sysret_signal: | 223 | sysret_signal: |
225 | sti | 224 | sti |
225 | testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx | ||
226 | jz 1f | ||
227 | |||
228 | /* Really a signal */ | ||
229 | /* edx: work flags (arg3) */ | ||
226 | leaq do_notify_resume(%rip),%rax | 230 | leaq do_notify_resume(%rip),%rax |
227 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 | 231 | leaq -ARGOFFSET(%rsp),%rdi # &pt_regs -> arg1 |
228 | xorl %esi,%esi # oldset -> arg2 | 232 | xorl %esi,%esi # oldset -> arg2 |
229 | call ptregscall_common | 233 | call ptregscall_common |
234 | 1: movl $_TIF_NEED_RESCHED,%edi | ||
230 | jmp sysret_check | 235 | jmp sysret_check |
231 | 236 | ||
232 | /* Do syscall tracing */ | 237 | /* Do syscall tracing */ |
@@ -484,6 +489,8 @@ retint_careful: | |||
484 | jmp retint_check | 489 | jmp retint_check |
485 | 490 | ||
486 | retint_signal: | 491 | retint_signal: |
492 | testl $(_TIF_SIGPENDING|_TIF_NOTIFY_RESUME|_TIF_SINGLESTEP),%edx | ||
493 | jz retint_swapgs | ||
487 | sti | 494 | sti |
488 | SAVE_REST | 495 | SAVE_REST |
489 | movq $-1,ORIG_RAX(%rsp) | 496 | movq $-1,ORIG_RAX(%rsp) |
@@ -492,8 +499,8 @@ retint_signal: | |||
492 | call do_notify_resume | 499 | call do_notify_resume |
493 | RESTORE_REST | 500 | RESTORE_REST |
494 | cli | 501 | cli |
502 | movl $_TIF_NEED_RESCHED,%edi | ||
495 | GET_THREAD_INFO(%rcx) | 503 | GET_THREAD_INFO(%rcx) |
496 | movl $_TIF_WORK_MASK,%edi | ||
497 | jmp retint_check | 504 | jmp retint_check |
498 | 505 | ||
499 | #ifdef CONFIG_PREEMPT | 506 | #ifdef CONFIG_PREEMPT |
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 60be58617eb9..80e9b498c443 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c | |||
@@ -42,6 +42,8 @@ | |||
42 | 42 | ||
43 | int sis_apic_bug; /* not actually supported, dummy for compile */ | 43 | int sis_apic_bug; /* not actually supported, dummy for compile */ |
44 | 44 | ||
45 | static int no_timer_check; | ||
46 | |||
45 | static DEFINE_SPINLOCK(ioapic_lock); | 47 | static DEFINE_SPINLOCK(ioapic_lock); |
46 | 48 | ||
47 | /* | 49 | /* |
@@ -1601,7 +1603,7 @@ static inline void check_timer(void) | |||
1601 | * Ok, does IRQ0 through the IOAPIC work? | 1603 | * Ok, does IRQ0 through the IOAPIC work? |
1602 | */ | 1604 | */ |
1603 | unmask_IO_APIC_irq(0); | 1605 | unmask_IO_APIC_irq(0); |
1604 | if (timer_irq_works()) { | 1606 | if (!no_timer_check && timer_irq_works()) { |
1605 | nmi_watchdog_default(); | 1607 | nmi_watchdog_default(); |
1606 | if (nmi_watchdog == NMI_IO_APIC) { | 1608 | if (nmi_watchdog == NMI_IO_APIC) { |
1607 | disable_8259A_irq(0); | 1609 | disable_8259A_irq(0); |
@@ -1671,6 +1673,13 @@ static inline void check_timer(void) | |||
1671 | panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); | 1673 | panic("IO-APIC + timer doesn't work! Try using the 'noapic' kernel parameter\n"); |
1672 | } | 1674 | } |
1673 | 1675 | ||
1676 | static int __init notimercheck(char *s) | ||
1677 | { | ||
1678 | no_timer_check = 1; | ||
1679 | return 1; | ||
1680 | } | ||
1681 | __setup("no_timer_check", notimercheck); | ||
1682 | |||
1674 | /* | 1683 | /* |
1675 | * | 1684 | * |
1676 | * IRQ's that are handled by the PIC in the MPS IOAPIC case. | 1685 | * IRQ's that are handled by the PIC in the MPS IOAPIC case. |
@@ -1804,76 +1813,6 @@ device_initcall(ioapic_init_sysfs); | |||
1804 | 1813 | ||
1805 | #define IO_APIC_MAX_ID 0xFE | 1814 | #define IO_APIC_MAX_ID 0xFE |
1806 | 1815 | ||
1807 | int __init io_apic_get_unique_id (int ioapic, int apic_id) | ||
1808 | { | ||
1809 | union IO_APIC_reg_00 reg_00; | ||
1810 | static physid_mask_t apic_id_map; | ||
1811 | unsigned long flags; | ||
1812 | int i = 0; | ||
1813 | |||
1814 | /* | ||
1815 | * The P4 platform supports up to 256 APIC IDs on two separate APIC | ||
1816 | * buses (one for LAPICs, one for IOAPICs), where predecessors only | ||
1817 | * supports up to 16 on one shared APIC bus. | ||
1818 | * | ||
1819 | * TBD: Expand LAPIC/IOAPIC support on P4-class systems to take full | ||
1820 | * advantage of new APIC bus architecture. | ||
1821 | */ | ||
1822 | |||
1823 | if (physids_empty(apic_id_map)) | ||
1824 | apic_id_map = phys_cpu_present_map; | ||
1825 | |||
1826 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1827 | reg_00.raw = io_apic_read(ioapic, 0); | ||
1828 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1829 | |||
1830 | if (apic_id >= IO_APIC_MAX_ID) { | ||
1831 | apic_printk(APIC_QUIET, KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying " | ||
1832 | "%d\n", ioapic, apic_id, reg_00.bits.ID); | ||
1833 | apic_id = reg_00.bits.ID; | ||
1834 | } | ||
1835 | |||
1836 | /* | ||
1837 | * Every APIC in a system must have a unique ID or we get lots of nice | ||
1838 | * 'stuck on smp_invalidate_needed IPI wait' messages. | ||
1839 | */ | ||
1840 | if (physid_isset(apic_id, apic_id_map)) { | ||
1841 | |||
1842 | for (i = 0; i < IO_APIC_MAX_ID; i++) { | ||
1843 | if (!physid_isset(i, apic_id_map)) | ||
1844 | break; | ||
1845 | } | ||
1846 | |||
1847 | if (i == IO_APIC_MAX_ID) | ||
1848 | panic("Max apic_id exceeded!\n"); | ||
1849 | |||
1850 | apic_printk(APIC_VERBOSE, KERN_WARNING "IOAPIC[%d]: apic_id %d already used, " | ||
1851 | "trying %d\n", ioapic, apic_id, i); | ||
1852 | |||
1853 | apic_id = i; | ||
1854 | } | ||
1855 | |||
1856 | physid_set(apic_id, apic_id_map); | ||
1857 | |||
1858 | if (reg_00.bits.ID != apic_id) { | ||
1859 | reg_00.bits.ID = apic_id; | ||
1860 | |||
1861 | spin_lock_irqsave(&ioapic_lock, flags); | ||
1862 | io_apic_write(ioapic, 0, reg_00.raw); | ||
1863 | reg_00.raw = io_apic_read(ioapic, 0); | ||
1864 | spin_unlock_irqrestore(&ioapic_lock, flags); | ||
1865 | |||
1866 | /* Sanity check */ | ||
1867 | if (reg_00.bits.ID != apic_id) | ||
1868 | panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); | ||
1869 | } | ||
1870 | |||
1871 | apic_printk(APIC_VERBOSE,KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); | ||
1872 | |||
1873 | return apic_id; | ||
1874 | } | ||
1875 | |||
1876 | |||
1877 | int __init io_apic_get_version (int ioapic) | 1816 | int __init io_apic_get_version (int ioapic) |
1878 | { | 1817 | { |
1879 | union IO_APIC_reg_01 reg_01; | 1818 | union IO_APIC_reg_01 reg_01; |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 4f2a852299b6..f77f8a0ff187 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -355,6 +355,13 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
355 | *tos &= ~(TF_MASK | IF_MASK); | 355 | *tos &= ~(TF_MASK | IF_MASK); |
356 | *tos |= kprobe_old_rflags; | 356 | *tos |= kprobe_old_rflags; |
357 | break; | 357 | break; |
358 | case 0xc3: /* ret/lret */ | ||
359 | case 0xcb: | ||
360 | case 0xc2: | ||
361 | case 0xca: | ||
362 | regs->eflags &= ~TF_MASK; | ||
363 | /* rip is already adjusted, no more changes required*/ | ||
364 | return; | ||
358 | case 0xe8: /* call relative - Fix return addr */ | 365 | case 0xe8: /* call relative - Fix return addr */ |
359 | *tos = orig_rip + (*tos - copy_rip); | 366 | *tos = orig_rip + (*tos - copy_rip); |
360 | break; | 367 | break; |
diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index c2ffea8845ed..bac195c74bcc 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c | |||
@@ -30,9 +30,12 @@ | |||
30 | 30 | ||
31 | #define DEBUGP(fmt...) | 31 | #define DEBUGP(fmt...) |
32 | 32 | ||
33 | #ifndef CONFIG_UML | ||
33 | void module_free(struct module *mod, void *module_region) | 34 | void module_free(struct module *mod, void *module_region) |
34 | { | 35 | { |
35 | vfree(module_region); | 36 | vfree(module_region); |
37 | /* FIXME: If module_region == mod->init_region, trim exception | ||
38 | table entries. */ | ||
36 | } | 39 | } |
37 | 40 | ||
38 | void *module_alloc(unsigned long size) | 41 | void *module_alloc(unsigned long size) |
@@ -51,6 +54,7 @@ void *module_alloc(unsigned long size) | |||
51 | 54 | ||
52 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); | 55 | return __vmalloc_area(area, GFP_KERNEL, PAGE_KERNEL_EXEC); |
53 | } | 56 | } |
57 | #endif | ||
54 | 58 | ||
55 | /* We don't need anything special. */ | 59 | /* We don't need anything special. */ |
56 | int module_frob_arch_sections(Elf_Ehdr *hdr, | 60 | int module_frob_arch_sections(Elf_Ehdr *hdr, |
diff --git a/arch/x86_64/kernel/mpparse.c b/arch/x86_64/kernel/mpparse.c index 7ec031c6ca10..f86d9db94bfc 100644 --- a/arch/x86_64/kernel/mpparse.c +++ b/arch/x86_64/kernel/mpparse.c | |||
@@ -107,6 +107,7 @@ static int __init mpf_checksum(unsigned char *mp, int len) | |||
107 | static void __init MP_processor_info (struct mpc_config_processor *m) | 107 | static void __init MP_processor_info (struct mpc_config_processor *m) |
108 | { | 108 | { |
109 | int ver; | 109 | int ver; |
110 | static int found_bsp=0; | ||
110 | 111 | ||
111 | if (!(m->mpc_cpuflag & CPU_ENABLED)) | 112 | if (!(m->mpc_cpuflag & CPU_ENABLED)) |
112 | return; | 113 | return; |
@@ -126,11 +127,6 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
126 | " Processor ignored.\n", NR_CPUS); | 127 | " Processor ignored.\n", NR_CPUS); |
127 | return; | 128 | return; |
128 | } | 129 | } |
129 | if (num_processors >= maxcpus) { | ||
130 | printk(KERN_WARNING "WARNING: maxcpus limit of %i reached." | ||
131 | " Processor ignored.\n", maxcpus); | ||
132 | return; | ||
133 | } | ||
134 | 130 | ||
135 | num_processors++; | 131 | num_processors++; |
136 | 132 | ||
@@ -150,7 +146,19 @@ static void __init MP_processor_info (struct mpc_config_processor *m) | |||
150 | ver = 0x10; | 146 | ver = 0x10; |
151 | } | 147 | } |
152 | apic_version[m->mpc_apicid] = ver; | 148 | apic_version[m->mpc_apicid] = ver; |
153 | bios_cpu_apicid[num_processors - 1] = m->mpc_apicid; | 149 | if (m->mpc_cpuflag & CPU_BOOTPROCESSOR) { |
150 | /* | ||
151 | * bios_cpu_apicid is required to have processors listed | ||
152 | * in same order as logical cpu numbers. Hence the first | ||
153 | * entry is BSP, and so on. | ||
154 | */ | ||
155 | bios_cpu_apicid[0] = m->mpc_apicid; | ||
156 | x86_cpu_to_apicid[0] = m->mpc_apicid; | ||
157 | found_bsp = 1; | ||
158 | } else { | ||
159 | bios_cpu_apicid[num_processors - found_bsp] = m->mpc_apicid; | ||
160 | x86_cpu_to_apicid[num_processors - found_bsp] = m->mpc_apicid; | ||
161 | } | ||
154 | } | 162 | } |
155 | 163 | ||
156 | static void __init MP_bus_info (struct mpc_config_bus *m) | 164 | static void __init MP_bus_info (struct mpc_config_bus *m) |
@@ -759,7 +767,7 @@ void __init mp_register_ioapic ( | |||
759 | mp_ioapics[idx].mpc_apicaddr = address; | 767 | mp_ioapics[idx].mpc_apicaddr = address; |
760 | 768 | ||
761 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); | 769 | set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); |
762 | mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id); | 770 | mp_ioapics[idx].mpc_apicid = id; |
763 | mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); | 771 | mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx); |
764 | 772 | ||
765 | /* | 773 | /* |
diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 61de0b34a01e..31c0f2e6ac91 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <asm/msr.h> | 33 | #include <asm/msr.h> |
34 | #include <asm/proto.h> | 34 | #include <asm/proto.h> |
35 | #include <asm/kdebug.h> | 35 | #include <asm/kdebug.h> |
36 | #include <asm/local.h> | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: | 39 | * lapic_nmi_owner tracks the ownership of the lapic NMI hardware: |
@@ -59,7 +60,8 @@ int panic_on_timeout; | |||
59 | 60 | ||
60 | unsigned int nmi_watchdog = NMI_DEFAULT; | 61 | unsigned int nmi_watchdog = NMI_DEFAULT; |
61 | static unsigned int nmi_hz = HZ; | 62 | static unsigned int nmi_hz = HZ; |
62 | unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ | 63 | static unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ |
64 | static unsigned int nmi_p4_cccr_val; | ||
63 | 65 | ||
64 | /* Note that these events don't tick when the CPU idles. This means | 66 | /* Note that these events don't tick when the CPU idles. This means |
65 | the frequency varies with CPU load. */ | 67 | the frequency varies with CPU load. */ |
@@ -71,61 +73,87 @@ unsigned int nmi_perfctr_msr; /* the MSR to reset in NMI handler */ | |||
71 | #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 | 73 | #define K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING 0x76 |
72 | #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING | 74 | #define K7_NMI_EVENT K7_EVENT_CYCLES_PROCESSOR_IS_RUNNING |
73 | 75 | ||
74 | #define P6_EVNTSEL0_ENABLE (1 << 22) | 76 | #define MSR_P4_MISC_ENABLE 0x1A0 |
75 | #define P6_EVNTSEL_INT (1 << 20) | 77 | #define MSR_P4_MISC_ENABLE_PERF_AVAIL (1<<7) |
76 | #define P6_EVNTSEL_OS (1 << 17) | 78 | #define MSR_P4_MISC_ENABLE_PEBS_UNAVAIL (1<<12) |
77 | #define P6_EVNTSEL_USR (1 << 16) | 79 | #define MSR_P4_PERFCTR0 0x300 |
78 | #define P6_EVENT_CPU_CLOCKS_NOT_HALTED 0x79 | 80 | #define MSR_P4_CCCR0 0x360 |
79 | #define P6_NMI_EVENT P6_EVENT_CPU_CLOCKS_NOT_HALTED | 81 | #define P4_ESCR_EVENT_SELECT(N) ((N)<<25) |
82 | #define P4_ESCR_OS (1<<3) | ||
83 | #define P4_ESCR_USR (1<<2) | ||
84 | #define P4_CCCR_OVF_PMI0 (1<<26) | ||
85 | #define P4_CCCR_OVF_PMI1 (1<<27) | ||
86 | #define P4_CCCR_THRESHOLD(N) ((N)<<20) | ||
87 | #define P4_CCCR_COMPLEMENT (1<<19) | ||
88 | #define P4_CCCR_COMPARE (1<<18) | ||
89 | #define P4_CCCR_REQUIRED (3<<16) | ||
90 | #define P4_CCCR_ESCR_SELECT(N) ((N)<<13) | ||
91 | #define P4_CCCR_ENABLE (1<<12) | ||
92 | /* Set up IQ_COUNTER0 to behave like a clock, by having IQ_CCCR0 filter | ||
93 | CRU_ESCR0 (with any non-null event selector) through a complemented | ||
94 | max threshold. [IA32-Vol3, Section 14.9.9] */ | ||
95 | #define MSR_P4_IQ_COUNTER0 0x30C | ||
96 | #define P4_NMI_CRU_ESCR0 (P4_ESCR_EVENT_SELECT(0x3F)|P4_ESCR_OS|P4_ESCR_USR) | ||
97 | #define P4_NMI_IQ_CCCR0 \ | ||
98 | (P4_CCCR_OVF_PMI0|P4_CCCR_THRESHOLD(15)|P4_CCCR_COMPLEMENT| \ | ||
99 | P4_CCCR_COMPARE|P4_CCCR_REQUIRED|P4_CCCR_ESCR_SELECT(4)|P4_CCCR_ENABLE) | ||
100 | |||
101 | static __init inline int nmi_known_cpu(void) | ||
102 | { | ||
103 | switch (boot_cpu_data.x86_vendor) { | ||
104 | case X86_VENDOR_AMD: | ||
105 | return boot_cpu_data.x86 == 15; | ||
106 | case X86_VENDOR_INTEL: | ||
107 | return boot_cpu_data.x86 == 15; | ||
108 | } | ||
109 | return 0; | ||
110 | } | ||
80 | 111 | ||
81 | /* Run after command line and cpu_init init, but before all other checks */ | 112 | /* Run after command line and cpu_init init, but before all other checks */ |
82 | void __init nmi_watchdog_default(void) | 113 | void __init nmi_watchdog_default(void) |
83 | { | 114 | { |
84 | if (nmi_watchdog != NMI_DEFAULT) | 115 | if (nmi_watchdog != NMI_DEFAULT) |
85 | return; | 116 | return; |
86 | 117 | if (nmi_known_cpu()) | |
87 | /* For some reason the IO APIC watchdog doesn't work on the AMD | 118 | nmi_watchdog = NMI_LOCAL_APIC; |
88 | 8111 chipset. For now switch to local APIC mode using | 119 | else |
89 | perfctr0 there. On Intel CPUs we don't have code to handle | ||
90 | the perfctr and the IO-APIC seems to work, so use that. */ | ||
91 | |||
92 | if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD) { | ||
93 | nmi_watchdog = NMI_LOCAL_APIC; | ||
94 | printk(KERN_INFO | ||
95 | "Using local APIC NMI watchdog using perfctr0\n"); | ||
96 | } else { | ||
97 | printk(KERN_INFO "Using IO APIC NMI watchdog\n"); | ||
98 | nmi_watchdog = NMI_IO_APIC; | 120 | nmi_watchdog = NMI_IO_APIC; |
99 | } | ||
100 | } | 121 | } |
101 | 122 | ||
102 | /* Why is there no CPUID flag for this? */ | 123 | #ifdef CONFIG_SMP |
103 | static __init int cpu_has_lapic(void) | 124 | /* The performance counters used by NMI_LOCAL_APIC don't trigger when |
125 | * the CPU is idle. To make sure the NMI watchdog really ticks on all | ||
126 | * CPUs during the test make them busy. | ||
127 | */ | ||
128 | static __init void nmi_cpu_busy(void *data) | ||
104 | { | 129 | { |
105 | switch (boot_cpu_data.x86_vendor) { | 130 | volatile int *endflag = data; |
106 | case X86_VENDOR_INTEL: | 131 | local_irq_enable(); |
107 | case X86_VENDOR_AMD: | 132 | /* Intentionally don't use cpu_relax here. This is |
108 | return boot_cpu_data.x86 >= 6; | 133 | to make sure that the performance counter really ticks, |
109 | /* .... add more cpus here or find a different way to figure this out. */ | 134 | even if there is a simulator or similar that catches the |
110 | default: | 135 | pause instruction. On a real HT machine this is fine because |
111 | return 0; | 136 | all other CPUs are busy with "useless" delay loops and don't |
112 | } | 137 | care if they get somewhat less cycles. */ |
138 | while (*endflag == 0) | ||
139 | barrier(); | ||
113 | } | 140 | } |
141 | #endif | ||
114 | 142 | ||
115 | static int __init check_nmi_watchdog (void) | 143 | int __init check_nmi_watchdog (void) |
116 | { | 144 | { |
117 | int counts[NR_CPUS]; | 145 | volatile int endflag = 0; |
146 | int *counts; | ||
118 | int cpu; | 147 | int cpu; |
119 | 148 | ||
120 | if (nmi_watchdog == NMI_NONE) | 149 | counts = kmalloc(NR_CPUS * sizeof(int), GFP_KERNEL); |
121 | return 0; | 150 | if (!counts) |
151 | return -1; | ||
122 | 152 | ||
123 | if (nmi_watchdog == NMI_LOCAL_APIC && !cpu_has_lapic()) { | 153 | printk(KERN_INFO "testing NMI watchdog ... "); |
124 | nmi_watchdog = NMI_NONE; | ||
125 | return -1; | ||
126 | } | ||
127 | 154 | ||
128 | printk(KERN_INFO "Testing NMI watchdog ... "); | 155 | if (nmi_watchdog == NMI_LOCAL_APIC) |
156 | smp_call_function(nmi_cpu_busy, (void *)&endflag, 0, 0); | ||
129 | 157 | ||
130 | for (cpu = 0; cpu < NR_CPUS; cpu++) | 158 | for (cpu = 0; cpu < NR_CPUS; cpu++) |
131 | counts[cpu] = cpu_pda[cpu].__nmi_count; | 159 | counts[cpu] = cpu_pda[cpu].__nmi_count; |
@@ -133,15 +161,22 @@ static int __init check_nmi_watchdog (void) | |||
133 | mdelay((10*1000)/nmi_hz); // wait 10 ticks | 161 | mdelay((10*1000)/nmi_hz); // wait 10 ticks |
134 | 162 | ||
135 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 163 | for (cpu = 0; cpu < NR_CPUS; cpu++) { |
164 | if (!cpu_online(cpu)) | ||
165 | continue; | ||
136 | if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { | 166 | if (cpu_pda[cpu].__nmi_count - counts[cpu] <= 5) { |
137 | printk("CPU#%d: NMI appears to be stuck (%d)!\n", | 167 | endflag = 1; |
168 | printk("CPU#%d: NMI appears to be stuck (%d->%d)!\n", | ||
138 | cpu, | 169 | cpu, |
170 | counts[cpu], | ||
139 | cpu_pda[cpu].__nmi_count); | 171 | cpu_pda[cpu].__nmi_count); |
140 | nmi_active = 0; | 172 | nmi_active = 0; |
141 | lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; | 173 | lapic_nmi_owner &= ~LAPIC_NMI_WATCHDOG; |
174 | nmi_perfctr_msr = 0; | ||
175 | kfree(counts); | ||
142 | return -1; | 176 | return -1; |
143 | } | 177 | } |
144 | } | 178 | } |
179 | endflag = 1; | ||
145 | printk("OK.\n"); | 180 | printk("OK.\n"); |
146 | 181 | ||
147 | /* now that we know it works we can reduce NMI frequency to | 182 | /* now that we know it works we can reduce NMI frequency to |
@@ -149,10 +184,9 @@ static int __init check_nmi_watchdog (void) | |||
149 | if (nmi_watchdog == NMI_LOCAL_APIC) | 184 | if (nmi_watchdog == NMI_LOCAL_APIC) |
150 | nmi_hz = 1; | 185 | nmi_hz = 1; |
151 | 186 | ||
187 | kfree(counts); | ||
152 | return 0; | 188 | return 0; |
153 | } | 189 | } |
154 | /* Have this called later during boot so counters are updating */ | ||
155 | late_initcall(check_nmi_watchdog); | ||
156 | 190 | ||
157 | int __init setup_nmi_watchdog(char *str) | 191 | int __init setup_nmi_watchdog(char *str) |
158 | { | 192 | { |
@@ -170,7 +204,7 @@ int __init setup_nmi_watchdog(char *str) | |||
170 | 204 | ||
171 | if (nmi >= NMI_INVALID) | 205 | if (nmi >= NMI_INVALID) |
172 | return 0; | 206 | return 0; |
173 | nmi_watchdog = nmi; | 207 | nmi_watchdog = nmi; |
174 | return 1; | 208 | return 1; |
175 | } | 209 | } |
176 | 210 | ||
@@ -185,7 +219,10 @@ static void disable_lapic_nmi_watchdog(void) | |||
185 | wrmsr(MSR_K7_EVNTSEL0, 0, 0); | 219 | wrmsr(MSR_K7_EVNTSEL0, 0, 0); |
186 | break; | 220 | break; |
187 | case X86_VENDOR_INTEL: | 221 | case X86_VENDOR_INTEL: |
188 | wrmsr(MSR_IA32_EVNTSEL0, 0, 0); | 222 | if (boot_cpu_data.x86 == 15) { |
223 | wrmsr(MSR_P4_IQ_CCCR0, 0, 0); | ||
224 | wrmsr(MSR_P4_CRU_ESCR0, 0, 0); | ||
225 | } | ||
189 | break; | 226 | break; |
190 | } | 227 | } |
191 | nmi_active = -1; | 228 | nmi_active = -1; |
@@ -253,7 +290,7 @@ void enable_timer_nmi_watchdog(void) | |||
253 | 290 | ||
254 | static int nmi_pm_active; /* nmi_active before suspend */ | 291 | static int nmi_pm_active; /* nmi_active before suspend */ |
255 | 292 | ||
256 | static int lapic_nmi_suspend(struct sys_device *dev, pm_message_t state) | 293 | static int lapic_nmi_suspend(struct sys_device *dev, u32 state) |
257 | { | 294 | { |
258 | nmi_pm_active = nmi_active; | 295 | nmi_pm_active = nmi_active; |
259 | disable_lapic_nmi_watchdog(); | 296 | disable_lapic_nmi_watchdog(); |
@@ -300,22 +337,27 @@ late_initcall(init_lapic_nmi_sysfs); | |||
300 | * Original code written by Keith Owens. | 337 | * Original code written by Keith Owens. |
301 | */ | 338 | */ |
302 | 339 | ||
340 | static void clear_msr_range(unsigned int base, unsigned int n) | ||
341 | { | ||
342 | unsigned int i; | ||
343 | |||
344 | for(i = 0; i < n; ++i) | ||
345 | wrmsr(base+i, 0, 0); | ||
346 | } | ||
347 | |||
303 | static void setup_k7_watchdog(void) | 348 | static void setup_k7_watchdog(void) |
304 | { | 349 | { |
305 | int i; | 350 | int i; |
306 | unsigned int evntsel; | 351 | unsigned int evntsel; |
307 | 352 | ||
308 | /* No check, so can start with slow frequency */ | ||
309 | nmi_hz = 1; | ||
310 | |||
311 | /* XXX should check these in EFER */ | ||
312 | |||
313 | nmi_perfctr_msr = MSR_K7_PERFCTR0; | 353 | nmi_perfctr_msr = MSR_K7_PERFCTR0; |
314 | 354 | ||
315 | for(i = 0; i < 4; ++i) { | 355 | for(i = 0; i < 4; ++i) { |
316 | /* Simulator may not support it */ | 356 | /* Simulator may not support it */ |
317 | if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) | 357 | if (checking_wrmsrl(MSR_K7_EVNTSEL0+i, 0UL)) { |
358 | nmi_perfctr_msr = 0; | ||
318 | return; | 359 | return; |
360 | } | ||
319 | wrmsrl(MSR_K7_PERFCTR0+i, 0UL); | 361 | wrmsrl(MSR_K7_PERFCTR0+i, 0UL); |
320 | } | 362 | } |
321 | 363 | ||
@@ -325,12 +367,54 @@ static void setup_k7_watchdog(void) | |||
325 | | K7_NMI_EVENT; | 367 | | K7_NMI_EVENT; |
326 | 368 | ||
327 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 369 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
328 | wrmsrl(MSR_K7_PERFCTR0, -((u64)cpu_khz*1000) / nmi_hz); | 370 | wrmsr(MSR_K7_PERFCTR0, -(cpu_khz/nmi_hz*1000), -1); |
329 | apic_write(APIC_LVTPC, APIC_DM_NMI); | 371 | apic_write(APIC_LVTPC, APIC_DM_NMI); |
330 | evntsel |= K7_EVNTSEL_ENABLE; | 372 | evntsel |= K7_EVNTSEL_ENABLE; |
331 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); | 373 | wrmsr(MSR_K7_EVNTSEL0, evntsel, 0); |
332 | } | 374 | } |
333 | 375 | ||
376 | |||
377 | static int setup_p4_watchdog(void) | ||
378 | { | ||
379 | unsigned int misc_enable, dummy; | ||
380 | |||
381 | rdmsr(MSR_P4_MISC_ENABLE, misc_enable, dummy); | ||
382 | if (!(misc_enable & MSR_P4_MISC_ENABLE_PERF_AVAIL)) | ||
383 | return 0; | ||
384 | |||
385 | nmi_perfctr_msr = MSR_P4_IQ_COUNTER0; | ||
386 | nmi_p4_cccr_val = P4_NMI_IQ_CCCR0; | ||
387 | #ifdef CONFIG_SMP | ||
388 | if (smp_num_siblings == 2) | ||
389 | nmi_p4_cccr_val |= P4_CCCR_OVF_PMI1; | ||
390 | #endif | ||
391 | |||
392 | if (!(misc_enable & MSR_P4_MISC_ENABLE_PEBS_UNAVAIL)) | ||
393 | clear_msr_range(0x3F1, 2); | ||
394 | /* MSR 0x3F0 seems to have a default value of 0xFC00, but current | ||
395 | docs doesn't fully define it, so leave it alone for now. */ | ||
396 | if (boot_cpu_data.x86_model >= 0x3) { | ||
397 | /* MSR_P4_IQ_ESCR0/1 (0x3ba/0x3bb) removed */ | ||
398 | clear_msr_range(0x3A0, 26); | ||
399 | clear_msr_range(0x3BC, 3); | ||
400 | } else { | ||
401 | clear_msr_range(0x3A0, 31); | ||
402 | } | ||
403 | clear_msr_range(0x3C0, 6); | ||
404 | clear_msr_range(0x3C8, 6); | ||
405 | clear_msr_range(0x3E0, 2); | ||
406 | clear_msr_range(MSR_P4_CCCR0, 18); | ||
407 | clear_msr_range(MSR_P4_PERFCTR0, 18); | ||
408 | |||
409 | wrmsr(MSR_P4_CRU_ESCR0, P4_NMI_CRU_ESCR0, 0); | ||
410 | wrmsr(MSR_P4_IQ_CCCR0, P4_NMI_IQ_CCCR0 & ~P4_CCCR_ENABLE, 0); | ||
411 | Dprintk("setting P4_IQ_COUNTER0 to 0x%08lx\n", -(cpu_khz/nmi_hz*1000)); | ||
412 | wrmsr(MSR_P4_IQ_COUNTER0, -(cpu_khz/nmi_hz*1000), -1); | ||
413 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
414 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); | ||
415 | return 1; | ||
416 | } | ||
417 | |||
334 | void setup_apic_nmi_watchdog(void) | 418 | void setup_apic_nmi_watchdog(void) |
335 | { | 419 | { |
336 | switch (boot_cpu_data.x86_vendor) { | 420 | switch (boot_cpu_data.x86_vendor) { |
@@ -341,6 +425,13 @@ void setup_apic_nmi_watchdog(void) | |||
341 | return; | 425 | return; |
342 | setup_k7_watchdog(); | 426 | setup_k7_watchdog(); |
343 | break; | 427 | break; |
428 | case X86_VENDOR_INTEL: | ||
429 | if (boot_cpu_data.x86 != 15) | ||
430 | return; | ||
431 | if (!setup_p4_watchdog()) | ||
432 | return; | ||
433 | break; | ||
434 | |||
344 | default: | 435 | default: |
345 | return; | 436 | return; |
346 | } | 437 | } |
@@ -355,56 +446,67 @@ void setup_apic_nmi_watchdog(void) | |||
355 | * | 446 | * |
356 | * as these watchdog NMI IRQs are generated on every CPU, we only | 447 | * as these watchdog NMI IRQs are generated on every CPU, we only |
357 | * have to check the current processor. | 448 | * have to check the current processor. |
358 | * | ||
359 | * since NMIs don't listen to _any_ locks, we have to be extremely | ||
360 | * careful not to rely on unsafe variables. The printk might lock | ||
361 | * up though, so we have to break up any console locks first ... | ||
362 | * [when there will be more tty-related locks, break them up | ||
363 | * here too!] | ||
364 | */ | 449 | */ |
365 | 450 | ||
366 | static unsigned int | 451 | static DEFINE_PER_CPU(unsigned, last_irq_sum); |
367 | last_irq_sums [NR_CPUS], | 452 | static DEFINE_PER_CPU(local_t, alert_counter); |
368 | alert_counter [NR_CPUS]; | 453 | static DEFINE_PER_CPU(int, nmi_touch); |
369 | 454 | ||
370 | void touch_nmi_watchdog (void) | 455 | void touch_nmi_watchdog (void) |
371 | { | 456 | { |
372 | int i; | 457 | int i; |
373 | 458 | ||
374 | /* | 459 | /* |
375 | * Just reset the alert counters, (other CPUs might be | 460 | * Tell other CPUs to reset their alert counters. We cannot |
376 | * spinning on locks we hold): | 461 | * do it ourselves because the alert count increase is not |
462 | * atomic. | ||
377 | */ | 463 | */ |
378 | for (i = 0; i < NR_CPUS; i++) | 464 | for (i = 0; i < NR_CPUS; i++) |
379 | alert_counter[i] = 0; | 465 | per_cpu(nmi_touch, i) = 1; |
380 | } | 466 | } |
381 | 467 | ||
382 | void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) | 468 | void nmi_watchdog_tick (struct pt_regs * regs, unsigned reason) |
383 | { | 469 | { |
384 | int sum, cpu; | 470 | int sum; |
471 | int touched = 0; | ||
385 | 472 | ||
386 | cpu = safe_smp_processor_id(); | ||
387 | sum = read_pda(apic_timer_irqs); | 473 | sum = read_pda(apic_timer_irqs); |
388 | if (last_irq_sums[cpu] == sum) { | 474 | if (__get_cpu_var(nmi_touch)) { |
475 | __get_cpu_var(nmi_touch) = 0; | ||
476 | touched = 1; | ||
477 | } | ||
478 | if (!touched && __get_cpu_var(last_irq_sum) == sum) { | ||
389 | /* | 479 | /* |
390 | * Ayiee, looks like this CPU is stuck ... | 480 | * Ayiee, looks like this CPU is stuck ... |
391 | * wait a few IRQs (5 seconds) before doing the oops ... | 481 | * wait a few IRQs (5 seconds) before doing the oops ... |
392 | */ | 482 | */ |
393 | alert_counter[cpu]++; | 483 | local_inc(&__get_cpu_var(alert_counter)); |
394 | if (alert_counter[cpu] == 5*nmi_hz) { | 484 | if (local_read(&__get_cpu_var(alert_counter)) == 5*nmi_hz) { |
395 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) | 485 | if (notify_die(DIE_NMI, "nmi", regs, reason, 2, SIGINT) |
396 | == NOTIFY_STOP) { | 486 | == NOTIFY_STOP) { |
397 | alert_counter[cpu] = 0; | 487 | local_set(&__get_cpu_var(alert_counter), 0); |
398 | return; | 488 | return; |
399 | } | 489 | } |
400 | die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs); | 490 | die_nmi("NMI Watchdog detected LOCKUP on CPU%d", regs); |
401 | } | 491 | } |
402 | } else { | 492 | } else { |
403 | last_irq_sums[cpu] = sum; | 493 | __get_cpu_var(last_irq_sum) = sum; |
404 | alert_counter[cpu] = 0; | 494 | local_set(&__get_cpu_var(alert_counter), 0); |
405 | } | 495 | } |
406 | if (nmi_perfctr_msr) | 496 | if (nmi_perfctr_msr) { |
497 | if (nmi_perfctr_msr == MSR_P4_IQ_COUNTER0) { | ||
498 | /* | ||
499 | * P4 quirks: | ||
500 | * - An overflown perfctr will assert its interrupt | ||
501 | * until the OVF flag in its CCCR is cleared. | ||
502 | * - LVTPC is masked on interrupt and must be | ||
503 | * unmasked by the LVTPC handler. | ||
504 | */ | ||
505 | wrmsr(MSR_P4_IQ_CCCR0, nmi_p4_cccr_val, 0); | ||
506 | apic_write(APIC_LVTPC, APIC_DM_NMI); | ||
507 | } | ||
407 | wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); | 508 | wrmsr(nmi_perfctr_msr, -(cpu_khz/nmi_hz*1000), -1); |
509 | } | ||
408 | } | 510 | } |
409 | 511 | ||
410 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) | 512 | static int dummy_nmi_callback(struct pt_regs * regs, int cpu) |
diff --git a/arch/x86_64/kernel/pmtimer.c b/arch/x86_64/kernel/pmtimer.c new file mode 100644 index 000000000000..feb5f108dd26 --- /dev/null +++ b/arch/x86_64/kernel/pmtimer.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* Ported over from i386 by AK, original copyright was: | ||
2 | * | ||
3 | * (C) Dominik Brodowski <linux@brodo.de> 2003 | ||
4 | * | ||
5 | * Driver to use the Power Management Timer (PMTMR) available in some | ||
6 | * southbridges as primary timing source for the Linux kernel. | ||
7 | * | ||
8 | * Based on parts of linux/drivers/acpi/hardware/hwtimer.c, timer_pit.c, | ||
9 | * timer_hpet.c, and on Arjan van de Ven's implementation for 2.4. | ||
10 | * | ||
11 | * This file is licensed under the GPL v2. | ||
12 | * | ||
13 | * Dropped all the hardware bug workarounds for now. Hopefully they | ||
14 | * are not needed on 64bit chipsets. | ||
15 | */ | ||
16 | |||
17 | #include <linux/jiffies.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/time.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/cpumask.h> | ||
22 | #include <asm/io.h> | ||
23 | #include <asm/proto.h> | ||
24 | #include <asm/msr.h> | ||
25 | #include <asm/vsyscall.h> | ||
26 | |||
27 | /* The I/O port the PMTMR resides at. | ||
28 | * The location is detected during setup_arch(), | ||
29 | * in arch/i386/kernel/acpi/boot.c */ | ||
30 | u32 pmtmr_ioport; | ||
31 | |||
32 | /* value of the Power timer at last timer interrupt */ | ||
33 | static u32 offset_delay; | ||
34 | static u32 last_pmtmr_tick; | ||
35 | |||
36 | #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */ | ||
37 | |||
38 | static inline u32 cyc2us(u32 cycles) | ||
39 | { | ||
40 | /* The Power Management Timer ticks at 3.579545 ticks per microsecond. | ||
41 | * 1 / PM_TIMER_FREQUENCY == 0.27936511 =~ 286/1024 [error: 0.024%] | ||
42 | * | ||
43 | * Even with HZ = 100, delta is at maximum 35796 ticks, so it can | ||
44 | * easily be multiplied with 286 (=0x11E) without having to fear | ||
45 | * u32 overflows. | ||
46 | */ | ||
47 | cycles *= 286; | ||
48 | return (cycles >> 10); | ||
49 | } | ||
50 | |||
51 | int pmtimer_mark_offset(void) | ||
52 | { | ||
53 | static int first_run = 1; | ||
54 | unsigned long tsc; | ||
55 | u32 lost; | ||
56 | |||
57 | u32 tick = inl(pmtmr_ioport); | ||
58 | u32 delta; | ||
59 | |||
60 | delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK); | ||
61 | |||
62 | last_pmtmr_tick = tick; | ||
63 | monotonic_base += delta * NSEC_PER_USEC; | ||
64 | |||
65 | delta += offset_delay; | ||
66 | |||
67 | lost = delta / (USEC_PER_SEC / HZ); | ||
68 | offset_delay = delta % (USEC_PER_SEC / HZ); | ||
69 | |||
70 | rdtscll(tsc); | ||
71 | vxtime.last_tsc = tsc - offset_delay * cpu_khz; | ||
72 | |||
73 | /* don't calculate delay for first run, | ||
74 | or if we've got less then a tick */ | ||
75 | if (first_run || (lost < 1)) { | ||
76 | first_run = 0; | ||
77 | offset_delay = 0; | ||
78 | } | ||
79 | |||
80 | return lost - 1; | ||
81 | } | ||
82 | |||
83 | unsigned int do_gettimeoffset_pm(void) | ||
84 | { | ||
85 | u32 now, offset, delta = 0; | ||
86 | |||
87 | offset = last_pmtmr_tick; | ||
88 | now = inl(pmtmr_ioport); | ||
89 | delta = (now - offset) & ACPI_PM_MASK; | ||
90 | |||
91 | return offset_delay + cyc2us(delta); | ||
92 | } | ||
93 | |||
94 | |||
95 | static int __init nopmtimer_setup(char *s) | ||
96 | { | ||
97 | pmtmr_ioport = 0; | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | __setup("nopmtimer", nopmtimer_setup); | ||
diff --git a/arch/x86_64/kernel/ptrace.c b/arch/x86_64/kernel/ptrace.c index e26e86bb56fe..525f6a128a27 100644 --- a/arch/x86_64/kernel/ptrace.c +++ b/arch/x86_64/kernel/ptrace.c | |||
@@ -257,13 +257,13 @@ static int putreg(struct task_struct *child, | |||
257 | value &= 0xffff; | 257 | value &= 0xffff; |
258 | return 0; | 258 | return 0; |
259 | case offsetof(struct user_regs_struct,fs_base): | 259 | case offsetof(struct user_regs_struct,fs_base): |
260 | if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) | 260 | if (value >= TASK_SIZE) |
261 | return -EIO; | 261 | return -EIO; |
262 | child->thread.fs = value; | 262 | child->thread.fs = value; |
263 | return 0; | 263 | return 0; |
264 | case offsetof(struct user_regs_struct,gs_base): | 264 | case offsetof(struct user_regs_struct,gs_base): |
265 | if (!((value >> 48) == 0 || (value >> 48) == 0xffff)) | 265 | if (value >= TASK_SIZE) |
266 | return -EIO; | 266 | return -EIO; |
267 | child->thread.gs = value; | 267 | child->thread.gs = value; |
268 | return 0; | 268 | return 0; |
269 | case offsetof(struct user_regs_struct, eflags): | 269 | case offsetof(struct user_regs_struct, eflags): |
@@ -277,6 +277,11 @@ static int putreg(struct task_struct *child, | |||
277 | return -EIO; | 277 | return -EIO; |
278 | value &= 0xffff; | 278 | value &= 0xffff; |
279 | break; | 279 | break; |
280 | case offsetof(struct user_regs_struct, rip): | ||
281 | /* Check if the new RIP address is canonical */ | ||
282 | if (value >= TASK_SIZE) | ||
283 | return -EIO; | ||
284 | break; | ||
280 | } | 285 | } |
281 | put_stack_long(child, regno - sizeof(struct pt_regs), value); | 286 | put_stack_long(child, regno - sizeof(struct pt_regs), value); |
282 | return 0; | 287 | return 0; |
@@ -375,7 +380,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
375 | break; | 380 | break; |
376 | 381 | ||
377 | switch (addr) { | 382 | switch (addr) { |
378 | case 0 ... sizeof(struct user_regs_struct): | 383 | case 0 ... sizeof(struct user_regs_struct) - sizeof(long): |
379 | tmp = getreg(child, addr); | 384 | tmp = getreg(child, addr); |
380 | break; | 385 | break; |
381 | case offsetof(struct user, u_debugreg[0]): | 386 | case offsetof(struct user, u_debugreg[0]): |
@@ -420,7 +425,7 @@ asmlinkage long sys_ptrace(long request, long pid, unsigned long addr, long data | |||
420 | break; | 425 | break; |
421 | 426 | ||
422 | switch (addr) { | 427 | switch (addr) { |
423 | case 0 ... sizeof(struct user_regs_struct): | 428 | case 0 ... sizeof(struct user_regs_struct) - sizeof(long): |
424 | ret = putreg(child, addr, data); | 429 | ret = putreg(child, addr, data); |
425 | break; | 430 | break; |
426 | /* Disallows to set a breakpoint into the vsyscall */ | 431 | /* Disallows to set a breakpoint into the vsyscall */ |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 2129cf9ba6b2..99f038ede23c 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -719,7 +719,6 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) | |||
719 | } | 719 | } |
720 | } | 720 | } |
721 | 721 | ||
722 | #ifdef CONFIG_SMP | ||
723 | /* | 722 | /* |
724 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. | 723 | * On a AMD dual core setup the lower bits of the APIC id distingush the cores. |
725 | * Assumes number of cores is a power of two. | 724 | * Assumes number of cores is a power of two. |
@@ -727,17 +726,26 @@ static void __init display_cacheinfo(struct cpuinfo_x86 *c) | |||
727 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | 726 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) |
728 | { | 727 | { |
729 | #ifdef CONFIG_SMP | 728 | #ifdef CONFIG_SMP |
730 | int cpu = c->x86_apicid; | 729 | int cpu = smp_processor_id(); |
731 | int node = 0; | 730 | int node = 0; |
731 | unsigned bits; | ||
732 | if (c->x86_num_cores == 1) | 732 | if (c->x86_num_cores == 1) |
733 | return; | 733 | return; |
734 | cpu_core_id[cpu] = cpu >> hweight32(c->x86_num_cores - 1); | 734 | |
735 | bits = 0; | ||
736 | while ((1 << bits) < c->x86_num_cores) | ||
737 | bits++; | ||
738 | |||
739 | /* Low order bits define the core id (index of core in socket) */ | ||
740 | cpu_core_id[cpu] = phys_proc_id[cpu] & ((1 << bits)-1); | ||
741 | /* Convert the APIC ID into the socket ID */ | ||
742 | phys_proc_id[cpu] >>= bits; | ||
735 | 743 | ||
736 | #ifdef CONFIG_NUMA | 744 | #ifdef CONFIG_NUMA |
737 | /* When an ACPI SRAT table is available use the mappings from SRAT | 745 | /* When an ACPI SRAT table is available use the mappings from SRAT |
738 | instead. */ | 746 | instead. */ |
739 | if (acpi_numa <= 0) { | 747 | if (acpi_numa <= 0) { |
740 | node = cpu_core_id[cpu]; | 748 | node = phys_proc_id[cpu]; |
741 | if (!node_online(node)) | 749 | if (!node_online(node)) |
742 | node = first_node(node_online_map); | 750 | node = first_node(node_online_map); |
743 | cpu_to_node[cpu] = node; | 751 | cpu_to_node[cpu] = node; |
@@ -745,15 +753,11 @@ static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | |||
745 | node = cpu_to_node[cpu]; | 753 | node = cpu_to_node[cpu]; |
746 | } | 754 | } |
747 | #endif | 755 | #endif |
756 | |||
748 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", | 757 | printk(KERN_INFO "CPU %d(%d) -> Node %d -> Core %d\n", |
749 | cpu, c->x86_num_cores, node, cpu_core_id[cpu]); | 758 | cpu, c->x86_num_cores, node, cpu_core_id[cpu]); |
750 | #endif | 759 | #endif |
751 | } | 760 | } |
752 | #else | ||
753 | static void __init amd_detect_cmp(struct cpuinfo_x86 *c) | ||
754 | { | ||
755 | } | ||
756 | #endif | ||
757 | 761 | ||
758 | static int __init init_amd(struct cpuinfo_x86 *c) | 762 | static int __init init_amd(struct cpuinfo_x86 *c) |
759 | { | 763 | { |
@@ -925,7 +929,6 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
925 | c->x86_clflush_size = 64; | 929 | c->x86_clflush_size = 64; |
926 | c->x86_cache_alignment = c->x86_clflush_size; | 930 | c->x86_cache_alignment = c->x86_clflush_size; |
927 | c->x86_num_cores = 1; | 931 | c->x86_num_cores = 1; |
928 | c->x86_apicid = c == &boot_cpu_data ? 0 : c - cpu_data; | ||
929 | c->extended_cpuid_level = 0; | 932 | c->extended_cpuid_level = 0; |
930 | memset(&c->x86_capability, 0, sizeof c->x86_capability); | 933 | memset(&c->x86_capability, 0, sizeof c->x86_capability); |
931 | 934 | ||
@@ -954,11 +957,14 @@ void __init early_identify_cpu(struct cpuinfo_x86 *c) | |||
954 | } | 957 | } |
955 | if (c->x86_capability[0] & (1<<19)) | 958 | if (c->x86_capability[0] & (1<<19)) |
956 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; | 959 | c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; |
957 | c->x86_apicid = misc >> 24; | ||
958 | } else { | 960 | } else { |
959 | /* Have CPUID level 0 only - unheard of */ | 961 | /* Have CPUID level 0 only - unheard of */ |
960 | c->x86 = 4; | 962 | c->x86 = 4; |
961 | } | 963 | } |
964 | |||
965 | #ifdef CONFIG_SMP | ||
966 | phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff; | ||
967 | #endif | ||
962 | } | 968 | } |
963 | 969 | ||
964 | /* | 970 | /* |
@@ -1088,7 +1094,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
1088 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1094 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1089 | 1095 | ||
1090 | /* Other (Linux-defined) */ | 1096 | /* Other (Linux-defined) */ |
1091 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", "k8c+", | 1097 | "cxmmx", NULL, "cyrix_arr", "centaur_mcr", NULL, |
1092 | "constant_tsc", NULL, NULL, | 1098 | "constant_tsc", NULL, NULL, |
1093 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1099 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
1094 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, | 1100 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index d439ced150c6..3fdcdba0fec5 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -452,7 +452,9 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
452 | regs->rip -= 2; | 452 | regs->rip -= 2; |
453 | } | 453 | } |
454 | if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { | 454 | if (regs->rax == (unsigned long)-ERESTART_RESTARTBLOCK) { |
455 | regs->rax = __NR_restart_syscall; | 455 | regs->rax = test_thread_flag(TIF_IA32) ? |
456 | __NR_ia32_restart_syscall : | ||
457 | __NR_restart_syscall; | ||
456 | regs->rip -= 2; | 458 | regs->rip -= 2; |
457 | } | 459 | } |
458 | } | 460 | } |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 73f7e8b9543a..f1ec0f345941 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <asm/kdebug.h> | 56 | #include <asm/kdebug.h> |
57 | #include <asm/tlbflush.h> | 57 | #include <asm/tlbflush.h> |
58 | #include <asm/proto.h> | 58 | #include <asm/proto.h> |
59 | #include <asm/nmi.h> | ||
59 | 60 | ||
60 | /* Change for real CPU hotplug. Note other files need to be fixed | 61 | /* Change for real CPU hotplug. Note other files need to be fixed |
61 | first too. */ | 62 | first too. */ |
@@ -93,6 +94,7 @@ int smp_threads_ready; | |||
93 | 94 | ||
94 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; | 95 | cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; |
95 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; | 96 | cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; |
97 | EXPORT_SYMBOL(cpu_core_map); | ||
96 | 98 | ||
97 | /* | 99 | /* |
98 | * Trampoline 80x86 program as an array. | 100 | * Trampoline 80x86 program as an array. |
@@ -125,96 +127,210 @@ static void __cpuinit smp_store_cpu_info(int id) | |||
125 | 127 | ||
126 | *c = boot_cpu_data; | 128 | *c = boot_cpu_data; |
127 | identify_cpu(c); | 129 | identify_cpu(c); |
130 | print_cpu_info(c); | ||
128 | } | 131 | } |
129 | 132 | ||
130 | /* | 133 | /* |
131 | * Synchronize TSCs of CPUs | 134 | * New Funky TSC sync algorithm borrowed from IA64. |
135 | * Main advantage is that it doesn't reset the TSCs fully and | ||
136 | * in general looks more robust and it works better than my earlier | ||
137 | * attempts. I believe it was written by David Mosberger. Some minor | ||
138 | * adjustments for x86-64 by me -AK | ||
132 | * | 139 | * |
133 | * This new algorithm is less accurate than the old "zero TSCs" | 140 | * Original comment reproduced below. |
134 | * one, but we cannot zero TSCs anymore in the new hotplug CPU | 141 | * |
135 | * model. | 142 | * Synchronize TSC of the current (slave) CPU with the TSC of the |
143 | * MASTER CPU (normally the time-keeper CPU). We use a closed loop to | ||
144 | * eliminate the possibility of unaccounted-for errors (such as | ||
145 | * getting a machine check in the middle of a calibration step). The | ||
146 | * basic idea is for the slave to ask the master what itc value it has | ||
147 | * and to read its own itc before and after the master responds. Each | ||
148 | * iteration gives us three timestamps: | ||
149 | * | ||
150 | * slave master | ||
151 | * | ||
152 | * t0 ---\ | ||
153 | * ---\ | ||
154 | * ---> | ||
155 | * tm | ||
156 | * /--- | ||
157 | * /--- | ||
158 | * t1 <--- | ||
159 | * | ||
160 | * | ||
161 | * The goal is to adjust the slave's TSC such that tm falls exactly | ||
162 | * half-way between t0 and t1. If we achieve this, the clocks are | ||
163 | * synchronized provided the interconnect between the slave and the | ||
164 | * master is symmetric. Even if the interconnect were asymmetric, we | ||
165 | * would still know that the synchronization error is smaller than the | ||
166 | * roundtrip latency (t0 - t1). | ||
167 | * | ||
168 | * When the interconnect is quiet and symmetric, this lets us | ||
169 | * synchronize the TSC to within one or two cycles. However, we can | ||
170 | * only *guarantee* that the synchronization is accurate to within a | ||
171 | * round-trip time, which is typically in the range of several hundred | ||
172 | * cycles (e.g., ~500 cycles). In practice, this means that the TSCs | ||
173 | * are usually almost perfectly synchronized, but we shouldn't assume | ||
174 | * that the accuracy is much better than half a micro second or so. | ||
175 | * | ||
176 | * [there are other errors like the latency of RDTSC and of the | ||
177 | * WRMSR. These can also account to hundreds of cycles. So it's | ||
178 | * probably worse. It claims 153 cycles error on a dual Opteron, | ||
179 | * but I suspect the numbers are actually somewhat worse -AK] | ||
136 | */ | 180 | */ |
137 | 181 | ||
138 | static atomic_t __cpuinitdata tsc_flag; | 182 | #define MASTER 0 |
183 | #define SLAVE (SMP_CACHE_BYTES/8) | ||
184 | |||
185 | /* Intentionally don't use cpu_relax() while TSC synchronization | ||
186 | because we don't want to go into funky power save modi or cause | ||
187 | hypervisors to schedule us away. Going to sleep would likely affect | ||
188 | latency and low latency is the primary objective here. -AK */ | ||
189 | #define no_cpu_relax() barrier() | ||
190 | |||
139 | static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); | 191 | static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); |
140 | static unsigned long long __cpuinitdata bp_tsc, ap_tsc; | 192 | static volatile __cpuinitdata unsigned long go[SLAVE + 1]; |
193 | static int notscsync __cpuinitdata; | ||
194 | |||
195 | #undef DEBUG_TSC_SYNC | ||
141 | 196 | ||
142 | #define NR_LOOPS 5 | 197 | #define NUM_ROUNDS 64 /* magic value */ |
198 | #define NUM_ITERS 5 /* likewise */ | ||
143 | 199 | ||
144 | static void __cpuinit sync_tsc_bp_init(int init) | 200 | /* Callback on boot CPU */ |
201 | static __cpuinit void sync_master(void *arg) | ||
145 | { | 202 | { |
146 | if (init) | 203 | unsigned long flags, i; |
147 | _raw_spin_lock(&tsc_sync_lock); | 204 | |
148 | else | 205 | if (smp_processor_id() != boot_cpu_id) |
149 | _raw_spin_unlock(&tsc_sync_lock); | 206 | return; |
150 | atomic_set(&tsc_flag, 0); | 207 | |
208 | go[MASTER] = 0; | ||
209 | |||
210 | local_irq_save(flags); | ||
211 | { | ||
212 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) { | ||
213 | while (!go[MASTER]) | ||
214 | no_cpu_relax(); | ||
215 | go[MASTER] = 0; | ||
216 | rdtscll(go[SLAVE]); | ||
217 | } | ||
218 | } | ||
219 | local_irq_restore(flags); | ||
151 | } | 220 | } |
152 | 221 | ||
153 | /* | 222 | /* |
154 | * Synchronize TSC on AP with BP. | 223 | * Return the number of cycles by which our tsc differs from the tsc |
224 | * on the master (time-keeper) CPU. A positive number indicates our | ||
225 | * tsc is ahead of the master, negative that it is behind. | ||
155 | */ | 226 | */ |
156 | static void __cpuinit __sync_tsc_ap(void) | 227 | static inline long |
228 | get_delta(long *rt, long *master) | ||
157 | { | 229 | { |
158 | if (!cpu_has_tsc) | 230 | unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0; |
159 | return; | 231 | unsigned long tcenter, t0, t1, tm; |
160 | Dprintk("AP %d syncing TSC\n", smp_processor_id()); | 232 | int i; |
161 | 233 | ||
162 | while (atomic_read(&tsc_flag) != 0) | 234 | for (i = 0; i < NUM_ITERS; ++i) { |
163 | cpu_relax(); | 235 | rdtscll(t0); |
164 | atomic_inc(&tsc_flag); | 236 | go[MASTER] = 1; |
165 | mb(); | 237 | while (!(tm = go[SLAVE])) |
166 | _raw_spin_lock(&tsc_sync_lock); | 238 | no_cpu_relax(); |
167 | wrmsrl(MSR_IA32_TSC, bp_tsc); | 239 | go[SLAVE] = 0; |
168 | _raw_spin_unlock(&tsc_sync_lock); | 240 | rdtscll(t1); |
169 | rdtscll(ap_tsc); | 241 | |
170 | mb(); | 242 | if (t1 - t0 < best_t1 - best_t0) |
171 | atomic_inc(&tsc_flag); | 243 | best_t0 = t0, best_t1 = t1, best_tm = tm; |
172 | mb(); | 244 | } |
245 | |||
246 | *rt = best_t1 - best_t0; | ||
247 | *master = best_tm - best_t0; | ||
248 | |||
249 | /* average best_t0 and best_t1 without overflow: */ | ||
250 | tcenter = (best_t0/2 + best_t1/2); | ||
251 | if (best_t0 % 2 + best_t1 % 2 == 2) | ||
252 | ++tcenter; | ||
253 | return tcenter - best_tm; | ||
173 | } | 254 | } |
174 | 255 | ||
175 | static void __cpuinit sync_tsc_ap(void) | 256 | static __cpuinit void sync_tsc(void) |
176 | { | 257 | { |
177 | int i; | 258 | int i, done = 0; |
178 | for (i = 0; i < NR_LOOPS; i++) | 259 | long delta, adj, adjust_latency = 0; |
179 | __sync_tsc_ap(); | 260 | unsigned long flags, rt, master_time_stamp, bound; |
261 | #if DEBUG_TSC_SYNC | ||
262 | static struct syncdebug { | ||
263 | long rt; /* roundtrip time */ | ||
264 | long master; /* master's timestamp */ | ||
265 | long diff; /* difference between midpoint and master's timestamp */ | ||
266 | long lat; /* estimate of tsc adjustment latency */ | ||
267 | } t[NUM_ROUNDS] __cpuinitdata; | ||
268 | #endif | ||
269 | |||
270 | go[MASTER] = 1; | ||
271 | |||
272 | smp_call_function(sync_master, NULL, 1, 0); | ||
273 | |||
274 | while (go[MASTER]) /* wait for master to be ready */ | ||
275 | no_cpu_relax(); | ||
276 | |||
277 | spin_lock_irqsave(&tsc_sync_lock, flags); | ||
278 | { | ||
279 | for (i = 0; i < NUM_ROUNDS; ++i) { | ||
280 | delta = get_delta(&rt, &master_time_stamp); | ||
281 | if (delta == 0) { | ||
282 | done = 1; /* let's lock on to this... */ | ||
283 | bound = rt; | ||
284 | } | ||
285 | |||
286 | if (!done) { | ||
287 | unsigned long t; | ||
288 | if (i > 0) { | ||
289 | adjust_latency += -delta; | ||
290 | adj = -delta + adjust_latency/4; | ||
291 | } else | ||
292 | adj = -delta; | ||
293 | |||
294 | rdtscll(t); | ||
295 | wrmsrl(MSR_IA32_TSC, t + adj); | ||
296 | } | ||
297 | #if DEBUG_TSC_SYNC | ||
298 | t[i].rt = rt; | ||
299 | t[i].master = master_time_stamp; | ||
300 | t[i].diff = delta; | ||
301 | t[i].lat = adjust_latency/4; | ||
302 | #endif | ||
303 | } | ||
304 | } | ||
305 | spin_unlock_irqrestore(&tsc_sync_lock, flags); | ||
306 | |||
307 | #if DEBUG_TSC_SYNC | ||
308 | for (i = 0; i < NUM_ROUNDS; ++i) | ||
309 | printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n", | ||
310 | t[i].rt, t[i].master, t[i].diff, t[i].lat); | ||
311 | #endif | ||
312 | |||
313 | printk(KERN_INFO | ||
314 | "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " | ||
315 | "maxerr %lu cycles)\n", | ||
316 | smp_processor_id(), boot_cpu_id, delta, rt); | ||
180 | } | 317 | } |
181 | 318 | ||
182 | /* | 319 | static void __cpuinit tsc_sync_wait(void) |
183 | * Synchronize TSC from BP to AP. | ||
184 | */ | ||
185 | static void __cpuinit __sync_tsc_bp(int cpu) | ||
186 | { | 320 | { |
187 | if (!cpu_has_tsc) | 321 | if (notscsync || !cpu_has_tsc) |
188 | return; | 322 | return; |
189 | 323 | printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), | |
190 | /* Wait for AP */ | 324 | boot_cpu_id); |
191 | while (atomic_read(&tsc_flag) == 0) | 325 | sync_tsc(); |
192 | cpu_relax(); | ||
193 | /* Save BPs TSC */ | ||
194 | sync_core(); | ||
195 | rdtscll(bp_tsc); | ||
196 | /* Don't do the sync core here to avoid too much latency. */ | ||
197 | mb(); | ||
198 | /* Start the AP */ | ||
199 | _raw_spin_unlock(&tsc_sync_lock); | ||
200 | /* Wait for AP again */ | ||
201 | while (atomic_read(&tsc_flag) < 2) | ||
202 | cpu_relax(); | ||
203 | rdtscl(bp_tsc); | ||
204 | barrier(); | ||
205 | } | 326 | } |
206 | 327 | ||
207 | static void __cpuinit sync_tsc_bp(int cpu) | 328 | static __init int notscsync_setup(char *s) |
208 | { | 329 | { |
209 | int i; | 330 | notscsync = 1; |
210 | for (i = 0; i < NR_LOOPS - 1; i++) { | 331 | return 0; |
211 | __sync_tsc_bp(cpu); | ||
212 | sync_tsc_bp_init(1); | ||
213 | } | ||
214 | __sync_tsc_bp(cpu); | ||
215 | printk(KERN_INFO "Synced TSC of CPU %d difference %Ld\n", | ||
216 | cpu, ap_tsc - bp_tsc); | ||
217 | } | 332 | } |
333 | __setup("notscsync", notscsync_setup); | ||
218 | 334 | ||
219 | static atomic_t init_deasserted __cpuinitdata; | 335 | static atomic_t init_deasserted __cpuinitdata; |
220 | 336 | ||
@@ -315,11 +431,6 @@ void __cpuinit start_secondary(void) | |||
315 | cpu_init(); | 431 | cpu_init(); |
316 | smp_callin(); | 432 | smp_callin(); |
317 | 433 | ||
318 | /* | ||
319 | * Synchronize the TSC with the BP | ||
320 | */ | ||
321 | sync_tsc_ap(); | ||
322 | |||
323 | /* otherwise gcc will move up the smp_processor_id before the cpu_init */ | 434 | /* otherwise gcc will move up the smp_processor_id before the cpu_init */ |
324 | barrier(); | 435 | barrier(); |
325 | 436 | ||
@@ -334,7 +445,6 @@ void __cpuinit start_secondary(void) | |||
334 | enable_8259A_irq(0); | 445 | enable_8259A_irq(0); |
335 | } | 446 | } |
336 | 447 | ||
337 | |||
338 | enable_APIC_timer(); | 448 | enable_APIC_timer(); |
339 | 449 | ||
340 | /* | 450 | /* |
@@ -343,6 +453,11 @@ void __cpuinit start_secondary(void) | |||
343 | cpu_set(smp_processor_id(), cpu_online_map); | 453 | cpu_set(smp_processor_id(), cpu_online_map); |
344 | mb(); | 454 | mb(); |
345 | 455 | ||
456 | /* Wait for TSC sync to not schedule things before. | ||
457 | We still process interrupts, which could see an inconsistent | ||
458 | time in that window unfortunately. */ | ||
459 | tsc_sync_wait(); | ||
460 | |||
346 | cpu_idle(); | 461 | cpu_idle(); |
347 | } | 462 | } |
348 | 463 | ||
@@ -531,7 +646,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) | |||
531 | printk("failed fork for CPU %d\n", cpu); | 646 | printk("failed fork for CPU %d\n", cpu); |
532 | return PTR_ERR(idle); | 647 | return PTR_ERR(idle); |
533 | } | 648 | } |
534 | x86_cpu_to_apicid[cpu] = apicid; | ||
535 | 649 | ||
536 | cpu_pda[cpu].pcurrent = idle; | 650 | cpu_pda[cpu].pcurrent = idle; |
537 | 651 | ||
@@ -600,8 +714,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) | |||
600 | 714 | ||
601 | if (cpu_isset(cpu, cpu_callin_map)) { | 715 | if (cpu_isset(cpu, cpu_callin_map)) { |
602 | /* number CPUs logically, starting from 1 (BSP is 0) */ | 716 | /* number CPUs logically, starting from 1 (BSP is 0) */ |
603 | Dprintk("OK.\n"); | ||
604 | print_cpu_info(&cpu_data[cpu]); | ||
605 | Dprintk("CPU has booted.\n"); | 717 | Dprintk("CPU has booted.\n"); |
606 | } else { | 718 | } else { |
607 | boot_error = 1; | 719 | boot_error = 1; |
@@ -842,7 +954,6 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) | |||
842 | GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); | 954 | GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); |
843 | /* Or can we switch back to PIC here? */ | 955 | /* Or can we switch back to PIC here? */ |
844 | } | 956 | } |
845 | x86_cpu_to_apicid[0] = boot_cpu_id; | ||
846 | 957 | ||
847 | /* | 958 | /* |
848 | * Now start the IO-APICs | 959 | * Now start the IO-APICs |
@@ -889,18 +1000,14 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
889 | printk("__cpu_up: bad cpu %d\n", cpu); | 1000 | printk("__cpu_up: bad cpu %d\n", cpu); |
890 | return -EINVAL; | 1001 | return -EINVAL; |
891 | } | 1002 | } |
892 | sync_tsc_bp_init(1); | ||
893 | 1003 | ||
894 | /* Boot it! */ | 1004 | /* Boot it! */ |
895 | err = do_boot_cpu(cpu, apicid); | 1005 | err = do_boot_cpu(cpu, apicid); |
896 | if (err < 0) { | 1006 | if (err < 0) { |
897 | sync_tsc_bp_init(0); | ||
898 | Dprintk("do_boot_cpu failed %d\n", err); | 1007 | Dprintk("do_boot_cpu failed %d\n", err); |
899 | return err; | 1008 | return err; |
900 | } | 1009 | } |
901 | 1010 | ||
902 | sync_tsc_bp(cpu); | ||
903 | |||
904 | /* Unleash the CPU! */ | 1011 | /* Unleash the CPU! */ |
905 | Dprintk("waiting for cpu %d\n", cpu); | 1012 | Dprintk("waiting for cpu %d\n", cpu); |
906 | 1013 | ||
@@ -923,4 +1030,6 @@ void __cpuinit smp_cpus_done(unsigned int max_cpus) | |||
923 | 1030 | ||
924 | detect_siblings(); | 1031 | detect_siblings(); |
925 | time_init_gtod(); | 1032 | time_init_gtod(); |
1033 | |||
1034 | check_nmi_watchdog(); | ||
926 | } | 1035 | } |
diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 0e3b60e1ac5b..735b6767c8ed 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c | |||
@@ -26,6 +26,8 @@ | |||
26 | #include <linux/sysdev.h> | 26 | #include <linux/sysdev.h> |
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/kallsyms.h> | 28 | #include <linux/kallsyms.h> |
29 | #include <linux/acpi.h> | ||
30 | #include <acpi/achware.h> /* for PM timer frequency */ | ||
29 | #include <asm/8253pit.h> | 31 | #include <asm/8253pit.h> |
30 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
31 | #include <asm/vsyscall.h> | 33 | #include <asm/vsyscall.h> |
@@ -396,6 +398,10 @@ static irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
396 | (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; | 398 | (offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick; |
397 | 399 | ||
398 | vxtime.last = offset; | 400 | vxtime.last = offset; |
401 | #ifdef CONFIG_X86_PM_TIMER | ||
402 | } else if (vxtime.mode == VXTIME_PMTMR) { | ||
403 | lost = pmtimer_mark_offset(); | ||
404 | #endif | ||
399 | } else { | 405 | } else { |
400 | offset = (((tsc - vxtime.last_tsc) * | 406 | offset = (((tsc - vxtime.last_tsc) * |
401 | vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); | 407 | vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ); |
@@ -898,6 +904,13 @@ void __init time_init(void) | |||
898 | hpet_period; | 904 | hpet_period; |
899 | cpu_khz = hpet_calibrate_tsc(); | 905 | cpu_khz = hpet_calibrate_tsc(); |
900 | timename = "HPET"; | 906 | timename = "HPET"; |
907 | #ifdef CONFIG_X86_PM_TIMER | ||
908 | } else if (pmtmr_ioport) { | ||
909 | vxtime_hz = PM_TIMER_FREQUENCY; | ||
910 | timename = "PM"; | ||
911 | pit_init(); | ||
912 | cpu_khz = pit_calibrate_tsc(); | ||
913 | #endif | ||
901 | } else { | 914 | } else { |
902 | pit_init(); | 915 | pit_init(); |
903 | cpu_khz = pit_calibrate_tsc(); | 916 | cpu_khz = pit_calibrate_tsc(); |
@@ -923,35 +936,50 @@ void __init time_init(void) | |||
923 | } | 936 | } |
924 | 937 | ||
925 | /* | 938 | /* |
939 | * Make an educated guess if the TSC is trustworthy and synchronized | ||
940 | * over all CPUs. | ||
941 | */ | ||
942 | static __init int unsynchronized_tsc(void) | ||
943 | { | ||
944 | #ifdef CONFIG_SMP | ||
945 | if (oem_force_hpet_timer()) | ||
946 | return 1; | ||
947 | /* Intel systems are normally all synchronized. Exceptions | ||
948 | are handled in the OEM check above. */ | ||
949 | if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) | ||
950 | return 0; | ||
951 | /* All in a single socket - should be synchronized */ | ||
952 | if (cpus_weight(cpu_core_map[0]) == num_online_cpus()) | ||
953 | return 0; | ||
954 | #endif | ||
955 | /* Assume multi socket systems are not synchronized */ | ||
956 | return num_online_cpus() > 1; | ||
957 | } | ||
958 | |||
959 | /* | ||
926 | * Decide after all CPUs are booted what mode gettimeofday should use. | 960 | * Decide after all CPUs are booted what mode gettimeofday should use. |
927 | */ | 961 | */ |
928 | void __init time_init_gtod(void) | 962 | void __init time_init_gtod(void) |
929 | { | 963 | { |
930 | char *timetype; | 964 | char *timetype; |
931 | 965 | ||
932 | /* | 966 | if (unsynchronized_tsc()) |
933 | * AMD systems with more than one CPU don't have fully synchronized | ||
934 | * TSCs. Always use HPET gettimeofday for these, although it is slower. | ||
935 | * Intel SMP systems usually have synchronized TSCs, so use always | ||
936 | * the TSC. | ||
937 | * | ||
938 | * Exceptions: | ||
939 | * IBM Summit2 checked by oem_force_hpet_timer(). | ||
940 | * AMD dual core may also not need HPET. Check me. | ||
941 | * | ||
942 | * Can be turned off with "notsc". | ||
943 | */ | ||
944 | if (num_online_cpus() > 1 && | ||
945 | boot_cpu_data.x86_vendor == X86_VENDOR_AMD) | ||
946 | notsc = 1; | ||
947 | /* Some systems will want to disable TSC and use HPET. */ | ||
948 | if (oem_force_hpet_timer()) | ||
949 | notsc = 1; | 967 | notsc = 1; |
950 | if (vxtime.hpet_address && notsc) { | 968 | if (vxtime.hpet_address && notsc) { |
951 | timetype = "HPET"; | 969 | timetype = "HPET"; |
952 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; | 970 | vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick; |
953 | vxtime.mode = VXTIME_HPET; | 971 | vxtime.mode = VXTIME_HPET; |
954 | do_gettimeoffset = do_gettimeoffset_hpet; | 972 | do_gettimeoffset = do_gettimeoffset_hpet; |
973 | #ifdef CONFIG_X86_PM_TIMER | ||
974 | /* Using PM for gettimeofday is quite slow, but we have no other | ||
975 | choice because the TSC is too unreliable on some systems. */ | ||
976 | } else if (pmtmr_ioport && !vxtime.hpet_address && notsc) { | ||
977 | timetype = "PM"; | ||
978 | do_gettimeoffset = do_gettimeoffset_pm; | ||
979 | vxtime.mode = VXTIME_PMTMR; | ||
980 | sysctl_vsyscall = 0; | ||
981 | printk(KERN_INFO "Disabling vsyscall due to use of PM timer\n"); | ||
982 | #endif | ||
955 | } else { | 983 | } else { |
956 | timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; | 984 | timetype = vxtime.hpet_address ? "HPET/TSC" : "PIT/TSC"; |
957 | vxtime.mode = VXTIME_TSC; | 985 | vxtime.mode = VXTIME_TSC; |
diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index b4b8dc59663a..2e5734425949 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c | |||
@@ -65,7 +65,7 @@ static force_inline void do_vgettimeofday(struct timeval * tv) | |||
65 | usec = (__xtime.tv_nsec / 1000) + | 65 | usec = (__xtime.tv_nsec / 1000) + |
66 | (__jiffies - __wall_jiffies) * (1000000 / HZ); | 66 | (__jiffies - __wall_jiffies) * (1000000 / HZ); |
67 | 67 | ||
68 | if (__vxtime.mode == VXTIME_TSC) { | 68 | if (__vxtime.mode != VXTIME_HPET) { |
69 | sync_core(); | 69 | sync_core(); |
70 | rdtscll(t); | 70 | rdtscll(t); |
71 | if (t < __vxtime.last_tsc) | 71 | if (t < __vxtime.last_tsc) |
@@ -217,8 +217,9 @@ static int __init vsyscall_init(void) | |||
217 | BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); | 217 | BUG_ON((unsigned long) &vtime != VSYSCALL_ADDR(__NR_vtime)); |
218 | BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); | 218 | BUG_ON((VSYSCALL_ADDR(0) != __fix_to_virt(VSYSCALL_FIRST_PAGE))); |
219 | map_vsyscall(); | 219 | map_vsyscall(); |
220 | sysctl_vsyscall = 1; | 220 | #ifdef CONFIG_SYSCTL |
221 | register_sysctl_table(kernel_root_table2, 0); | 221 | register_sysctl_table(kernel_root_table2, 0); |
222 | #endif | ||
222 | return 0; | 223 | return 0; |
223 | } | 224 | } |
224 | 225 | ||
diff --git a/arch/x86_64/kernel/x8664_ksyms.c b/arch/x86_64/kernel/x8664_ksyms.c index 88626e626886..a43dedb58fa2 100644 --- a/arch/x86_64/kernel/x8664_ksyms.c +++ b/arch/x86_64/kernel/x8664_ksyms.c | |||
@@ -139,35 +139,23 @@ EXPORT_SYMBOL_GPL(unset_nmi_callback); | |||
139 | #undef memmove | 139 | #undef memmove |
140 | #undef memchr | 140 | #undef memchr |
141 | #undef strlen | 141 | #undef strlen |
142 | #undef strcpy | ||
143 | #undef strncmp | 142 | #undef strncmp |
144 | #undef strncpy | 143 | #undef strncpy |
145 | #undef strchr | 144 | #undef strchr |
146 | #undef strcmp | ||
147 | #undef strcpy | ||
148 | #undef strcat | ||
149 | #undef memcmp | ||
150 | 145 | ||
151 | extern void * memset(void *,int,__kernel_size_t); | 146 | extern void * memset(void *,int,__kernel_size_t); |
152 | extern size_t strlen(const char *); | 147 | extern size_t strlen(const char *); |
153 | extern void * memmove(void * dest,const void *src,size_t count); | 148 | extern void * memmove(void * dest,const void *src,size_t count); |
154 | extern char * strcpy(char * dest,const char *src); | ||
155 | extern int strcmp(const char * cs,const char * ct); | ||
156 | extern void *memchr(const void *s, int c, size_t n); | 149 | extern void *memchr(const void *s, int c, size_t n); |
157 | extern void * memcpy(void *,const void *,__kernel_size_t); | 150 | extern void * memcpy(void *,const void *,__kernel_size_t); |
158 | extern void * __memcpy(void *,const void *,__kernel_size_t); | 151 | extern void * __memcpy(void *,const void *,__kernel_size_t); |
159 | extern char * strcat(char *, const char *); | ||
160 | extern int memcmp(const void * cs,const void * ct,size_t count); | ||
161 | 152 | ||
162 | EXPORT_SYMBOL(memset); | 153 | EXPORT_SYMBOL(memset); |
163 | EXPORT_SYMBOL(strlen); | 154 | EXPORT_SYMBOL(strlen); |
164 | EXPORT_SYMBOL(memmove); | 155 | EXPORT_SYMBOL(memmove); |
165 | EXPORT_SYMBOL(strcpy); | ||
166 | EXPORT_SYMBOL(strncmp); | 156 | EXPORT_SYMBOL(strncmp); |
167 | EXPORT_SYMBOL(strncpy); | 157 | EXPORT_SYMBOL(strncpy); |
168 | EXPORT_SYMBOL(strchr); | 158 | EXPORT_SYMBOL(strchr); |
169 | EXPORT_SYMBOL(strcmp); | ||
170 | EXPORT_SYMBOL(strcat); | ||
171 | EXPORT_SYMBOL(strncat); | 159 | EXPORT_SYMBOL(strncat); |
172 | EXPORT_SYMBOL(memchr); | 160 | EXPORT_SYMBOL(memchr); |
173 | EXPORT_SYMBOL(strrchr); | 161 | EXPORT_SYMBOL(strrchr); |
@@ -175,7 +163,6 @@ EXPORT_SYMBOL(strnlen); | |||
175 | EXPORT_SYMBOL(memscan); | 163 | EXPORT_SYMBOL(memscan); |
176 | EXPORT_SYMBOL(memcpy); | 164 | EXPORT_SYMBOL(memcpy); |
177 | EXPORT_SYMBOL(__memcpy); | 165 | EXPORT_SYMBOL(__memcpy); |
178 | EXPORT_SYMBOL(memcmp); | ||
179 | 166 | ||
180 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM | 167 | #ifdef CONFIG_RWSEM_XCHGADD_ALGORITHM |
181 | /* prototypes are wrong, these are assembly with custom calling functions */ | 168 | /* prototypes are wrong, these are assembly with custom calling functions */ |
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index e03309216764..5d6b2114cc9a 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -234,6 +234,8 @@ static noinline void pgtable_bad(unsigned long address, struct pt_regs *regs, | |||
234 | 234 | ||
235 | /* | 235 | /* |
236 | * Handle a fault on the vmalloc or module mapping area | 236 | * Handle a fault on the vmalloc or module mapping area |
237 | * | ||
238 | * This assumes no large pages in there. | ||
237 | */ | 239 | */ |
238 | static int vmalloc_fault(unsigned long address) | 240 | static int vmalloc_fault(unsigned long address) |
239 | { | 241 | { |
@@ -272,7 +274,10 @@ static int vmalloc_fault(unsigned long address) | |||
272 | if (!pte_present(*pte_ref)) | 274 | if (!pte_present(*pte_ref)) |
273 | return -1; | 275 | return -1; |
274 | pte = pte_offset_kernel(pmd, address); | 276 | pte = pte_offset_kernel(pmd, address); |
275 | if (!pte_present(*pte) || pte_page(*pte) != pte_page(*pte_ref)) | 277 | /* Don't use pte_page here, because the mappings can point |
278 | outside mem_map, and the NUMA hash lookup cannot handle | ||
279 | that. */ | ||
280 | if (!pte_present(*pte) || pte_pfn(*pte) != pte_pfn(*pte_ref)) | ||
276 | BUG(); | 281 | BUG(); |
277 | __flush_tlb_all(); | 282 | __flush_tlb_all(); |
278 | return 0; | 283 | return 0; |
@@ -346,7 +351,9 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long error_code) | |||
346 | * protection error (error_code & 1) == 0. | 351 | * protection error (error_code & 1) == 0. |
347 | */ | 352 | */ |
348 | if (unlikely(address >= TASK_SIZE)) { | 353 | if (unlikely(address >= TASK_SIZE)) { |
349 | if (!(error_code & 5)) { | 354 | if (!(error_code & 5) && |
355 | ((address >= VMALLOC_START && address < VMALLOC_END) || | ||
356 | (address >= MODULES_VADDR && address < MODULES_END))) { | ||
350 | if (vmalloc_fault(address) < 0) | 357 | if (vmalloc_fault(address) < 0) |
351 | goto bad_area_nosemaphore; | 358 | goto bad_area_nosemaphore; |
352 | return; | 359 | return; |
diff --git a/arch/x86_64/mm/ioremap.c b/arch/x86_64/mm/ioremap.c index 74ec8554b195..58aac23760ef 100644 --- a/arch/x86_64/mm/ioremap.c +++ b/arch/x86_64/mm/ioremap.c | |||
@@ -133,7 +133,7 @@ ioremap_change_attr(unsigned long phys_addr, unsigned long size, | |||
133 | unsigned long flags) | 133 | unsigned long flags) |
134 | { | 134 | { |
135 | int err = 0; | 135 | int err = 0; |
136 | if (flags && phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) { | 136 | if (phys_addr + size - 1 < (end_pfn_map << PAGE_SHIFT)) { |
137 | unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; | 137 | unsigned long npages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT; |
138 | unsigned long vaddr = (unsigned long) __va(phys_addr); | 138 | unsigned long vaddr = (unsigned long) __va(phys_addr); |
139 | 139 | ||
@@ -214,7 +214,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l | |||
214 | remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); | 214 | remove_vm_area((void *)(PAGE_MASK & (unsigned long) addr)); |
215 | return NULL; | 215 | return NULL; |
216 | } | 216 | } |
217 | if (ioremap_change_attr(phys_addr, size, flags) < 0) { | 217 | if (flags && ioremap_change_attr(phys_addr, size, flags) < 0) { |
218 | area->flags &= 0xffffff; | 218 | area->flags &= 0xffffff; |
219 | vunmap(addr); | 219 | vunmap(addr); |
220 | return NULL; | 220 | return NULL; |
@@ -251,7 +251,7 @@ void __iomem *ioremap_nocache (unsigned long phys_addr, unsigned long size) | |||
251 | 251 | ||
252 | void iounmap(volatile void __iomem *addr) | 252 | void iounmap(volatile void __iomem *addr) |
253 | { | 253 | { |
254 | struct vm_struct *p, **pprev; | 254 | struct vm_struct *p; |
255 | 255 | ||
256 | if (addr <= high_memory) | 256 | if (addr <= high_memory) |
257 | return; | 257 | return; |
@@ -260,24 +260,11 @@ void iounmap(volatile void __iomem *addr) | |||
260 | return; | 260 | return; |
261 | 261 | ||
262 | write_lock(&vmlist_lock); | 262 | write_lock(&vmlist_lock); |
263 | for (p = vmlist, pprev = &vmlist; p != NULL; pprev = &p->next, p = *pprev) | 263 | p = __remove_vm_area((void *)((unsigned long)addr & PAGE_MASK)); |
264 | if (p->addr == (void *)(PAGE_MASK & (unsigned long)addr)) | 264 | if (!p) |
265 | break; | 265 | printk("iounmap: bad address %p\n", addr); |
266 | if (!p) { | 266 | else if (p->flags >> 20) |
267 | printk("__iounmap: bad address %p\n", addr); | 267 | ioremap_change_attr(p->phys_addr, p->size, 0); |
268 | goto out_unlock; | ||
269 | } | ||
270 | *pprev = p->next; | ||
271 | unmap_vm_area(p); | ||
272 | if ((p->flags >> 20) && | ||
273 | p->phys_addr + p->size - 1 < virt_to_phys(high_memory)) { | ||
274 | /* p->size includes the guard page, but cpa doesn't like that */ | ||
275 | change_page_attr(virt_to_page(__va(p->phys_addr)), | ||
276 | p->size >> PAGE_SHIFT, | ||
277 | PAGE_KERNEL); | ||
278 | global_flush_tlb(); | ||
279 | } | ||
280 | out_unlock: | ||
281 | write_unlock(&vmlist_lock); | 268 | write_unlock(&vmlist_lock); |
282 | kfree(p); | 269 | kfree(p); |
283 | } | 270 | } |
diff --git a/crypto/crypto_null.c b/crypto/crypto_null.c index f691d31fa9ee..3fcf6e887e87 100644 --- a/crypto/crypto_null.c +++ b/crypto/crypto_null.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
22 | #include <asm/scatterlist.h> | 22 | #include <asm/scatterlist.h> |
23 | #include <linux/crypto.h> | 23 | #include <linux/crypto.h> |
24 | #include <linux/string.h> | ||
24 | 25 | ||
25 | #define NULL_KEY_SIZE 0 | 26 | #define NULL_KEY_SIZE 0 |
26 | #define NULL_BLOCK_SIZE 1 | 27 | #define NULL_BLOCK_SIZE 1 |
@@ -28,11 +29,13 @@ | |||
28 | 29 | ||
29 | static int null_compress(void *ctx, const u8 *src, unsigned int slen, | 30 | static int null_compress(void *ctx, const u8 *src, unsigned int slen, |
30 | u8 *dst, unsigned int *dlen) | 31 | u8 *dst, unsigned int *dlen) |
31 | { return 0; } | 32 | { |
32 | 33 | if (slen > *dlen) | |
33 | static int null_decompress(void *ctx, const u8 *src, unsigned int slen, | 34 | return -EINVAL; |
34 | u8 *dst, unsigned int *dlen) | 35 | memcpy(dst, src, slen); |
35 | { return 0; } | 36 | *dlen = slen; |
37 | return 0; | ||
38 | } | ||
36 | 39 | ||
37 | static void null_init(void *ctx) | 40 | static void null_init(void *ctx) |
38 | { } | 41 | { } |
@@ -47,11 +50,10 @@ static int null_setkey(void *ctx, const u8 *key, | |||
47 | unsigned int keylen, u32 *flags) | 50 | unsigned int keylen, u32 *flags) |
48 | { return 0; } | 51 | { return 0; } |
49 | 52 | ||
50 | static void null_encrypt(void *ctx, u8 *dst, const u8 *src) | 53 | static void null_crypt(void *ctx, u8 *dst, const u8 *src) |
51 | { } | 54 | { |
52 | 55 | memcpy(dst, src, NULL_BLOCK_SIZE); | |
53 | static void null_decrypt(void *ctx, u8 *dst, const u8 *src) | 56 | } |
54 | { } | ||
55 | 57 | ||
56 | static struct crypto_alg compress_null = { | 58 | static struct crypto_alg compress_null = { |
57 | .cra_name = "compress_null", | 59 | .cra_name = "compress_null", |
@@ -62,7 +64,7 @@ static struct crypto_alg compress_null = { | |||
62 | .cra_list = LIST_HEAD_INIT(compress_null.cra_list), | 64 | .cra_list = LIST_HEAD_INIT(compress_null.cra_list), |
63 | .cra_u = { .compress = { | 65 | .cra_u = { .compress = { |
64 | .coa_compress = null_compress, | 66 | .coa_compress = null_compress, |
65 | .coa_decompress = null_decompress } } | 67 | .coa_decompress = null_compress } } |
66 | }; | 68 | }; |
67 | 69 | ||
68 | static struct crypto_alg digest_null = { | 70 | static struct crypto_alg digest_null = { |
@@ -90,8 +92,8 @@ static struct crypto_alg cipher_null = { | |||
90 | .cia_min_keysize = NULL_KEY_SIZE, | 92 | .cia_min_keysize = NULL_KEY_SIZE, |
91 | .cia_max_keysize = NULL_KEY_SIZE, | 93 | .cia_max_keysize = NULL_KEY_SIZE, |
92 | .cia_setkey = null_setkey, | 94 | .cia_setkey = null_setkey, |
93 | .cia_encrypt = null_encrypt, | 95 | .cia_encrypt = null_crypt, |
94 | .cia_decrypt = null_decrypt } } | 96 | .cia_decrypt = null_crypt } } |
95 | }; | 97 | }; |
96 | 98 | ||
97 | MODULE_ALIAS("compress_null"); | 99 | MODULE_ALIAS("compress_null"); |
diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 6662b545e0a9..a47928a2e575 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | # Makefile for the Linux device tree | 1 | # Makefile for the Linux device tree |
2 | 2 | ||
3 | obj-y := core.o sys.o interface.o bus.o \ | 3 | obj-y := core.o sys.o bus.o \ |
4 | driver.o class.o class_simple.o platform.o \ | 4 | driver.o class.o class_simple.o platform.o \ |
5 | cpu.o firmware.o init.o map.o dmapool.o \ | 5 | cpu.o firmware.o init.o map.o dmapool.o \ |
6 | attribute_container.o transport_class.o | 6 | attribute_container.o transport_class.o |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 2b3902c867da..3cb04bb04c2b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -390,7 +390,6 @@ void device_release_driver(struct device * dev) | |||
390 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); | 390 | sysfs_remove_link(&drv->kobj, kobject_name(&dev->kobj)); |
391 | sysfs_remove_link(&dev->kobj, "driver"); | 391 | sysfs_remove_link(&dev->kobj, "driver"); |
392 | list_del_init(&dev->driver_list); | 392 | list_del_init(&dev->driver_list); |
393 | device_detach_shutdown(dev); | ||
394 | if (drv->remove) | 393 | if (drv->remove) |
395 | drv->remove(dev); | 394 | drv->remove(dev); |
396 | dev->driver = NULL; | 395 | dev->driver = NULL; |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 268a9c8d168b..d21eb7744496 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -31,8 +31,6 @@ int (*platform_notify_remove)(struct device * dev) = NULL; | |||
31 | #define to_dev(obj) container_of(obj, struct device, kobj) | 31 | #define to_dev(obj) container_of(obj, struct device, kobj) |
32 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) | 32 | #define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr) |
33 | 33 | ||
34 | extern struct attribute * dev_default_attrs[]; | ||
35 | |||
36 | static ssize_t | 34 | static ssize_t |
37 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) | 35 | dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf) |
38 | { | 36 | { |
@@ -89,7 +87,6 @@ static void device_release(struct kobject * kobj) | |||
89 | static struct kobj_type ktype_device = { | 87 | static struct kobj_type ktype_device = { |
90 | .release = device_release, | 88 | .release = device_release, |
91 | .sysfs_ops = &dev_sysfs_ops, | 89 | .sysfs_ops = &dev_sysfs_ops, |
92 | .default_attrs = dev_default_attrs, | ||
93 | }; | 90 | }; |
94 | 91 | ||
95 | 92 | ||
diff --git a/drivers/base/interface.c b/drivers/base/interface.c deleted file mode 100644 index bd515843a0cb..000000000000 --- a/drivers/base/interface.c +++ /dev/null | |||
@@ -1,51 +0,0 @@ | |||
1 | /* | ||
2 | * drivers/base/interface.c - common driverfs interface that's exported to | ||
3 | * the world for all devices. | ||
4 | * | ||
5 | * Copyright (c) 2002-3 Patrick Mochel | ||
6 | * Copyright (c) 2002-3 Open Source Development Labs | ||
7 | * | ||
8 | * This file is released under the GPLv2 | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #include <linux/device.h> | ||
13 | #include <linux/err.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/string.h> | ||
16 | |||
17 | /** | ||
18 | * detach_state - control the default power state for the device. | ||
19 | * | ||
20 | * This is the state the device enters when it's driver module is | ||
21 | * unloaded. The value is an unsigned integer, in the range of 0-4. | ||
22 | * '0' indicates 'On', so no action will be taken when the driver is | ||
23 | * unloaded. This is the default behavior. | ||
24 | * '4' indicates 'Off', meaning the driver core will call the driver's | ||
25 | * shutdown method to quiesce the device. | ||
26 | * 1-3 indicate a low-power state for the device to enter via the | ||
27 | * driver's suspend method. | ||
28 | */ | ||
29 | |||
30 | static ssize_t detach_show(struct device * dev, char * buf) | ||
31 | { | ||
32 | return sprintf(buf, "%u\n", dev->detach_state); | ||
33 | } | ||
34 | |||
35 | static ssize_t detach_store(struct device * dev, const char * buf, size_t n) | ||
36 | { | ||
37 | u32 state; | ||
38 | state = simple_strtoul(buf, NULL, 10); | ||
39 | if (state > 4) | ||
40 | return -EINVAL; | ||
41 | dev->detach_state = state; | ||
42 | return n; | ||
43 | } | ||
44 | |||
45 | static DEVICE_ATTR(detach_state, 0644, detach_show, detach_store); | ||
46 | |||
47 | |||
48 | struct attribute * dev_default_attrs[] = { | ||
49 | &dev_attr_detach_state.attr, | ||
50 | NULL, | ||
51 | }; | ||
diff --git a/drivers/base/power/power.h b/drivers/base/power/power.h index e5eda746f2a6..2e700d795cf1 100644 --- a/drivers/base/power/power.h +++ b/drivers/base/power/power.h | |||
@@ -1,18 +1,7 @@ | |||
1 | |||
2 | |||
3 | enum { | ||
4 | DEVICE_PM_ON, | ||
5 | DEVICE_PM1, | ||
6 | DEVICE_PM2, | ||
7 | DEVICE_PM3, | ||
8 | DEVICE_PM_OFF, | ||
9 | }; | ||
10 | |||
11 | /* | 1 | /* |
12 | * shutdown.c | 2 | * shutdown.c |
13 | */ | 3 | */ |
14 | 4 | ||
15 | extern int device_detach_shutdown(struct device *); | ||
16 | extern void device_shutdown(void); | 5 | extern void device_shutdown(void); |
17 | 6 | ||
18 | 7 | ||
diff --git a/drivers/base/power/resume.c b/drivers/base/power/resume.c index f8f5055754d6..26468971ef5a 100644 --- a/drivers/base/power/resume.c +++ b/drivers/base/power/resume.c | |||
@@ -22,8 +22,17 @@ extern int sysdev_resume(void); | |||
22 | 22 | ||
23 | int resume_device(struct device * dev) | 23 | int resume_device(struct device * dev) |
24 | { | 24 | { |
25 | if (dev->bus && dev->bus->resume) | 25 | if (dev->power.pm_parent |
26 | && dev->power.pm_parent->power.power_state) { | ||
27 | dev_err(dev, "PM: resume from %d, parent %s still %d\n", | ||
28 | dev->power.power_state, | ||
29 | dev->power.pm_parent->bus_id, | ||
30 | dev->power.pm_parent->power.power_state); | ||
31 | } | ||
32 | if (dev->bus && dev->bus->resume) { | ||
33 | dev_dbg(dev,"resuming\n"); | ||
26 | return dev->bus->resume(dev); | 34 | return dev->bus->resume(dev); |
35 | } | ||
27 | return 0; | 36 | return 0; |
28 | } | 37 | } |
29 | 38 | ||
diff --git a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c index d1e023fbe169..f50a08be424b 100644 --- a/drivers/base/power/shutdown.c +++ b/drivers/base/power/shutdown.c | |||
@@ -19,20 +19,6 @@ | |||
19 | extern struct subsystem devices_subsys; | 19 | extern struct subsystem devices_subsys; |
20 | 20 | ||
21 | 21 | ||
22 | int device_detach_shutdown(struct device * dev) | ||
23 | { | ||
24 | if (!dev->detach_state) | ||
25 | return 0; | ||
26 | |||
27 | if (dev->detach_state == DEVICE_PM_OFF) { | ||
28 | if (dev->driver && dev->driver->shutdown) | ||
29 | dev->driver->shutdown(dev); | ||
30 | return 0; | ||
31 | } | ||
32 | return dpm_runtime_suspend(dev, dev->detach_state); | ||
33 | } | ||
34 | |||
35 | |||
36 | /** | 22 | /** |
37 | * We handle system devices differently - we suspend and shut them | 23 | * We handle system devices differently - we suspend and shut them |
38 | * down last and resume them first. That way, we don't do anything stupid like | 24 | * down last and resume them first. That way, we don't do anything stupid like |
@@ -52,13 +38,12 @@ void device_shutdown(void) | |||
52 | struct device * dev; | 38 | struct device * dev; |
53 | 39 | ||
54 | down_write(&devices_subsys.rwsem); | 40 | down_write(&devices_subsys.rwsem); |
55 | list_for_each_entry_reverse(dev, &devices_subsys.kset.list, kobj.entry) { | 41 | list_for_each_entry_reverse(dev, &devices_subsys.kset.list, |
56 | pr_debug("shutting down %s: ", dev->bus_id); | 42 | kobj.entry) { |
57 | if (dev->driver && dev->driver->shutdown) { | 43 | if (dev->driver && dev->driver->shutdown) { |
58 | pr_debug("Ok\n"); | 44 | dev_dbg(dev, "shutdown\n"); |
59 | dev->driver->shutdown(dev); | 45 | dev->driver->shutdown(dev); |
60 | } else | 46 | } |
61 | pr_debug("Ignored.\n"); | ||
62 | } | 47 | } |
63 | up_write(&devices_subsys.rwsem); | 48 | up_write(&devices_subsys.rwsem); |
64 | 49 | ||
diff --git a/drivers/base/power/suspend.c b/drivers/base/power/suspend.c index a0b5cf689e63..0ec44ef840be 100644 --- a/drivers/base/power/suspend.c +++ b/drivers/base/power/suspend.c | |||
@@ -39,12 +39,25 @@ int suspend_device(struct device * dev, pm_message_t state) | |||
39 | { | 39 | { |
40 | int error = 0; | 40 | int error = 0; |
41 | 41 | ||
42 | dev_dbg(dev, "suspending\n"); | 42 | if (dev->power.power_state) { |
43 | dev_dbg(dev, "PM: suspend %d-->%d\n", | ||
44 | dev->power.power_state, state); | ||
45 | } | ||
46 | if (dev->power.pm_parent | ||
47 | && dev->power.pm_parent->power.power_state) { | ||
48 | dev_err(dev, | ||
49 | "PM: suspend %d->%d, parent %s already %d\n", | ||
50 | dev->power.power_state, state, | ||
51 | dev->power.pm_parent->bus_id, | ||
52 | dev->power.pm_parent->power.power_state); | ||
53 | } | ||
43 | 54 | ||
44 | dev->power.prev_state = dev->power.power_state; | 55 | dev->power.prev_state = dev->power.power_state; |
45 | 56 | ||
46 | if (dev->bus && dev->bus->suspend && !dev->power.power_state) | 57 | if (dev->bus && dev->bus->suspend && !dev->power.power_state) { |
58 | dev_dbg(dev, "suspending\n"); | ||
47 | error = dev->bus->suspend(dev, state); | 59 | error = dev->bus->suspend(dev, state); |
60 | } | ||
48 | 61 | ||
49 | return error; | 62 | return error; |
50 | } | 63 | } |
diff --git a/drivers/block/DAC960.c b/drivers/block/DAC960.c index 423bbf2000d2..3760edfdc65c 100644 --- a/drivers/block/DAC960.c +++ b/drivers/block/DAC960.c | |||
@@ -3,6 +3,7 @@ | |||
3 | Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers | 3 | Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers |
4 | 4 | ||
5 | Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com> | 5 | Copyright 1998-2001 by Leonard N. Zubkoff <lnz@dandelion.com> |
6 | Portions Copyright 2002 by Mylex (An IBM Business Unit) | ||
6 | 7 | ||
7 | This program is free software; you may redistribute and/or modify it under | 8 | This program is free software; you may redistribute and/or modify it under |
8 | the terms of the GNU General Public License Version 2 as published by the | 9 | the terms of the GNU General Public License Version 2 as published by the |
@@ -532,6 +533,34 @@ static void DAC960_WaitForCommand(DAC960_Controller_T *Controller) | |||
532 | spin_lock_irq(&Controller->queue_lock); | 533 | spin_lock_irq(&Controller->queue_lock); |
533 | } | 534 | } |
534 | 535 | ||
536 | /* | ||
537 | DAC960_GEM_QueueCommand queues Command for DAC960 GEM Series Controllers. | ||
538 | */ | ||
539 | |||
540 | static void DAC960_GEM_QueueCommand(DAC960_Command_T *Command) | ||
541 | { | ||
542 | DAC960_Controller_T *Controller = Command->Controller; | ||
543 | void __iomem *ControllerBaseAddress = Controller->BaseAddress; | ||
544 | DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox; | ||
545 | DAC960_V2_CommandMailbox_T *NextCommandMailbox = | ||
546 | Controller->V2.NextCommandMailbox; | ||
547 | |||
548 | CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier; | ||
549 | DAC960_GEM_WriteCommandMailbox(NextCommandMailbox, CommandMailbox); | ||
550 | |||
551 | if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 || | ||
552 | Controller->V2.PreviousCommandMailbox2->Words[0] == 0) | ||
553 | DAC960_GEM_MemoryMailboxNewCommand(ControllerBaseAddress); | ||
554 | |||
555 | Controller->V2.PreviousCommandMailbox2 = | ||
556 | Controller->V2.PreviousCommandMailbox1; | ||
557 | Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox; | ||
558 | |||
559 | if (++NextCommandMailbox > Controller->V2.LastCommandMailbox) | ||
560 | NextCommandMailbox = Controller->V2.FirstCommandMailbox; | ||
561 | |||
562 | Controller->V2.NextCommandMailbox = NextCommandMailbox; | ||
563 | } | ||
535 | 564 | ||
536 | /* | 565 | /* |
537 | DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers. | 566 | DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers. |
@@ -1464,6 +1493,17 @@ static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T | |||
1464 | Controller->V2.FirstStatusMailboxDMA; | 1493 | Controller->V2.FirstStatusMailboxDMA; |
1465 | switch (Controller->HardwareType) | 1494 | switch (Controller->HardwareType) |
1466 | { | 1495 | { |
1496 | case DAC960_GEM_Controller: | ||
1497 | while (DAC960_GEM_HardwareMailboxFullP(ControllerBaseAddress)) | ||
1498 | udelay(1); | ||
1499 | DAC960_GEM_WriteHardwareMailbox(ControllerBaseAddress, CommandMailboxDMA); | ||
1500 | DAC960_GEM_HardwareMailboxNewCommand(ControllerBaseAddress); | ||
1501 | while (!DAC960_GEM_HardwareMailboxStatusAvailableP(ControllerBaseAddress)) | ||
1502 | udelay(1); | ||
1503 | CommandStatus = DAC960_GEM_ReadCommandStatus(ControllerBaseAddress); | ||
1504 | DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress); | ||
1505 | DAC960_GEM_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress); | ||
1506 | break; | ||
1467 | case DAC960_BA_Controller: | 1507 | case DAC960_BA_Controller: |
1468 | while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) | 1508 | while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress)) |
1469 | udelay(1); | 1509 | udelay(1); |
@@ -2627,6 +2667,9 @@ static void DAC960_DetectCleanup(DAC960_Controller_T *Controller) | |||
2627 | if (Controller->MemoryMappedAddress) { | 2667 | if (Controller->MemoryMappedAddress) { |
2628 | switch(Controller->HardwareType) | 2668 | switch(Controller->HardwareType) |
2629 | { | 2669 | { |
2670 | case DAC960_GEM_Controller: | ||
2671 | DAC960_GEM_DisableInterrupts(Controller->BaseAddress); | ||
2672 | break; | ||
2630 | case DAC960_BA_Controller: | 2673 | case DAC960_BA_Controller: |
2631 | DAC960_BA_DisableInterrupts(Controller->BaseAddress); | 2674 | DAC960_BA_DisableInterrupts(Controller->BaseAddress); |
2632 | break; | 2675 | break; |
@@ -2705,6 +2748,9 @@ DAC960_DetectController(struct pci_dev *PCI_Device, | |||
2705 | 2748 | ||
2706 | switch (Controller->HardwareType) | 2749 | switch (Controller->HardwareType) |
2707 | { | 2750 | { |
2751 | case DAC960_GEM_Controller: | ||
2752 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); | ||
2753 | break; | ||
2708 | case DAC960_BA_Controller: | 2754 | case DAC960_BA_Controller: |
2709 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); | 2755 | Controller->PCI_Address = pci_resource_start(PCI_Device, 0); |
2710 | break; | 2756 | break; |
@@ -2756,6 +2802,36 @@ DAC960_DetectController(struct pci_dev *PCI_Device, | |||
2756 | BaseAddress = Controller->BaseAddress; | 2802 | BaseAddress = Controller->BaseAddress; |
2757 | switch (Controller->HardwareType) | 2803 | switch (Controller->HardwareType) |
2758 | { | 2804 | { |
2805 | case DAC960_GEM_Controller: | ||
2806 | DAC960_GEM_DisableInterrupts(BaseAddress); | ||
2807 | DAC960_GEM_AcknowledgeHardwareMailboxStatus(BaseAddress); | ||
2808 | udelay(1000); | ||
2809 | while (DAC960_GEM_InitializationInProgressP(BaseAddress)) | ||
2810 | { | ||
2811 | if (DAC960_GEM_ReadErrorStatus(BaseAddress, &ErrorStatus, | ||
2812 | &Parameter0, &Parameter1) && | ||
2813 | DAC960_ReportErrorStatus(Controller, ErrorStatus, | ||
2814 | Parameter0, Parameter1)) | ||
2815 | goto Failure; | ||
2816 | udelay(10); | ||
2817 | } | ||
2818 | if (!DAC960_V2_EnableMemoryMailboxInterface(Controller)) | ||
2819 | { | ||
2820 | DAC960_Error("Unable to Enable Memory Mailbox Interface " | ||
2821 | "for Controller at\n", Controller); | ||
2822 | goto Failure; | ||
2823 | } | ||
2824 | DAC960_GEM_EnableInterrupts(BaseAddress); | ||
2825 | Controller->QueueCommand = DAC960_GEM_QueueCommand; | ||
2826 | Controller->ReadControllerConfiguration = | ||
2827 | DAC960_V2_ReadControllerConfiguration; | ||
2828 | Controller->ReadDeviceConfiguration = | ||
2829 | DAC960_V2_ReadDeviceConfiguration; | ||
2830 | Controller->ReportDeviceConfiguration = | ||
2831 | DAC960_V2_ReportDeviceConfiguration; | ||
2832 | Controller->QueueReadWriteCommand = | ||
2833 | DAC960_V2_QueueReadWriteCommand; | ||
2834 | break; | ||
2759 | case DAC960_BA_Controller: | 2835 | case DAC960_BA_Controller: |
2760 | DAC960_BA_DisableInterrupts(BaseAddress); | 2836 | DAC960_BA_DisableInterrupts(BaseAddress); |
2761 | DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress); | 2837 | DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress); |
@@ -5189,6 +5265,47 @@ static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command) | |||
5189 | wake_up(&Controller->CommandWaitQueue); | 5265 | wake_up(&Controller->CommandWaitQueue); |
5190 | } | 5266 | } |
5191 | 5267 | ||
5268 | /* | ||
5269 | DAC960_GEM_InterruptHandler handles hardware interrupts from DAC960 GEM Series | ||
5270 | Controllers. | ||
5271 | */ | ||
5272 | |||
5273 | static irqreturn_t DAC960_GEM_InterruptHandler(int IRQ_Channel, | ||
5274 | void *DeviceIdentifier, | ||
5275 | struct pt_regs *InterruptRegisters) | ||
5276 | { | ||
5277 | DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier; | ||
5278 | void __iomem *ControllerBaseAddress = Controller->BaseAddress; | ||
5279 | DAC960_V2_StatusMailbox_T *NextStatusMailbox; | ||
5280 | unsigned long flags; | ||
5281 | |||
5282 | spin_lock_irqsave(&Controller->queue_lock, flags); | ||
5283 | DAC960_GEM_AcknowledgeInterrupt(ControllerBaseAddress); | ||
5284 | NextStatusMailbox = Controller->V2.NextStatusMailbox; | ||
5285 | while (NextStatusMailbox->Fields.CommandIdentifier > 0) | ||
5286 | { | ||
5287 | DAC960_V2_CommandIdentifier_T CommandIdentifier = | ||
5288 | NextStatusMailbox->Fields.CommandIdentifier; | ||
5289 | DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1]; | ||
5290 | Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus; | ||
5291 | Command->V2.RequestSenseLength = | ||
5292 | NextStatusMailbox->Fields.RequestSenseLength; | ||
5293 | Command->V2.DataTransferResidue = | ||
5294 | NextStatusMailbox->Fields.DataTransferResidue; | ||
5295 | NextStatusMailbox->Words[0] = 0; | ||
5296 | if (++NextStatusMailbox > Controller->V2.LastStatusMailbox) | ||
5297 | NextStatusMailbox = Controller->V2.FirstStatusMailbox; | ||
5298 | DAC960_V2_ProcessCompletedCommand(Command); | ||
5299 | } | ||
5300 | Controller->V2.NextStatusMailbox = NextStatusMailbox; | ||
5301 | /* | ||
5302 | Attempt to remove additional I/O Requests from the Controller's | ||
5303 | I/O Request Queue and queue them to the Controller. | ||
5304 | */ | ||
5305 | DAC960_ProcessRequest(Controller); | ||
5306 | spin_unlock_irqrestore(&Controller->queue_lock, flags); | ||
5307 | return IRQ_HANDLED; | ||
5308 | } | ||
5192 | 5309 | ||
5193 | /* | 5310 | /* |
5194 | DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series | 5311 | DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series |
@@ -6962,6 +7079,14 @@ static void DAC960_gam_cleanup(void) | |||
6962 | 7079 | ||
6963 | #endif /* DAC960_GAM_MINOR */ | 7080 | #endif /* DAC960_GAM_MINOR */ |
6964 | 7081 | ||
7082 | static struct DAC960_privdata DAC960_GEM_privdata = { | ||
7083 | .HardwareType = DAC960_GEM_Controller, | ||
7084 | .FirmwareType = DAC960_V2_Controller, | ||
7085 | .InterruptHandler = DAC960_GEM_InterruptHandler, | ||
7086 | .MemoryWindowSize = DAC960_GEM_RegisterWindowSize, | ||
7087 | }; | ||
7088 | |||
7089 | |||
6965 | static struct DAC960_privdata DAC960_BA_privdata = { | 7090 | static struct DAC960_privdata DAC960_BA_privdata = { |
6966 | .HardwareType = DAC960_BA_Controller, | 7091 | .HardwareType = DAC960_BA_Controller, |
6967 | .FirmwareType = DAC960_V2_Controller, | 7092 | .FirmwareType = DAC960_V2_Controller, |
@@ -7007,6 +7132,13 @@ static struct DAC960_privdata DAC960_P_privdata = { | |||
7007 | static struct pci_device_id DAC960_id_table[] = { | 7132 | static struct pci_device_id DAC960_id_table[] = { |
7008 | { | 7133 | { |
7009 | .vendor = PCI_VENDOR_ID_MYLEX, | 7134 | .vendor = PCI_VENDOR_ID_MYLEX, |
7135 | .device = PCI_DEVICE_ID_MYLEX_DAC960_GEM, | ||
7136 | .subvendor = PCI_ANY_ID, | ||
7137 | .subdevice = PCI_ANY_ID, | ||
7138 | .driver_data = (unsigned long) &DAC960_GEM_privdata, | ||
7139 | }, | ||
7140 | { | ||
7141 | .vendor = PCI_VENDOR_ID_MYLEX, | ||
7010 | .device = PCI_DEVICE_ID_MYLEX_DAC960_BA, | 7142 | .device = PCI_DEVICE_ID_MYLEX_DAC960_BA, |
7011 | .subvendor = PCI_ANY_ID, | 7143 | .subvendor = PCI_ANY_ID, |
7012 | .subdevice = PCI_ANY_ID, | 7144 | .subdevice = PCI_ANY_ID, |
diff --git a/drivers/block/DAC960.h b/drivers/block/DAC960.h index d5e8e7190c90..a82f37f749a5 100644 --- a/drivers/block/DAC960.h +++ b/drivers/block/DAC960.h | |||
@@ -2114,7 +2114,8 @@ typedef enum | |||
2114 | DAC960_LA_Controller = 3, /* DAC1164P */ | 2114 | DAC960_LA_Controller = 3, /* DAC1164P */ |
2115 | DAC960_PG_Controller = 4, /* DAC960PTL/PJ/PG */ | 2115 | DAC960_PG_Controller = 4, /* DAC960PTL/PJ/PG */ |
2116 | DAC960_PD_Controller = 5, /* DAC960PU/PD/PL/P */ | 2116 | DAC960_PD_Controller = 5, /* DAC960PU/PD/PL/P */ |
2117 | DAC960_P_Controller = 6 /* DAC960PU/PD/PL/P */ | 2117 | DAC960_P_Controller = 6, /* DAC960PU/PD/PL/P */ |
2118 | DAC960_GEM_Controller = 7, /* AcceleRAID 4/5/600 */ | ||
2118 | } | 2119 | } |
2119 | DAC960_HardwareType_T; | 2120 | DAC960_HardwareType_T; |
2120 | 2121 | ||
@@ -2541,6 +2542,320 @@ void dma_addr_writeql(dma_addr_t addr, void __iomem *write_address) | |||
2541 | } | 2542 | } |
2542 | 2543 | ||
2543 | /* | 2544 | /* |
2545 | Define the DAC960 GEM Series Controller Interface Register Offsets. | ||
2546 | */ | ||
2547 | |||
2548 | #define DAC960_GEM_RegisterWindowSize 0x600 | ||
2549 | |||
2550 | typedef enum | ||
2551 | { | ||
2552 | DAC960_GEM_InboundDoorBellRegisterReadSetOffset = 0x214, | ||
2553 | DAC960_GEM_InboundDoorBellRegisterClearOffset = 0x218, | ||
2554 | DAC960_GEM_OutboundDoorBellRegisterReadSetOffset = 0x224, | ||
2555 | DAC960_GEM_OutboundDoorBellRegisterClearOffset = 0x228, | ||
2556 | DAC960_GEM_InterruptStatusRegisterOffset = 0x208, | ||
2557 | DAC960_GEM_InterruptMaskRegisterReadSetOffset = 0x22C, | ||
2558 | DAC960_GEM_InterruptMaskRegisterClearOffset = 0x230, | ||
2559 | DAC960_GEM_CommandMailboxBusAddressOffset = 0x510, | ||
2560 | DAC960_GEM_CommandStatusOffset = 0x518, | ||
2561 | DAC960_GEM_ErrorStatusRegisterReadSetOffset = 0x224, | ||
2562 | DAC960_GEM_ErrorStatusRegisterClearOffset = 0x228, | ||
2563 | } | ||
2564 | DAC960_GEM_RegisterOffsets_T; | ||
2565 | |||
2566 | /* | ||
2567 | Define the structure of the DAC960 GEM Series Inbound Door Bell | ||
2568 | */ | ||
2569 | |||
2570 | typedef union DAC960_GEM_InboundDoorBellRegister | ||
2571 | { | ||
2572 | unsigned int All; | ||
2573 | struct { | ||
2574 | unsigned int :24; | ||
2575 | boolean HardwareMailboxNewCommand:1; | ||
2576 | boolean AcknowledgeHardwareMailboxStatus:1; | ||
2577 | boolean GenerateInterrupt:1; | ||
2578 | boolean ControllerReset:1; | ||
2579 | boolean MemoryMailboxNewCommand:1; | ||
2580 | unsigned int :3; | ||
2581 | } Write; | ||
2582 | struct { | ||
2583 | unsigned int :24; | ||
2584 | boolean HardwareMailboxFull:1; | ||
2585 | boolean InitializationInProgress:1; | ||
2586 | unsigned int :6; | ||
2587 | } Read; | ||
2588 | } | ||
2589 | DAC960_GEM_InboundDoorBellRegister_T; | ||
2590 | |||
2591 | /* | ||
2592 | Define the structure of the DAC960 GEM Series Outbound Door Bell Register. | ||
2593 | */ | ||
2594 | typedef union DAC960_GEM_OutboundDoorBellRegister | ||
2595 | { | ||
2596 | unsigned int All; | ||
2597 | struct { | ||
2598 | unsigned int :24; | ||
2599 | boolean AcknowledgeHardwareMailboxInterrupt:1; | ||
2600 | boolean AcknowledgeMemoryMailboxInterrupt:1; | ||
2601 | unsigned int :6; | ||
2602 | } Write; | ||
2603 | struct { | ||
2604 | unsigned int :24; | ||
2605 | boolean HardwareMailboxStatusAvailable:1; | ||
2606 | boolean MemoryMailboxStatusAvailable:1; | ||
2607 | unsigned int :6; | ||
2608 | } Read; | ||
2609 | } | ||
2610 | DAC960_GEM_OutboundDoorBellRegister_T; | ||
2611 | |||
2612 | /* | ||
2613 | Define the structure of the DAC960 GEM Series Interrupt Mask Register. | ||
2614 | */ | ||
2615 | typedef union DAC960_GEM_InterruptMaskRegister | ||
2616 | { | ||
2617 | unsigned int All; | ||
2618 | struct { | ||
2619 | unsigned int :16; | ||
2620 | unsigned int :8; | ||
2621 | unsigned int HardwareMailboxInterrupt:1; | ||
2622 | unsigned int MemoryMailboxInterrupt:1; | ||
2623 | unsigned int :6; | ||
2624 | } Bits; | ||
2625 | } | ||
2626 | DAC960_GEM_InterruptMaskRegister_T; | ||
2627 | |||
2628 | /* | ||
2629 | Define the structure of the DAC960 GEM Series Error Status Register. | ||
2630 | */ | ||
2631 | |||
2632 | typedef union DAC960_GEM_ErrorStatusRegister | ||
2633 | { | ||
2634 | unsigned int All; | ||
2635 | struct { | ||
2636 | unsigned int :24; | ||
2637 | unsigned int :5; | ||
2638 | boolean ErrorStatusPending:1; | ||
2639 | unsigned int :2; | ||
2640 | } Bits; | ||
2641 | } | ||
2642 | DAC960_GEM_ErrorStatusRegister_T; | ||
2643 | |||
2644 | /* | ||
2645 | Define inline functions to provide an abstraction for reading and writing the | ||
2646 | DAC960 GEM Series Controller Interface Registers. | ||
2647 | */ | ||
2648 | |||
2649 | static inline | ||
2650 | void DAC960_GEM_HardwareMailboxNewCommand(void __iomem *ControllerBaseAddress) | ||
2651 | { | ||
2652 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2653 | InboundDoorBellRegister.All = 0; | ||
2654 | InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true; | ||
2655 | writel(InboundDoorBellRegister.All, | ||
2656 | ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2657 | } | ||
2658 | |||
2659 | static inline | ||
2660 | void DAC960_GEM_AcknowledgeHardwareMailboxStatus(void __iomem *ControllerBaseAddress) | ||
2661 | { | ||
2662 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2663 | InboundDoorBellRegister.All = 0; | ||
2664 | InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true; | ||
2665 | writel(InboundDoorBellRegister.All, | ||
2666 | ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterClearOffset); | ||
2667 | } | ||
2668 | |||
2669 | static inline | ||
2670 | void DAC960_GEM_GenerateInterrupt(void __iomem *ControllerBaseAddress) | ||
2671 | { | ||
2672 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2673 | InboundDoorBellRegister.All = 0; | ||
2674 | InboundDoorBellRegister.Write.GenerateInterrupt = true; | ||
2675 | writel(InboundDoorBellRegister.All, | ||
2676 | ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2677 | } | ||
2678 | |||
2679 | static inline | ||
2680 | void DAC960_GEM_ControllerReset(void __iomem *ControllerBaseAddress) | ||
2681 | { | ||
2682 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2683 | InboundDoorBellRegister.All = 0; | ||
2684 | InboundDoorBellRegister.Write.ControllerReset = true; | ||
2685 | writel(InboundDoorBellRegister.All, | ||
2686 | ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2687 | } | ||
2688 | |||
2689 | static inline | ||
2690 | void DAC960_GEM_MemoryMailboxNewCommand(void __iomem *ControllerBaseAddress) | ||
2691 | { | ||
2692 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2693 | InboundDoorBellRegister.All = 0; | ||
2694 | InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true; | ||
2695 | writel(InboundDoorBellRegister.All, | ||
2696 | ControllerBaseAddress + DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2697 | } | ||
2698 | |||
2699 | static inline | ||
2700 | boolean DAC960_GEM_HardwareMailboxFullP(void __iomem *ControllerBaseAddress) | ||
2701 | { | ||
2702 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2703 | InboundDoorBellRegister.All = | ||
2704 | readl(ControllerBaseAddress + | ||
2705 | DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2706 | return InboundDoorBellRegister.Read.HardwareMailboxFull; | ||
2707 | } | ||
2708 | |||
2709 | static inline | ||
2710 | boolean DAC960_GEM_InitializationInProgressP(void __iomem *ControllerBaseAddress) | ||
2711 | { | ||
2712 | DAC960_GEM_InboundDoorBellRegister_T InboundDoorBellRegister; | ||
2713 | InboundDoorBellRegister.All = | ||
2714 | readl(ControllerBaseAddress + | ||
2715 | DAC960_GEM_InboundDoorBellRegisterReadSetOffset); | ||
2716 | return InboundDoorBellRegister.Read.InitializationInProgress; | ||
2717 | } | ||
2718 | |||
2719 | static inline | ||
2720 | void DAC960_GEM_AcknowledgeHardwareMailboxInterrupt(void __iomem *ControllerBaseAddress) | ||
2721 | { | ||
2722 | DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; | ||
2723 | OutboundDoorBellRegister.All = 0; | ||
2724 | OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; | ||
2725 | writel(OutboundDoorBellRegister.All, | ||
2726 | ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); | ||
2727 | } | ||
2728 | |||
2729 | static inline | ||
2730 | void DAC960_GEM_AcknowledgeMemoryMailboxInterrupt(void __iomem *ControllerBaseAddress) | ||
2731 | { | ||
2732 | DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; | ||
2733 | OutboundDoorBellRegister.All = 0; | ||
2734 | OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; | ||
2735 | writel(OutboundDoorBellRegister.All, | ||
2736 | ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); | ||
2737 | } | ||
2738 | |||
2739 | static inline | ||
2740 | void DAC960_GEM_AcknowledgeInterrupt(void __iomem *ControllerBaseAddress) | ||
2741 | { | ||
2742 | DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; | ||
2743 | OutboundDoorBellRegister.All = 0; | ||
2744 | OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true; | ||
2745 | OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true; | ||
2746 | writel(OutboundDoorBellRegister.All, | ||
2747 | ControllerBaseAddress + DAC960_GEM_OutboundDoorBellRegisterClearOffset); | ||
2748 | } | ||
2749 | |||
2750 | static inline | ||
2751 | boolean DAC960_GEM_HardwareMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) | ||
2752 | { | ||
2753 | DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; | ||
2754 | OutboundDoorBellRegister.All = | ||
2755 | readl(ControllerBaseAddress + | ||
2756 | DAC960_GEM_OutboundDoorBellRegisterReadSetOffset); | ||
2757 | return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable; | ||
2758 | } | ||
2759 | |||
2760 | static inline | ||
2761 | boolean DAC960_GEM_MemoryMailboxStatusAvailableP(void __iomem *ControllerBaseAddress) | ||
2762 | { | ||
2763 | DAC960_GEM_OutboundDoorBellRegister_T OutboundDoorBellRegister; | ||
2764 | OutboundDoorBellRegister.All = | ||
2765 | readl(ControllerBaseAddress + | ||
2766 | DAC960_GEM_OutboundDoorBellRegisterReadSetOffset); | ||
2767 | return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable; | ||
2768 | } | ||
2769 | |||
2770 | static inline | ||
2771 | void DAC960_GEM_EnableInterrupts(void __iomem *ControllerBaseAddress) | ||
2772 | { | ||
2773 | DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; | ||
2774 | InterruptMaskRegister.All = 0; | ||
2775 | InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true; | ||
2776 | InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true; | ||
2777 | writel(InterruptMaskRegister.All, | ||
2778 | ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterClearOffset); | ||
2779 | } | ||
2780 | |||
2781 | static inline | ||
2782 | void DAC960_GEM_DisableInterrupts(void __iomem *ControllerBaseAddress) | ||
2783 | { | ||
2784 | DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; | ||
2785 | InterruptMaskRegister.All = 0; | ||
2786 | InterruptMaskRegister.Bits.HardwareMailboxInterrupt = true; | ||
2787 | InterruptMaskRegister.Bits.MemoryMailboxInterrupt = true; | ||
2788 | writel(InterruptMaskRegister.All, | ||
2789 | ControllerBaseAddress + DAC960_GEM_InterruptMaskRegisterReadSetOffset); | ||
2790 | } | ||
2791 | |||
2792 | static inline | ||
2793 | boolean DAC960_GEM_InterruptsEnabledP(void __iomem *ControllerBaseAddress) | ||
2794 | { | ||
2795 | DAC960_GEM_InterruptMaskRegister_T InterruptMaskRegister; | ||
2796 | InterruptMaskRegister.All = | ||
2797 | readl(ControllerBaseAddress + | ||
2798 | DAC960_GEM_InterruptMaskRegisterReadSetOffset); | ||
2799 | return !(InterruptMaskRegister.Bits.HardwareMailboxInterrupt || | ||
2800 | InterruptMaskRegister.Bits.MemoryMailboxInterrupt); | ||
2801 | } | ||
2802 | |||
2803 | static inline | ||
2804 | void DAC960_GEM_WriteCommandMailbox(DAC960_V2_CommandMailbox_T | ||
2805 | *MemoryCommandMailbox, | ||
2806 | DAC960_V2_CommandMailbox_T | ||
2807 | *CommandMailbox) | ||
2808 | { | ||
2809 | memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1], | ||
2810 | sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int)); | ||
2811 | wmb(); | ||
2812 | MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0]; | ||
2813 | mb(); | ||
2814 | } | ||
2815 | |||
2816 | static inline | ||
2817 | void DAC960_GEM_WriteHardwareMailbox(void __iomem *ControllerBaseAddress, | ||
2818 | dma_addr_t CommandMailboxDMA) | ||
2819 | { | ||
2820 | dma_addr_writeql(CommandMailboxDMA, | ||
2821 | ControllerBaseAddress + | ||
2822 | DAC960_GEM_CommandMailboxBusAddressOffset); | ||
2823 | } | ||
2824 | |||
2825 | static inline DAC960_V2_CommandIdentifier_T | ||
2826 | DAC960_GEM_ReadCommandIdentifier(void __iomem *ControllerBaseAddress) | ||
2827 | { | ||
2828 | return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset); | ||
2829 | } | ||
2830 | |||
2831 | static inline DAC960_V2_CommandStatus_T | ||
2832 | DAC960_GEM_ReadCommandStatus(void __iomem *ControllerBaseAddress) | ||
2833 | { | ||
2834 | return readw(ControllerBaseAddress + DAC960_GEM_CommandStatusOffset + 2); | ||
2835 | } | ||
2836 | |||
2837 | static inline boolean | ||
2838 | DAC960_GEM_ReadErrorStatus(void __iomem *ControllerBaseAddress, | ||
2839 | unsigned char *ErrorStatus, | ||
2840 | unsigned char *Parameter0, | ||
2841 | unsigned char *Parameter1) | ||
2842 | { | ||
2843 | DAC960_GEM_ErrorStatusRegister_T ErrorStatusRegister; | ||
2844 | ErrorStatusRegister.All = | ||
2845 | readl(ControllerBaseAddress + DAC960_GEM_ErrorStatusRegisterReadSetOffset); | ||
2846 | if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false; | ||
2847 | ErrorStatusRegister.Bits.ErrorStatusPending = false; | ||
2848 | *ErrorStatus = ErrorStatusRegister.All; | ||
2849 | *Parameter0 = | ||
2850 | readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 0); | ||
2851 | *Parameter1 = | ||
2852 | readb(ControllerBaseAddress + DAC960_GEM_CommandMailboxBusAddressOffset + 1); | ||
2853 | writel(0x03000000, ControllerBaseAddress + | ||
2854 | DAC960_GEM_ErrorStatusRegisterClearOffset); | ||
2855 | return true; | ||
2856 | } | ||
2857 | |||
2858 | /* | ||
2544 | Define the DAC960 BA Series Controller Interface Register Offsets. | 2859 | Define the DAC960 BA Series Controller Interface Register Offsets. |
2545 | */ | 2860 | */ |
2546 | 2861 | ||
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 42dfa281a880..f0c1084b840f 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3345,7 +3345,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g, | |||
3345 | struct block_device *bdev = opened_bdev[cnt]; | 3345 | struct block_device *bdev = opened_bdev[cnt]; |
3346 | if (!bdev || ITYPE(drive_state[cnt].fd_device) != type) | 3346 | if (!bdev || ITYPE(drive_state[cnt].fd_device) != type) |
3347 | continue; | 3347 | continue; |
3348 | __invalidate_device(bdev, 0); | 3348 | __invalidate_device(bdev); |
3349 | } | 3349 | } |
3350 | up(&open_lock); | 3350 | up(&open_lock); |
3351 | } else { | 3351 | } else { |
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c index ab4db71375e0..8bbe01d4b487 100644 --- a/drivers/block/genhd.c +++ b/drivers/block/genhd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
15 | #include <linux/kmod.h> | 15 | #include <linux/kmod.h> |
16 | #include <linux/kobj_map.h> | 16 | #include <linux/kobj_map.h> |
17 | #include <linux/buffer_head.h> | ||
17 | 18 | ||
18 | #define MAX_PROBE_HASH 255 /* random */ | 19 | #define MAX_PROBE_HASH 255 /* random */ |
19 | 20 | ||
@@ -676,7 +677,8 @@ int invalidate_partition(struct gendisk *disk, int index) | |||
676 | int res = 0; | 677 | int res = 0; |
677 | struct block_device *bdev = bdget_disk(disk, index); | 678 | struct block_device *bdev = bdget_disk(disk, index); |
678 | if (bdev) { | 679 | if (bdev) { |
679 | res = __invalidate_device(bdev, 1); | 680 | fsync_bdev(bdev); |
681 | res = __invalidate_device(bdev); | ||
680 | bdput(bdev); | 682 | bdput(bdev); |
681 | } | 683 | } |
682 | return res; | 684 | return res; |
diff --git a/drivers/block/ioctl.c b/drivers/block/ioctl.c index 5e03f5157ef9..6d7bcc9da9e7 100644 --- a/drivers/block/ioctl.c +++ b/drivers/block/ioctl.c | |||
@@ -237,3 +237,5 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg) | |||
237 | } | 237 | } |
238 | return ret; | 238 | return ret; |
239 | } | 239 | } |
240 | |||
241 | EXPORT_SYMBOL_GPL(blkdev_ioctl); | ||
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 1a1fa3ccb913..bc56770bcc90 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c | |||
@@ -914,8 +914,10 @@ static int pkt_handle_queue(struct pktcdvd_device *pd) | |||
914 | bio = node->bio; | 914 | bio = node->bio; |
915 | zone = ZONE(bio->bi_sector, pd); | 915 | zone = ZONE(bio->bi_sector, pd); |
916 | list_for_each_entry(p, &pd->cdrw.pkt_active_list, list) { | 916 | list_for_each_entry(p, &pd->cdrw.pkt_active_list, list) { |
917 | if (p->sector == zone) | 917 | if (p->sector == zone) { |
918 | bio = NULL; | ||
918 | goto try_next_bio; | 919 | goto try_next_bio; |
920 | } | ||
919 | } | 921 | } |
920 | break; | 922 | break; |
921 | try_next_bio: | 923 | try_next_bio: |
@@ -2019,7 +2021,13 @@ static int pkt_open(struct inode *inode, struct file *file) | |||
2019 | BUG_ON(pd->refcnt < 0); | 2021 | BUG_ON(pd->refcnt < 0); |
2020 | 2022 | ||
2021 | pd->refcnt++; | 2023 | pd->refcnt++; |
2022 | if (pd->refcnt == 1) { | 2024 | if (pd->refcnt > 1) { |
2025 | if ((file->f_mode & FMODE_WRITE) && | ||
2026 | !test_bit(PACKET_WRITABLE, &pd->flags)) { | ||
2027 | ret = -EBUSY; | ||
2028 | goto out_dec; | ||
2029 | } | ||
2030 | } else { | ||
2023 | if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { | 2031 | if (pkt_open_dev(pd, file->f_mode & FMODE_WRITE)) { |
2024 | ret = -EIO; | 2032 | ret = -EIO; |
2025 | goto out_dec; | 2033 | goto out_dec; |
@@ -2406,7 +2414,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2406 | case CDROM_LAST_WRITTEN: | 2414 | case CDROM_LAST_WRITTEN: |
2407 | case CDROM_SEND_PACKET: | 2415 | case CDROM_SEND_PACKET: |
2408 | case SCSI_IOCTL_SEND_COMMAND: | 2416 | case SCSI_IOCTL_SEND_COMMAND: |
2409 | return ioctl_by_bdev(pd->bdev, cmd, arg); | 2417 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2410 | 2418 | ||
2411 | case CDROMEJECT: | 2419 | case CDROMEJECT: |
2412 | /* | 2420 | /* |
@@ -2414,7 +2422,7 @@ static int pkt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
2414 | * have to unlock it or else the eject command fails. | 2422 | * have to unlock it or else the eject command fails. |
2415 | */ | 2423 | */ |
2416 | pkt_lock_door(pd, 0); | 2424 | pkt_lock_door(pd, 0); |
2417 | return ioctl_by_bdev(pd->bdev, cmd, arg); | 2425 | return blkdev_ioctl(pd->bdev->bd_inode, file, cmd, arg); |
2418 | 2426 | ||
2419 | default: | 2427 | default: |
2420 | printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); | 2428 | printk("pktcdvd: Unknown ioctl for %s (%x)\n", pd->name, cmd); |
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c index 647a71b12a2a..ac96de15d833 100644 --- a/drivers/cdrom/cdu31a.c +++ b/drivers/cdrom/cdu31a.c | |||
@@ -292,7 +292,7 @@ module_param(cdu31a_irq, int, 0); | |||
292 | 292 | ||
293 | /* The interrupt handler will wake this queue up when it gets an | 293 | /* The interrupt handler will wake this queue up when it gets an |
294 | interrupts. */ | 294 | interrupts. */ |
295 | DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); | 295 | static DECLARE_WAIT_QUEUE_HEAD(cdu31a_irq_wait); |
296 | static int irq_flag = 0; | 296 | static int irq_flag = 0; |
297 | 297 | ||
298 | static int curr_control_reg = 0; /* Current value of the control register */ | 298 | static int curr_control_reg = 0; /* Current value of the control register */ |
@@ -2947,7 +2947,7 @@ static int scd_block_media_changed(struct gendisk *disk) | |||
2947 | return cdrom_media_changed(&scd_info); | 2947 | return cdrom_media_changed(&scd_info); |
2948 | } | 2948 | } |
2949 | 2949 | ||
2950 | struct block_device_operations scd_bdops = | 2950 | static struct block_device_operations scd_bdops = |
2951 | { | 2951 | { |
2952 | .owner = THIS_MODULE, | 2952 | .owner = THIS_MODULE, |
2953 | .open = scd_block_open, | 2953 | .open = scd_block_open, |
@@ -3216,7 +3216,7 @@ errout3: | |||
3216 | } | 3216 | } |
3217 | 3217 | ||
3218 | 3218 | ||
3219 | void __exit cdu31a_exit(void) | 3219 | static void __exit cdu31a_exit(void) |
3220 | { | 3220 | { |
3221 | del_gendisk(scd_gendisk); | 3221 | del_gendisk(scd_gendisk); |
3222 | put_disk(scd_gendisk); | 3222 | put_disk(scd_gendisk); |
diff --git a/drivers/cdrom/mcdx.c b/drivers/cdrom/mcdx.c index ccde7ab491d4..07bbd24e3c18 100644 --- a/drivers/cdrom/mcdx.c +++ b/drivers/cdrom/mcdx.c | |||
@@ -107,20 +107,20 @@ static const char *mcdx_c_version | |||
107 | The _direct_ size is the number of sectors we're allowed to skip | 107 | The _direct_ size is the number of sectors we're allowed to skip |
108 | directly (performing a read instead of requesting the new sector | 108 | directly (performing a read instead of requesting the new sector |
109 | needed */ | 109 | needed */ |
110 | const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */ | 110 | static const int REQUEST_SIZE = 800; /* should be less then 255 * 4 */ |
111 | const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */ | 111 | static const int DIRECT_SIZE = 400; /* should be less then REQUEST_SIZE */ |
112 | 112 | ||
113 | enum drivemodes { TOC, DATA, RAW, COOKED }; | 113 | enum drivemodes { TOC, DATA, RAW, COOKED }; |
114 | enum datamodes { MODE0, MODE1, MODE2 }; | 114 | enum datamodes { MODE0, MODE1, MODE2 }; |
115 | enum resetmodes { SOFT, HARD }; | 115 | enum resetmodes { SOFT, HARD }; |
116 | 116 | ||
117 | const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */ | 117 | static const int SINGLE = 0x01; /* single speed drive (FX001S, LU) */ |
118 | const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */ | 118 | static const int DOUBLE = 0x02; /* double speed drive (FX001D, ..? */ |
119 | const int DOOR = 0x04; /* door locking capability */ | 119 | static const int DOOR = 0x04; /* door locking capability */ |
120 | const int MULTI = 0x08; /* multi session capability */ | 120 | static const int MULTI = 0x08; /* multi session capability */ |
121 | 121 | ||
122 | const unsigned char READ1X = 0xc0; | 122 | static const unsigned char READ1X = 0xc0; |
123 | const unsigned char READ2X = 0xc1; | 123 | static const unsigned char READ2X = 0xc1; |
124 | 124 | ||
125 | 125 | ||
126 | /* DECLARATIONS ****************************************************/ | 126 | /* DECLARATIONS ****************************************************/ |
@@ -210,9 +210,7 @@ struct s_drive_stuff { | |||
210 | repeated here to show what's going on. And to sense, if they're | 210 | repeated here to show what's going on. And to sense, if they're |
211 | changed elsewhere. */ | 211 | changed elsewhere. */ |
212 | 212 | ||
213 | /* declared in blk.h */ | 213 | static int mcdx_init(void); |
214 | int mcdx_init(void); | ||
215 | void do_mcdx_request(request_queue_t * q); | ||
216 | 214 | ||
217 | static int mcdx_block_open(struct inode *inode, struct file *file) | 215 | static int mcdx_block_open(struct inode *inode, struct file *file) |
218 | { | 216 | { |
@@ -569,7 +567,7 @@ static int mcdx_audio_ioctl(struct cdrom_device_info *cdi, | |||
569 | } | 567 | } |
570 | } | 568 | } |
571 | 569 | ||
572 | void do_mcdx_request(request_queue_t * q) | 570 | static void do_mcdx_request(request_queue_t * q) |
573 | { | 571 | { |
574 | struct s_drive_stuff *stuffp; | 572 | struct s_drive_stuff *stuffp; |
575 | struct request *req; | 573 | struct request *req; |
@@ -1028,7 +1026,7 @@ int __mcdx_init(void) | |||
1028 | return 0; | 1026 | return 0; |
1029 | } | 1027 | } |
1030 | 1028 | ||
1031 | void __exit mcdx_exit(void) | 1029 | static void __exit mcdx_exit(void) |
1032 | { | 1030 | { |
1033 | int i; | 1031 | int i; |
1034 | 1032 | ||
@@ -1075,7 +1073,7 @@ module_exit(mcdx_exit); | |||
1075 | 1073 | ||
1076 | /* Support functions ************************************************/ | 1074 | /* Support functions ************************************************/ |
1077 | 1075 | ||
1078 | int __init mcdx_init_drive(int drive) | 1076 | static int __init mcdx_init_drive(int drive) |
1079 | { | 1077 | { |
1080 | struct s_version version; | 1078 | struct s_version version; |
1081 | struct gendisk *disk; | 1079 | struct gendisk *disk; |
@@ -1261,7 +1259,7 @@ int __init mcdx_init_drive(int drive) | |||
1261 | return 0; | 1259 | return 0; |
1262 | } | 1260 | } |
1263 | 1261 | ||
1264 | int __init mcdx_init(void) | 1262 | static int __init mcdx_init(void) |
1265 | { | 1263 | { |
1266 | int drive; | 1264 | int drive; |
1267 | xwarn("Version 2.14(hs) \n"); | 1265 | xwarn("Version 2.14(hs) \n"); |
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c index fc2c433f6a29..452d34675159 100644 --- a/drivers/cdrom/sbpcd.c +++ b/drivers/cdrom/sbpcd.c | |||
@@ -5895,7 +5895,7 @@ int __init sbpcd_init(void) | |||
5895 | } | 5895 | } |
5896 | /*==========================================================================*/ | 5896 | /*==========================================================================*/ |
5897 | #ifdef MODULE | 5897 | #ifdef MODULE |
5898 | void sbpcd_exit(void) | 5898 | static void sbpcd_exit(void) |
5899 | { | 5899 | { |
5900 | int j; | 5900 | int j; |
5901 | 5901 | ||
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index 49d67f5384a2..4bb9af736fba 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/ipmi.h> | 44 | #include <linux/ipmi.h> |
45 | #include <asm/semaphore.h> | 45 | #include <asm/semaphore.h> |
46 | #include <linux/init.h> | 46 | #include <linux/init.h> |
47 | #include <linux/device.h> | ||
47 | 48 | ||
48 | #define IPMI_DEVINTF_VERSION "v33" | 49 | #define IPMI_DEVINTF_VERSION "v33" |
49 | 50 | ||
@@ -519,15 +520,21 @@ MODULE_PARM_DESC(ipmi_major, "Sets the major number of the IPMI device. By" | |||
519 | " interface. Other values will set the major device number" | 520 | " interface. Other values will set the major device number" |
520 | " to that value."); | 521 | " to that value."); |
521 | 522 | ||
523 | static struct class *ipmi_class; | ||
524 | |||
522 | static void ipmi_new_smi(int if_num) | 525 | static void ipmi_new_smi(int if_num) |
523 | { | 526 | { |
524 | devfs_mk_cdev(MKDEV(ipmi_major, if_num), | 527 | dev_t dev = MKDEV(ipmi_major, if_num); |
525 | S_IFCHR | S_IRUSR | S_IWUSR, | 528 | |
529 | devfs_mk_cdev(dev, S_IFCHR | S_IRUSR | S_IWUSR, | ||
526 | "ipmidev/%d", if_num); | 530 | "ipmidev/%d", if_num); |
531 | |||
532 | class_simple_device_add(ipmi_class, dev, NULL, "ipmi%d", if_num); | ||
527 | } | 533 | } |
528 | 534 | ||
529 | static void ipmi_smi_gone(int if_num) | 535 | static void ipmi_smi_gone(int if_num) |
530 | { | 536 | { |
537 | class_simple_device_remove(ipmi_class, MKDEV(ipmi_major, if_num)); | ||
531 | devfs_remove("ipmidev/%d", if_num); | 538 | devfs_remove("ipmidev/%d", if_num); |
532 | } | 539 | } |
533 | 540 | ||
@@ -548,8 +555,15 @@ static __init int init_ipmi_devintf(void) | |||
548 | printk(KERN_INFO "ipmi device interface version " | 555 | printk(KERN_INFO "ipmi device interface version " |
549 | IPMI_DEVINTF_VERSION "\n"); | 556 | IPMI_DEVINTF_VERSION "\n"); |
550 | 557 | ||
558 | ipmi_class = class_simple_create(THIS_MODULE, "ipmi"); | ||
559 | if (IS_ERR(ipmi_class)) { | ||
560 | printk(KERN_ERR "ipmi: can't register device class\n"); | ||
561 | return PTR_ERR(ipmi_class); | ||
562 | } | ||
563 | |||
551 | rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops); | 564 | rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops); |
552 | if (rv < 0) { | 565 | if (rv < 0) { |
566 | class_simple_destroy(ipmi_class); | ||
553 | printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major); | 567 | printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major); |
554 | return rv; | 568 | return rv; |
555 | } | 569 | } |
@@ -563,6 +577,7 @@ static __init int init_ipmi_devintf(void) | |||
563 | rv = ipmi_smi_watcher_register(&smi_watcher); | 577 | rv = ipmi_smi_watcher_register(&smi_watcher); |
564 | if (rv) { | 578 | if (rv) { |
565 | unregister_chrdev(ipmi_major, DEVICE_NAME); | 579 | unregister_chrdev(ipmi_major, DEVICE_NAME); |
580 | class_simple_destroy(ipmi_class); | ||
566 | printk(KERN_WARNING "ipmi: can't register smi watcher\n"); | 581 | printk(KERN_WARNING "ipmi: can't register smi watcher\n"); |
567 | return rv; | 582 | return rv; |
568 | } | 583 | } |
@@ -573,6 +588,7 @@ module_init(init_ipmi_devintf); | |||
573 | 588 | ||
574 | static __exit void cleanup_ipmi(void) | 589 | static __exit void cleanup_ipmi(void) |
575 | { | 590 | { |
591 | class_simple_destroy(ipmi_class); | ||
576 | ipmi_smi_watcher_unregister(&smi_watcher); | 592 | ipmi_smi_watcher_unregister(&smi_watcher); |
577 | devfs_remove(DEVICE_NAME); | 593 | devfs_remove(DEVICE_NAME); |
578 | unregister_chrdev(ipmi_major, DEVICE_NAME); | 594 | unregister_chrdev(ipmi_major, DEVICE_NAME); |
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 3ce51c6a1b18..7b19e02f112f 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -1026,7 +1026,8 @@ static void kbd_rawcode(unsigned char data) | |||
1026 | put_queue(vc, data); | 1026 | put_queue(vc, data); |
1027 | } | 1027 | } |
1028 | 1028 | ||
1029 | void kbd_keycode(unsigned int keycode, int down, int hw_raw, struct pt_regs *regs) | 1029 | static void kbd_keycode(unsigned int keycode, int down, |
1030 | int hw_raw, struct pt_regs *regs) | ||
1030 | { | 1031 | { |
1031 | struct vc_data *vc = vc_cons[fg_console].d; | 1032 | struct vc_data *vc = vc_cons[fg_console].d; |
1032 | unsigned short keysym, *key_map; | 1033 | unsigned short keysym, *key_map; |
diff --git a/drivers/char/raw.c b/drivers/char/raw.c index a2e33ec79615..ca5f42bcaad9 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c | |||
@@ -122,7 +122,7 @@ raw_ioctl(struct inode *inode, struct file *filp, | |||
122 | { | 122 | { |
123 | struct block_device *bdev = filp->private_data; | 123 | struct block_device *bdev = filp->private_data; |
124 | 124 | ||
125 | return ioctl_by_bdev(bdev, command, arg); | 125 | return blkdev_ioctl(bdev->bd_inode, NULL, command, arg); |
126 | } | 126 | } |
127 | 127 | ||
128 | static void bind_device(struct raw_config_request *rq) | 128 | static void bind_device(struct raw_config_request *rq) |
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 06e5a3f1836d..26e5e19ed854 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -185,7 +185,7 @@ char *tty_name(struct tty_struct *tty, char *buf) | |||
185 | 185 | ||
186 | EXPORT_SYMBOL(tty_name); | 186 | EXPORT_SYMBOL(tty_name); |
187 | 187 | ||
188 | inline int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, | 188 | int tty_paranoia_check(struct tty_struct *tty, struct inode *inode, |
189 | const char *routine) | 189 | const char *routine) |
190 | { | 190 | { |
191 | #ifdef TTY_PARANOIA_CHECK | 191 | #ifdef TTY_PARANOIA_CHECK |
diff --git a/drivers/char/watchdog/i8xx_tco.c b/drivers/char/watchdog/i8xx_tco.c index c337978dc966..b14d642439ed 100644 --- a/drivers/char/watchdog/i8xx_tco.c +++ b/drivers/char/watchdog/i8xx_tco.c | |||
@@ -382,6 +382,7 @@ static struct pci_device_id i8xx_tco_pci_tbl[] = { | |||
382 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, }, | 382 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_2, PCI_ANY_ID, PCI_ANY_ID, }, |
383 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, }, | 383 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_0, PCI_ANY_ID, PCI_ANY_ID, }, |
384 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, }, | 384 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH7_1, PCI_ANY_ID, PCI_ANY_ID, }, |
385 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ESB_1, PCI_ANY_ID, PCI_ANY_ID, }, | ||
385 | { 0, }, /* End of list */ | 386 | { 0, }, /* End of list */ |
386 | }; | 387 | }; |
387 | MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl); | 388 | MODULE_DEVICE_TABLE (pci, i8xx_tco_pci_tbl); |
diff --git a/drivers/ide/ide-proc.c b/drivers/ide/ide-proc.c index bdff5ac58053..4b1e43b4118b 100644 --- a/drivers/ide/ide-proc.c +++ b/drivers/ide/ide-proc.c | |||
@@ -516,6 +516,6 @@ void proc_ide_create(void) | |||
516 | 516 | ||
517 | void proc_ide_destroy(void) | 517 | void proc_ide_destroy(void) |
518 | { | 518 | { |
519 | remove_proc_entry("ide/drivers", proc_ide_root); | 519 | remove_proc_entry("drivers", proc_ide_root); |
520 | remove_proc_entry("ide", NULL); | 520 | remove_proc_entry("ide", NULL); |
521 | } | 521 | } |
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c index 9d70ba5ea59b..16b3e2d8bfb1 100644 --- a/drivers/ide/pci/sis5513.c +++ b/drivers/ide/pci/sis5513.c | |||
@@ -726,7 +726,7 @@ static int sis5513_config_xfer_rate (ide_drive_t *drive) | |||
726 | */ | 726 | */ |
727 | 727 | ||
728 | /* Chip detection and general config */ | 728 | /* Chip detection and general config */ |
729 | static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char *name) | 729 | static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) |
730 | { | 730 | { |
731 | struct pci_dev *host; | 731 | struct pci_dev *host; |
732 | int i = 0; | 732 | int i = 0; |
@@ -879,7 +879,7 @@ static unsigned int __init init_chipset_sis5513 (struct pci_dev *dev, const char | |||
879 | return 0; | 879 | return 0; |
880 | } | 880 | } |
881 | 881 | ||
882 | static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif) | 882 | static unsigned int __devinit ata66_sis5513 (ide_hwif_t *hwif) |
883 | { | 883 | { |
884 | u8 ata66 = 0; | 884 | u8 ata66 = 0; |
885 | 885 | ||
@@ -897,7 +897,7 @@ static unsigned int __init ata66_sis5513 (ide_hwif_t *hwif) | |||
897 | return ata66; | 897 | return ata66; |
898 | } | 898 | } |
899 | 899 | ||
900 | static void __init init_hwif_sis5513 (ide_hwif_t *hwif) | 900 | static void __devinit init_hwif_sis5513 (ide_hwif_t *hwif) |
901 | { | 901 | { |
902 | hwif->autodma = 0; | 902 | hwif->autodma = 0; |
903 | 903 | ||
diff --git a/drivers/ieee1394/Kconfig b/drivers/ieee1394/Kconfig index 78b201fb5e8a..7d58af1ae306 100644 --- a/drivers/ieee1394/Kconfig +++ b/drivers/ieee1394/Kconfig | |||
@@ -84,11 +84,6 @@ config IEEE1394_PCILYNX | |||
84 | To compile this driver as a module, say M here: the | 84 | To compile this driver as a module, say M here: the |
85 | module will be called pcilynx. | 85 | module will be called pcilynx. |
86 | 86 | ||
87 | # Non-maintained pcilynx options | ||
88 | # if [ "$CONFIG_IEEE1394_PCILYNX" != "n" ]; then | ||
89 | # bool ' Use PCILynx local RAM' CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
90 | # bool ' Support for non-IEEE1394 local ports' CONFIG_IEEE1394_PCILYNX_PORTS | ||
91 | # fi | ||
92 | config IEEE1394_OHCI1394 | 87 | config IEEE1394_OHCI1394 |
93 | tristate "OHCI-1394 support" | 88 | tristate "OHCI-1394 support" |
94 | depends on PCI && IEEE1394 | 89 | depends on PCI && IEEE1394 |
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c index 1c5845f7e4ab..a294e45c77cd 100644 --- a/drivers/ieee1394/ieee1394_core.c +++ b/drivers/ieee1394/ieee1394_core.c | |||
@@ -520,7 +520,7 @@ int hpsb_send_packet(struct hpsb_packet *packet) | |||
520 | 520 | ||
521 | if (!packet->no_waiter || packet->expect_response) { | 521 | if (!packet->no_waiter || packet->expect_response) { |
522 | atomic_inc(&packet->refcnt); | 522 | atomic_inc(&packet->refcnt); |
523 | packet->sendtime = jiffies; | 523 | packet->sendtime = jiffies + 10 * HZ; |
524 | skb_queue_tail(&host->pending_packet_queue, packet->skb); | 524 | skb_queue_tail(&host->pending_packet_queue, packet->skb); |
525 | } | 525 | } |
526 | 526 | ||
@@ -1248,7 +1248,6 @@ EXPORT_SYMBOL(hpsb_make_phypacket); | |||
1248 | EXPORT_SYMBOL(hpsb_make_isopacket); | 1248 | EXPORT_SYMBOL(hpsb_make_isopacket); |
1249 | EXPORT_SYMBOL(hpsb_read); | 1249 | EXPORT_SYMBOL(hpsb_read); |
1250 | EXPORT_SYMBOL(hpsb_write); | 1250 | EXPORT_SYMBOL(hpsb_write); |
1251 | EXPORT_SYMBOL(hpsb_lock); | ||
1252 | EXPORT_SYMBOL(hpsb_packet_success); | 1251 | EXPORT_SYMBOL(hpsb_packet_success); |
1253 | 1252 | ||
1254 | /** highlevel.c **/ | 1253 | /** highlevel.c **/ |
diff --git a/drivers/ieee1394/ieee1394_transactions.c b/drivers/ieee1394/ieee1394_transactions.c index 09908b9564d8..0aa876360f9b 100644 --- a/drivers/ieee1394/ieee1394_transactions.c +++ b/drivers/ieee1394/ieee1394_transactions.c | |||
@@ -535,6 +535,7 @@ hpsb_write_fail: | |||
535 | return retval; | 535 | return retval; |
536 | } | 536 | } |
537 | 537 | ||
538 | #if 0 | ||
538 | 539 | ||
539 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | 540 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, |
540 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg) | 541 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg) |
@@ -599,3 +600,5 @@ int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, | |||
599 | 600 | ||
600 | return retval; | 601 | return retval; |
601 | } | 602 | } |
603 | |||
604 | #endif /* 0 */ | ||
diff --git a/drivers/ieee1394/ieee1394_transactions.h b/drivers/ieee1394/ieee1394_transactions.h index 526a43ceb496..45ba784fe6da 100644 --- a/drivers/ieee1394/ieee1394_transactions.h +++ b/drivers/ieee1394/ieee1394_transactions.h | |||
@@ -53,12 +53,5 @@ int hpsb_read(struct hpsb_host *host, nodeid_t node, unsigned int generation, | |||
53 | u64 addr, quadlet_t *buffer, size_t length); | 53 | u64 addr, quadlet_t *buffer, size_t length); |
54 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, | 54 | int hpsb_write(struct hpsb_host *host, nodeid_t node, unsigned int generation, |
55 | u64 addr, quadlet_t *buffer, size_t length); | 55 | u64 addr, quadlet_t *buffer, size_t length); |
56 | int hpsb_lock(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
57 | u64 addr, int extcode, quadlet_t *data, quadlet_t arg); | ||
58 | int hpsb_lock64(struct hpsb_host *host, nodeid_t node, unsigned int generation, | ||
59 | u64 addr, int extcode, octlet_t *data, octlet_t arg); | ||
60 | int hpsb_send_gasp(struct hpsb_host *host, int channel, unsigned int generation, | ||
61 | quadlet_t *buffer, size_t length, u32 specifier_id, | ||
62 | unsigned int version); | ||
63 | 56 | ||
64 | #endif /* _IEEE1394_TRANSACTIONS_H */ | 57 | #endif /* _IEEE1394_TRANSACTIONS_H */ |
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c index a1e30a66297b..83e66ed97ab5 100644 --- a/drivers/ieee1394/nodemgr.c +++ b/drivers/ieee1394/nodemgr.c | |||
@@ -1005,8 +1005,7 @@ static struct unit_directory *nodemgr_process_unit_directory | |||
1005 | return ud; | 1005 | return ud; |
1006 | 1006 | ||
1007 | unit_directory_error: | 1007 | unit_directory_error: |
1008 | if (ud != NULL) | 1008 | kfree(ud); |
1009 | kfree(ud); | ||
1010 | return NULL; | 1009 | return NULL; |
1011 | } | 1010 | } |
1012 | 1011 | ||
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index 6cb0b586c297..36e25ac823dc 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -2931,7 +2931,7 @@ static void free_dma_rcv_ctx(struct dma_rcv_ctx *d) | |||
2931 | kfree(d->prg_cpu); | 2931 | kfree(d->prg_cpu); |
2932 | kfree(d->prg_bus); | 2932 | kfree(d->prg_bus); |
2933 | } | 2933 | } |
2934 | if (d->spb) kfree(d->spb); | 2934 | kfree(d->spb); |
2935 | 2935 | ||
2936 | /* Mark this context as freed. */ | 2936 | /* Mark this context as freed. */ |
2937 | d->ohci = NULL; | 2937 | d->ohci = NULL; |
diff --git a/drivers/ieee1394/ohci1394.h b/drivers/ieee1394/ohci1394.h index d1758d409610..cc66c1cae250 100644 --- a/drivers/ieee1394/ohci1394.h +++ b/drivers/ieee1394/ohci1394.h | |||
@@ -236,6 +236,9 @@ struct ti_ohci { | |||
236 | 236 | ||
237 | static inline int cross_bound(unsigned long addr, unsigned int size) | 237 | static inline int cross_bound(unsigned long addr, unsigned int size) |
238 | { | 238 | { |
239 | if (size == 0) | ||
240 | return 0; | ||
241 | |||
239 | if (size > PAGE_SIZE) | 242 | if (size > PAGE_SIZE) |
240 | return 1; | 243 | return 1; |
241 | 244 | ||
diff --git a/drivers/ieee1394/pcilynx.c b/drivers/ieee1394/pcilynx.c index a261d2b0e5ac..bdb3a85cafa6 100644 --- a/drivers/ieee1394/pcilynx.c +++ b/drivers/ieee1394/pcilynx.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/fs.h> | 43 | #include <linux/fs.h> |
44 | #include <linux/poll.h> | 44 | #include <linux/poll.h> |
45 | #include <linux/kdev_t.h> | 45 | #include <linux/kdev_t.h> |
46 | #include <linux/dma-mapping.h> | ||
46 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
47 | #include <asm/atomic.h> | 48 | #include <asm/atomic.h> |
48 | #include <asm/io.h> | 49 | #include <asm/io.h> |
@@ -834,327 +835,6 @@ static int lynx_devctl(struct hpsb_host *host, enum devctl_cmd cmd, int arg) | |||
834 | * IEEE-1394 functionality section END * | 835 | * IEEE-1394 functionality section END * |
835 | ***************************************/ | 836 | ***************************************/ |
836 | 837 | ||
837 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
838 | /* VFS functions for local bus / aux device access. Access to those | ||
839 | * is implemented as a character device instead of block devices | ||
840 | * because buffers are not wanted for this. Therefore llseek (from | ||
841 | * VFS) can be used for these char devices with obvious effects. | ||
842 | */ | ||
843 | static int mem_open(struct inode*, struct file*); | ||
844 | static int mem_release(struct inode*, struct file*); | ||
845 | static unsigned int aux_poll(struct file*, struct poll_table_struct*); | ||
846 | static loff_t mem_llseek(struct file*, loff_t, int); | ||
847 | static ssize_t mem_read (struct file*, char*, size_t, loff_t*); | ||
848 | static ssize_t mem_write(struct file*, const char*, size_t, loff_t*); | ||
849 | |||
850 | |||
851 | static struct file_operations aux_ops = { | ||
852 | .owner = THIS_MODULE, | ||
853 | .read = mem_read, | ||
854 | .write = mem_write, | ||
855 | .poll = aux_poll, | ||
856 | .llseek = mem_llseek, | ||
857 | .open = mem_open, | ||
858 | .release = mem_release, | ||
859 | }; | ||
860 | |||
861 | |||
862 | static void aux_setup_pcls(struct ti_lynx *lynx) | ||
863 | { | ||
864 | struct ti_pcl pcl; | ||
865 | |||
866 | pcl.next = PCL_NEXT_INVALID; | ||
867 | pcl.user_data = pcl_bus(lynx, lynx->dmem_pcl); | ||
868 | put_pcl(lynx, lynx->dmem_pcl, &pcl); | ||
869 | } | ||
870 | |||
871 | static int mem_open(struct inode *inode, struct file *file) | ||
872 | { | ||
873 | int cid = iminor(inode); | ||
874 | enum { t_rom, t_aux, t_ram } type; | ||
875 | struct memdata *md; | ||
876 | |||
877 | if (cid < PCILYNX_MINOR_AUX_START) { | ||
878 | /* just for completeness */ | ||
879 | return -ENXIO; | ||
880 | } else if (cid < PCILYNX_MINOR_ROM_START) { | ||
881 | cid -= PCILYNX_MINOR_AUX_START; | ||
882 | if (cid >= num_of_cards || !cards[cid].aux_port) | ||
883 | return -ENXIO; | ||
884 | type = t_aux; | ||
885 | } else if (cid < PCILYNX_MINOR_RAM_START) { | ||
886 | cid -= PCILYNX_MINOR_ROM_START; | ||
887 | if (cid >= num_of_cards || !cards[cid].local_rom) | ||
888 | return -ENXIO; | ||
889 | type = t_rom; | ||
890 | } else { | ||
891 | /* WARNING: Know what you are doing when opening RAM. | ||
892 | * It is currently used inside the driver! */ | ||
893 | cid -= PCILYNX_MINOR_RAM_START; | ||
894 | if (cid >= num_of_cards || !cards[cid].local_ram) | ||
895 | return -ENXIO; | ||
896 | type = t_ram; | ||
897 | } | ||
898 | |||
899 | md = (struct memdata *)kmalloc(sizeof(struct memdata), SLAB_KERNEL); | ||
900 | if (md == NULL) | ||
901 | return -ENOMEM; | ||
902 | |||
903 | md->lynx = &cards[cid]; | ||
904 | md->cid = cid; | ||
905 | |||
906 | switch (type) { | ||
907 | case t_rom: | ||
908 | md->type = rom; | ||
909 | break; | ||
910 | case t_ram: | ||
911 | md->type = ram; | ||
912 | break; | ||
913 | case t_aux: | ||
914 | atomic_set(&md->aux_intr_last_seen, | ||
915 | atomic_read(&cards[cid].aux_intr_seen)); | ||
916 | md->type = aux; | ||
917 | break; | ||
918 | } | ||
919 | |||
920 | file->private_data = md; | ||
921 | |||
922 | return 0; | ||
923 | } | ||
924 | |||
925 | static int mem_release(struct inode *inode, struct file *file) | ||
926 | { | ||
927 | kfree(file->private_data); | ||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | static unsigned int aux_poll(struct file *file, poll_table *pt) | ||
932 | { | ||
933 | struct memdata *md = (struct memdata *)file->private_data; | ||
934 | int cid = md->cid; | ||
935 | unsigned int mask; | ||
936 | |||
937 | /* reading and writing is always allowed */ | ||
938 | mask = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM; | ||
939 | |||
940 | if (md->type == aux) { | ||
941 | poll_wait(file, &cards[cid].aux_intr_wait, pt); | ||
942 | |||
943 | if (atomic_read(&md->aux_intr_last_seen) | ||
944 | != atomic_read(&cards[cid].aux_intr_seen)) { | ||
945 | mask |= POLLPRI; | ||
946 | atomic_inc(&md->aux_intr_last_seen); | ||
947 | } | ||
948 | } | ||
949 | |||
950 | return mask; | ||
951 | } | ||
952 | |||
953 | loff_t mem_llseek(struct file *file, loff_t offs, int orig) | ||
954 | { | ||
955 | loff_t newoffs; | ||
956 | |||
957 | switch (orig) { | ||
958 | case 0: | ||
959 | newoffs = offs; | ||
960 | break; | ||
961 | case 1: | ||
962 | newoffs = offs + file->f_pos; | ||
963 | break; | ||
964 | case 2: | ||
965 | newoffs = PCILYNX_MAX_MEMORY + 1 + offs; | ||
966 | break; | ||
967 | default: | ||
968 | return -EINVAL; | ||
969 | } | ||
970 | |||
971 | if (newoffs < 0 || newoffs > PCILYNX_MAX_MEMORY + 1) return -EINVAL; | ||
972 | |||
973 | file->f_pos = newoffs; | ||
974 | return newoffs; | ||
975 | } | ||
976 | |||
977 | /* | ||
978 | * do not DMA if count is too small because this will have a serious impact | ||
979 | * on performance - the value 2400 was found by experiment and may not work | ||
980 | * everywhere as good as here - use mem_mindma option for modules to change | ||
981 | */ | ||
982 | static short mem_mindma = 2400; | ||
983 | module_param(mem_mindma, short, 0444); | ||
984 | MODULE_PARM_DESC(mem_mindma, "Minimum amount of data required to use DMA"); | ||
985 | |||
986 | static ssize_t mem_dmaread(struct memdata *md, u32 physbuf, ssize_t count, | ||
987 | int offset) | ||
988 | { | ||
989 | pcltmp_t pcltmp; | ||
990 | struct ti_pcl *pcl; | ||
991 | size_t retval; | ||
992 | int i; | ||
993 | DECLARE_WAITQUEUE(wait, current); | ||
994 | |||
995 | count &= ~3; | ||
996 | count = min(count, 53196); | ||
997 | retval = count; | ||
998 | |||
999 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1000 | & DMA_CHAN_CTRL_BUSY) { | ||
1001 | PRINT(KERN_WARNING, md->lynx->id, "DMA ALREADY ACTIVE!"); | ||
1002 | } | ||
1003 | |||
1004 | reg_write(md->lynx, LBUS_ADDR, md->type | offset); | ||
1005 | |||
1006 | pcl = edit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
1007 | pcl->buffer[0].control = PCL_CMD_LBUS_TO_PCI | min(count, 4092); | ||
1008 | pcl->buffer[0].pointer = physbuf; | ||
1009 | count -= 4092; | ||
1010 | |||
1011 | i = 0; | ||
1012 | while (count > 0) { | ||
1013 | i++; | ||
1014 | pcl->buffer[i].control = min(count, 4092); | ||
1015 | pcl->buffer[i].pointer = physbuf + i * 4092; | ||
1016 | count -= 4092; | ||
1017 | } | ||
1018 | pcl->buffer[i].control |= PCL_LAST_BUFF; | ||
1019 | commit_pcl(md->lynx, md->lynx->dmem_pcl, &pcltmp); | ||
1020 | |||
1021 | set_current_state(TASK_INTERRUPTIBLE); | ||
1022 | add_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
1023 | run_sub_pcl(md->lynx, md->lynx->dmem_pcl, 2, CHANNEL_LOCALBUS); | ||
1024 | |||
1025 | schedule(); | ||
1026 | while (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1027 | & DMA_CHAN_CTRL_BUSY) { | ||
1028 | if (signal_pending(current)) { | ||
1029 | retval = -EINTR; | ||
1030 | break; | ||
1031 | } | ||
1032 | schedule(); | ||
1033 | } | ||
1034 | |||
1035 | reg_write(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS), 0); | ||
1036 | remove_wait_queue(&md->lynx->mem_dma_intr_wait, &wait); | ||
1037 | |||
1038 | if (reg_read(md->lynx, DMA_CHAN_CTRL(CHANNEL_LOCALBUS)) | ||
1039 | & DMA_CHAN_CTRL_BUSY) { | ||
1040 | PRINT(KERN_ERR, md->lynx->id, "DMA STILL ACTIVE!"); | ||
1041 | } | ||
1042 | |||
1043 | return retval; | ||
1044 | } | ||
1045 | |||
1046 | static ssize_t mem_read(struct file *file, char *buffer, size_t count, | ||
1047 | loff_t *offset) | ||
1048 | { | ||
1049 | struct memdata *md = (struct memdata *)file->private_data; | ||
1050 | ssize_t bcount; | ||
1051 | size_t alignfix; | ||
1052 | loff_t off = *offset; /* avoid useless 64bit-arithmetic */ | ||
1053 | ssize_t retval; | ||
1054 | void *membase; | ||
1055 | |||
1056 | if ((off + count) > PCILYNX_MAX_MEMORY+1) { | ||
1057 | count = PCILYNX_MAX_MEMORY+1 - off; | ||
1058 | } | ||
1059 | if (count == 0 || off > PCILYNX_MAX_MEMORY) { | ||
1060 | return -ENOSPC; | ||
1061 | } | ||
1062 | |||
1063 | switch (md->type) { | ||
1064 | case rom: | ||
1065 | membase = md->lynx->local_rom; | ||
1066 | break; | ||
1067 | case ram: | ||
1068 | membase = md->lynx->local_ram; | ||
1069 | break; | ||
1070 | case aux: | ||
1071 | membase = md->lynx->aux_port; | ||
1072 | break; | ||
1073 | default: | ||
1074 | panic("pcilynx%d: unsupported md->type %d in %s", | ||
1075 | md->lynx->id, md->type, __FUNCTION__); | ||
1076 | } | ||
1077 | |||
1078 | down(&md->lynx->mem_dma_mutex); | ||
1079 | |||
1080 | if (count < mem_mindma) { | ||
1081 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, count); | ||
1082 | goto out; | ||
1083 | } | ||
1084 | |||
1085 | bcount = count; | ||
1086 | alignfix = 4 - (off % 4); | ||
1087 | if (alignfix != 4) { | ||
1088 | if (bcount < alignfix) { | ||
1089 | alignfix = bcount; | ||
1090 | } | ||
1091 | memcpy_fromio(md->lynx->mem_dma_buffer, membase+off, | ||
1092 | alignfix); | ||
1093 | if (bcount == alignfix) { | ||
1094 | goto out; | ||
1095 | } | ||
1096 | bcount -= alignfix; | ||
1097 | off += alignfix; | ||
1098 | } | ||
1099 | |||
1100 | while (bcount >= 4) { | ||
1101 | retval = mem_dmaread(md, md->lynx->mem_dma_buffer_dma | ||
1102 | + count - bcount, bcount, off); | ||
1103 | if (retval < 0) return retval; | ||
1104 | |||
1105 | bcount -= retval; | ||
1106 | off += retval; | ||
1107 | } | ||
1108 | |||
1109 | if (bcount) { | ||
1110 | memcpy_fromio(md->lynx->mem_dma_buffer + count - bcount, | ||
1111 | membase+off, bcount); | ||
1112 | } | ||
1113 | |||
1114 | out: | ||
1115 | retval = copy_to_user(buffer, md->lynx->mem_dma_buffer, count); | ||
1116 | up(&md->lynx->mem_dma_mutex); | ||
1117 | |||
1118 | if (retval) return -EFAULT; | ||
1119 | *offset += count; | ||
1120 | return count; | ||
1121 | } | ||
1122 | |||
1123 | |||
1124 | static ssize_t mem_write(struct file *file, const char *buffer, size_t count, | ||
1125 | loff_t *offset) | ||
1126 | { | ||
1127 | struct memdata *md = (struct memdata *)file->private_data; | ||
1128 | |||
1129 | if (((*offset) + count) > PCILYNX_MAX_MEMORY+1) { | ||
1130 | count = PCILYNX_MAX_MEMORY+1 - *offset; | ||
1131 | } | ||
1132 | if (count == 0 || *offset > PCILYNX_MAX_MEMORY) { | ||
1133 | return -ENOSPC; | ||
1134 | } | ||
1135 | |||
1136 | /* FIXME: dereferencing pointers to PCI mem doesn't work everywhere */ | ||
1137 | switch (md->type) { | ||
1138 | case aux: | ||
1139 | if (copy_from_user(md->lynx->aux_port+(*offset), buffer, count)) | ||
1140 | return -EFAULT; | ||
1141 | break; | ||
1142 | case ram: | ||
1143 | if (copy_from_user(md->lynx->local_ram+(*offset), buffer, count)) | ||
1144 | return -EFAULT; | ||
1145 | break; | ||
1146 | case rom: | ||
1147 | /* the ROM may be writeable */ | ||
1148 | if (copy_from_user(md->lynx->local_rom+(*offset), buffer, count)) | ||
1149 | return -EFAULT; | ||
1150 | break; | ||
1151 | } | ||
1152 | |||
1153 | file->f_pos += count; | ||
1154 | return count; | ||
1155 | } | ||
1156 | #endif /* CONFIG_IEEE1394_PCILYNX_PORTS */ | ||
1157 | |||
1158 | 838 | ||
1159 | /******************************************************** | 839 | /******************************************************** |
1160 | * Global stuff (interrupt handler, init/shutdown code) * | 840 | * Global stuff (interrupt handler, init/shutdown code) * |
@@ -1181,18 +861,6 @@ static irqreturn_t lynx_irq_handler(int irq, void *dev_id, | |||
1181 | reg_write(lynx, LINK_INT_STATUS, linkint); | 861 | reg_write(lynx, LINK_INT_STATUS, linkint); |
1182 | reg_write(lynx, PCI_INT_STATUS, intmask); | 862 | reg_write(lynx, PCI_INT_STATUS, intmask); |
1183 | 863 | ||
1184 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1185 | if (intmask & PCI_INT_AUX_INT) { | ||
1186 | atomic_inc(&lynx->aux_intr_seen); | ||
1187 | wake_up_interruptible(&lynx->aux_intr_wait); | ||
1188 | } | ||
1189 | |||
1190 | if (intmask & PCI_INT_DMA_HLT(CHANNEL_LOCALBUS)) { | ||
1191 | wake_up_interruptible(&lynx->mem_dma_intr_wait); | ||
1192 | } | ||
1193 | #endif | ||
1194 | |||
1195 | |||
1196 | if (intmask & PCI_INT_1394) { | 864 | if (intmask & PCI_INT_1394) { |
1197 | if (linkint & LINK_INT_PHY_TIMEOUT) { | 865 | if (linkint & LINK_INT_PHY_TIMEOUT) { |
1198 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); | 866 | PRINT(KERN_INFO, lynx->id, "PHY timeout occurred"); |
@@ -1484,15 +1152,9 @@ static void remove_card(struct pci_dev *dev) | |||
1484 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, | 1152 | pci_free_consistent(lynx->dev, PAGE_SIZE, lynx->rcv_page, |
1485 | lynx->rcv_page_dma); | 1153 | lynx->rcv_page_dma); |
1486 | case have_aux_buf: | 1154 | case have_aux_buf: |
1487 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1488 | pci_free_consistent(lynx->dev, 65536, lynx->mem_dma_buffer, | ||
1489 | lynx->mem_dma_buffer_dma); | ||
1490 | #endif | ||
1491 | case have_pcl_mem: | 1155 | case have_pcl_mem: |
1492 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1493 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, | 1156 | pci_free_consistent(lynx->dev, LOCALRAM_SIZE, lynx->pcl_mem, |
1494 | lynx->pcl_mem_dma); | 1157 | lynx->pcl_mem_dma); |
1495 | #endif | ||
1496 | case clear: | 1158 | case clear: |
1497 | /* do nothing - already freed */ | 1159 | /* do nothing - already freed */ |
1498 | ; | 1160 | ; |
@@ -1524,7 +1186,7 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1524 | 1186 | ||
1525 | error = -ENXIO; | 1187 | error = -ENXIO; |
1526 | 1188 | ||
1527 | if (pci_set_dma_mask(dev, 0xffffffff)) | 1189 | if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) |
1528 | FAIL("DMA address limits not supported for PCILynx hardware"); | 1190 | FAIL("DMA address limits not supported for PCILynx hardware"); |
1529 | if (pci_enable_device(dev)) | 1191 | if (pci_enable_device(dev)) |
1530 | FAIL("failed to enable PCILynx hardware"); | 1192 | FAIL("failed to enable PCILynx hardware"); |
@@ -1546,7 +1208,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1546 | spin_lock_init(&lynx->lock); | 1208 | spin_lock_init(&lynx->lock); |
1547 | spin_lock_init(&lynx->phy_reg_lock); | 1209 | spin_lock_init(&lynx->phy_reg_lock); |
1548 | 1210 | ||
1549 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1550 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, | 1211 | lynx->pcl_mem = pci_alloc_consistent(dev, LOCALRAM_SIZE, |
1551 | &lynx->pcl_mem_dma); | 1212 | &lynx->pcl_mem_dma); |
1552 | 1213 | ||
@@ -1558,16 +1219,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1558 | } else { | 1219 | } else { |
1559 | FAIL("failed to allocate PCL memory area"); | 1220 | FAIL("failed to allocate PCL memory area"); |
1560 | } | 1221 | } |
1561 | #endif | ||
1562 | |||
1563 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1564 | lynx->mem_dma_buffer = pci_alloc_consistent(dev, 65536, | ||
1565 | &lynx->mem_dma_buffer_dma); | ||
1566 | if (lynx->mem_dma_buffer == NULL) { | ||
1567 | FAIL("failed to allocate DMA buffer for aux"); | ||
1568 | } | ||
1569 | lynx->state = have_aux_buf; | ||
1570 | #endif | ||
1571 | 1222 | ||
1572 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, | 1223 | lynx->rcv_page = pci_alloc_consistent(dev, PAGE_SIZE, |
1573 | &lynx->rcv_page_dma); | 1224 | &lynx->rcv_page_dma); |
@@ -1597,13 +1248,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1597 | FAIL("failed to remap registers - card not accessible"); | 1248 | FAIL("failed to remap registers - card not accessible"); |
1598 | } | 1249 | } |
1599 | 1250 | ||
1600 | #ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
1601 | if (lynx->local_ram == NULL) { | ||
1602 | FAIL("failed to remap local RAM which is required for " | ||
1603 | "operation"); | ||
1604 | } | ||
1605 | #endif | ||
1606 | |||
1607 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); | 1251 | reg_set_bits(lynx, MISC_CONTROL, MISC_CONTROL_SWRESET); |
1608 | /* Fix buggy cards with autoboot pin not tied low: */ | 1252 | /* Fix buggy cards with autoboot pin not tied low: */ |
1609 | reg_write(lynx, DMA0_CHAN_CTRL, 0); | 1253 | reg_write(lynx, DMA0_CHAN_CTRL, 0); |
@@ -1624,13 +1268,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1624 | 1268 | ||
1625 | /* alloc_pcl return values are not checked, it is expected that the | 1269 | /* alloc_pcl return values are not checked, it is expected that the |
1626 | * provided PCL space is sufficient for the initial allocations */ | 1270 | * provided PCL space is sufficient for the initial allocations */ |
1627 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1628 | if (lynx->aux_port != NULL) { | ||
1629 | lynx->dmem_pcl = alloc_pcl(lynx); | ||
1630 | aux_setup_pcls(lynx); | ||
1631 | sema_init(&lynx->mem_dma_mutex, 1); | ||
1632 | } | ||
1633 | #endif | ||
1634 | lynx->rcv_pcl = alloc_pcl(lynx); | 1271 | lynx->rcv_pcl = alloc_pcl(lynx); |
1635 | lynx->rcv_pcl_start = alloc_pcl(lynx); | 1272 | lynx->rcv_pcl_start = alloc_pcl(lynx); |
1636 | lynx->async.pcl = alloc_pcl(lynx); | 1273 | lynx->async.pcl = alloc_pcl(lynx); |
@@ -1647,12 +1284,6 @@ static int __devinit add_card(struct pci_dev *dev, | |||
1647 | 1284 | ||
1648 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); | 1285 | reg_write(lynx, PCI_INT_ENABLE, PCI_INT_DMA_ALL); |
1649 | 1286 | ||
1650 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1651 | reg_set_bits(lynx, PCI_INT_ENABLE, PCI_INT_AUX_INT); | ||
1652 | init_waitqueue_head(&lynx->mem_dma_intr_wait); | ||
1653 | init_waitqueue_head(&lynx->aux_intr_wait); | ||
1654 | #endif | ||
1655 | |||
1656 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, | 1287 | tasklet_init(&lynx->iso_rcv.tq, (void (*)(unsigned long))iso_rcv_bh, |
1657 | (unsigned long)lynx); | 1288 | (unsigned long)lynx); |
1658 | 1289 | ||
@@ -1944,37 +1575,18 @@ static int __init pcilynx_init(void) | |||
1944 | { | 1575 | { |
1945 | int ret; | 1576 | int ret; |
1946 | 1577 | ||
1947 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1948 | if (register_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME, &aux_ops)) { | ||
1949 | PRINT_G(KERN_ERR, "allocation of char major number %d failed", | ||
1950 | PCILYNX_MAJOR); | ||
1951 | return -EBUSY; | ||
1952 | } | ||
1953 | #endif | ||
1954 | |||
1955 | ret = pci_register_driver(&lynx_pci_driver); | 1578 | ret = pci_register_driver(&lynx_pci_driver); |
1956 | if (ret < 0) { | 1579 | if (ret < 0) { |
1957 | PRINT_G(KERN_ERR, "PCI module init failed"); | 1580 | PRINT_G(KERN_ERR, "PCI module init failed"); |
1958 | goto free_char_dev; | 1581 | return ret; |
1959 | } | 1582 | } |
1960 | 1583 | ||
1961 | return 0; | 1584 | return 0; |
1962 | |||
1963 | free_char_dev: | ||
1964 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1965 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
1966 | #endif | ||
1967 | |||
1968 | return ret; | ||
1969 | } | 1585 | } |
1970 | 1586 | ||
1971 | static void __exit pcilynx_cleanup(void) | 1587 | static void __exit pcilynx_cleanup(void) |
1972 | { | 1588 | { |
1973 | pci_unregister_driver(&lynx_pci_driver); | 1589 | pci_unregister_driver(&lynx_pci_driver); |
1974 | |||
1975 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
1976 | unregister_chrdev(PCILYNX_MAJOR, PCILYNX_DRIVER_NAME); | ||
1977 | #endif | ||
1978 | } | 1590 | } |
1979 | 1591 | ||
1980 | 1592 | ||
diff --git a/drivers/ieee1394/pcilynx.h b/drivers/ieee1394/pcilynx.h index 644ec55d3d46..d631aa8383ad 100644 --- a/drivers/ieee1394/pcilynx.h +++ b/drivers/ieee1394/pcilynx.h | |||
@@ -55,16 +55,6 @@ struct ti_lynx { | |||
55 | void __iomem *aux_port; | 55 | void __iomem *aux_port; |
56 | quadlet_t bus_info_block[5]; | 56 | quadlet_t bus_info_block[5]; |
57 | 57 | ||
58 | #ifdef CONFIG_IEEE1394_PCILYNX_PORTS | ||
59 | atomic_t aux_intr_seen; | ||
60 | wait_queue_head_t aux_intr_wait; | ||
61 | |||
62 | void *mem_dma_buffer; | ||
63 | dma_addr_t mem_dma_buffer_dma; | ||
64 | struct semaphore mem_dma_mutex; | ||
65 | wait_queue_head_t mem_dma_intr_wait; | ||
66 | #endif | ||
67 | |||
68 | /* | 58 | /* |
69 | * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for | 59 | * use local RAM of LOCALRAM_SIZE bytes for PCLs, which allows for |
70 | * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); | 60 | * LOCALRAM_SIZE * 8 PCLs (each sized 128 bytes); |
@@ -72,11 +62,9 @@ struct ti_lynx { | |||
72 | */ | 62 | */ |
73 | u8 pcl_bmap[LOCALRAM_SIZE / 1024]; | 63 | u8 pcl_bmap[LOCALRAM_SIZE / 1024]; |
74 | 64 | ||
75 | #ifndef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
76 | /* point to PCLs memory area if needed */ | 65 | /* point to PCLs memory area if needed */ |
77 | void *pcl_mem; | 66 | void *pcl_mem; |
78 | dma_addr_t pcl_mem_dma; | 67 | dma_addr_t pcl_mem_dma; |
79 | #endif | ||
80 | 68 | ||
81 | /* PCLs for local mem / aux transfers */ | 69 | /* PCLs for local mem / aux transfers */ |
82 | pcl_t dmem_pcl; | 70 | pcl_t dmem_pcl; |
@@ -378,39 +366,6 @@ struct ti_pcl { | |||
378 | #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER)) | 366 | #define pcloffs(MEMBER) (offsetof(struct ti_pcl, MEMBER)) |
379 | 367 | ||
380 | 368 | ||
381 | #ifdef CONFIG_IEEE1394_PCILYNX_LOCALRAM | ||
382 | |||
383 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, | ||
384 | const struct ti_pcl *pcl) | ||
385 | { | ||
386 | int i; | ||
387 | u32 *in = (u32 *)pcl; | ||
388 | u32 *out = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); | ||
389 | |||
390 | for (i = 0; i < 32; i++, out++, in++) { | ||
391 | writel(*in, out); | ||
392 | } | ||
393 | } | ||
394 | |||
395 | static inline void get_pcl(const struct ti_lynx *lynx, pcl_t pclid, | ||
396 | struct ti_pcl *pcl) | ||
397 | { | ||
398 | int i; | ||
399 | u32 *out = (u32 *)pcl; | ||
400 | u32 *in = (u32 *)(lynx->local_ram + pclid * sizeof(struct ti_pcl)); | ||
401 | |||
402 | for (i = 0; i < 32; i++, out++, in++) { | ||
403 | *out = readl(in); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) | ||
408 | { | ||
409 | return pci_resource_start(lynx->dev, 1) + pclid * sizeof(struct ti_pcl); | ||
410 | } | ||
411 | |||
412 | #else /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ | ||
413 | |||
414 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, | 369 | static inline void put_pcl(const struct ti_lynx *lynx, pcl_t pclid, |
415 | const struct ti_pcl *pcl) | 370 | const struct ti_pcl *pcl) |
416 | { | 371 | { |
@@ -431,10 +386,8 @@ static inline u32 pcl_bus(const struct ti_lynx *lynx, pcl_t pclid) | |||
431 | return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl); | 386 | return lynx->pcl_mem_dma + pclid * sizeof(struct ti_pcl); |
432 | } | 387 | } |
433 | 388 | ||
434 | #endif /* CONFIG_IEEE1394_PCILYNX_LOCALRAM */ | ||
435 | |||
436 | 389 | ||
437 | #if defined (CONFIG_IEEE1394_PCILYNX_LOCALRAM) || defined (__BIG_ENDIAN) | 390 | #if defined (__BIG_ENDIAN) |
438 | typedef struct ti_pcl pcltmp_t; | 391 | typedef struct ti_pcl pcltmp_t; |
439 | 392 | ||
440 | static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, | 393 | static inline struct ti_pcl *edit_pcl(const struct ti_lynx *lynx, pcl_t pclid, |
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c index 4bedf7113f40..d68c4658f2fc 100644 --- a/drivers/ieee1394/video1394.c +++ b/drivers/ieee1394/video1394.c | |||
@@ -35,6 +35,11 @@ | |||
35 | * | 35 | * |
36 | */ | 36 | */ |
37 | 37 | ||
38 | /* Markus Tavenrath <speedygoo@speedygoo.de> : | ||
39 | - fixed checks for valid buffer-numbers in video1394_icotl | ||
40 | - changed the ways the dma prg's are used, now it's possible to use | ||
41 | even a single dma buffer | ||
42 | */ | ||
38 | #include <linux/config.h> | 43 | #include <linux/config.h> |
39 | #include <linux/kernel.h> | 44 | #include <linux/kernel.h> |
40 | #include <linux/list.h> | 45 | #include <linux/list.h> |
@@ -112,6 +117,7 @@ struct dma_iso_ctx { | |||
112 | struct it_dma_prg **it_prg; | 117 | struct it_dma_prg **it_prg; |
113 | 118 | ||
114 | unsigned int *buffer_status; | 119 | unsigned int *buffer_status; |
120 | unsigned int *buffer_prg_assignment; | ||
115 | struct timeval *buffer_time; /* time when the buffer was received */ | 121 | struct timeval *buffer_time; /* time when the buffer was received */ |
116 | unsigned int *last_used_cmd; /* For ISO Transmit with | 122 | unsigned int *last_used_cmd; /* For ISO Transmit with |
117 | variable sized packets only ! */ | 123 | variable sized packets only ! */ |
@@ -180,23 +186,14 @@ static int free_dma_iso_ctx(struct dma_iso_ctx *d) | |||
180 | kfree(d->prg_reg); | 186 | kfree(d->prg_reg); |
181 | } | 187 | } |
182 | 188 | ||
183 | if (d->ir_prg) | 189 | kfree(d->ir_prg); |
184 | kfree(d->ir_prg); | 190 | kfree(d->it_prg); |
185 | 191 | kfree(d->buffer_status); | |
186 | if (d->it_prg) | 192 | kfree(d->buffer_prg_assignment); |
187 | kfree(d->it_prg); | 193 | kfree(d->buffer_time); |
188 | 194 | kfree(d->last_used_cmd); | |
189 | if (d->buffer_status) | 195 | kfree(d->next_buffer); |
190 | kfree(d->buffer_status); | ||
191 | if (d->buffer_time) | ||
192 | kfree(d->buffer_time); | ||
193 | if (d->last_used_cmd) | ||
194 | kfree(d->last_used_cmd); | ||
195 | if (d->next_buffer) | ||
196 | kfree(d->next_buffer); | ||
197 | |||
198 | list_del(&d->link); | 196 | list_del(&d->link); |
199 | |||
200 | kfree(d); | 197 | kfree(d); |
201 | 198 | ||
202 | return 0; | 199 | return 0; |
@@ -230,7 +227,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
230 | /* Init the regions for easy cleanup */ | 227 | /* Init the regions for easy cleanup */ |
231 | dma_region_init(&d->dma); | 228 | dma_region_init(&d->dma); |
232 | 229 | ||
233 | if (dma_region_alloc(&d->dma, d->num_desc * d->buf_size, ohci->dev, | 230 | if (dma_region_alloc(&d->dma, (d->num_desc - 1) * d->buf_size, ohci->dev, |
234 | PCI_DMA_BIDIRECTIONAL)) { | 231 | PCI_DMA_BIDIRECTIONAL)) { |
235 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer"); | 232 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate dma buffer"); |
236 | free_dma_iso_ctx(d); | 233 | free_dma_iso_ctx(d); |
@@ -342,6 +339,8 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
342 | 339 | ||
343 | d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), | 340 | d->buffer_status = kmalloc(d->num_desc * sizeof(unsigned int), |
344 | GFP_KERNEL); | 341 | GFP_KERNEL); |
342 | d->buffer_prg_assignment = kmalloc(d->num_desc * sizeof(unsigned int), | ||
343 | GFP_KERNEL); | ||
345 | d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), | 344 | d->buffer_time = kmalloc(d->num_desc * sizeof(struct timeval), |
346 | GFP_KERNEL); | 345 | GFP_KERNEL); |
347 | d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int), | 346 | d->last_used_cmd = kmalloc(d->num_desc * sizeof(unsigned int), |
@@ -354,6 +353,11 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
354 | free_dma_iso_ctx(d); | 353 | free_dma_iso_ctx(d); |
355 | return NULL; | 354 | return NULL; |
356 | } | 355 | } |
356 | if (d->buffer_prg_assignment == NULL) { | ||
357 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_prg_assignment"); | ||
358 | free_dma_iso_ctx(d); | ||
359 | return NULL; | ||
360 | } | ||
357 | if (d->buffer_time == NULL) { | 361 | if (d->buffer_time == NULL) { |
358 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); | 362 | PRINT(KERN_ERR, ohci->host->id, "Failed to allocate buffer_time"); |
359 | free_dma_iso_ctx(d); | 363 | free_dma_iso_ctx(d); |
@@ -370,6 +374,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
370 | return NULL; | 374 | return NULL; |
371 | } | 375 | } |
372 | memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); | 376 | memset(d->buffer_status, 0, d->num_desc * sizeof(unsigned int)); |
377 | memset(d->buffer_prg_assignment, 0, d->num_desc * sizeof(unsigned int)); | ||
373 | memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); | 378 | memset(d->buffer_time, 0, d->num_desc * sizeof(struct timeval)); |
374 | memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); | 379 | memset(d->last_used_cmd, 0, d->num_desc * sizeof(unsigned int)); |
375 | memset(d->next_buffer, -1, d->num_desc * sizeof(int)); | 380 | memset(d->next_buffer, -1, d->num_desc * sizeof(int)); |
@@ -379,7 +384,7 @@ alloc_dma_iso_ctx(struct ti_ohci *ohci, int type, int num_desc, | |||
379 | PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " | 384 | PRINT(KERN_INFO, ohci->host->id, "Iso %s DMA: %d buffers " |
380 | "of size %d allocated for a frame size %d, each with %d prgs", | 385 | "of size %d allocated for a frame size %d, each with %d prgs", |
381 | (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit", | 386 | (type == OHCI_ISO_RECEIVE) ? "receive" : "transmit", |
382 | d->num_desc, d->buf_size, d->frame_size, d->nb_cmd); | 387 | d->num_desc - 1, d->buf_size, d->frame_size, d->nb_cmd); |
383 | 388 | ||
384 | return d; | 389 | return d; |
385 | } | 390 | } |
@@ -394,11 +399,36 @@ static void reset_ir_status(struct dma_iso_ctx *d, int n) | |||
394 | d->ir_prg[n][i].status = cpu_to_le32(d->left_size); | 399 | d->ir_prg[n][i].status = cpu_to_le32(d->left_size); |
395 | } | 400 | } |
396 | 401 | ||
402 | static void reprogram_dma_ir_prg(struct dma_iso_ctx *d, int n, int buffer, int flags) | ||
403 | { | ||
404 | struct dma_cmd *ir_prg = d->ir_prg[n]; | ||
405 | unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; | ||
406 | int i; | ||
407 | |||
408 | d->buffer_prg_assignment[n] = buffer; | ||
409 | |||
410 | ir_prg[0].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, buf - | ||
411 | (unsigned long)d->dma.kvirt)); | ||
412 | ir_prg[1].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
413 | (buf + 4) - (unsigned long)d->dma.kvirt)); | ||
414 | |||
415 | for (i=2;i<d->nb_cmd-1;i++) { | ||
416 | ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
417 | (buf+(i-1)*PAGE_SIZE) - | ||
418 | (unsigned long)d->dma.kvirt)); | ||
419 | } | ||
420 | |||
421 | ir_prg[i].control = cpu_to_le32(DMA_CTL_INPUT_MORE | DMA_CTL_UPDATE | | ||
422 | DMA_CTL_IRQ | DMA_CTL_BRANCH | d->left_size); | ||
423 | ir_prg[i].address = cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
424 | (buf+(i-1)*PAGE_SIZE) - (unsigned long)d->dma.kvirt)); | ||
425 | } | ||
426 | |||
397 | static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) | 427 | static void initialize_dma_ir_prg(struct dma_iso_ctx *d, int n, int flags) |
398 | { | 428 | { |
399 | struct dma_cmd *ir_prg = d->ir_prg[n]; | 429 | struct dma_cmd *ir_prg = d->ir_prg[n]; |
400 | struct dma_prog_region *ir_reg = &d->prg_reg[n]; | 430 | struct dma_prog_region *ir_reg = &d->prg_reg[n]; |
401 | unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; | 431 | unsigned long buf = (unsigned long)d->dma.kvirt; |
402 | int i; | 432 | int i; |
403 | 433 | ||
404 | /* the first descriptor will read only 4 bytes */ | 434 | /* the first descriptor will read only 4 bytes */ |
@@ -508,7 +538,7 @@ static void wakeup_dma_ir_ctx(unsigned long l) | |||
508 | for (i = 0; i < d->num_desc; i++) { | 538 | for (i = 0; i < d->num_desc; i++) { |
509 | if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) { | 539 | if (d->ir_prg[i][d->nb_cmd-1].status & cpu_to_le32(0xFFFF0000)) { |
510 | reset_ir_status(d, i); | 540 | reset_ir_status(d, i); |
511 | d->buffer_status[i] = VIDEO1394_BUFFER_READY; | 541 | d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; |
512 | do_gettimeofday(&d->buffer_time[i]); | 542 | do_gettimeofday(&d->buffer_time[i]); |
513 | } | 543 | } |
514 | } | 544 | } |
@@ -585,7 +615,7 @@ static void wakeup_dma_it_ctx(unsigned long l) | |||
585 | int next = d->next_buffer[i]; | 615 | int next = d->next_buffer[i]; |
586 | put_timestamp(ohci, d, next); | 616 | put_timestamp(ohci, d, next); |
587 | d->it_prg[i][d->last_used_cmd[i]].end.status = 0; | 617 | d->it_prg[i][d->last_used_cmd[i]].end.status = 0; |
588 | d->buffer_status[i] = VIDEO1394_BUFFER_READY; | 618 | d->buffer_status[d->buffer_prg_assignment[i]] = VIDEO1394_BUFFER_READY; |
589 | } | 619 | } |
590 | } | 620 | } |
591 | 621 | ||
@@ -595,11 +625,25 @@ static void wakeup_dma_it_ctx(unsigned long l) | |||
595 | wake_up_interruptible(&d->waitq); | 625 | wake_up_interruptible(&d->waitq); |
596 | } | 626 | } |
597 | 627 | ||
628 | static void reprogram_dma_it_prg(struct dma_iso_ctx *d, int n, int buffer) | ||
629 | { | ||
630 | struct it_dma_prg *it_prg = d->it_prg[n]; | ||
631 | unsigned long buf = (unsigned long)d->dma.kvirt + buffer * d->buf_size; | ||
632 | int i; | ||
633 | |||
634 | d->buffer_prg_assignment[n] = buffer; | ||
635 | for (i=0;i<d->nb_cmd;i++) { | ||
636 | it_prg[i].end.address = | ||
637 | cpu_to_le32(dma_region_offset_to_bus(&d->dma, | ||
638 | (buf+i*d->packet_size) - (unsigned long)d->dma.kvirt)); | ||
639 | } | ||
640 | } | ||
641 | |||
598 | static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) | 642 | static void initialize_dma_it_prg(struct dma_iso_ctx *d, int n, int sync_tag) |
599 | { | 643 | { |
600 | struct it_dma_prg *it_prg = d->it_prg[n]; | 644 | struct it_dma_prg *it_prg = d->it_prg[n]; |
601 | struct dma_prog_region *it_reg = &d->prg_reg[n]; | 645 | struct dma_prog_region *it_reg = &d->prg_reg[n]; |
602 | unsigned long buf = (unsigned long)d->dma.kvirt + n * d->buf_size; | 646 | unsigned long buf = (unsigned long)d->dma.kvirt; |
603 | int i; | 647 | int i; |
604 | d->last_used_cmd[n] = d->nb_cmd - 1; | 648 | d->last_used_cmd[n] = d->nb_cmd - 1; |
605 | for (i=0;i<d->nb_cmd;i++) { | 649 | for (i=0;i<d->nb_cmd;i++) { |
@@ -796,7 +840,7 @@ static int __video1394_ioctl(struct file *file, | |||
796 | 840 | ||
797 | if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { | 841 | if (cmd == VIDEO1394_IOC_LISTEN_CHANNEL) { |
798 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, | 842 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_RECEIVE, |
799 | v.nb_buffers, v.buf_size, | 843 | v.nb_buffers + 1, v.buf_size, |
800 | v.channel, 0); | 844 | v.channel, 0); |
801 | 845 | ||
802 | if (d == NULL) { | 846 | if (d == NULL) { |
@@ -817,7 +861,7 @@ static int __video1394_ioctl(struct file *file, | |||
817 | } | 861 | } |
818 | else { | 862 | else { |
819 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, | 863 | d = alloc_dma_iso_ctx(ohci, OHCI_ISO_TRANSMIT, |
820 | v.nb_buffers, v.buf_size, | 864 | v.nb_buffers + 1, v.buf_size, |
821 | v.channel, v.packet_size); | 865 | v.channel, v.packet_size); |
822 | 866 | ||
823 | if (d == NULL) { | 867 | if (d == NULL) { |
@@ -889,6 +933,7 @@ static int __video1394_ioctl(struct file *file, | |||
889 | { | 933 | { |
890 | struct video1394_wait v; | 934 | struct video1394_wait v; |
891 | struct dma_iso_ctx *d; | 935 | struct dma_iso_ctx *d; |
936 | int next_prg; | ||
892 | 937 | ||
893 | if (copy_from_user(&v, argp, sizeof(v))) | 938 | if (copy_from_user(&v, argp, sizeof(v))) |
894 | return -EFAULT; | 939 | return -EFAULT; |
@@ -896,7 +941,7 @@ static int __video1394_ioctl(struct file *file, | |||
896 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); | 941 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); |
897 | if (d == NULL) return -EFAULT; | 942 | if (d == NULL) return -EFAULT; |
898 | 943 | ||
899 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 944 | if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
900 | PRINT(KERN_ERR, ohci->host->id, | 945 | PRINT(KERN_ERR, ohci->host->id, |
901 | "Buffer %d out of range",v.buffer); | 946 | "Buffer %d out of range",v.buffer); |
902 | return -EINVAL; | 947 | return -EINVAL; |
@@ -913,12 +958,14 @@ static int __video1394_ioctl(struct file *file, | |||
913 | 958 | ||
914 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; | 959 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; |
915 | 960 | ||
961 | next_prg = (d->last_buffer + 1) % d->num_desc; | ||
916 | if (d->last_buffer>=0) | 962 | if (d->last_buffer>=0) |
917 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = | 963 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = |
918 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 964 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) |
919 | & 0xfffffff0) | 0x1); | 965 | & 0xfffffff0) | 0x1); |
920 | 966 | ||
921 | d->last_buffer = v.buffer; | 967 | d->last_buffer = next_prg; |
968 | reprogram_dma_ir_prg(d, d->last_buffer, v.buffer, d->flags); | ||
922 | 969 | ||
923 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0; | 970 | d->ir_prg[d->last_buffer][d->nb_cmd-1].branchAddress = 0; |
924 | 971 | ||
@@ -930,7 +977,7 @@ static int __video1394_ioctl(struct file *file, | |||
930 | 977 | ||
931 | /* Tell the controller where the first program is */ | 978 | /* Tell the controller where the first program is */ |
932 | reg_write(ohci, d->cmdPtr, | 979 | reg_write(ohci, d->cmdPtr, |
933 | dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x1); | 980 | dma_prog_region_offset_to_bus(&d->prg_reg[d->last_buffer], 0) | 0x1); |
934 | 981 | ||
935 | /* Run IR context */ | 982 | /* Run IR context */ |
936 | reg_write(ohci, d->ctrlSet, 0x8000); | 983 | reg_write(ohci, d->ctrlSet, 0x8000); |
@@ -951,7 +998,7 @@ static int __video1394_ioctl(struct file *file, | |||
951 | { | 998 | { |
952 | struct video1394_wait v; | 999 | struct video1394_wait v; |
953 | struct dma_iso_ctx *d; | 1000 | struct dma_iso_ctx *d; |
954 | int i; | 1001 | int i = 0; |
955 | 1002 | ||
956 | if (copy_from_user(&v, argp, sizeof(v))) | 1003 | if (copy_from_user(&v, argp, sizeof(v))) |
957 | return -EFAULT; | 1004 | return -EFAULT; |
@@ -959,7 +1006,7 @@ static int __video1394_ioctl(struct file *file, | |||
959 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); | 1006 | d = find_ctx(&ctx->context_list, OHCI_ISO_RECEIVE, v.channel); |
960 | if (d == NULL) return -EFAULT; | 1007 | if (d == NULL) return -EFAULT; |
961 | 1008 | ||
962 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1009 | if ((v.buffer<0) || (v.buffer>d->num_desc - 1)) { |
963 | PRINT(KERN_ERR, ohci->host->id, | 1010 | PRINT(KERN_ERR, ohci->host->id, |
964 | "Buffer %d out of range",v.buffer); | 1011 | "Buffer %d out of range",v.buffer); |
965 | return -EINVAL; | 1012 | return -EINVAL; |
@@ -1005,9 +1052,9 @@ static int __video1394_ioctl(struct file *file, | |||
1005 | * Look ahead to see how many more buffers have been received | 1052 | * Look ahead to see how many more buffers have been received |
1006 | */ | 1053 | */ |
1007 | i=0; | 1054 | i=0; |
1008 | while (d->buffer_status[(v.buffer+1)%d->num_desc]== | 1055 | while (d->buffer_status[(v.buffer+1)%(d->num_desc - 1)]== |
1009 | VIDEO1394_BUFFER_READY) { | 1056 | VIDEO1394_BUFFER_READY) { |
1010 | v.buffer=(v.buffer+1)%d->num_desc; | 1057 | v.buffer=(v.buffer+1)%(d->num_desc - 1); |
1011 | i++; | 1058 | i++; |
1012 | } | 1059 | } |
1013 | spin_unlock_irqrestore(&d->lock, flags); | 1060 | spin_unlock_irqrestore(&d->lock, flags); |
@@ -1023,6 +1070,7 @@ static int __video1394_ioctl(struct file *file, | |||
1023 | struct video1394_wait v; | 1070 | struct video1394_wait v; |
1024 | unsigned int *psizes = NULL; | 1071 | unsigned int *psizes = NULL; |
1025 | struct dma_iso_ctx *d; | 1072 | struct dma_iso_ctx *d; |
1073 | int next_prg; | ||
1026 | 1074 | ||
1027 | if (copy_from_user(&v, argp, sizeof(v))) | 1075 | if (copy_from_user(&v, argp, sizeof(v))) |
1028 | return -EFAULT; | 1076 | return -EFAULT; |
@@ -1030,7 +1078,7 @@ static int __video1394_ioctl(struct file *file, | |||
1030 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); | 1078 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
1031 | if (d == NULL) return -EFAULT; | 1079 | if (d == NULL) return -EFAULT; |
1032 | 1080 | ||
1033 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1081 | if ((v.buffer<0) || (v.buffer>=d->num_desc - 1)) { |
1034 | PRINT(KERN_ERR, ohci->host->id, | 1082 | PRINT(KERN_ERR, ohci->host->id, |
1035 | "Buffer %d out of range",v.buffer); | 1083 | "Buffer %d out of range",v.buffer); |
1036 | return -EINVAL; | 1084 | return -EINVAL; |
@@ -1056,19 +1104,19 @@ static int __video1394_ioctl(struct file *file, | |||
1056 | 1104 | ||
1057 | spin_lock_irqsave(&d->lock,flags); | 1105 | spin_lock_irqsave(&d->lock,flags); |
1058 | 1106 | ||
1107 | // last_buffer is last_prg | ||
1108 | next_prg = (d->last_buffer + 1) % d->num_desc; | ||
1059 | if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { | 1109 | if (d->buffer_status[v.buffer]!=VIDEO1394_BUFFER_FREE) { |
1060 | PRINT(KERN_ERR, ohci->host->id, | 1110 | PRINT(KERN_ERR, ohci->host->id, |
1061 | "Buffer %d is already used",v.buffer); | 1111 | "Buffer %d is already used",v.buffer); |
1062 | spin_unlock_irqrestore(&d->lock,flags); | 1112 | spin_unlock_irqrestore(&d->lock,flags); |
1063 | if (psizes) | 1113 | kfree(psizes); |
1064 | kfree(psizes); | ||
1065 | return -EBUSY; | 1114 | return -EBUSY; |
1066 | } | 1115 | } |
1067 | 1116 | ||
1068 | if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { | 1117 | if (d->flags & VIDEO1394_VARIABLE_PACKET_SIZE) { |
1069 | initialize_dma_it_prg_var_packet_queue( | 1118 | initialize_dma_it_prg_var_packet_queue( |
1070 | d, v.buffer, psizes, | 1119 | d, next_prg, psizes, ohci); |
1071 | ohci); | ||
1072 | } | 1120 | } |
1073 | 1121 | ||
1074 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; | 1122 | d->buffer_status[v.buffer]=VIDEO1394_BUFFER_QUEUED; |
@@ -1076,16 +1124,17 @@ static int __video1394_ioctl(struct file *file, | |||
1076 | if (d->last_buffer >= 0) { | 1124 | if (d->last_buffer >= 0) { |
1077 | d->it_prg[d->last_buffer] | 1125 | d->it_prg[d->last_buffer] |
1078 | [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = | 1126 | [ d->last_used_cmd[d->last_buffer] ].end.branchAddress = |
1079 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], | 1127 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], |
1080 | 0) & 0xfffffff0) | 0x3); | 1128 | 0) & 0xfffffff0) | 0x3); |
1081 | 1129 | ||
1082 | d->it_prg[d->last_buffer] | 1130 | d->it_prg[d->last_buffer] |
1083 | [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = | 1131 | [ d->last_used_cmd[d->last_buffer] ].begin.branchAddress = |
1084 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], | 1132 | cpu_to_le32((dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], |
1085 | 0) & 0xfffffff0) | 0x3); | 1133 | 0) & 0xfffffff0) | 0x3); |
1086 | d->next_buffer[d->last_buffer] = v.buffer; | 1134 | d->next_buffer[d->last_buffer] = (v.buffer + 1) % (d->num_desc - 1); |
1087 | } | 1135 | } |
1088 | d->last_buffer = v.buffer; | 1136 | d->last_buffer = next_prg; |
1137 | reprogram_dma_it_prg(d, d->last_buffer, v.buffer); | ||
1089 | d->next_buffer[d->last_buffer] = -1; | 1138 | d->next_buffer[d->last_buffer] = -1; |
1090 | 1139 | ||
1091 | d->it_prg[d->last_buffer][d->last_used_cmd[d->last_buffer]].end.branchAddress = 0; | 1140 | d->it_prg[d->last_buffer][d->last_used_cmd[d->last_buffer]].end.branchAddress = 0; |
@@ -1100,7 +1149,7 @@ static int __video1394_ioctl(struct file *file, | |||
1100 | 1149 | ||
1101 | /* Tell the controller where the first program is */ | 1150 | /* Tell the controller where the first program is */ |
1102 | reg_write(ohci, d->cmdPtr, | 1151 | reg_write(ohci, d->cmdPtr, |
1103 | dma_prog_region_offset_to_bus(&d->prg_reg[v.buffer], 0) | 0x3); | 1152 | dma_prog_region_offset_to_bus(&d->prg_reg[next_prg], 0) | 0x3); |
1104 | 1153 | ||
1105 | /* Run IT context */ | 1154 | /* Run IT context */ |
1106 | reg_write(ohci, d->ctrlSet, 0x8000); | 1155 | reg_write(ohci, d->ctrlSet, 0x8000); |
@@ -1116,9 +1165,7 @@ static int __video1394_ioctl(struct file *file, | |||
1116 | } | 1165 | } |
1117 | } | 1166 | } |
1118 | 1167 | ||
1119 | if (psizes) | 1168 | kfree(psizes); |
1120 | kfree(psizes); | ||
1121 | |||
1122 | return 0; | 1169 | return 0; |
1123 | 1170 | ||
1124 | } | 1171 | } |
@@ -1133,7 +1180,7 @@ static int __video1394_ioctl(struct file *file, | |||
1133 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); | 1180 | d = find_ctx(&ctx->context_list, OHCI_ISO_TRANSMIT, v.channel); |
1134 | if (d == NULL) return -EFAULT; | 1181 | if (d == NULL) return -EFAULT; |
1135 | 1182 | ||
1136 | if ((v.buffer<0) || (v.buffer>d->num_desc)) { | 1183 | if ((v.buffer<0) || (v.buffer>=d->num_desc-1)) { |
1137 | PRINT(KERN_ERR, ohci->host->id, | 1184 | PRINT(KERN_ERR, ohci->host->id, |
1138 | "Buffer %d out of range",v.buffer); | 1185 | "Buffer %d out of range",v.buffer); |
1139 | return -EINVAL; | 1186 | return -EINVAL; |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ff66ed4ee2cd..79c332f16fc7 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -465,8 +465,10 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co | |||
465 | if (atkbd->softrepeat) return 0; | 465 | if (atkbd->softrepeat) return 0; |
466 | 466 | ||
467 | i = j = 0; | 467 | i = j = 0; |
468 | while (i < 32 && period[i] < dev->rep[REP_PERIOD]) i++; | 468 | while (i < 31 && period[i] < dev->rep[REP_PERIOD]) |
469 | while (j < 4 && delay[j] < dev->rep[REP_DELAY]) j++; | 469 | i++; |
470 | while (j < 3 && delay[j] < dev->rep[REP_DELAY]) | ||
471 | j++; | ||
470 | dev->rep[REP_PERIOD] = period[i]; | 472 | dev->rep[REP_PERIOD] = period[i]; |
471 | dev->rep[REP_DELAY] = delay[j]; | 473 | dev->rep[REP_DELAY] = delay[j]; |
472 | param[0] = i | (j << 5); | 474 | param[0] = i | (j << 5); |
diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c index 1f85a9718c89..42a9f7f6f8cb 100644 --- a/drivers/input/mouse/alps.c +++ b/drivers/input/mouse/alps.c | |||
@@ -341,6 +341,8 @@ static int alps_reconnect(struct psmouse *psmouse) | |||
341 | unsigned char param[4]; | 341 | unsigned char param[4]; |
342 | int version; | 342 | int version; |
343 | 343 | ||
344 | psmouse_reset(psmouse); | ||
345 | |||
344 | if (!(priv->i = alps_get_model(psmouse, &version))) | 346 | if (!(priv->i = alps_get_model(psmouse, &version))) |
345 | return -1; | 347 | return -1; |
346 | 348 | ||
@@ -395,7 +397,7 @@ int alps_init(struct psmouse *psmouse) | |||
395 | } | 397 | } |
396 | 398 | ||
397 | if (param[0] & 0x04) { | 399 | if (param[0] & 0x04) { |
398 | printk(KERN_INFO " Enabling hardware tapping\n"); | 400 | printk(KERN_INFO "alps.c: Enabling hardware tapping\n"); |
399 | if (alps_tap_mode(psmouse, 1)) | 401 | if (alps_tap_mode(psmouse, 1)) |
400 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); | 402 | printk(KERN_WARNING "alps.c: Failed to enable hardware tapping\n"); |
401 | } | 403 | } |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 3313e2daeab0..0beacb77ee18 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -388,6 +388,24 @@ static ssize_t serio_show_id_extra(struct device *dev, char *buf) | |||
388 | return sprintf(buf, "%02x\n", serio->id.extra); | 388 | return sprintf(buf, "%02x\n", serio->id.extra); |
389 | } | 389 | } |
390 | 390 | ||
391 | static DEVICE_ATTR(type, S_IRUGO, serio_show_id_type, NULL); | ||
392 | static DEVICE_ATTR(proto, S_IRUGO, serio_show_id_proto, NULL); | ||
393 | static DEVICE_ATTR(id, S_IRUGO, serio_show_id_id, NULL); | ||
394 | static DEVICE_ATTR(extra, S_IRUGO, serio_show_id_extra, NULL); | ||
395 | |||
396 | static struct attribute *serio_device_id_attrs[] = { | ||
397 | &dev_attr_type.attr, | ||
398 | &dev_attr_proto.attr, | ||
399 | &dev_attr_id.attr, | ||
400 | &dev_attr_extra.attr, | ||
401 | NULL | ||
402 | }; | ||
403 | |||
404 | static struct attribute_group serio_id_attr_group = { | ||
405 | .name = "id", | ||
406 | .attrs = serio_device_id_attrs, | ||
407 | }; | ||
408 | |||
391 | static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count) | 409 | static ssize_t serio_rebind_driver(struct device *dev, const char *buf, size_t count) |
392 | { | 410 | { |
393 | struct serio *serio = to_serio_port(dev); | 411 | struct serio *serio = to_serio_port(dev); |
@@ -444,10 +462,6 @@ static ssize_t serio_set_bind_mode(struct device *dev, const char *buf, size_t c | |||
444 | 462 | ||
445 | static struct device_attribute serio_device_attrs[] = { | 463 | static struct device_attribute serio_device_attrs[] = { |
446 | __ATTR(description, S_IRUGO, serio_show_description, NULL), | 464 | __ATTR(description, S_IRUGO, serio_show_description, NULL), |
447 | __ATTR(id_type, S_IRUGO, serio_show_id_type, NULL), | ||
448 | __ATTR(id_proto, S_IRUGO, serio_show_id_proto, NULL), | ||
449 | __ATTR(id_id, S_IRUGO, serio_show_id_id, NULL), | ||
450 | __ATTR(id_extra, S_IRUGO, serio_show_id_extra, NULL), | ||
451 | __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), | 465 | __ATTR(drvctl, S_IWUSR, NULL, serio_rebind_driver), |
452 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), | 466 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, serio_show_bind_mode, serio_set_bind_mode), |
453 | __ATTR_NULL | 467 | __ATTR_NULL |
@@ -498,6 +512,7 @@ static void serio_add_port(struct serio *serio) | |||
498 | if (serio->start) | 512 | if (serio->start) |
499 | serio->start(serio); | 513 | serio->start(serio); |
500 | device_add(&serio->dev); | 514 | device_add(&serio->dev); |
515 | sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
501 | serio->registered = 1; | 516 | serio->registered = 1; |
502 | } | 517 | } |
503 | 518 | ||
@@ -526,6 +541,7 @@ static void serio_destroy_port(struct serio *serio) | |||
526 | } | 541 | } |
527 | 542 | ||
528 | if (serio->registered) { | 543 | if (serio->registered) { |
544 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | ||
529 | device_del(&serio->dev); | 545 | device_del(&serio->dev); |
530 | list_del_init(&serio->node); | 546 | list_del_init(&serio->node); |
531 | serio->registered = 0; | 547 | serio->registered = 0; |
@@ -779,7 +795,6 @@ static int serio_resume(struct device *dev) | |||
779 | struct serio *serio = to_serio_port(dev); | 795 | struct serio *serio = to_serio_port(dev); |
780 | 796 | ||
781 | if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) { | 797 | if (!serio->drv || !serio->drv->reconnect || serio->drv->reconnect(serio)) { |
782 | serio_disconnect_port(serio); | ||
783 | /* | 798 | /* |
784 | * Driver re-probing can take a while, so better let kseriod | 799 | * Driver re-probing can take a while, so better let kseriod |
785 | * deal with it. | 800 | * deal with it. |
diff --git a/drivers/input/serio/serport.c b/drivers/input/serio/serport.c index 22f73683952b..f6b85222ba3d 100644 --- a/drivers/input/serio/serport.c +++ b/drivers/input/serio/serport.c | |||
@@ -27,11 +27,15 @@ MODULE_LICENSE("GPL"); | |||
27 | MODULE_ALIAS_LDISC(N_MOUSE); | 27 | MODULE_ALIAS_LDISC(N_MOUSE); |
28 | 28 | ||
29 | #define SERPORT_BUSY 1 | 29 | #define SERPORT_BUSY 1 |
30 | #define SERPORT_ACTIVE 2 | ||
31 | #define SERPORT_DEAD 3 | ||
30 | 32 | ||
31 | struct serport { | 33 | struct serport { |
32 | struct tty_struct *tty; | 34 | struct tty_struct *tty; |
33 | wait_queue_head_t wait; | 35 | wait_queue_head_t wait; |
34 | struct serio *serio; | 36 | struct serio *serio; |
37 | struct serio_device_id id; | ||
38 | spinlock_t lock; | ||
35 | unsigned long flags; | 39 | unsigned long flags; |
36 | }; | 40 | }; |
37 | 41 | ||
@@ -45,11 +49,29 @@ static int serport_serio_write(struct serio *serio, unsigned char data) | |||
45 | return -(serport->tty->driver->write(serport->tty, &data, 1) != 1); | 49 | return -(serport->tty->driver->write(serport->tty, &data, 1) != 1); |
46 | } | 50 | } |
47 | 51 | ||
52 | static int serport_serio_open(struct serio *serio) | ||
53 | { | ||
54 | struct serport *serport = serio->port_data; | ||
55 | unsigned long flags; | ||
56 | |||
57 | spin_lock_irqsave(&serport->lock, flags); | ||
58 | set_bit(SERPORT_ACTIVE, &serport->flags); | ||
59 | spin_unlock_irqrestore(&serport->lock, flags); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | |||
48 | static void serport_serio_close(struct serio *serio) | 65 | static void serport_serio_close(struct serio *serio) |
49 | { | 66 | { |
50 | struct serport *serport = serio->port_data; | 67 | struct serport *serport = serio->port_data; |
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&serport->lock, flags); | ||
71 | clear_bit(SERPORT_ACTIVE, &serport->flags); | ||
72 | set_bit(SERPORT_DEAD, &serport->flags); | ||
73 | spin_unlock_irqrestore(&serport->lock, flags); | ||
51 | 74 | ||
52 | serport->serio->id.type = 0; | ||
53 | wake_up_interruptible(&serport->wait); | 75 | wake_up_interruptible(&serport->wait); |
54 | } | 76 | } |
55 | 77 | ||
@@ -61,36 +83,21 @@ static void serport_serio_close(struct serio *serio) | |||
61 | static int serport_ldisc_open(struct tty_struct *tty) | 83 | static int serport_ldisc_open(struct tty_struct *tty) |
62 | { | 84 | { |
63 | struct serport *serport; | 85 | struct serport *serport; |
64 | struct serio *serio; | ||
65 | char name[64]; | ||
66 | 86 | ||
67 | if (!capable(CAP_SYS_ADMIN)) | 87 | if (!capable(CAP_SYS_ADMIN)) |
68 | return -EPERM; | 88 | return -EPERM; |
69 | 89 | ||
70 | serport = kmalloc(sizeof(struct serport), GFP_KERNEL); | 90 | serport = kcalloc(1, sizeof(struct serport), GFP_KERNEL); |
71 | serio = kmalloc(sizeof(struct serio), GFP_KERNEL); | 91 | if (!serport) |
72 | if (unlikely(!serport || !serio)) { | ||
73 | kfree(serport); | ||
74 | kfree(serio); | ||
75 | return -ENOMEM; | 92 | return -ENOMEM; |
76 | } | ||
77 | 93 | ||
78 | memset(serport, 0, sizeof(struct serport)); | ||
79 | serport->serio = serio; | ||
80 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | ||
81 | serport->tty = tty; | 94 | serport->tty = tty; |
82 | tty->disc_data = serport; | 95 | spin_lock_init(&serport->lock); |
83 | |||
84 | memset(serio, 0, sizeof(struct serio)); | ||
85 | strlcpy(serio->name, "Serial port", sizeof(serio->name)); | ||
86 | snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name)); | ||
87 | serio->id.type = SERIO_RS232; | ||
88 | serio->write = serport_serio_write; | ||
89 | serio->close = serport_serio_close; | ||
90 | serio->port_data = serport; | ||
91 | |||
92 | init_waitqueue_head(&serport->wait); | 96 | init_waitqueue_head(&serport->wait); |
93 | 97 | ||
98 | tty->disc_data = serport; | ||
99 | set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | ||
100 | |||
94 | return 0; | 101 | return 0; |
95 | } | 102 | } |
96 | 103 | ||
@@ -100,7 +107,8 @@ static int serport_ldisc_open(struct tty_struct *tty) | |||
100 | 107 | ||
101 | static void serport_ldisc_close(struct tty_struct *tty) | 108 | static void serport_ldisc_close(struct tty_struct *tty) |
102 | { | 109 | { |
103 | struct serport *serport = (struct serport*) tty->disc_data; | 110 | struct serport *serport = (struct serport *) tty->disc_data; |
111 | |||
104 | kfree(serport); | 112 | kfree(serport); |
105 | } | 113 | } |
106 | 114 | ||
@@ -116,9 +124,19 @@ static void serport_ldisc_close(struct tty_struct *tty) | |||
116 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) | 124 | static void serport_ldisc_receive(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) |
117 | { | 125 | { |
118 | struct serport *serport = (struct serport*) tty->disc_data; | 126 | struct serport *serport = (struct serport*) tty->disc_data; |
127 | unsigned long flags; | ||
119 | int i; | 128 | int i; |
129 | |||
130 | spin_lock_irqsave(&serport->lock, flags); | ||
131 | |||
132 | if (!test_bit(SERPORT_ACTIVE, &serport->flags)) | ||
133 | goto out; | ||
134 | |||
120 | for (i = 0; i < count; i++) | 135 | for (i = 0; i < count; i++) |
121 | serio_interrupt(serport->serio, cp[i], 0, NULL); | 136 | serio_interrupt(serport->serio, cp[i], 0, NULL); |
137 | |||
138 | out: | ||
139 | spin_unlock_irqrestore(&serport->lock, flags); | ||
122 | } | 140 | } |
123 | 141 | ||
124 | /* | 142 | /* |
@@ -141,16 +159,33 @@ static int serport_ldisc_room(struct tty_struct *tty) | |||
141 | static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr) | 159 | static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, unsigned char __user * buf, size_t nr) |
142 | { | 160 | { |
143 | struct serport *serport = (struct serport*) tty->disc_data; | 161 | struct serport *serport = (struct serport*) tty->disc_data; |
162 | struct serio *serio; | ||
144 | char name[64]; | 163 | char name[64]; |
145 | 164 | ||
146 | if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) | 165 | if (test_and_set_bit(SERPORT_BUSY, &serport->flags)) |
147 | return -EBUSY; | 166 | return -EBUSY; |
148 | 167 | ||
168 | serport->serio = serio = kcalloc(1, sizeof(struct serio), GFP_KERNEL); | ||
169 | if (!serio) | ||
170 | return -ENOMEM; | ||
171 | |||
172 | strlcpy(serio->name, "Serial port", sizeof(serio->name)); | ||
173 | snprintf(serio->phys, sizeof(serio->phys), "%s/serio0", tty_name(tty, name)); | ||
174 | serio->id = serport->id; | ||
175 | serio->id.type = SERIO_RS232; | ||
176 | serio->write = serport_serio_write; | ||
177 | serio->open = serport_serio_open; | ||
178 | serio->close = serport_serio_close; | ||
179 | serio->port_data = serport; | ||
180 | |||
149 | serio_register_port(serport->serio); | 181 | serio_register_port(serport->serio); |
150 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); | 182 | printk(KERN_INFO "serio: Serial port %s\n", tty_name(tty, name)); |
151 | wait_event_interruptible(serport->wait, !serport->serio->id.type); | 183 | |
184 | wait_event_interruptible(serport->wait, test_bit(SERPORT_DEAD, &serport->flags)); | ||
152 | serio_unregister_port(serport->serio); | 185 | serio_unregister_port(serport->serio); |
186 | serport->serio = NULL; | ||
153 | 187 | ||
188 | clear_bit(SERPORT_DEAD, &serport->flags); | ||
154 | clear_bit(SERPORT_BUSY, &serport->flags); | 189 | clear_bit(SERPORT_BUSY, &serport->flags); |
155 | 190 | ||
156 | return 0; | 191 | return 0; |
@@ -163,16 +198,15 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u | |||
163 | static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) | 198 | static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg) |
164 | { | 199 | { |
165 | struct serport *serport = (struct serport*) tty->disc_data; | 200 | struct serport *serport = (struct serport*) tty->disc_data; |
166 | struct serio *serio = serport->serio; | ||
167 | unsigned long type; | 201 | unsigned long type; |
168 | 202 | ||
169 | if (cmd == SPIOCSTYPE) { | 203 | if (cmd == SPIOCSTYPE) { |
170 | if (get_user(type, (unsigned long __user *) arg)) | 204 | if (get_user(type, (unsigned long __user *) arg)) |
171 | return -EFAULT; | 205 | return -EFAULT; |
172 | 206 | ||
173 | serio->id.proto = type & 0x000000ff; | 207 | serport->id.proto = type & 0x000000ff; |
174 | serio->id.id = (type & 0x0000ff00) >> 8; | 208 | serport->id.id = (type & 0x0000ff00) >> 8; |
175 | serio->id.extra = (type & 0x00ff0000) >> 16; | 209 | serport->id.extra = (type & 0x00ff0000) >> 16; |
176 | 210 | ||
177 | return 0; | 211 | return 0; |
178 | } | 212 | } |
@@ -182,9 +216,13 @@ static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsi | |||
182 | 216 | ||
183 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) | 217 | static void serport_ldisc_write_wakeup(struct tty_struct * tty) |
184 | { | 218 | { |
185 | struct serport *sp = (struct serport *) tty->disc_data; | 219 | struct serport *serport = (struct serport *) tty->disc_data; |
220 | unsigned long flags; | ||
186 | 221 | ||
187 | serio_drv_write_wakeup(sp->serio); | 222 | spin_lock_irqsave(&serport->lock, flags); |
223 | if (test_bit(SERPORT_ACTIVE, &serport->flags)) | ||
224 | serio_drv_write_wakeup(serport->serio); | ||
225 | spin_unlock_irqrestore(&serport->lock, flags); | ||
188 | } | 226 | } |
189 | 227 | ||
190 | /* | 228 | /* |
diff --git a/drivers/md/dm-emc.c b/drivers/md/dm-emc.c index 700658664594..c7067674dcb7 100644 --- a/drivers/md/dm-emc.c +++ b/drivers/md/dm-emc.c | |||
@@ -223,8 +223,10 @@ static struct emc_handler *alloc_emc_handler(void) | |||
223 | { | 223 | { |
224 | struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL); | 224 | struct emc_handler *h = kmalloc(sizeof(*h), GFP_KERNEL); |
225 | 225 | ||
226 | if (h) | 226 | if (h) { |
227 | memset(h, 0, sizeof(*h)); | ||
227 | spin_lock_init(&h->lock); | 228 | spin_lock_init(&h->lock); |
229 | } | ||
228 | 230 | ||
229 | return h; | 231 | return h; |
230 | } | 232 | } |
@@ -259,8 +261,6 @@ static int emc_create(struct hw_handler *hwh, unsigned argc, char **argv) | |||
259 | if (!h) | 261 | if (!h) |
260 | return -ENOMEM; | 262 | return -ENOMEM; |
261 | 263 | ||
262 | memset(h, 0, sizeof(*h)); | ||
263 | |||
264 | hwh->context = h; | 264 | hwh->context = h; |
265 | 265 | ||
266 | if ((h->short_trespass = short_trespass)) | 266 | if ((h->short_trespass = short_trespass)) |
diff --git a/drivers/md/dm-hw-handler.c b/drivers/md/dm-hw-handler.c index ae63772e44c9..4cc0010e0156 100644 --- a/drivers/md/dm-hw-handler.c +++ b/drivers/md/dm-hw-handler.c | |||
@@ -23,7 +23,7 @@ struct hwh_internal { | |||
23 | static LIST_HEAD(_hw_handlers); | 23 | static LIST_HEAD(_hw_handlers); |
24 | static DECLARE_RWSEM(_hwh_lock); | 24 | static DECLARE_RWSEM(_hwh_lock); |
25 | 25 | ||
26 | struct hwh_internal *__find_hw_handler_type(const char *name) | 26 | static struct hwh_internal *__find_hw_handler_type(const char *name) |
27 | { | 27 | { |
28 | struct hwh_internal *hwhi; | 28 | struct hwh_internal *hwhi; |
29 | 29 | ||
diff --git a/drivers/md/dm-mpath.c b/drivers/md/dm-mpath.c index 43763a0bd096..1e97b3c12bd5 100644 --- a/drivers/md/dm-mpath.c +++ b/drivers/md/dm-mpath.c | |||
@@ -101,6 +101,7 @@ typedef int (*action_fn) (struct pgpath *pgpath); | |||
101 | 101 | ||
102 | static kmem_cache_t *_mpio_cache; | 102 | static kmem_cache_t *_mpio_cache; |
103 | 103 | ||
104 | struct workqueue_struct *kmultipathd; | ||
104 | static void process_queued_ios(void *data); | 105 | static void process_queued_ios(void *data); |
105 | static void trigger_event(void *data); | 106 | static void trigger_event(void *data); |
106 | 107 | ||
@@ -308,7 +309,7 @@ static int map_io(struct multipath *m, struct bio *bio, struct mpath_io *mpio, | |||
308 | bio_list_add(&m->queued_ios, bio); | 309 | bio_list_add(&m->queued_ios, bio); |
309 | m->queue_size++; | 310 | m->queue_size++; |
310 | if (m->pg_init_required || !m->queue_io) | 311 | if (m->pg_init_required || !m->queue_io) |
311 | schedule_work(&m->process_queued_ios); | 312 | queue_work(kmultipathd, &m->process_queued_ios); |
312 | pgpath = NULL; | 313 | pgpath = NULL; |
313 | r = 0; | 314 | r = 0; |
314 | } else if (!pgpath) | 315 | } else if (!pgpath) |
@@ -334,7 +335,7 @@ static int queue_if_no_path(struct multipath *m, unsigned queue_if_no_path) | |||
334 | 335 | ||
335 | m->queue_if_no_path = queue_if_no_path; | 336 | m->queue_if_no_path = queue_if_no_path; |
336 | if (!m->queue_if_no_path) | 337 | if (!m->queue_if_no_path) |
337 | schedule_work(&m->process_queued_ios); | 338 | queue_work(kmultipathd, &m->process_queued_ios); |
338 | 339 | ||
339 | spin_unlock_irqrestore(&m->lock, flags); | 340 | spin_unlock_irqrestore(&m->lock, flags); |
340 | 341 | ||
@@ -800,7 +801,7 @@ static int fail_path(struct pgpath *pgpath) | |||
800 | if (pgpath == m->current_pgpath) | 801 | if (pgpath == m->current_pgpath) |
801 | m->current_pgpath = NULL; | 802 | m->current_pgpath = NULL; |
802 | 803 | ||
803 | schedule_work(&m->trigger_event); | 804 | queue_work(kmultipathd, &m->trigger_event); |
804 | 805 | ||
805 | out: | 806 | out: |
806 | spin_unlock_irqrestore(&m->lock, flags); | 807 | spin_unlock_irqrestore(&m->lock, flags); |
@@ -837,9 +838,9 @@ static int reinstate_path(struct pgpath *pgpath) | |||
837 | 838 | ||
838 | m->current_pgpath = NULL; | 839 | m->current_pgpath = NULL; |
839 | if (!m->nr_valid_paths++) | 840 | if (!m->nr_valid_paths++) |
840 | schedule_work(&m->process_queued_ios); | 841 | queue_work(kmultipathd, &m->process_queued_ios); |
841 | 842 | ||
842 | schedule_work(&m->trigger_event); | 843 | queue_work(kmultipathd, &m->trigger_event); |
843 | 844 | ||
844 | out: | 845 | out: |
845 | spin_unlock_irqrestore(&m->lock, flags); | 846 | spin_unlock_irqrestore(&m->lock, flags); |
@@ -883,7 +884,7 @@ static void bypass_pg(struct multipath *m, struct priority_group *pg, | |||
883 | 884 | ||
884 | spin_unlock_irqrestore(&m->lock, flags); | 885 | spin_unlock_irqrestore(&m->lock, flags); |
885 | 886 | ||
886 | schedule_work(&m->trigger_event); | 887 | queue_work(kmultipathd, &m->trigger_event); |
887 | } | 888 | } |
888 | 889 | ||
889 | /* | 890 | /* |
@@ -913,7 +914,7 @@ static int switch_pg_num(struct multipath *m, const char *pgstr) | |||
913 | } | 914 | } |
914 | spin_unlock_irqrestore(&m->lock, flags); | 915 | spin_unlock_irqrestore(&m->lock, flags); |
915 | 916 | ||
916 | schedule_work(&m->trigger_event); | 917 | queue_work(kmultipathd, &m->trigger_event); |
917 | return 0; | 918 | return 0; |
918 | } | 919 | } |
919 | 920 | ||
@@ -968,7 +969,7 @@ void dm_pg_init_complete(struct path *path, unsigned err_flags) | |||
968 | m->current_pgpath = NULL; | 969 | m->current_pgpath = NULL; |
969 | m->current_pg = NULL; | 970 | m->current_pg = NULL; |
970 | } | 971 | } |
971 | schedule_work(&m->process_queued_ios); | 972 | queue_work(kmultipathd, &m->process_queued_ios); |
972 | spin_unlock_irqrestore(&m->lock, flags); | 973 | spin_unlock_irqrestore(&m->lock, flags); |
973 | } | 974 | } |
974 | 975 | ||
@@ -1018,7 +1019,7 @@ static int do_end_io(struct multipath *m, struct bio *bio, | |||
1018 | bio_list_add(&m->queued_ios, bio); | 1019 | bio_list_add(&m->queued_ios, bio); |
1019 | m->queue_size++; | 1020 | m->queue_size++; |
1020 | if (!m->queue_io) | 1021 | if (!m->queue_io) |
1021 | schedule_work(&m->process_queued_ios); | 1022 | queue_work(kmultipathd, &m->process_queued_ios); |
1022 | spin_unlock(&m->lock); | 1023 | spin_unlock(&m->lock); |
1023 | 1024 | ||
1024 | return 1; /* io not complete */ | 1025 | return 1; /* io not complete */ |
@@ -1057,7 +1058,7 @@ static void multipath_presuspend(struct dm_target *ti) | |||
1057 | spin_lock_irqsave(&m->lock, flags); | 1058 | spin_lock_irqsave(&m->lock, flags); |
1058 | m->suspended = 1; | 1059 | m->suspended = 1; |
1059 | if (m->queue_if_no_path) | 1060 | if (m->queue_if_no_path) |
1060 | schedule_work(&m->process_queued_ios); | 1061 | queue_work(kmultipathd, &m->process_queued_ios); |
1061 | spin_unlock_irqrestore(&m->lock, flags); | 1062 | spin_unlock_irqrestore(&m->lock, flags); |
1062 | } | 1063 | } |
1063 | 1064 | ||
@@ -1274,6 +1275,15 @@ static int __init dm_multipath_init(void) | |||
1274 | return -EINVAL; | 1275 | return -EINVAL; |
1275 | } | 1276 | } |
1276 | 1277 | ||
1278 | kmultipathd = create_workqueue("kmpathd"); | ||
1279 | if (!kmultipathd) { | ||
1280 | DMERR("%s: failed to create workqueue kmpathd", | ||
1281 | multipath_target.name); | ||
1282 | dm_unregister_target(&multipath_target); | ||
1283 | kmem_cache_destroy(_mpio_cache); | ||
1284 | return -ENOMEM; | ||
1285 | } | ||
1286 | |||
1277 | DMINFO("dm-multipath version %u.%u.%u loaded", | 1287 | DMINFO("dm-multipath version %u.%u.%u loaded", |
1278 | multipath_target.version[0], multipath_target.version[1], | 1288 | multipath_target.version[0], multipath_target.version[1], |
1279 | multipath_target.version[2]); | 1289 | multipath_target.version[2]); |
@@ -1285,6 +1295,8 @@ static void __exit dm_multipath_exit(void) | |||
1285 | { | 1295 | { |
1286 | int r; | 1296 | int r; |
1287 | 1297 | ||
1298 | destroy_workqueue(kmultipathd); | ||
1299 | |||
1288 | r = dm_unregister_target(&multipath_target); | 1300 | r = dm_unregister_target(&multipath_target); |
1289 | if (r < 0) | 1301 | if (r < 0) |
1290 | DMERR("%s: target unregister failed %d", | 1302 | DMERR("%s: target unregister failed %d", |
diff --git a/drivers/md/dm-path-selector.c b/drivers/md/dm-path-selector.c index ac5c4bbec6c1..a28c1c2b4ef5 100644 --- a/drivers/md/dm-path-selector.c +++ b/drivers/md/dm-path-selector.c | |||
@@ -26,7 +26,7 @@ struct ps_internal { | |||
26 | static LIST_HEAD(_path_selectors); | 26 | static LIST_HEAD(_path_selectors); |
27 | static DECLARE_RWSEM(_ps_lock); | 27 | static DECLARE_RWSEM(_ps_lock); |
28 | 28 | ||
29 | struct ps_internal *__find_path_selector_type(const char *name) | 29 | static struct ps_internal *__find_path_selector_type(const char *name) |
30 | { | 30 | { |
31 | struct ps_internal *psi; | 31 | struct ps_internal *psi; |
32 | 32 | ||
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index ee175d4906c4..18e9b9953fcd 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c | |||
@@ -242,7 +242,7 @@ static void free_devices(struct list_head *devices) | |||
242 | } | 242 | } |
243 | } | 243 | } |
244 | 244 | ||
245 | void table_destroy(struct dm_table *t) | 245 | static void table_destroy(struct dm_table *t) |
246 | { | 246 | { |
247 | unsigned int i; | 247 | unsigned int i; |
248 | 248 | ||
diff --git a/drivers/md/dm-zero.c b/drivers/md/dm-zero.c index 7febc2cac73d..51c0639b2487 100644 --- a/drivers/md/dm-zero.c +++ b/drivers/md/dm-zero.c | |||
@@ -55,7 +55,7 @@ static struct target_type zero_target = { | |||
55 | .map = zero_map, | 55 | .map = zero_map, |
56 | }; | 56 | }; |
57 | 57 | ||
58 | int __init dm_zero_init(void) | 58 | static int __init dm_zero_init(void) |
59 | { | 59 | { |
60 | int r = dm_register_target(&zero_target); | 60 | int r = dm_register_target(&zero_target); |
61 | 61 | ||
@@ -65,7 +65,7 @@ int __init dm_zero_init(void) | |||
65 | return r; | 65 | return r; |
66 | } | 66 | } |
67 | 67 | ||
68 | void __exit dm_zero_exit(void) | 68 | static void __exit dm_zero_exit(void) |
69 | { | 69 | { |
70 | int r = dm_unregister_target(&zero_target); | 70 | int r = dm_unregister_target(&zero_target); |
71 | 71 | ||
diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 243ff6884e83..f6b03957efc7 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c | |||
@@ -97,6 +97,7 @@ struct mapped_device { | |||
97 | * freeze/thaw support require holding onto a super block | 97 | * freeze/thaw support require holding onto a super block |
98 | */ | 98 | */ |
99 | struct super_block *frozen_sb; | 99 | struct super_block *frozen_sb; |
100 | struct block_device *frozen_bdev; | ||
100 | }; | 101 | }; |
101 | 102 | ||
102 | #define MIN_IOS 256 | 103 | #define MIN_IOS 256 |
@@ -990,44 +991,50 @@ int dm_swap_table(struct mapped_device *md, struct dm_table *table) | |||
990 | */ | 991 | */ |
991 | static int __lock_fs(struct mapped_device *md) | 992 | static int __lock_fs(struct mapped_device *md) |
992 | { | 993 | { |
993 | struct block_device *bdev; | 994 | int error = -ENOMEM; |
994 | 995 | ||
995 | if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) | 996 | if (test_and_set_bit(DMF_FS_LOCKED, &md->flags)) |
996 | return 0; | 997 | return 0; |
997 | 998 | ||
998 | bdev = bdget_disk(md->disk, 0); | 999 | md->frozen_bdev = bdget_disk(md->disk, 0); |
999 | if (!bdev) { | 1000 | if (!md->frozen_bdev) { |
1000 | DMWARN("bdget failed in __lock_fs"); | 1001 | DMWARN("bdget failed in __lock_fs"); |
1001 | return -ENOMEM; | 1002 | goto out; |
1002 | } | 1003 | } |
1003 | 1004 | ||
1004 | WARN_ON(md->frozen_sb); | 1005 | WARN_ON(md->frozen_sb); |
1005 | md->frozen_sb = freeze_bdev(bdev); | 1006 | |
1007 | md->frozen_sb = freeze_bdev(md->frozen_bdev); | ||
1008 | if (IS_ERR(md->frozen_sb)) { | ||
1009 | error = PTR_ERR(md->frozen_sb); | ||
1010 | goto out_bdput; | ||
1011 | } | ||
1012 | |||
1006 | /* don't bdput right now, we don't want the bdev | 1013 | /* don't bdput right now, we don't want the bdev |
1007 | * to go away while it is locked. We'll bdput | 1014 | * to go away while it is locked. We'll bdput |
1008 | * in __unlock_fs | 1015 | * in __unlock_fs |
1009 | */ | 1016 | */ |
1010 | return 0; | 1017 | return 0; |
1018 | |||
1019 | out_bdput: | ||
1020 | bdput(md->frozen_bdev); | ||
1021 | md->frozen_sb = NULL; | ||
1022 | md->frozen_bdev = NULL; | ||
1023 | out: | ||
1024 | clear_bit(DMF_FS_LOCKED, &md->flags); | ||
1025 | return error; | ||
1011 | } | 1026 | } |
1012 | 1027 | ||
1013 | static int __unlock_fs(struct mapped_device *md) | 1028 | static void __unlock_fs(struct mapped_device *md) |
1014 | { | 1029 | { |
1015 | struct block_device *bdev; | ||
1016 | |||
1017 | if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) | 1030 | if (!test_and_clear_bit(DMF_FS_LOCKED, &md->flags)) |
1018 | return 0; | 1031 | return; |
1019 | 1032 | ||
1020 | bdev = bdget_disk(md->disk, 0); | 1033 | thaw_bdev(md->frozen_bdev, md->frozen_sb); |
1021 | if (!bdev) { | 1034 | bdput(md->frozen_bdev); |
1022 | DMWARN("bdget failed in __unlock_fs"); | ||
1023 | return -ENOMEM; | ||
1024 | } | ||
1025 | 1035 | ||
1026 | thaw_bdev(bdev, md->frozen_sb); | ||
1027 | md->frozen_sb = NULL; | 1036 | md->frozen_sb = NULL; |
1028 | bdput(bdev); | 1037 | md->frozen_bdev = NULL; |
1029 | bdput(bdev); | ||
1030 | return 0; | ||
1031 | } | 1038 | } |
1032 | 1039 | ||
1033 | /* | 1040 | /* |
@@ -1041,37 +1048,37 @@ int dm_suspend(struct mapped_device *md) | |||
1041 | { | 1048 | { |
1042 | struct dm_table *map; | 1049 | struct dm_table *map; |
1043 | DECLARE_WAITQUEUE(wait, current); | 1050 | DECLARE_WAITQUEUE(wait, current); |
1051 | int error = -EINVAL; | ||
1044 | 1052 | ||
1045 | /* Flush I/O to the device. */ | 1053 | /* Flush I/O to the device. */ |
1046 | down_read(&md->lock); | 1054 | down_read(&md->lock); |
1047 | if (test_bit(DMF_BLOCK_IO, &md->flags)) { | 1055 | if (test_bit(DMF_BLOCK_IO, &md->flags)) |
1048 | up_read(&md->lock); | 1056 | goto out_read_unlock; |
1049 | return -EINVAL; | 1057 | |
1050 | } | 1058 | error = __lock_fs(md); |
1059 | if (error) | ||
1060 | goto out_read_unlock; | ||
1051 | 1061 | ||
1052 | map = dm_get_table(md); | 1062 | map = dm_get_table(md); |
1053 | if (map) | 1063 | if (map) |
1054 | dm_table_presuspend_targets(map); | 1064 | dm_table_presuspend_targets(map); |
1055 | __lock_fs(md); | ||
1056 | 1065 | ||
1057 | up_read(&md->lock); | 1066 | up_read(&md->lock); |
1058 | 1067 | ||
1059 | /* | 1068 | /* |
1060 | * First we set the BLOCK_IO flag so no more ios will be | 1069 | * First we set the BLOCK_IO flag so no more ios will be mapped. |
1061 | * mapped. | 1070 | * |
1071 | * If the flag is already set we know another thread is trying to | ||
1072 | * suspend as well, so we leave the fs locked for this thread. | ||
1062 | */ | 1073 | */ |
1074 | error = -EINVAL; | ||
1063 | down_write(&md->lock); | 1075 | down_write(&md->lock); |
1064 | if (test_bit(DMF_BLOCK_IO, &md->flags)) { | 1076 | if (test_and_set_bit(DMF_BLOCK_IO, &md->flags)) { |
1065 | /* | 1077 | if (map) |
1066 | * If we get here we know another thread is | 1078 | dm_table_put(map); |
1067 | * trying to suspend as well, so we leave the fs | 1079 | goto out_write_unlock; |
1068 | * locked for this thread. | ||
1069 | */ | ||
1070 | up_write(&md->lock); | ||
1071 | return -EINVAL; | ||
1072 | } | 1080 | } |
1073 | 1081 | ||
1074 | set_bit(DMF_BLOCK_IO, &md->flags); | ||
1075 | add_wait_queue(&md->wait, &wait); | 1082 | add_wait_queue(&md->wait, &wait); |
1076 | up_write(&md->lock); | 1083 | up_write(&md->lock); |
1077 | 1084 | ||
@@ -1099,12 +1106,9 @@ int dm_suspend(struct mapped_device *md) | |||
1099 | remove_wait_queue(&md->wait, &wait); | 1106 | remove_wait_queue(&md->wait, &wait); |
1100 | 1107 | ||
1101 | /* were we interrupted ? */ | 1108 | /* were we interrupted ? */ |
1102 | if (atomic_read(&md->pending)) { | 1109 | error = -EINTR; |
1103 | __unlock_fs(md); | 1110 | if (atomic_read(&md->pending)) |
1104 | clear_bit(DMF_BLOCK_IO, &md->flags); | 1111 | goto out_unfreeze; |
1105 | up_write(&md->lock); | ||
1106 | return -EINTR; | ||
1107 | } | ||
1108 | 1112 | ||
1109 | set_bit(DMF_SUSPENDED, &md->flags); | 1113 | set_bit(DMF_SUSPENDED, &md->flags); |
1110 | 1114 | ||
@@ -1115,6 +1119,18 @@ int dm_suspend(struct mapped_device *md) | |||
1115 | up_write(&md->lock); | 1119 | up_write(&md->lock); |
1116 | 1120 | ||
1117 | return 0; | 1121 | return 0; |
1122 | |||
1123 | out_unfreeze: | ||
1124 | /* FIXME Undo dm_table_presuspend_targets */ | ||
1125 | __unlock_fs(md); | ||
1126 | clear_bit(DMF_BLOCK_IO, &md->flags); | ||
1127 | out_write_unlock: | ||
1128 | up_write(&md->lock); | ||
1129 | return error; | ||
1130 | |||
1131 | out_read_unlock: | ||
1132 | up_read(&md->lock); | ||
1133 | return error; | ||
1118 | } | 1134 | } |
1119 | 1135 | ||
1120 | int dm_resume(struct mapped_device *md) | 1136 | int dm_resume(struct mapped_device *md) |
diff --git a/drivers/md/linear.c b/drivers/md/linear.c index 161e9aa87291..b1941b887f46 100644 --- a/drivers/md/linear.c +++ b/drivers/md/linear.c | |||
@@ -269,9 +269,8 @@ static int linear_make_request (request_queue_t *q, struct bio *bio) | |||
269 | * split it. | 269 | * split it. |
270 | */ | 270 | */ |
271 | struct bio_pair *bp; | 271 | struct bio_pair *bp; |
272 | bp = bio_split(bio, bio_split_pool, | 272 | bp = bio_split(bio, bio_split_pool, |
273 | (bio->bi_sector + (bio->bi_size >> 9) - | 273 | ((tmp_dev->offset + tmp_dev->size)<<1) - bio->bi_sector); |
274 | (tmp_dev->offset + tmp_dev->size))<<1); | ||
275 | if (linear_make_request(q, &bp->bio1)) | 274 | if (linear_make_request(q, &bp->bio1)) |
276 | generic_make_request(&bp->bio1); | 275 | generic_make_request(&bp->bio1); |
277 | if (linear_make_request(q, &bp->bio2)) | 276 | if (linear_make_request(q, &bp->bio2)) |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 97af857d8a88..d899204d3743 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -957,7 +957,7 @@ static void super_1_sync(mddev_t *mddev, mdk_rdev_t *rdev) | |||
957 | } | 957 | } |
958 | 958 | ||
959 | 959 | ||
960 | struct super_type super_types[] = { | 960 | static struct super_type super_types[] = { |
961 | [0] = { | 961 | [0] = { |
962 | .name = "0.90.0", | 962 | .name = "0.90.0", |
963 | .owner = THIS_MODULE, | 963 | .owner = THIS_MODULE, |
@@ -2740,7 +2740,7 @@ static struct block_device_operations md_fops = | |||
2740 | .revalidate_disk= md_revalidate, | 2740 | .revalidate_disk= md_revalidate, |
2741 | }; | 2741 | }; |
2742 | 2742 | ||
2743 | int md_thread(void * arg) | 2743 | static int md_thread(void * arg) |
2744 | { | 2744 | { |
2745 | mdk_thread_t *thread = arg; | 2745 | mdk_thread_t *thread = arg; |
2746 | 2746 | ||
@@ -3232,7 +3232,7 @@ void md_handle_safemode(mddev_t *mddev) | |||
3232 | } | 3232 | } |
3233 | 3233 | ||
3234 | 3234 | ||
3235 | DECLARE_WAIT_QUEUE_HEAD(resync_wait); | 3235 | static DECLARE_WAIT_QUEUE_HEAD(resync_wait); |
3236 | 3236 | ||
3237 | #define SYNC_MARKS 10 | 3237 | #define SYNC_MARKS 10 |
3238 | #define SYNC_MARK_STEP (3*HZ) | 3238 | #define SYNC_MARK_STEP (3*HZ) |
@@ -3575,8 +3575,8 @@ void md_check_recovery(mddev_t *mddev) | |||
3575 | } | 3575 | } |
3576 | } | 3576 | } |
3577 | 3577 | ||
3578 | int md_notify_reboot(struct notifier_block *this, | 3578 | static int md_notify_reboot(struct notifier_block *this, |
3579 | unsigned long code, void *x) | 3579 | unsigned long code, void *x) |
3580 | { | 3580 | { |
3581 | struct list_head *tmp; | 3581 | struct list_head *tmp; |
3582 | mddev_t *mddev; | 3582 | mddev_t *mddev; |
@@ -3599,7 +3599,7 @@ int md_notify_reboot(struct notifier_block *this, | |||
3599 | return NOTIFY_DONE; | 3599 | return NOTIFY_DONE; |
3600 | } | 3600 | } |
3601 | 3601 | ||
3602 | struct notifier_block md_notifier = { | 3602 | static struct notifier_block md_notifier = { |
3603 | .notifier_call = md_notify_reboot, | 3603 | .notifier_call = md_notify_reboot, |
3604 | .next = NULL, | 3604 | .next = NULL, |
3605 | .priority = INT_MAX, /* before any real devices */ | 3605 | .priority = INT_MAX, /* before any real devices */ |
@@ -3616,7 +3616,7 @@ static void md_geninit(void) | |||
3616 | p->proc_fops = &md_seq_fops; | 3616 | p->proc_fops = &md_seq_fops; |
3617 | } | 3617 | } |
3618 | 3618 | ||
3619 | int __init md_init(void) | 3619 | static int __init md_init(void) |
3620 | { | 3620 | { |
3621 | int minor; | 3621 | int minor; |
3622 | 3622 | ||
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c index 1891e4930dcc..2ae2d709cb15 100644 --- a/drivers/md/multipath.c +++ b/drivers/md/multipath.c | |||
@@ -103,7 +103,8 @@ static void multipath_end_bh_io (struct multipath_bh *mp_bh, int err) | |||
103 | mempool_free(mp_bh, conf->pool); | 103 | mempool_free(mp_bh, conf->pool); |
104 | } | 104 | } |
105 | 105 | ||
106 | int multipath_end_request(struct bio *bio, unsigned int bytes_done, int error) | 106 | static int multipath_end_request(struct bio *bio, unsigned int bytes_done, |
107 | int error) | ||
107 | { | 108 | { |
108 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); | 109 | int uptodate = test_bit(BIO_UPTODATE, &bio->bi_flags); |
109 | struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private); | 110 | struct multipath_bh * mp_bh = (struct multipath_bh *)(bio->bi_private); |
@@ -461,10 +462,6 @@ static int multipath_run (mddev_t *mddev) | |||
461 | } | 462 | } |
462 | memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks); | 463 | memset(conf->multipaths, 0, sizeof(struct multipath_info)*mddev->raid_disks); |
463 | 464 | ||
464 | mddev->queue->unplug_fn = multipath_unplug; | ||
465 | |||
466 | mddev->queue->issue_flush_fn = multipath_issue_flush; | ||
467 | |||
468 | conf->working_disks = 0; | 465 | conf->working_disks = 0; |
469 | ITERATE_RDEV(mddev,rdev,tmp) { | 466 | ITERATE_RDEV(mddev,rdev,tmp) { |
470 | disk_idx = rdev->raid_disk; | 467 | disk_idx = rdev->raid_disk; |
@@ -527,6 +524,10 @@ static int multipath_run (mddev_t *mddev) | |||
527 | * Ok, everything is just fine now | 524 | * Ok, everything is just fine now |
528 | */ | 525 | */ |
529 | mddev->array_size = mddev->size; | 526 | mddev->array_size = mddev->size; |
527 | |||
528 | mddev->queue->unplug_fn = multipath_unplug; | ||
529 | mddev->queue->issue_flush_fn = multipath_issue_flush; | ||
530 | |||
530 | return 0; | 531 | return 0; |
531 | 532 | ||
532 | out_free_conf: | 533 | out_free_conf: |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 83380b5d6593..1db5de52d376 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -1197,10 +1197,6 @@ static int run(mddev_t *mddev) | |||
1197 | if (!conf->r1bio_pool) | 1197 | if (!conf->r1bio_pool) |
1198 | goto out_no_mem; | 1198 | goto out_no_mem; |
1199 | 1199 | ||
1200 | mddev->queue->unplug_fn = raid1_unplug; | ||
1201 | |||
1202 | mddev->queue->issue_flush_fn = raid1_issue_flush; | ||
1203 | |||
1204 | ITERATE_RDEV(mddev, rdev, tmp) { | 1200 | ITERATE_RDEV(mddev, rdev, tmp) { |
1205 | disk_idx = rdev->raid_disk; | 1201 | disk_idx = rdev->raid_disk; |
1206 | if (disk_idx >= mddev->raid_disks | 1202 | if (disk_idx >= mddev->raid_disks |
@@ -1282,6 +1278,9 @@ static int run(mddev_t *mddev) | |||
1282 | */ | 1278 | */ |
1283 | mddev->array_size = mddev->size; | 1279 | mddev->array_size = mddev->size; |
1284 | 1280 | ||
1281 | mddev->queue->unplug_fn = raid1_unplug; | ||
1282 | mddev->queue->issue_flush_fn = raid1_issue_flush; | ||
1283 | |||
1285 | return 0; | 1284 | return 0; |
1286 | 1285 | ||
1287 | out_no_mem: | 1286 | out_no_mem: |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index e9dc2876a626..3c37be6423d7 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -1639,9 +1639,6 @@ static int run(mddev_t *mddev) | |||
1639 | mdname(mddev)); | 1639 | mdname(mddev)); |
1640 | goto out_free_conf; | 1640 | goto out_free_conf; |
1641 | } | 1641 | } |
1642 | mddev->queue->unplug_fn = raid10_unplug; | ||
1643 | |||
1644 | mddev->queue->issue_flush_fn = raid10_issue_flush; | ||
1645 | 1642 | ||
1646 | ITERATE_RDEV(mddev, rdev, tmp) { | 1643 | ITERATE_RDEV(mddev, rdev, tmp) { |
1647 | disk_idx = rdev->raid_disk; | 1644 | disk_idx = rdev->raid_disk; |
@@ -1713,6 +1710,9 @@ static int run(mddev_t *mddev) | |||
1713 | mddev->array_size = size/2; | 1710 | mddev->array_size = size/2; |
1714 | mddev->resync_max_sectors = size; | 1711 | mddev->resync_max_sectors = size; |
1715 | 1712 | ||
1713 | mddev->queue->unplug_fn = raid10_unplug; | ||
1714 | mddev->queue->issue_flush_fn = raid10_issue_flush; | ||
1715 | |||
1716 | /* Calculate max read-ahead size. | 1716 | /* Calculate max read-ahead size. |
1717 | * We need to readahead at least twice a whole stripe.... | 1717 | * We need to readahead at least twice a whole stripe.... |
1718 | * maybe... | 1718 | * maybe... |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index e96e2a10a9c9..3cb11ac232fa 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -1620,9 +1620,6 @@ static int run (mddev_t *mddev) | |||
1620 | atomic_set(&conf->active_stripes, 0); | 1620 | atomic_set(&conf->active_stripes, 0); |
1621 | atomic_set(&conf->preread_active_stripes, 0); | 1621 | atomic_set(&conf->preread_active_stripes, 0); |
1622 | 1622 | ||
1623 | mddev->queue->unplug_fn = raid5_unplug_device; | ||
1624 | mddev->queue->issue_flush_fn = raid5_issue_flush; | ||
1625 | |||
1626 | PRINTK("raid5: run(%s) called.\n", mdname(mddev)); | 1623 | PRINTK("raid5: run(%s) called.\n", mdname(mddev)); |
1627 | 1624 | ||
1628 | ITERATE_RDEV(mddev,rdev,tmp) { | 1625 | ITERATE_RDEV(mddev,rdev,tmp) { |
@@ -1728,6 +1725,10 @@ memory = conf->max_nr_stripes * (sizeof(struct stripe_head) + | |||
1728 | } | 1725 | } |
1729 | 1726 | ||
1730 | /* Ok, everything is just fine now */ | 1727 | /* Ok, everything is just fine now */ |
1728 | |||
1729 | mddev->queue->unplug_fn = raid5_unplug_device; | ||
1730 | mddev->queue->issue_flush_fn = raid5_issue_flush; | ||
1731 | |||
1731 | mddev->array_size = mddev->size * (mddev->raid_disks - 1); | 1732 | mddev->array_size = mddev->size * (mddev->raid_disks - 1); |
1732 | return 0; | 1733 | return 0; |
1733 | abort: | 1734 | abort: |
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c index 8a33f351e092..908edd78a792 100644 --- a/drivers/md/raid6main.c +++ b/drivers/md/raid6main.c | |||
@@ -1779,9 +1779,6 @@ static int run (mddev_t *mddev) | |||
1779 | atomic_set(&conf->active_stripes, 0); | 1779 | atomic_set(&conf->active_stripes, 0); |
1780 | atomic_set(&conf->preread_active_stripes, 0); | 1780 | atomic_set(&conf->preread_active_stripes, 0); |
1781 | 1781 | ||
1782 | mddev->queue->unplug_fn = raid6_unplug_device; | ||
1783 | mddev->queue->issue_flush_fn = raid6_issue_flush; | ||
1784 | |||
1785 | PRINTK("raid6: run(%s) called.\n", mdname(mddev)); | 1782 | PRINTK("raid6: run(%s) called.\n", mdname(mddev)); |
1786 | 1783 | ||
1787 | ITERATE_RDEV(mddev,rdev,tmp) { | 1784 | ITERATE_RDEV(mddev,rdev,tmp) { |
@@ -1895,6 +1892,9 @@ static int run (mddev_t *mddev) | |||
1895 | 1892 | ||
1896 | /* Ok, everything is just fine now */ | 1893 | /* Ok, everything is just fine now */ |
1897 | mddev->array_size = mddev->size * (mddev->raid_disks - 2); | 1894 | mddev->array_size = mddev->size * (mddev->raid_disks - 2); |
1895 | |||
1896 | mddev->queue->unplug_fn = raid6_unplug_device; | ||
1897 | mddev->queue->issue_flush_fn = raid6_issue_flush; | ||
1898 | return 0; | 1898 | return 0; |
1899 | abort: | 1899 | abort: |
1900 | if (conf) { | 1900 | if (conf) { |
diff --git a/drivers/media/common/saa7146_core.c b/drivers/media/common/saa7146_core.c index 9f6c19ac1285..50e8b8654018 100644 --- a/drivers/media/common/saa7146_core.c +++ b/drivers/media/common/saa7146_core.c | |||
@@ -23,9 +23,9 @@ | |||
23 | LIST_HEAD(saa7146_devices); | 23 | LIST_HEAD(saa7146_devices); |
24 | DECLARE_MUTEX(saa7146_devices_lock); | 24 | DECLARE_MUTEX(saa7146_devices_lock); |
25 | 25 | ||
26 | static int saa7146_num = 0; | 26 | static int saa7146_num; |
27 | 27 | ||
28 | unsigned int saa7146_debug = 0; | 28 | unsigned int saa7146_debug; |
29 | 29 | ||
30 | module_param(saa7146_debug, int, 0644); | 30 | module_param(saa7146_debug, int, 0644); |
31 | MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); | 31 | MODULE_PARM_DESC(saa7146_debug, "debug level (default: 0)"); |
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig index 883ec08490f4..4983e1b1bb1d 100644 --- a/drivers/media/dvb/Kconfig +++ b/drivers/media/dvb/Kconfig | |||
@@ -33,7 +33,7 @@ source "drivers/media/dvb/dibusb/Kconfig" | |||
33 | source "drivers/media/dvb/cinergyT2/Kconfig" | 33 | source "drivers/media/dvb/cinergyT2/Kconfig" |
34 | 34 | ||
35 | comment "Supported FlexCopII (B2C2) Adapters" | 35 | comment "Supported FlexCopII (B2C2) Adapters" |
36 | depends on DVB_CORE && PCI | 36 | depends on DVB_CORE && (PCI || USB) |
37 | source "drivers/media/dvb/b2c2/Kconfig" | 37 | source "drivers/media/dvb/b2c2/Kconfig" |
38 | 38 | ||
39 | comment "Supported BT878 Adapters" | 39 | comment "Supported BT878 Adapters" |
diff --git a/drivers/media/dvb/b2c2/Kconfig b/drivers/media/dvb/b2c2/Kconfig index 52596907a0be..99bd675df955 100644 --- a/drivers/media/dvb/b2c2/Kconfig +++ b/drivers/media/dvb/b2c2/Kconfig | |||
@@ -1,26 +1,50 @@ | |||
1 | config DVB_B2C2_SKYSTAR | 1 | config DVB_B2C2_FLEXCOP |
2 | tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI" | 2 | tristate "Technisat/B2C2 FlexCopII(b) and FlexCopIII adapters" |
3 | depends on DVB_CORE && PCI | 3 | depends on DVB_CORE |
4 | select DVB_STV0299 | 4 | select DVB_STV0299 |
5 | select DVB_MT352 | 5 | select DVB_MT352 |
6 | select DVB_MT312 | 6 | select DVB_MT312 |
7 | select DVB_NXT2002 | 7 | select DVB_NXT2002 |
8 | select DVB_STV0297 | ||
8 | help | 9 | help |
9 | Support for the Skystar2 PCI DVB card by Technisat, which | 10 | Support for the digital TV receiver chip made by B2C2 Inc. included in |
10 | is equipped with the FlexCopII chipset by B2C2, and | 11 | Technisats PCI cards and USB boxes. |
11 | for the B2C2/BBTI Air2PC-ATSC card. | ||
12 | 12 | ||
13 | Say Y if you own such a device and want to use it. | 13 | Say Y if you own such a device and want to use it. |
14 | 14 | ||
15 | config DVB_B2C2_USB | 15 | config DVB_B2C2_FLEXCOP_PCI |
16 | tristate "B2C2/Technisat Air/Sky/Cable2PC USB" | 16 | tristate "Technisat/B2C2 Air/Sky/Cable2PC PCI" |
17 | depends on DVB_CORE && USB && EXPERIMENTAL | 17 | depends on DVB_B2C2_FLEXCOP && PCI |
18 | help | ||
19 | Support for the Air/Sky/CableStar2 PCI card (DVB/ATSC) by Technisat/B2C2. | ||
20 | |||
21 | Say Y if you own such a device and want to use it. | ||
22 | |||
23 | config DVB_B2C2_FLEXCOP_USB | ||
24 | tristate "Technisat/B2C2 Air/Sky/Cable2PC USB" | ||
25 | depends on DVB_B2C2_FLEXCOP && USB | ||
26 | help | ||
27 | Support for the Air/Sky/Cable2PC USB1.1 box (DVB/ATSC) by Technisat/B2C2, | ||
28 | |||
29 | Say Y if you own such a device and want to use it. | ||
30 | |||
31 | config DVB_B2C2_FLEXCOP_DEBUG | ||
32 | bool "Enable debug for the B2C2 FlexCop drivers" | ||
33 | depends on DVB_B2C2_FLEXCOP | ||
34 | help | ||
35 | Say Y if you want to enable the module option to control debug messages | ||
36 | of all B2C2 FlexCop drivers. | ||
37 | |||
38 | config DVB_B2C2_SKYSTAR | ||
39 | tristate "B2C2/Technisat Air/Sky/CableStar 2 PCI" | ||
40 | depends on DVB_CORE && PCI | ||
18 | select DVB_STV0299 | 41 | select DVB_STV0299 |
19 | select DVB_MT352 | 42 | select DVB_MT352 |
43 | select DVB_MT312 | ||
44 | select DVB_NXT2002 | ||
20 | help | 45 | help |
21 | Support for the Air/Sky/Cable2PC USB DVB device by B2C2. Currently | 46 | Support for the Skystar2 PCI DVB card by Technisat, which |
22 | the does nothing, but providing basic function for the used usb | 47 | is equipped with the FlexCopII chipset by B2C2, and |
23 | protocol. | 48 | for the B2C2/BBTI Air2PC-ATSC card. |
24 | 49 | ||
25 | Say Y if you own such a device and want to use it. | 50 | Say Y if you own such a device and want to use it. |
26 | |||
diff --git a/drivers/media/dvb/b2c2/Makefile b/drivers/media/dvb/b2c2/Makefile index 9fb1247bfab8..7703812af34f 100644 --- a/drivers/media/dvb/b2c2/Makefile +++ b/drivers/media/dvb/b2c2/Makefile | |||
@@ -1,6 +1,14 @@ | |||
1 | obj-b2c2-usb = b2c2-usb-core.o b2c2-common.o | 1 | b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \ |
2 | flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o \ | ||
3 | flexcop-dma.o | ||
4 | obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o | ||
5 | |||
6 | b2c2-flexcop-pci-objs = flexcop-pci.o | ||
7 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_PCI) += b2c2-flexcop-pci.o | ||
8 | |||
9 | b2c2-flexcop-usb-objs = flexcop-usb.o | ||
10 | obj-$(CONFIG_DVB_B2C2_FLEXCOP_USB) += b2c2-flexcop-usb.o | ||
2 | 11 | ||
3 | obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o | 12 | obj-$(CONFIG_DVB_B2C2_SKYSTAR) += skystar2.o |
4 | obj-$(CONFIG_DVB_B2C2_USB) + = b2c2-usb.o | ||
5 | 13 | ||
6 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ | 14 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ |
diff --git a/drivers/media/dvb/b2c2/b2c2-common.c b/drivers/media/dvb/b2c2/b2c2-common.c deleted file mode 100644 index 000d60c405e3..000000000000 --- a/drivers/media/dvb/b2c2/b2c2-common.c +++ /dev/null | |||
@@ -1,214 +0,0 @@ | |||
1 | /* | ||
2 | * b2c2-common.c - common methods for the B2C2/Technisat SkyStar2 PCI DVB card and | ||
3 | * for the B2C2/Technisat Sky/Cable/AirStar USB devices | ||
4 | * based on the FlexCopII/FlexCopIII by B2C2, Inc. | ||
5 | * | ||
6 | * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc | ||
7 | * | ||
8 | * FIX: DISEQC Tone Burst in flexcop_diseqc_ioctl() | ||
9 | * FIX: FULL soft DiSEqC for skystar2 (FlexCopII rev 130) VP310 equipped | ||
10 | * Vincenzo Di Massa, hawk.it at tiscalinet.it | ||
11 | * | ||
12 | * Converted to Linux coding style | ||
13 | * Misc reorganization, polishing, restyling | ||
14 | * Roberto Ragusa, r.ragusa at libero.it | ||
15 | * | ||
16 | * Added hardware filtering support, | ||
17 | * Niklas Peinecke, peinecke at gdv.uni-hannover.de | ||
18 | * | ||
19 | * This program is free software; you can redistribute it and/or | ||
20 | * modify it under the terms of the GNU Lesser General Public License | ||
21 | * as published by the Free Software Foundation; either version 2.1 | ||
22 | * of the License, or (at your option) any later version. | ||
23 | * | ||
24 | * This program is distributed in the hope that it will be useful, | ||
25 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
26 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
27 | * GNU General Public License for more details. | ||
28 | * | ||
29 | * You should have received a copy of the GNU Lesser General Public License | ||
30 | * along with this program; if not, write to the Free Software | ||
31 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
32 | * | ||
33 | */ | ||
34 | #include "stv0299.h" | ||
35 | #include "mt352.h" | ||
36 | #include "mt312.h" | ||
37 | |||
38 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
39 | { | ||
40 | u8 aclk = 0; | ||
41 | u8 bclk = 0; | ||
42 | |||
43 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
44 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
45 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
46 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
47 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
48 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
49 | |||
50 | stv0299_writereg (fe, 0x13, aclk); | ||
51 | stv0299_writereg (fe, 0x14, bclk); | ||
52 | stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); | ||
53 | stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); | ||
54 | stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
60 | { | ||
61 | u8 buf[4]; | ||
62 | u32 div; | ||
63 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
64 | // struct adapter* adapter = (struct adapter*) fe->dvb->priv; | ||
65 | |||
66 | div = params->frequency / 125; | ||
67 | |||
68 | buf[0] = (div >> 8) & 0x7f; | ||
69 | buf[1] = div & 0xff; | ||
70 | buf[2] = 0x84; // 0xC4 | ||
71 | buf[3] = 0x08; | ||
72 | |||
73 | if (params->frequency < 1500000) buf[3] |= 0x10; | ||
74 | |||
75 | // if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO; | ||
76 | return 0; | ||
77 | } | ||
78 | |||
79 | static u8 samsung_tbmu24112_inittab[] = { | ||
80 | 0x01, 0x15, | ||
81 | 0x02, 0x30, | ||
82 | 0x03, 0x00, | ||
83 | 0x04, 0x7D, | ||
84 | 0x05, 0x35, | ||
85 | 0x06, 0x02, | ||
86 | 0x07, 0x00, | ||
87 | 0x08, 0xC3, | ||
88 | 0x0C, 0x00, | ||
89 | 0x0D, 0x81, | ||
90 | 0x0E, 0x23, | ||
91 | 0x0F, 0x12, | ||
92 | 0x10, 0x7E, | ||
93 | 0x11, 0x84, | ||
94 | 0x12, 0xB9, | ||
95 | 0x13, 0x88, | ||
96 | 0x14, 0x89, | ||
97 | 0x15, 0xC9, | ||
98 | 0x16, 0x00, | ||
99 | 0x17, 0x5C, | ||
100 | 0x18, 0x00, | ||
101 | 0x19, 0x00, | ||
102 | 0x1A, 0x00, | ||
103 | 0x1C, 0x00, | ||
104 | 0x1D, 0x00, | ||
105 | 0x1E, 0x00, | ||
106 | 0x1F, 0x3A, | ||
107 | 0x20, 0x2E, | ||
108 | 0x21, 0x80, | ||
109 | 0x22, 0xFF, | ||
110 | 0x23, 0xC1, | ||
111 | 0x28, 0x00, | ||
112 | 0x29, 0x1E, | ||
113 | 0x2A, 0x14, | ||
114 | 0x2B, 0x0F, | ||
115 | 0x2C, 0x09, | ||
116 | 0x2D, 0x05, | ||
117 | 0x31, 0x1F, | ||
118 | 0x32, 0x19, | ||
119 | 0x33, 0xFE, | ||
120 | 0x34, 0x93, | ||
121 | 0xff, 0xff, | ||
122 | }; | ||
123 | |||
124 | static struct stv0299_config samsung_tbmu24112_config = { | ||
125 | .demod_address = 0x68, | ||
126 | .inittab = samsung_tbmu24112_inittab, | ||
127 | .mclk = 88000000UL, | ||
128 | .invert = 0, | ||
129 | .enhanced_tuning = 0, | ||
130 | .skip_reinit = 0, | ||
131 | .lock_output = STV0229_LOCKOUTPUT_LK, | ||
132 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
133 | .min_delay_ms = 100, | ||
134 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, | ||
135 | .pll_set = samsung_tbmu24112_pll_set, | ||
136 | }; | ||
137 | |||
138 | |||
139 | |||
140 | |||
141 | |||
142 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | ||
143 | { | ||
144 | static u8 mt352_clock_config [] = { 0x89, 0x10, 0x2d }; | ||
145 | static u8 mt352_reset [] = { 0x50, 0x80 }; | ||
146 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
147 | static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; | ||
148 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | ||
149 | |||
150 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | ||
151 | udelay(2000); | ||
152 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | ||
153 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | ||
154 | |||
155 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); | ||
156 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | ||
162 | { | ||
163 | u32 div; | ||
164 | unsigned char bs = 0; | ||
165 | |||
166 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | ||
167 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | ||
168 | |||
169 | if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; | ||
170 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; | ||
171 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; | ||
172 | |||
173 | pllbuf[0] = 0xc2; // Note: non-linux standard PLL i2c address | ||
174 | pllbuf[1] = div >> 8; | ||
175 | pllbuf[2] = div & 0xff; | ||
176 | pllbuf[3] = 0xcc; | ||
177 | pllbuf[4] = bs; | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | static struct mt352_config samsung_tdtc9251dh0_config = { | ||
183 | |||
184 | .demod_address = 0x0f, | ||
185 | .demod_init = samsung_tdtc9251dh0_demod_init, | ||
186 | .pll_set = samsung_tdtc9251dh0_pll_set, | ||
187 | }; | ||
188 | |||
189 | static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
190 | { | ||
191 | u8 buf[4]; | ||
192 | u32 div; | ||
193 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
194 | // struct adapter* adapter = (struct adapter*) fe->dvb->priv; | ||
195 | |||
196 | div = (params->frequency + (125/2)) / 125; | ||
197 | |||
198 | buf[0] = (div >> 8) & 0x7f; | ||
199 | buf[1] = (div >> 0) & 0xff; | ||
200 | buf[2] = 0x84 | ((div >> 10) & 0x60); | ||
201 | buf[3] = 0x80; | ||
202 | |||
203 | if (params->frequency < 1550000) | ||
204 | buf[3] |= 0x02; | ||
205 | |||
206 | //if (i2c_transfer (&adapter->i2c_adap, &msg, 1) != 1) return -EIO; | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | ||
211 | |||
212 | .demod_address = 0x0e, | ||
213 | .pll_set = skystar23_samsung_tbdu18132_pll_set, | ||
214 | }; | ||
diff --git a/drivers/media/dvb/b2c2/b2c2-usb-core.c b/drivers/media/dvb/b2c2/b2c2-usb-core.c deleted file mode 100644 index 9306da046c91..000000000000 --- a/drivers/media/dvb/b2c2/b2c2-usb-core.c +++ /dev/null | |||
@@ -1,549 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Patrick Boettcher <patrick.boettcher@desy.de>, | ||
3 | * Luca Bertagnolio <>, | ||
4 | * | ||
5 | * based on information provided by John Jurrius from BBTI, Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or | ||
8 | * modify it under the terms of the GNU General Public License as | ||
9 | * published by the Free Software Foundation, version 2. | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #include <linux/config.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/usb.h> | ||
16 | #include <linux/moduleparam.h> | ||
17 | #include <linux/pci.h> | ||
18 | #include <linux/version.h> | ||
19 | |||
20 | #include "dmxdev.h" | ||
21 | #include "dvb_demux.h" | ||
22 | #include "dvb_filter.h" | ||
23 | #include "dvb_net.h" | ||
24 | #include "dvb_frontend.h" | ||
25 | |||
26 | /* debug */ | ||
27 | #define dprintk(level,args...) \ | ||
28 | do { if ((debug & level)) { printk(args); } } while (0) | ||
29 | #define debug_dump(b,l) if (debug) {\ | ||
30 | int i; deb_xfer("%s: %d > ",__FUNCTION__,l); \ | ||
31 | for (i = 0; i < l; i++) deb_xfer("%02x ", b[i]); \ | ||
32 | deb_xfer("\n");\ | ||
33 | } | ||
34 | |||
35 | static int debug; | ||
36 | module_param(debug, int, 0644); | ||
37 | MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4 (or-able))."); | ||
38 | |||
39 | #define deb_info(args...) dprintk(0x01,args) | ||
40 | #define deb_ts(args...) dprintk(0x02,args) | ||
41 | #define deb_ctrl(args...) dprintk(0x04,args) | ||
42 | |||
43 | /* Version information */ | ||
44 | #define DRIVER_VERSION "0.0" | ||
45 | #define DRIVER_DESC "Driver for B2C2/Technisat Air/Cable/Sky-2-PC USB devices" | ||
46 | #define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de" | ||
47 | |||
48 | /* transfer parameters */ | ||
49 | #define B2C2_USB_FRAMES_PER_ISO 4 | ||
50 | #define B2C2_USB_NUM_ISO_URB 4 /* TODO check out a good value */ | ||
51 | |||
52 | #define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(b2c2->udev,0) | ||
53 | #define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(b2c2->udev,0) | ||
54 | #define B2C2_USB_DATA_PIPE usb_rcvisocpipe(b2c2->udev,0x81) | ||
55 | |||
56 | struct usb_b2c2_usb { | ||
57 | struct usb_device *udev; | ||
58 | struct usb_interface *uintf; | ||
59 | |||
60 | u8 *iso_buffer; | ||
61 | int buffer_size; | ||
62 | dma_addr_t iso_dma_handle; | ||
63 | struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; | ||
64 | }; | ||
65 | |||
66 | |||
67 | /* | ||
68 | * USB | ||
69 | * 10 90 34 12 78 56 04 00 | ||
70 | * usb_control_msg(udev, usb_sndctrlpipe(udev,0), | ||
71 | * 0x90, | ||
72 | * 0x10, | ||
73 | * 0x1234, | ||
74 | * 0x5678, | ||
75 | * buf, | ||
76 | * 4, | ||
77 | * 5*HZ); | ||
78 | * | ||
79 | * extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, | ||
80 | * __u8 request, | ||
81 | * __u8 requesttype, | ||
82 | * __u16 value, | ||
83 | * __u16 index, | ||
84 | * void *data, | ||
85 | * __u16 size, | ||
86 | * int timeout); | ||
87 | * | ||
88 | */ | ||
89 | |||
90 | /* request types */ | ||
91 | typedef enum { | ||
92 | |||
93 | /* something is wrong with this part | ||
94 | RTYPE_READ_DW = (1 << 6), | ||
95 | RTYPE_WRITE_DW_1 = (3 << 6), | ||
96 | RTYPE_READ_V8_MEMORY = (6 << 6), | ||
97 | RTYPE_WRITE_V8_MEMORY = (7 << 6), | ||
98 | RTYPE_WRITE_V8_FLASH = (8 << 6), | ||
99 | RTYPE_GENERIC = (9 << 6), | ||
100 | */ | ||
101 | RTYPE_READ_DW = (3 << 6), | ||
102 | RTYPE_WRITE_DW_1 = (1 << 6), | ||
103 | |||
104 | RTYPE_READ_V8_MEMORY = (6 << 6), | ||
105 | RTYPE_WRITE_V8_MEMORY = (7 << 6), | ||
106 | RTYPE_WRITE_V8_FLASH = (8 << 6), | ||
107 | RTYPE_GENERIC = (9 << 6), | ||
108 | } b2c2_usb_request_type_t; | ||
109 | |||
110 | /* request */ | ||
111 | typedef enum { | ||
112 | B2C2_USB_WRITE_V8_MEM = 0x04, | ||
113 | B2C2_USB_READ_V8_MEM = 0x05, | ||
114 | B2C2_USB_READ_REG = 0x08, | ||
115 | B2C2_USB_WRITE_REG = 0x0A, | ||
116 | /* B2C2_USB_WRITEREGLO = 0x0A, */ | ||
117 | B2C2_USB_WRITEREGHI = 0x0B, | ||
118 | B2C2_USB_FLASH_BLOCK = 0x10, | ||
119 | B2C2_USB_I2C_REQUEST = 0x11, | ||
120 | B2C2_USB_UTILITY = 0x12, | ||
121 | } b2c2_usb_request_t; | ||
122 | |||
123 | /* function definition for I2C_REQUEST */ | ||
124 | typedef enum { | ||
125 | USB_FUNC_I2C_WRITE = 0x01, | ||
126 | USB_FUNC_I2C_MULTIWRITE = 0x02, | ||
127 | USB_FUNC_I2C_READ = 0x03, | ||
128 | USB_FUNC_I2C_REPEATWRITE = 0x04, | ||
129 | USB_FUNC_GET_DESCRIPTOR = 0x05, | ||
130 | USB_FUNC_I2C_REPEATREAD = 0x06, | ||
131 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
132 | USB_FUNC_I2C_CHECKWRITE = 0x07, | ||
133 | USB_FUNC_I2C_CHECKRESULT = 0x08, | ||
134 | } b2c2_usb_i2c_function_t; | ||
135 | |||
136 | /* | ||
137 | * function definition for UTILITY request 0x12 | ||
138 | * DKT 020304 - new utility function | ||
139 | */ | ||
140 | typedef enum { | ||
141 | UTILITY_SET_FILTER = 0x01, | ||
142 | UTILITY_DATA_ENABLE = 0x02, | ||
143 | UTILITY_FLEX_MULTIWRITE = 0x03, | ||
144 | UTILITY_SET_BUFFER_SIZE = 0x04, | ||
145 | UTILITY_FLEX_OPERATOR = 0x05, | ||
146 | UTILITY_FLEX_RESET300_START = 0x06, | ||
147 | UTILITY_FLEX_RESET300_STOP = 0x07, | ||
148 | UTILITY_FLEX_RESET300 = 0x08, | ||
149 | UTILITY_SET_ISO_SIZE = 0x09, | ||
150 | UTILITY_DATA_RESET = 0x0A, | ||
151 | UTILITY_GET_DATA_STATUS = 0x10, | ||
152 | UTILITY_GET_V8_REG = 0x11, | ||
153 | /* DKT 020326 - add function for v1.14 */ | ||
154 | UTILITY_SRAM_WRITE = 0x12, | ||
155 | UTILITY_SRAM_READ = 0x13, | ||
156 | UTILITY_SRAM_TESTFILL = 0x14, | ||
157 | UTILITY_SRAM_TESTSET = 0x15, | ||
158 | UTILITY_SRAM_TESTVERIFY = 0x16, | ||
159 | } b2c2_usb_utility_function_t; | ||
160 | |||
161 | #define B2C2_WAIT_FOR_OPERATION_RW 1 // 1 s | ||
162 | #define B2C2_WAIT_FOR_OPERATION_RDW 3 // 3 s | ||
163 | #define B2C2_WAIT_FOR_OPERATION_WDW 1 // 1 s | ||
164 | |||
165 | #define B2C2_WAIT_FOR_OPERATION_V8READ 3 // 3 s | ||
166 | #define B2C2_WAIT_FOR_OPERATION_V8WRITE 3 // 3 s | ||
167 | #define B2C2_WAIT_FOR_OPERATION_V8FLASH 3 // 3 s | ||
168 | |||
169 | /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits | ||
170 | * in the IBI address, to make the V8 code simpler. | ||
171 | * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used) | ||
172 | * in general: 0000 0HHH 000L LL00 | ||
173 | * IBI ADDRESS FORMAT: RHHH BLLL | ||
174 | * | ||
175 | * where R is the read(1)/write(0) bit, B is the busy bit | ||
176 | * and HHH and LLL are the two sets of three bits from the PCI address. | ||
177 | */ | ||
178 | #define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) | ||
179 | #define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) | ||
180 | |||
181 | /* | ||
182 | * DKT 020228 - forget about this VENDOR_BUFFER_SIZE, read and write register | ||
183 | * deal with DWORD or 4 bytes, that should be should from now on | ||
184 | */ | ||
185 | static u32 b2c2_usb_read_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI) | ||
186 | { | ||
187 | u32 val; | ||
188 | u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | 0x0080; | ||
189 | int len = usb_control_msg(b2c2->udev, | ||
190 | B2C2_USB_CTRL_PIPE_IN, | ||
191 | B2C2_USB_READ_REG, | ||
192 | RTYPE_READ_DW, | ||
193 | wAddress, | ||
194 | 0, | ||
195 | &val, | ||
196 | sizeof(u32), | ||
197 | B2C2_WAIT_FOR_OPERATION_RDW * 1000); | ||
198 | |||
199 | if (len != sizeof(u32)) { | ||
200 | err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI); | ||
201 | return -EIO; | ||
202 | } else | ||
203 | return val; | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * DKT 020228 - from now on, we don't support anything older than firm 1.00 | ||
208 | * I eliminated the write register as a 2 trip of writing hi word and lo word | ||
209 | * and force this to write only 4 bytes at a time. | ||
210 | * NOTE: this should work with all the firmware from 1.00 and newer | ||
211 | */ | ||
212 | static int b2c2_usb_write_dw(struct usb_b2c2_usb *b2c2, u16 wRegOffsPCI, u32 val) | ||
213 | { | ||
214 | u16 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI); | ||
215 | int len = usb_control_msg(b2c2->udev, | ||
216 | B2C2_USB_CTRL_PIPE_OUT, | ||
217 | B2C2_USB_WRITE_REG, | ||
218 | RTYPE_WRITE_DW_1, | ||
219 | wAddress, | ||
220 | 0, | ||
221 | &val, | ||
222 | sizeof(u32), | ||
223 | B2C2_WAIT_FOR_OPERATION_RDW * 1000); | ||
224 | |||
225 | if (len != sizeof(u32)) { | ||
226 | err("error while reading dword from %d (%d).",wAddress,wRegOffsPCI); | ||
227 | return -EIO; | ||
228 | } else | ||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * DKT 010817 - add support for V8 memory read/write and flash update | ||
234 | */ | ||
235 | static int b2c2_usb_v8_memory_req(struct usb_b2c2_usb *b2c2, | ||
236 | b2c2_usb_request_t req, u8 page, u16 wAddress, | ||
237 | u16 buflen, u8 *pbBuffer) | ||
238 | { | ||
239 | u8 dwRequestType; | ||
240 | u16 wIndex; | ||
241 | int nWaitTime,pipe,len; | ||
242 | |||
243 | wIndex = page << 8; | ||
244 | |||
245 | switch (req) { | ||
246 | case B2C2_USB_READ_V8_MEM: | ||
247 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; | ||
248 | dwRequestType = (u8) RTYPE_READ_V8_MEMORY; | ||
249 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
250 | break; | ||
251 | case B2C2_USB_WRITE_V8_MEM: | ||
252 | wIndex |= pbBuffer[0]; | ||
253 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; | ||
254 | dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY; | ||
255 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
256 | break; | ||
257 | case B2C2_USB_FLASH_BLOCK: | ||
258 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; | ||
259 | dwRequestType = (u8) RTYPE_WRITE_V8_FLASH; | ||
260 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
261 | break; | ||
262 | default: | ||
263 | deb_info("unsupported request for v8_mem_req %x.\n",req); | ||
264 | return -EINVAL; | ||
265 | } | ||
266 | len = usb_control_msg(b2c2->udev,pipe, | ||
267 | req, | ||
268 | dwRequestType, | ||
269 | wAddress, | ||
270 | wIndex, | ||
271 | pbBuffer, | ||
272 | buflen, | ||
273 | nWaitTime * 1000); | ||
274 | return len == buflen ? 0 : -EIO; | ||
275 | } | ||
276 | |||
277 | static int b2c2_usb_i2c_req(struct usb_b2c2_usb *b2c2, | ||
278 | b2c2_usb_request_t req, b2c2_usb_i2c_function_t func, | ||
279 | u8 port, u8 chipaddr, u8 addr, u8 buflen, u8 *buf) | ||
280 | { | ||
281 | u16 wValue, wIndex; | ||
282 | int nWaitTime,pipe,len; | ||
283 | u8 dwRequestType; | ||
284 | |||
285 | switch (func) { | ||
286 | case USB_FUNC_I2C_WRITE: | ||
287 | case USB_FUNC_I2C_MULTIWRITE: | ||
288 | case USB_FUNC_I2C_REPEATWRITE: | ||
289 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
290 | case USB_FUNC_I2C_CHECKWRITE: | ||
291 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
292 | nWaitTime = 2; | ||
293 | dwRequestType = (u8) RTYPE_GENERIC; | ||
294 | break; | ||
295 | case USB_FUNC_I2C_READ: | ||
296 | case USB_FUNC_I2C_REPEATREAD: | ||
297 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
298 | nWaitTime = 2; | ||
299 | dwRequestType = (u8) RTYPE_GENERIC; | ||
300 | break; | ||
301 | default: | ||
302 | deb_info("unsupported function for i2c_req %x\n",func); | ||
303 | return -EINVAL; | ||
304 | } | ||
305 | wValue = (func << 8 ) | port; | ||
306 | wIndex = (chipaddr << 8 ) | addr; | ||
307 | |||
308 | len = usb_control_msg(b2c2->udev,pipe, | ||
309 | req, | ||
310 | dwRequestType, | ||
311 | addr, | ||
312 | wIndex, | ||
313 | buf, | ||
314 | buflen, | ||
315 | nWaitTime * 1000); | ||
316 | return len == buflen ? 0 : -EIO; | ||
317 | } | ||
318 | |||
319 | int static b2c2_usb_utility_req(struct usb_b2c2_usb *b2c2, int set, | ||
320 | b2c2_usb_utility_function_t func, u8 extra, u16 wIndex, | ||
321 | u16 buflen, u8 *pvBuffer) | ||
322 | { | ||
323 | u16 wValue; | ||
324 | int nWaitTime = 2, | ||
325 | pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, | ||
326 | len; | ||
327 | |||
328 | wValue = (func << 8) | extra; | ||
329 | |||
330 | len = usb_control_msg(b2c2->udev,pipe, | ||
331 | B2C2_USB_UTILITY, | ||
332 | (u8) RTYPE_GENERIC, | ||
333 | wValue, | ||
334 | wIndex, | ||
335 | pvBuffer, | ||
336 | buflen, | ||
337 | nWaitTime * 1000); | ||
338 | return len == buflen ? 0 : -EIO; | ||
339 | } | ||
340 | |||
341 | |||
342 | |||
343 | static void b2c2_dumpfourreg(struct usb_b2c2_usb *b2c2, u16 offs) | ||
344 | { | ||
345 | u32 r0,r1,r2,r3; | ||
346 | r0 = r1 = r2 = r3 = 0; | ||
347 | r0 = b2c2_usb_read_dw(b2c2,offs); | ||
348 | r1 = b2c2_usb_read_dw(b2c2,offs + 0x04); | ||
349 | r2 = b2c2_usb_read_dw(b2c2,offs + 0x08); | ||
350 | r3 = b2c2_usb_read_dw(b2c2,offs + 0x0c); | ||
351 | deb_ctrl("dump: offset: %03x, %08x, %08x, %08x, %08x\n",offs,r0,r1,r2,r3); | ||
352 | } | ||
353 | |||
354 | static void b2c2_urb_complete(struct urb *urb, struct pt_regs *ptregs) | ||
355 | { | ||
356 | struct usb_b2c2_usb *b2c2 = urb->context; | ||
357 | deb_ts("urb completed, bufsize: %d\n",urb->transfer_buffer_length); | ||
358 | |||
359 | // urb_submit_urb(urb,GFP_ATOMIC); enable for real action | ||
360 | } | ||
361 | |||
362 | static void b2c2_exit_usb(struct usb_b2c2_usb *b2c2) | ||
363 | { | ||
364 | int i; | ||
365 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) | ||
366 | if (b2c2->iso_urb[i] != NULL) { /* not sure about unlink_urb and iso-urbs TODO */ | ||
367 | deb_info("unlinking/killing urb no. %d\n",i); | ||
368 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,7) | ||
369 | usb_unlink_urb(b2c2->iso_urb[i]); | ||
370 | #else | ||
371 | usb_kill_urb(b2c2->iso_urb[i]); | ||
372 | #endif | ||
373 | usb_free_urb(b2c2->iso_urb[i]); | ||
374 | } | ||
375 | |||
376 | if (b2c2->iso_buffer != NULL) | ||
377 | pci_free_consistent(NULL,b2c2->buffer_size, b2c2->iso_buffer, b2c2->iso_dma_handle); | ||
378 | |||
379 | } | ||
380 | |||
381 | static int b2c2_init_usb(struct usb_b2c2_usb *b2c2) | ||
382 | { | ||
383 | u16 frame_size = le16_to_cpu(b2c2->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize); | ||
384 | int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; | ||
385 | int buffer_offset = 0; | ||
386 | |||
387 | deb_info("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", | ||
388 | B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize); | ||
389 | |||
390 | b2c2->iso_buffer = pci_alloc_consistent(NULL,bufsize,&b2c2->iso_dma_handle); | ||
391 | if (b2c2->iso_buffer == NULL) | ||
392 | return -ENOMEM; | ||
393 | memset(b2c2->iso_buffer, 0, bufsize); | ||
394 | b2c2->buffer_size = bufsize; | ||
395 | |||
396 | /* creating iso urbs */ | ||
397 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) | ||
398 | if (!(b2c2->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) { | ||
399 | ret = -ENOMEM; | ||
400 | goto urb_error; | ||
401 | } | ||
402 | /* initialising and submitting iso urbs */ | ||
403 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { | ||
404 | int frame_offset = 0; | ||
405 | struct urb *urb = b2c2->iso_urb[i]; | ||
406 | deb_info("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset); | ||
407 | |||
408 | urb->dev = b2c2->udev; | ||
409 | urb->context = b2c2; | ||
410 | urb->complete = b2c2_urb_complete; | ||
411 | urb->pipe = B2C2_USB_DATA_PIPE; | ||
412 | urb->transfer_flags = URB_ISO_ASAP; | ||
413 | urb->interval = 1; | ||
414 | urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO; | ||
415 | urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
416 | urb->transfer_buffer = b2c2->iso_buffer + buffer_offset; | ||
417 | |||
418 | buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
419 | for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { | ||
420 | deb_info("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset); | ||
421 | urb->iso_frame_desc[j].offset = frame_offset; | ||
422 | urb->iso_frame_desc[j].length = frame_size; | ||
423 | frame_offset += frame_size; | ||
424 | } | ||
425 | |||
426 | if ((ret = usb_submit_urb(b2c2->iso_urb[i],GFP_ATOMIC))) { | ||
427 | err("submitting urb %d failed with %d.",i,ret); | ||
428 | goto urb_error; | ||
429 | } | ||
430 | deb_info("submitted urb no. %d.\n",i); | ||
431 | } | ||
432 | |||
433 | ret = 0; | ||
434 | goto success; | ||
435 | urb_error: | ||
436 | b2c2_exit_usb(b2c2); | ||
437 | success: | ||
438 | return ret; | ||
439 | } | ||
440 | |||
441 | static int b2c2_usb_probe(struct usb_interface *intf, | ||
442 | const struct usb_device_id *id) | ||
443 | { | ||
444 | struct usb_device *udev = interface_to_usbdev(intf); | ||
445 | struct usb_b2c2_usb *b2c2 = NULL; | ||
446 | int ret; | ||
447 | |||
448 | b2c2 = kmalloc(sizeof(struct usb_b2c2_usb),GFP_KERNEL); | ||
449 | if (b2c2 == NULL) { | ||
450 | err("no memory"); | ||
451 | return -ENOMEM; | ||
452 | } | ||
453 | b2c2->udev = udev; | ||
454 | b2c2->uintf = intf; | ||
455 | |||
456 | /* use the alternate setting with the larges buffer */ | ||
457 | usb_set_interface(udev,0,1); | ||
458 | |||
459 | if ((ret = b2c2_init_usb(b2c2))) | ||
460 | goto usb_init_error; | ||
461 | |||
462 | usb_set_intfdata(intf,b2c2); | ||
463 | |||
464 | switch (udev->speed) { | ||
465 | case USB_SPEED_LOW: | ||
466 | err("cannot handle USB speed because it is to sLOW."); | ||
467 | break; | ||
468 | case USB_SPEED_FULL: | ||
469 | info("running at FULL speed."); | ||
470 | break; | ||
471 | case USB_SPEED_HIGH: | ||
472 | info("running at HIGH speed."); | ||
473 | break; | ||
474 | case USB_SPEED_UNKNOWN: /* fall through */ | ||
475 | default: | ||
476 | err("cannot handle USB speed because it is unkown."); | ||
477 | break; | ||
478 | } | ||
479 | |||
480 | b2c2_dumpfourreg(b2c2,0x200); | ||
481 | b2c2_dumpfourreg(b2c2,0x300); | ||
482 | b2c2_dumpfourreg(b2c2,0x400); | ||
483 | b2c2_dumpfourreg(b2c2,0x700); | ||
484 | |||
485 | |||
486 | if (ret == 0) | ||
487 | info("%s successfully initialized and connected.",DRIVER_DESC); | ||
488 | else | ||
489 | info("%s error while loading driver (%d)",DRIVER_DESC,ret); | ||
490 | |||
491 | ret = 0; | ||
492 | goto success; | ||
493 | |||
494 | usb_init_error: | ||
495 | kfree(b2c2); | ||
496 | success: | ||
497 | return ret; | ||
498 | } | ||
499 | |||
500 | static void b2c2_usb_disconnect(struct usb_interface *intf) | ||
501 | { | ||
502 | struct usb_b2c2_usb *b2c2 = usb_get_intfdata(intf); | ||
503 | usb_set_intfdata(intf,NULL); | ||
504 | if (b2c2 != NULL) { | ||
505 | b2c2_exit_usb(b2c2); | ||
506 | kfree(b2c2); | ||
507 | } | ||
508 | info("%s successfully deinitialized and disconnected.",DRIVER_DESC); | ||
509 | |||
510 | } | ||
511 | |||
512 | static struct usb_device_id b2c2_usb_table [] = { | ||
513 | { USB_DEVICE(0x0af7, 0x0101) } | ||
514 | }; | ||
515 | |||
516 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
517 | static struct usb_driver b2c2_usb_driver = { | ||
518 | .owner = THIS_MODULE, | ||
519 | .name = "dvb_b2c2_usb", | ||
520 | .probe = b2c2_usb_probe, | ||
521 | .disconnect = b2c2_usb_disconnect, | ||
522 | .id_table = b2c2_usb_table, | ||
523 | }; | ||
524 | |||
525 | /* module stuff */ | ||
526 | static int __init b2c2_usb_init(void) | ||
527 | { | ||
528 | int result; | ||
529 | if ((result = usb_register(&b2c2_usb_driver))) { | ||
530 | err("usb_register failed. Error number %d",result); | ||
531 | return result; | ||
532 | } | ||
533 | |||
534 | return 0; | ||
535 | } | ||
536 | |||
537 | static void __exit b2c2_usb_exit(void) | ||
538 | { | ||
539 | /* deregister this driver from the USB subsystem */ | ||
540 | usb_deregister(&b2c2_usb_driver); | ||
541 | } | ||
542 | |||
543 | module_init (b2c2_usb_init); | ||
544 | module_exit (b2c2_usb_exit); | ||
545 | |||
546 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
547 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
548 | MODULE_LICENSE("GPL"); | ||
549 | MODULE_DEVICE_TABLE(usb, b2c2_usb_table); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-common.h b/drivers/media/dvb/b2c2/flexcop-common.h new file mode 100644 index 000000000000..773d158032df --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-common.h | |||
@@ -0,0 +1,164 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-common.h - common header file for device-specific source files also. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #ifndef __FLEXCOP_COMMON_H__ | ||
9 | #define __FLEXCOP_COMMON_H__ | ||
10 | |||
11 | #include <linux/config.h> | ||
12 | #include <linux/pci.h> | ||
13 | |||
14 | #include "flexcop-reg.h" | ||
15 | |||
16 | #include "dmxdev.h" | ||
17 | #include "dvb_demux.h" | ||
18 | #include "dvb_filter.h" | ||
19 | #include "dvb_net.h" | ||
20 | #include "dvb_frontend.h" | ||
21 | |||
22 | #define FC_MAX_FEED 256 | ||
23 | |||
24 | #ifndef FC_LOG_PREFIX | ||
25 | #warning please define a log prefix for your file, using a default one | ||
26 | #define FC_LOG_PREFIX "b2c2-undef" | ||
27 | #endif | ||
28 | |||
29 | /* Steal from usb.h */ | ||
30 | #undef err | ||
31 | #define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg) | ||
32 | #undef info | ||
33 | #define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg) | ||
34 | #undef warn | ||
35 | #define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg) | ||
36 | |||
37 | struct flexcop_dma { | ||
38 | struct pci_dev *pdev; | ||
39 | |||
40 | u8 *cpu_addr0; | ||
41 | dma_addr_t dma_addr0; | ||
42 | u8 *cpu_addr1; | ||
43 | dma_addr_t dma_addr1; | ||
44 | u32 size; /* size of each address in bytes */ | ||
45 | }; | ||
46 | |||
47 | /* Control structure for data definitions that are common to | ||
48 | * the B2C2-based PCI and USB devices. | ||
49 | */ | ||
50 | struct flexcop_device { | ||
51 | /* general */ | ||
52 | struct device *dev; /* for firmware_class */ | ||
53 | |||
54 | #define FC_STATE_DVB_INIT 0x01 | ||
55 | #define FC_STATE_I2C_INIT 0x02 | ||
56 | #define FC_STATE_FE_INIT 0x04 | ||
57 | int init_state; | ||
58 | |||
59 | /* device information */ | ||
60 | int has_32_hw_pid_filter; | ||
61 | flexcop_revision_t rev; | ||
62 | flexcop_device_type_t dev_type; | ||
63 | flexcop_bus_t bus_type; | ||
64 | |||
65 | /* dvb stuff */ | ||
66 | struct dvb_adapter dvb_adapter; | ||
67 | struct dvb_frontend *fe; | ||
68 | struct dvb_net dvbnet; | ||
69 | struct dvb_demux demux; | ||
70 | struct dmxdev dmxdev; | ||
71 | struct dmx_frontend hw_frontend; | ||
72 | struct dmx_frontend mem_frontend; | ||
73 | int (*fe_sleep) (struct dvb_frontend *); | ||
74 | |||
75 | struct i2c_adapter i2c_adap; | ||
76 | struct semaphore i2c_sem; | ||
77 | |||
78 | struct module *owner; | ||
79 | |||
80 | /* options and status */ | ||
81 | int extra_feedcount; | ||
82 | int feedcount; | ||
83 | int pid_filtering; | ||
84 | int fullts_streaming_state; | ||
85 | |||
86 | /* bus specific callbacks */ | ||
87 | flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register); | ||
88 | int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value); | ||
89 | |||
90 | |||
91 | int (*i2c_request) (struct flexcop_device*, flexcop_access_op_t, flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); | ||
92 | int (*stream_control) (struct flexcop_device*, int); | ||
93 | |||
94 | int (*get_mac_addr) (struct flexcop_device *fc, int extended); | ||
95 | |||
96 | void *bus_specific; | ||
97 | }; | ||
98 | |||
99 | /* exported prototypes */ | ||
100 | |||
101 | /* from flexcop.c */ | ||
102 | void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len); | ||
103 | void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no); | ||
104 | |||
105 | struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len); | ||
106 | void flexcop_device_kfree(struct flexcop_device*); | ||
107 | |||
108 | int flexcop_device_initialize(struct flexcop_device*); | ||
109 | void flexcop_device_exit(struct flexcop_device *fc); | ||
110 | |||
111 | /* from flexcop-dma.c */ | ||
112 | int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size); | ||
113 | void flexcop_dma_free(struct flexcop_dma *dma); | ||
114 | |||
115 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | ||
116 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | ||
117 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff); | ||
118 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index); | ||
119 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles); | ||
120 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets); | ||
121 | |||
122 | /* from flexcop-eeprom.c */ | ||
123 | /* the PCI part uses this call to get the MAC address, the USB part has its own */ | ||
124 | int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended); | ||
125 | |||
126 | /* from flexcop-i2c.c */ | ||
127 | /* the PCI part uses this a i2c_request callback, whereas the usb part has its own | ||
128 | * one. We have it in flexcop-i2c.c, because it is going via the actual | ||
129 | * I2C-channel of the flexcop. | ||
130 | */ | ||
131 | int flexcop_i2c_request(struct flexcop_device*, flexcop_access_op_t, | ||
132 | flexcop_i2c_port_t, u8 chipaddr, u8 addr, u8 *buf, u16 len); | ||
133 | |||
134 | /* from flexcop-sram.c */ | ||
135 | int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target); | ||
136 | void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s); | ||
137 | void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill); | ||
138 | |||
139 | /* global prototypes for the flexcop-chip */ | ||
140 | /* from flexcop-fe-tuner.c */ | ||
141 | int flexcop_frontend_init(struct flexcop_device *card); | ||
142 | void flexcop_frontend_exit(struct flexcop_device *fc); | ||
143 | |||
144 | /* from flexcop-i2c.c */ | ||
145 | int flexcop_i2c_init(struct flexcop_device *fc); | ||
146 | void flexcop_i2c_exit(struct flexcop_device *fc); | ||
147 | |||
148 | /* from flexcop-sram.c */ | ||
149 | int flexcop_sram_init(struct flexcop_device *fc); | ||
150 | |||
151 | /* from flexcop-misc.c */ | ||
152 | void flexcop_determine_revision(struct flexcop_device *fc); | ||
153 | void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix); | ||
154 | |||
155 | /* from flexcop-hw-filter.c */ | ||
156 | int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff); | ||
157 | void flexcop_hw_filter_init(struct flexcop_device *fc); | ||
158 | |||
159 | void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff); | ||
160 | |||
161 | void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]); | ||
162 | void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff); | ||
163 | |||
164 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-dma.c b/drivers/media/dvb/b2c2/flexcop-dma.c new file mode 100644 index 000000000000..8d2706075360 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-dma.c | |||
@@ -0,0 +1,149 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size) | ||
11 | { | ||
12 | u8 *tcpu; | ||
13 | dma_addr_t tdma; | ||
14 | |||
15 | if (size % 2) { | ||
16 | err("dma buffersize has to be even."); | ||
17 | return -EINVAL; | ||
18 | } | ||
19 | |||
20 | if ((tcpu = pci_alloc_consistent(pdev, size, &tdma)) != NULL) { | ||
21 | dma->pdev = pdev; | ||
22 | dma->cpu_addr0 = tcpu; | ||
23 | dma->dma_addr0 = tdma; | ||
24 | dma->cpu_addr1 = tcpu + size/2; | ||
25 | dma->dma_addr1 = tdma + size/2; | ||
26 | dma->size = size/2; | ||
27 | return 0; | ||
28 | } | ||
29 | return -ENOMEM; | ||
30 | } | ||
31 | EXPORT_SYMBOL(flexcop_dma_allocate); | ||
32 | |||
33 | void flexcop_dma_free(struct flexcop_dma *dma) | ||
34 | { | ||
35 | pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0); | ||
36 | memset(dma,0,sizeof(struct flexcop_dma)); | ||
37 | } | ||
38 | EXPORT_SYMBOL(flexcop_dma_free); | ||
39 | |||
40 | int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | ||
41 | { | ||
42 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
43 | |||
44 | if (no & FC_DMA_1) | ||
45 | v.ctrl_208.DMA1_Timer_Enable_sig = onoff; | ||
46 | |||
47 | if (no & FC_DMA_2) | ||
48 | v.ctrl_208.DMA2_Timer_Enable_sig = onoff; | ||
49 | |||
50 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
51 | return 0; | ||
52 | } | ||
53 | EXPORT_SYMBOL(flexcop_dma_control_timer_irq); | ||
54 | |||
55 | int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | ||
56 | { | ||
57 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
58 | |||
59 | if (no & FC_DMA_1) | ||
60 | v.ctrl_208.DMA1_IRQ_Enable_sig = onoff; | ||
61 | |||
62 | if (no & FC_DMA_2) | ||
63 | v.ctrl_208.DMA2_IRQ_Enable_sig = onoff; | ||
64 | |||
65 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
66 | return 0; | ||
67 | } | ||
68 | EXPORT_SYMBOL(flexcop_dma_control_size_irq); | ||
69 | |||
70 | int flexcop_dma_control_packet_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff) | ||
71 | { | ||
72 | flexcop_ibi_value v = fc->read_ibi_reg(fc,ctrl_208); | ||
73 | |||
74 | if (no & FC_DMA_1) | ||
75 | v.ctrl_208.DMA1_Size_IRQ_Enable_sig = onoff; | ||
76 | |||
77 | if (no & FC_DMA_2) | ||
78 | v.ctrl_208.DMA2_Size_IRQ_Enable_sig = onoff; | ||
79 | |||
80 | fc->write_ibi_reg(fc,ctrl_208,v); | ||
81 | return 0; | ||
82 | } | ||
83 | EXPORT_SYMBOL(flexcop_dma_control_packet_irq); | ||
84 | |||
85 | int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx,flexcop_dma_addr_index_t index) | ||
86 | { | ||
87 | |||
88 | flexcop_ibi_value v0x0,v0x4,v0xc; | ||
89 | v0x0.raw = v0x4.raw = v0xc.raw = 0; | ||
90 | |||
91 | v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2; | ||
92 | v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2; | ||
93 | v0x4.dma_0x4_write.dma_addr_size = dma->size / 4; | ||
94 | |||
95 | if (index & FC_DMA_SUBADDR_0) | ||
96 | v0x0.dma_0x0.dma_0start = 1; | ||
97 | |||
98 | if (index & FC_DMA_SUBADDR_1) | ||
99 | v0xc.dma_0xc.dma_1start = 1; | ||
100 | |||
101 | if (dma_idx & FC_DMA_1) { | ||
102 | fc->write_ibi_reg(fc,dma1_000,v0x0); | ||
103 | fc->write_ibi_reg(fc,dma1_004,v0x4); | ||
104 | fc->write_ibi_reg(fc,dma1_00c,v0xc); | ||
105 | } else { /* (dma_idx & FC_DMA_2) */ | ||
106 | fc->write_ibi_reg(fc,dma2_010,v0x0); | ||
107 | fc->write_ibi_reg(fc,dma2_014,v0x4); | ||
108 | fc->write_ibi_reg(fc,dma2_01c,v0xc); | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | EXPORT_SYMBOL(flexcop_dma_config); | ||
114 | |||
115 | static int flexcop_dma_remap(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, int onoff) | ||
116 | { | ||
117 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c; | ||
118 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
119 | v.dma_0xc.remap_enable = onoff; | ||
120 | fc->write_ibi_reg(fc,r,v); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | /* 1 cycles = 1.97 msec */ | ||
125 | int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles) | ||
126 | { | ||
127 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
128 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
129 | |||
130 | flexcop_dma_remap(fc,dma_idx,0); | ||
131 | |||
132 | v.dma_0x4_write.dmatimer = cycles >> 1; | ||
133 | fc->write_ibi_reg(fc,r,v); | ||
134 | return 0; | ||
135 | } | ||
136 | EXPORT_SYMBOL(flexcop_dma_config_timer); | ||
137 | |||
138 | int flexcop_dma_config_packet_count(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 packets) | ||
139 | { | ||
140 | flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014; | ||
141 | flexcop_ibi_value v = fc->read_ibi_reg(fc,r); | ||
142 | |||
143 | flexcop_dma_remap(fc,dma_idx,1); | ||
144 | |||
145 | v.dma_0x4_remap.DMA_maxpackets = packets; | ||
146 | fc->write_ibi_reg(fc,r,v); | ||
147 | return 0; | ||
148 | } | ||
149 | EXPORT_SYMBOL(flexcop_dma_config_packet_count); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-eeprom.c b/drivers/media/dvb/b2c2/flexcop-eeprom.c new file mode 100644 index 000000000000..bbcf070a178d --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-eeprom.c | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used) | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | #if 0 | ||
11 | /*EEPROM (Skystar2 has one "24LC08B" chip on board) */ | ||
12 | static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len) | ||
13 | { | ||
14 | return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len); | ||
15 | } | ||
16 | |||
17 | static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries) | ||
18 | { | ||
19 | int i; | ||
20 | |||
21 | for (i = 0; i < retries; i++) { | ||
22 | if (eeprom_write(adapter, addr, wbuf, len) == len) { | ||
23 | if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1) | ||
24 | return 1; | ||
25 | } | ||
26 | } | ||
27 | |||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | /* These functions could be used to unlock SkyStar2 cards. */ | ||
32 | |||
33 | static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len) | ||
34 | { | ||
35 | u8 rbuf[20]; | ||
36 | u8 wbuf[20]; | ||
37 | |||
38 | if (len != 16) | ||
39 | return 0; | ||
40 | |||
41 | memcpy(wbuf, key, len); | ||
42 | |||
43 | wbuf[16] = 0; | ||
44 | wbuf[17] = 0; | ||
45 | wbuf[18] = 0; | ||
46 | wbuf[19] = calc_lrc(wbuf, 19); | ||
47 | |||
48 | return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4); | ||
49 | } | ||
50 | |||
51 | static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len) | ||
52 | { | ||
53 | u8 buf[20]; | ||
54 | |||
55 | if (len != 16) | ||
56 | return 0; | ||
57 | |||
58 | if (eeprom_lrc_read(adapter, 0x3e4, 20, buf, 4) == 0) | ||
59 | return 0; | ||
60 | |||
61 | memcpy(key, buf, len); | ||
62 | |||
63 | return 1; | ||
64 | } | ||
65 | |||
66 | static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac) | ||
67 | { | ||
68 | u8 tmp[8]; | ||
69 | |||
70 | if (type != 0) { | ||
71 | tmp[0] = mac[0]; | ||
72 | tmp[1] = mac[1]; | ||
73 | tmp[2] = mac[2]; | ||
74 | tmp[3] = mac[5]; | ||
75 | tmp[4] = mac[6]; | ||
76 | tmp[5] = mac[7]; | ||
77 | |||
78 | } else { | ||
79 | |||
80 | tmp[0] = mac[0]; | ||
81 | tmp[1] = mac[1]; | ||
82 | tmp[2] = mac[2]; | ||
83 | tmp[3] = mac[3]; | ||
84 | tmp[4] = mac[4]; | ||
85 | tmp[5] = mac[5]; | ||
86 | } | ||
87 | |||
88 | tmp[6] = 0; | ||
89 | tmp[7] = calc_lrc(tmp, 7); | ||
90 | |||
91 | if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8) | ||
92 | return 1; | ||
93 | |||
94 | return 0; | ||
95 | } | ||
96 | |||
97 | static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len) | ||
98 | { | ||
99 | return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len); | ||
100 | } | ||
101 | |||
102 | #endif | ||
103 | |||
104 | static u8 calc_lrc(u8 *buf, int len) | ||
105 | { | ||
106 | int i; | ||
107 | u8 sum = 0; | ||
108 | for (i = 0; i < len; i++) | ||
109 | sum = sum ^ buf[i]; | ||
110 | return sum; | ||
111 | } | ||
112 | |||
113 | static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries) | ||
114 | { | ||
115 | int i,ret = 0; | ||
116 | u8 chipaddr = 0x50 | ((addr >> 8) & 3); | ||
117 | for (i = 0; i < retries; i++) | ||
118 | if ((ret = fc->i2c_request(fc,op,FC_I2C_PORT_EEPROM,chipaddr,addr & 0xff,buf,len)) == 0) | ||
119 | break; | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries) | ||
124 | { | ||
125 | int ret = flexcop_eeprom_request(fc,FC_READ,addr,buf,len,retries); | ||
126 | if (ret == 0) | ||
127 | if (calc_lrc(buf, len - 1) != buf[len - 1]) | ||
128 | ret = -EINVAL; | ||
129 | return ret; | ||
130 | } | ||
131 | |||
132 | /* JJ's comment about extended == 1: it is not presently used anywhere but was | ||
133 | * added to the low-level functions for possible support of EUI64 | ||
134 | */ | ||
135 | int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended) | ||
136 | { | ||
137 | u8 buf[8]; | ||
138 | int ret = 0; | ||
139 | |||
140 | if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) { | ||
141 | if (extended != 0) { | ||
142 | err("TODO: extended (EUI64) MAC addresses aren't completely supported yet"); | ||
143 | ret = -EINVAL; | ||
144 | /* memcpy(fc->dvb_adapter.proposed_mac,buf,3); | ||
145 | mac[3] = 0xfe; | ||
146 | mac[4] = 0xff; | ||
147 | memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */ | ||
148 | } else | ||
149 | memcpy(fc->dvb_adapter.proposed_mac,buf,6); | ||
150 | } | ||
151 | return ret; | ||
152 | } | ||
153 | EXPORT_SYMBOL(flexcop_eeprom_check_mac_addr); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c new file mode 100644 index 000000000000..71be400e9aeb --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-fe-tuner.c - methods for attaching a frontend and controlling DiSEqC. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | #include "stv0299.h" | ||
11 | #include "mt352.h" | ||
12 | #include "nxt2002.h" | ||
13 | #include "stv0297.h" | ||
14 | #include "mt312.h" | ||
15 | |||
16 | /* lnb control */ | ||
17 | |||
18 | static int flexcop_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) | ||
19 | { | ||
20 | struct flexcop_device *fc = fe->dvb->priv; | ||
21 | flexcop_ibi_value v; | ||
22 | deb_tuner("polarity/voltage = %u\n", voltage); | ||
23 | |||
24 | v = fc->read_ibi_reg(fc, misc_204); | ||
25 | switch (voltage) { | ||
26 | case SEC_VOLTAGE_OFF: | ||
27 | v.misc_204.ACPI1_sig = 1; | ||
28 | break; | ||
29 | case SEC_VOLTAGE_13: | ||
30 | v.misc_204.ACPI1_sig = 0; | ||
31 | v.misc_204.LNB_L_H_sig = 0; | ||
32 | break; | ||
33 | case SEC_VOLTAGE_18: | ||
34 | v.misc_204.ACPI1_sig = 0; | ||
35 | v.misc_204.LNB_L_H_sig = 1; | ||
36 | break; | ||
37 | default: | ||
38 | err("unknown SEC_VOLTAGE value"); | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | return fc->write_ibi_reg(fc, misc_204, v); | ||
42 | } | ||
43 | |||
44 | static int flexcop_sleep(struct dvb_frontend* fe) | ||
45 | { | ||
46 | struct flexcop_device *fc = fe->dvb->priv; | ||
47 | /* flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); */ | ||
48 | |||
49 | if (fc->fe_sleep) | ||
50 | return fc->fe_sleep(fe); | ||
51 | |||
52 | /* v.misc_204.ACPI3_sig = 1; | ||
53 | fc->write_ibi_reg(fc,misc_204,v);*/ | ||
54 | |||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | static int flexcop_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) | ||
59 | { | ||
60 | /* u16 wz_half_period_for_45_mhz[] = { 0x01ff, 0x0154, 0x00ff, 0x00cc }; */ | ||
61 | struct flexcop_device *fc = fe->dvb->priv; | ||
62 | flexcop_ibi_value v; | ||
63 | u16 ax; | ||
64 | v.raw = 0; | ||
65 | |||
66 | deb_tuner("tone = %u\n",tone); | ||
67 | |||
68 | switch (tone) { | ||
69 | case SEC_TONE_ON: | ||
70 | ax = 0x01ff; | ||
71 | break; | ||
72 | case SEC_TONE_OFF: | ||
73 | ax = 0; | ||
74 | break; | ||
75 | default: | ||
76 | err("unknown SEC_TONE value"); | ||
77 | return -EINVAL; | ||
78 | } | ||
79 | |||
80 | v.lnb_switch_freq_200.LNB_CTLPrescaler_sig = 1; /* divide by 2 */ | ||
81 | |||
82 | v.lnb_switch_freq_200.LNB_CTLHighCount_sig = ax; | ||
83 | v.lnb_switch_freq_200.LNB_CTLLowCount_sig = ax == 0 ? 0x1ff : ax; | ||
84 | |||
85 | return fc->write_ibi_reg(fc,lnb_switch_freq_200,v); | ||
86 | } | ||
87 | |||
88 | static void flexcop_diseqc_send_bit(struct dvb_frontend* fe, int data) | ||
89 | { | ||
90 | flexcop_set_tone(fe, SEC_TONE_ON); | ||
91 | udelay(data ? 500 : 1000); | ||
92 | flexcop_set_tone(fe, SEC_TONE_OFF); | ||
93 | udelay(data ? 1000 : 500); | ||
94 | } | ||
95 | |||
96 | static void flexcop_diseqc_send_byte(struct dvb_frontend* fe, int data) | ||
97 | { | ||
98 | int i, par = 1, d; | ||
99 | |||
100 | for (i = 7; i >= 0; i--) { | ||
101 | d = (data >> i) & 1; | ||
102 | par ^= d; | ||
103 | flexcop_diseqc_send_bit(fe, d); | ||
104 | } | ||
105 | |||
106 | flexcop_diseqc_send_bit(fe, par); | ||
107 | } | ||
108 | |||
109 | static int flexcop_send_diseqc_msg(struct dvb_frontend* fe, int len, u8 *msg, unsigned long burst) | ||
110 | { | ||
111 | int i; | ||
112 | |||
113 | flexcop_set_tone(fe, SEC_TONE_OFF); | ||
114 | mdelay(16); | ||
115 | |||
116 | for (i = 0; i < len; i++) | ||
117 | flexcop_diseqc_send_byte(fe,msg[i]); | ||
118 | |||
119 | mdelay(16); | ||
120 | |||
121 | if (burst != -1) { | ||
122 | if (burst) | ||
123 | flexcop_diseqc_send_byte(fe, 0xff); | ||
124 | else { | ||
125 | flexcop_set_tone(fe, SEC_TONE_ON); | ||
126 | udelay(12500); | ||
127 | flexcop_set_tone(fe, SEC_TONE_OFF); | ||
128 | } | ||
129 | msleep(20); | ||
130 | } | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int flexcop_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd* cmd) | ||
135 | { | ||
136 | return flexcop_send_diseqc_msg(fe, cmd->msg_len, cmd->msg, 0); | ||
137 | } | ||
138 | |||
139 | static int flexcop_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd) | ||
140 | { | ||
141 | return flexcop_send_diseqc_msg(fe, 0, NULL, minicmd); | ||
142 | } | ||
143 | |||
144 | /* dvb-s stv0299 */ | ||
145 | static int samsung_tbmu24112_set_symbol_rate(struct dvb_frontend* fe, u32 srate, u32 ratio) | ||
146 | { | ||
147 | u8 aclk = 0; | ||
148 | u8 bclk = 0; | ||
149 | |||
150 | if (srate < 1500000) { aclk = 0xb7; bclk = 0x47; } | ||
151 | else if (srate < 3000000) { aclk = 0xb7; bclk = 0x4b; } | ||
152 | else if (srate < 7000000) { aclk = 0xb7; bclk = 0x4f; } | ||
153 | else if (srate < 14000000) { aclk = 0xb7; bclk = 0x53; } | ||
154 | else if (srate < 30000000) { aclk = 0xb6; bclk = 0x53; } | ||
155 | else if (srate < 45000000) { aclk = 0xb4; bclk = 0x51; } | ||
156 | |||
157 | stv0299_writereg (fe, 0x13, aclk); | ||
158 | stv0299_writereg (fe, 0x14, bclk); | ||
159 | stv0299_writereg (fe, 0x1f, (ratio >> 16) & 0xff); | ||
160 | stv0299_writereg (fe, 0x20, (ratio >> 8) & 0xff); | ||
161 | stv0299_writereg (fe, 0x21, (ratio ) & 0xf0); | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int samsung_tbmu24112_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
167 | { | ||
168 | u8 buf[4]; | ||
169 | u32 div; | ||
170 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
171 | struct flexcop_device *fc = fe->dvb->priv; | ||
172 | |||
173 | div = params->frequency / 125; | ||
174 | |||
175 | buf[0] = (div >> 8) & 0x7f; | ||
176 | buf[1] = div & 0xff; | ||
177 | buf[2] = 0x84; /* 0xC4 */ | ||
178 | buf[3] = 0x08; | ||
179 | |||
180 | if (params->frequency < 1500000) buf[3] |= 0x10; | ||
181 | |||
182 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) | ||
183 | return -EIO; | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | static u8 samsung_tbmu24112_inittab[] = { | ||
188 | 0x01, 0x15, | ||
189 | 0x02, 0x30, | ||
190 | 0x03, 0x00, | ||
191 | 0x04, 0x7D, | ||
192 | 0x05, 0x35, | ||
193 | 0x06, 0x02, | ||
194 | 0x07, 0x00, | ||
195 | 0x08, 0xC3, | ||
196 | 0x0C, 0x00, | ||
197 | 0x0D, 0x81, | ||
198 | 0x0E, 0x23, | ||
199 | 0x0F, 0x12, | ||
200 | 0x10, 0x7E, | ||
201 | 0x11, 0x84, | ||
202 | 0x12, 0xB9, | ||
203 | 0x13, 0x88, | ||
204 | 0x14, 0x89, | ||
205 | 0x15, 0xC9, | ||
206 | 0x16, 0x00, | ||
207 | 0x17, 0x5C, | ||
208 | 0x18, 0x00, | ||
209 | 0x19, 0x00, | ||
210 | 0x1A, 0x00, | ||
211 | 0x1C, 0x00, | ||
212 | 0x1D, 0x00, | ||
213 | 0x1E, 0x00, | ||
214 | 0x1F, 0x3A, | ||
215 | 0x20, 0x2E, | ||
216 | 0x21, 0x80, | ||
217 | 0x22, 0xFF, | ||
218 | 0x23, 0xC1, | ||
219 | 0x28, 0x00, | ||
220 | 0x29, 0x1E, | ||
221 | 0x2A, 0x14, | ||
222 | 0x2B, 0x0F, | ||
223 | 0x2C, 0x09, | ||
224 | 0x2D, 0x05, | ||
225 | 0x31, 0x1F, | ||
226 | 0x32, 0x19, | ||
227 | 0x33, 0xFE, | ||
228 | 0x34, 0x93, | ||
229 | 0xff, 0xff, | ||
230 | }; | ||
231 | |||
232 | static struct stv0299_config samsung_tbmu24112_config = { | ||
233 | .demod_address = 0x68, | ||
234 | .inittab = samsung_tbmu24112_inittab, | ||
235 | .mclk = 88000000UL, | ||
236 | .invert = 0, | ||
237 | .enhanced_tuning = 0, | ||
238 | .skip_reinit = 0, | ||
239 | .lock_output = STV0229_LOCKOUTPUT_LK, | ||
240 | .volt13_op0_op1 = STV0299_VOLT13_OP1, | ||
241 | .min_delay_ms = 100, | ||
242 | .set_symbol_rate = samsung_tbmu24112_set_symbol_rate, | ||
243 | .pll_set = samsung_tbmu24112_pll_set, | ||
244 | }; | ||
245 | |||
246 | /* dvb-t mt352 */ | ||
247 | static int samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | ||
248 | { | ||
249 | static u8 mt352_clock_config [] = { 0x89, 0x18, 0x2d }; | ||
250 | static u8 mt352_reset [] = { 0x50, 0x80 }; | ||
251 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | ||
252 | static u8 mt352_agc_cfg [] = { 0x67, 0x28, 0xa1 }; | ||
253 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | ||
254 | |||
255 | mt352_write(fe, mt352_clock_config, sizeof(mt352_clock_config)); | ||
256 | udelay(2000); | ||
257 | mt352_write(fe, mt352_reset, sizeof(mt352_reset)); | ||
258 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | ||
259 | |||
260 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); | ||
261 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
266 | static int samsung_tdtc9251dh0_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params, u8* pllbuf) | ||
267 | { | ||
268 | u32 div; | ||
269 | unsigned char bs = 0; | ||
270 | |||
271 | #define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */ | ||
272 | div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6; | ||
273 | |||
274 | if (params->frequency >= 48000000 && params->frequency <= 154000000) bs = 0x09; | ||
275 | if (params->frequency >= 161000000 && params->frequency <= 439000000) bs = 0x0a; | ||
276 | if (params->frequency >= 447000000 && params->frequency <= 863000000) bs = 0x08; | ||
277 | |||
278 | pllbuf[0] = 0xc2; /* Note: non-linux standard PLL i2c address */ | ||
279 | pllbuf[1] = div >> 8; | ||
280 | pllbuf[2] = div & 0xff; | ||
281 | pllbuf[3] = 0xcc; | ||
282 | pllbuf[4] = bs; | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static struct mt352_config samsung_tdtc9251dh0_config = { | ||
288 | |||
289 | .demod_address = 0x0f, | ||
290 | .demod_init = samsung_tdtc9251dh0_demod_init, | ||
291 | .pll_set = samsung_tdtc9251dh0_pll_set, | ||
292 | }; | ||
293 | |||
294 | static int nxt2002_request_firmware(struct dvb_frontend* fe, const struct firmware **fw, char* name) | ||
295 | { | ||
296 | struct flexcop_device *fc = fe->dvb->priv; | ||
297 | return request_firmware(fw, name, fc->dev); | ||
298 | } | ||
299 | |||
300 | static struct nxt2002_config samsung_tbmv_config = { | ||
301 | .demod_address = 0x0a, | ||
302 | .request_firmware = nxt2002_request_firmware, | ||
303 | }; | ||
304 | |||
305 | static int skystar23_samsung_tbdu18132_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
306 | { | ||
307 | u8 buf[4]; | ||
308 | u32 div; | ||
309 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = buf, .len = sizeof(buf) }; | ||
310 | struct flexcop_device *fc = fe->dvb->priv; | ||
311 | |||
312 | div = (params->frequency + (125/2)) / 125; | ||
313 | |||
314 | buf[0] = (div >> 8) & 0x7f; | ||
315 | buf[1] = (div >> 0) & 0xff; | ||
316 | buf[2] = 0x84 | ((div >> 10) & 0x60); | ||
317 | buf[3] = 0x80; | ||
318 | |||
319 | if (params->frequency < 1550000) | ||
320 | buf[3] |= 0x02; | ||
321 | |||
322 | if (i2c_transfer(&fc->i2c_adap, &msg, 1) != 1) | ||
323 | return -EIO; | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static struct mt312_config skystar23_samsung_tbdu18132_config = { | ||
328 | |||
329 | .demod_address = 0x0e, | ||
330 | .pll_set = skystar23_samsung_tbdu18132_pll_set, | ||
331 | }; | ||
332 | |||
333 | static struct stv0297_config alps_tdee4_stv0297_config = { | ||
334 | .demod_address = 0x1c, | ||
335 | // .invert = 1, | ||
336 | // .pll_set = alps_tdee4_stv0297_pll_set, | ||
337 | }; | ||
338 | |||
339 | /* try to figure out the frontend, each card/box can have on of the following list */ | ||
340 | int flexcop_frontend_init(struct flexcop_device *fc) | ||
341 | { | ||
342 | /* try the sky v2.6 (stv0299/Samsung tbmu24112(sl1935)) */ | ||
343 | if ((fc->fe = stv0299_attach(&samsung_tbmu24112_config, &fc->i2c_adap)) != NULL) { | ||
344 | fc->fe->ops->set_voltage = flexcop_set_voltage; | ||
345 | |||
346 | fc->fe_sleep = fc->fe->ops->sleep; | ||
347 | fc->fe->ops->sleep = flexcop_sleep; | ||
348 | |||
349 | fc->dev_type = FC_SKY; | ||
350 | info("found the stv0299 at i2c address: 0x%02x",samsung_tbmu24112_config.demod_address); | ||
351 | } else | ||
352 | /* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */ | ||
353 | if ((fc->fe = mt352_attach(&samsung_tdtc9251dh0_config, &fc->i2c_adap)) != NULL ) { | ||
354 | fc->dev_type = FC_AIR_DVB; | ||
355 | info("found the mt352 at i2c address: 0x%02x",samsung_tdtc9251dh0_config.demod_address); | ||
356 | } else | ||
357 | /* try the air atsc (nxt2002) */ | ||
358 | if ((fc->fe = nxt2002_attach(&samsung_tbmv_config, &fc->i2c_adap)) != NULL) { | ||
359 | fc->dev_type = FC_AIR_ATSC; | ||
360 | info("found the nxt2002 at i2c address: 0x%02x",samsung_tbmv_config.demod_address); | ||
361 | } else | ||
362 | /* try the cable dvb (stv0297) */ | ||
363 | if ((fc->fe = stv0297_attach(&alps_tdee4_stv0297_config, &fc->i2c_adap, 0xf8)) != NULL) { | ||
364 | fc->dev_type = FC_CABLE; | ||
365 | info("found the stv0297 at i2c address: 0x%02x",alps_tdee4_stv0297_config.demod_address); | ||
366 | } else | ||
367 | /* try the sky v2.3 (vp310/Samsung tbdu18132(tsa5059)) */ | ||
368 | if ((fc->fe = vp310_attach(&skystar23_samsung_tbdu18132_config, &fc->i2c_adap)) != NULL) { | ||
369 | fc->fe->ops->diseqc_send_master_cmd = flexcop_diseqc_send_master_cmd; | ||
370 | fc->fe->ops->diseqc_send_burst = flexcop_diseqc_send_burst; | ||
371 | fc->fe->ops->set_tone = flexcop_set_tone; | ||
372 | fc->fe->ops->set_voltage = flexcop_set_voltage; | ||
373 | |||
374 | fc->fe_sleep = fc->fe->ops->sleep; | ||
375 | fc->fe->ops->sleep = flexcop_sleep; | ||
376 | |||
377 | fc->dev_type = FC_SKY_OLD; | ||
378 | info("found the vp310 (aka mt312) at i2c address: 0x%02x",skystar23_samsung_tbdu18132_config.demod_address); | ||
379 | } | ||
380 | |||
381 | if (fc->fe == NULL) { | ||
382 | err("no frontend driver found for this B2C2/FlexCop adapter"); | ||
383 | return -ENODEV; | ||
384 | } else { | ||
385 | if (dvb_register_frontend(&fc->dvb_adapter, fc->fe)) { | ||
386 | err("frontend registration failed!"); | ||
387 | if (fc->fe->ops->release != NULL) | ||
388 | fc->fe->ops->release(fc->fe); | ||
389 | fc->fe = NULL; | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | } | ||
393 | fc->init_state |= FC_STATE_FE_INIT; | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | void flexcop_frontend_exit(struct flexcop_device *fc) | ||
398 | { | ||
399 | if (fc->init_state & FC_STATE_FE_INIT) | ||
400 | dvb_unregister_frontend(fc->fe); | ||
401 | |||
402 | fc->init_state &= ~FC_STATE_FE_INIT; | ||
403 | } | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/drivers/media/dvb/b2c2/flexcop-hw-filter.c new file mode 100644 index 000000000000..2baf43d3ce8f --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-hw-filter.c | |||
@@ -0,0 +1,204 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff) | ||
11 | { | ||
12 | flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff); | ||
13 | } | ||
14 | |||
15 | void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff) | ||
16 | { | ||
17 | flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff); | ||
18 | } | ||
19 | |||
20 | void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff) | ||
21 | { | ||
22 | flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff); | ||
23 | } | ||
24 | |||
25 | void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6]) | ||
26 | { | ||
27 | flexcop_ibi_value v418,v41c; | ||
28 | v41c = fc->read_ibi_reg(fc,mac_address_41c); | ||
29 | |||
30 | v418.mac_address_418.MAC1 = mac[0]; | ||
31 | v418.mac_address_418.MAC2 = mac[1]; | ||
32 | v418.mac_address_418.MAC3 = mac[2]; | ||
33 | v418.mac_address_418.MAC6 = mac[3]; | ||
34 | v41c.mac_address_41c.MAC7 = mac[4]; | ||
35 | v41c.mac_address_41c.MAC8 = mac[5]; | ||
36 | |||
37 | fc->write_ibi_reg(fc,mac_address_418,v418); | ||
38 | fc->write_ibi_reg(fc,mac_address_41c,v41c); | ||
39 | } | ||
40 | |||
41 | void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff) | ||
42 | { | ||
43 | flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff); | ||
44 | } | ||
45 | |||
46 | static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask) | ||
47 | { | ||
48 | /* index_reg_310.extra_index_reg need to 0 or 7 to work */ | ||
49 | flexcop_ibi_value v30c; | ||
50 | v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid; | ||
51 | v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask; | ||
52 | fc->write_ibi_reg(fc,pid_filter_30c,v30c); | ||
53 | } | ||
54 | |||
55 | static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff) | ||
56 | { | ||
57 | flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff); | ||
58 | } | ||
59 | |||
60 | /* this fancy define reduces the code size of the quite similar PID controlling of | ||
61 | * the first 6 PIDs | ||
62 | */ | ||
63 | |||
64 | #define pid_ctrl(vregname,field,enablefield,trans_field,transval) \ | ||
65 | flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \ | ||
66 | v208 = fc->read_ibi_reg(fc, ctrl_208); \ | ||
67 | \ | ||
68 | vpid.vregname.field = onoff ? pid : 0x1fff; \ | ||
69 | vpid.vregname.trans_field = transval; \ | ||
70 | v208.ctrl_208.enablefield = onoff; \ | ||
71 | \ | ||
72 | fc->write_ibi_reg(fc,vregname,vpid); \ | ||
73 | fc->write_ibi_reg(fc,ctrl_208,v208); | ||
74 | |||
75 | static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
76 | { | ||
77 | pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0); | ||
78 | } | ||
79 | |||
80 | static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
81 | { | ||
82 | pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0); | ||
83 | } | ||
84 | |||
85 | static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
86 | { | ||
87 | pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0); | ||
88 | } | ||
89 | |||
90 | static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
91 | { | ||
92 | pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0); | ||
93 | } | ||
94 | |||
95 | static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
96 | { | ||
97 | pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0); | ||
98 | } | ||
99 | |||
100 | static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff) | ||
101 | { | ||
102 | pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0); | ||
103 | } | ||
104 | |||
105 | static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff) | ||
106 | { | ||
107 | if (pid == 0x2000) | ||
108 | return; | ||
109 | |||
110 | deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off"); | ||
111 | |||
112 | /* We could use bit magic here to reduce source code size. | ||
113 | * I decided against it, but to use the real register names */ | ||
114 | switch (index) { | ||
115 | case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break; | ||
116 | case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break; | ||
117 | case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break; | ||
118 | case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break; | ||
119 | case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break; | ||
120 | case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break; | ||
121 | default: | ||
122 | if (fc->has_32_hw_pid_filter && index < 38) { | ||
123 | flexcop_ibi_value vpid,vid; | ||
124 | |||
125 | /* set the index */ | ||
126 | vid = fc->read_ibi_reg(fc,index_reg_310); | ||
127 | vid.index_reg_310.index_reg = index - 6; | ||
128 | fc->write_ibi_reg(fc,index_reg_310, vid); | ||
129 | |||
130 | vpid = fc->read_ibi_reg(fc,pid_n_reg_314); | ||
131 | vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff; | ||
132 | vpid.pid_n_reg_314.PID_enable_bit = onoff; | ||
133 | fc->write_ibi_reg(fc,pid_n_reg_314, vpid); | ||
134 | } | ||
135 | break; | ||
136 | } | ||
137 | } | ||
138 | |||
139 | static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff) | ||
140 | { | ||
141 | if (fc->fullts_streaming_state != onoff) { | ||
142 | deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling"); | ||
143 | flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff)); | ||
144 | flexcop_pid_group_filter_ctrl(fc,onoff); | ||
145 | fc->fullts_streaming_state = onoff; | ||
146 | } | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff) | ||
151 | { | ||
152 | int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32; | ||
153 | |||
154 | fc->feedcount += onoff ? 1 : -1; | ||
155 | if (dvbdmxfeed->index >= max_pid_filter) | ||
156 | fc->extra_feedcount += onoff ? 1 : -1; | ||
157 | |||
158 | /* toggle complete-TS-streaming when: | ||
159 | * - pid_filtering is not enabled and it is the first or last feed requested | ||
160 | * - pid_filtering is enabled, | ||
161 | * - but the number of requested feeds is exceeded | ||
162 | * - or the requested pid is 0x2000 */ | ||
163 | |||
164 | if (!fc->pid_filtering && fc->feedcount == onoff) | ||
165 | flexcop_toggle_fullts_streaming(fc,onoff); | ||
166 | |||
167 | if (fc->pid_filtering) { | ||
168 | flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff); | ||
169 | |||
170 | if (fc->extra_feedcount > 0) | ||
171 | flexcop_toggle_fullts_streaming(fc,1); | ||
172 | else if (dvbdmxfeed->pid == 0x2000) | ||
173 | flexcop_toggle_fullts_streaming(fc,onoff); | ||
174 | else | ||
175 | flexcop_toggle_fullts_streaming(fc,0); | ||
176 | } | ||
177 | |||
178 | /* if it was the first or last feed request change the stream-status */ | ||
179 | if (fc->feedcount == onoff) { | ||
180 | flexcop_rcv_data_ctrl(fc,onoff); | ||
181 | if (fc->stream_control) | ||
182 | fc->stream_control(fc,onoff); | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | void flexcop_hw_filter_init(struct flexcop_device *fc) | ||
189 | { | ||
190 | int i; | ||
191 | flexcop_ibi_value v; | ||
192 | for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++) | ||
193 | flexcop_pid_control(fc,i,0x1fff,0); | ||
194 | |||
195 | flexcop_pid_group_filter(fc, 0, 0x1fe0); | ||
196 | flexcop_pid_group_filter_ctrl(fc,0); | ||
197 | |||
198 | v = fc->read_ibi_reg(fc,pid_filter_308); | ||
199 | v.pid_filter_308.EMM_filter_4 = 1; | ||
200 | v.pid_filter_308.EMM_filter_6 = 0; | ||
201 | fc->write_ibi_reg(fc,pid_filter_308,v); | ||
202 | |||
203 | flexcop_null_filter_ctrl(fc, 1); | ||
204 | } | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c new file mode 100644 index 000000000000..be4266d4ae91 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c | |||
@@ -0,0 +1,210 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | #define FC_MAX_I2C_RETRIES 100000 | ||
11 | |||
12 | static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100) | ||
13 | { | ||
14 | int i; | ||
15 | flexcop_ibi_value r; | ||
16 | |||
17 | r100->tw_sm_c_100.working_start = 1; | ||
18 | deb_i2c("r100 before: %08x\n",r100->raw); | ||
19 | |||
20 | fc->write_ibi_reg(fc, tw_sm_c_100, ibi_zero); | ||
21 | fc->write_ibi_reg(fc, tw_sm_c_100, *r100); /* initiating i2c operation */ | ||
22 | |||
23 | for (i = 0; i < FC_MAX_I2C_RETRIES; i++) { | ||
24 | r = fc->read_ibi_reg(fc, tw_sm_c_100); | ||
25 | |||
26 | if (!r.tw_sm_c_100.no_base_addr_ack_error) { | ||
27 | if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */ | ||
28 | *r100 = r; | ||
29 | deb_i2c("i2c success\n"); | ||
30 | return 0; | ||
31 | } | ||
32 | } else { | ||
33 | deb_i2c("suffering from an i2c ack_error\n"); | ||
34 | return -EREMOTEIO; | ||
35 | } | ||
36 | } | ||
37 | deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i); | ||
38 | return -EREMOTEIO; | ||
39 | } | ||
40 | |||
41 | static int flexcop_i2c_read4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) | ||
42 | { | ||
43 | flexcop_ibi_value r104; | ||
44 | int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */ | ||
45 | ret; | ||
46 | |||
47 | if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) { | ||
48 | /* The Cablestar needs a different kind of i2c-transfer (does not | ||
49 | * support "Repeat Start"): | ||
50 | * wait for the ACK failure, | ||
51 | * and do a subsequent read with the Bit 30 enabled | ||
52 | */ | ||
53 | r100.tw_sm_c_100.no_base_addr_ack_error = 1; | ||
54 | if ((ret = flexcop_i2c_operation(fc,&r100)) != 0) { | ||
55 | deb_i2c("no_base_addr read failed. %d\n",ret); | ||
56 | return ret; | ||
57 | } | ||
58 | } | ||
59 | |||
60 | buf[0] = r100.tw_sm_c_100.data1_reg; | ||
61 | |||
62 | if (len > 0) { | ||
63 | r104 = fc->read_ibi_reg(fc,tw_sm_c_104); | ||
64 | deb_i2c("read: r100: %08x, r104: %08x\n",r100.raw,r104.raw); | ||
65 | |||
66 | /* there is at least one more byte, otherwise we wouldn't be here */ | ||
67 | buf[1] = r104.tw_sm_c_104.data2_reg; | ||
68 | if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg; | ||
69 | if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg; | ||
70 | } | ||
71 | |||
72 | return 0; | ||
73 | } | ||
74 | |||
75 | static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf) | ||
76 | { | ||
77 | flexcop_ibi_value r104; | ||
78 | int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */ | ||
79 | r104.raw = 0; | ||
80 | |||
81 | /* there is at least one byte, otherwise we wouldn't be here */ | ||
82 | r100.tw_sm_c_100.data1_reg = buf[0]; | ||
83 | |||
84 | r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0; | ||
85 | r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0; | ||
86 | r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0; | ||
87 | |||
88 | deb_i2c("write: r100: %08x, r104: %08x\n",r100.raw,r104.raw); | ||
89 | |||
90 | /* write the additional i2c data before doing the actual i2c operation */ | ||
91 | fc->write_ibi_reg(fc,tw_sm_c_104,r104); | ||
92 | return flexcop_i2c_operation(fc,&r100); | ||
93 | } | ||
94 | |||
95 | int flexcop_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, | ||
96 | flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len) | ||
97 | { | ||
98 | int ret; | ||
99 | u16 bytes_to_transfer; | ||
100 | flexcop_ibi_value r100; | ||
101 | |||
102 | deb_i2c("op = %d\n",op); | ||
103 | r100.raw = 0; | ||
104 | r100.tw_sm_c_100.chipaddr = chipaddr; | ||
105 | r100.tw_sm_c_100.twoWS_rw = op; | ||
106 | r100.tw_sm_c_100.twoWS_port_reg = port; | ||
107 | |||
108 | while (len != 0) { | ||
109 | bytes_to_transfer = len > 4 ? 4 : len; | ||
110 | |||
111 | r100.tw_sm_c_100.total_bytes = bytes_to_transfer - 1; | ||
112 | r100.tw_sm_c_100.baseaddr = addr; | ||
113 | |||
114 | if (op == FC_READ) | ||
115 | ret = flexcop_i2c_read4(fc, r100, buf); | ||
116 | else | ||
117 | ret = flexcop_i2c_write4(fc,r100, buf); | ||
118 | |||
119 | if (ret < 0) | ||
120 | return ret; | ||
121 | |||
122 | buf += bytes_to_transfer; | ||
123 | addr += bytes_to_transfer; | ||
124 | len -= bytes_to_transfer; | ||
125 | }; | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | /* exported for PCI i2c */ | ||
130 | EXPORT_SYMBOL(flexcop_i2c_request); | ||
131 | |||
132 | /* master xfer callback for demodulator */ | ||
133 | static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num) | ||
134 | { | ||
135 | struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); | ||
136 | int i, ret = 0; | ||
137 | |||
138 | if (down_interruptible(&fc->i2c_sem)) | ||
139 | return -ERESTARTSYS; | ||
140 | |||
141 | /* reading */ | ||
142 | if (num == 2 && | ||
143 | msgs[0].flags == 0 && | ||
144 | msgs[1].flags == I2C_M_RD && | ||
145 | msgs[0].buf != NULL && | ||
146 | msgs[1].buf != NULL) { | ||
147 | |||
148 | ret = fc->i2c_request(fc, FC_READ, FC_I2C_PORT_DEMOD, msgs[0].addr, msgs[0].buf[0], msgs[1].buf, msgs[1].len); | ||
149 | |||
150 | } else for (i = 0; i < num; i++) { /* writing command */ | ||
151 | if (msgs[i].flags != 0 || msgs[i].buf == NULL || msgs[i].len < 2) { | ||
152 | ret = -EINVAL; | ||
153 | break; | ||
154 | } | ||
155 | |||
156 | ret = fc->i2c_request(fc, FC_WRITE, FC_I2C_PORT_DEMOD, msgs[i].addr, msgs[i].buf[0], &msgs[i].buf[1], msgs[i].len - 1); | ||
157 | } | ||
158 | |||
159 | if (ret < 0) | ||
160 | err("i2c master_xfer failed"); | ||
161 | else | ||
162 | ret = num; | ||
163 | |||
164 | up(&fc->i2c_sem); | ||
165 | |||
166 | return ret; | ||
167 | } | ||
168 | |||
169 | static u32 flexcop_i2c_func(struct i2c_adapter *adapter) | ||
170 | { | ||
171 | return I2C_FUNC_I2C; | ||
172 | } | ||
173 | |||
174 | static struct i2c_algorithm flexcop_algo = { | ||
175 | .name = "FlexCop I2C algorithm", | ||
176 | .id = I2C_ALGO_BIT, | ||
177 | .master_xfer = flexcop_master_xfer, | ||
178 | .functionality = flexcop_i2c_func, | ||
179 | }; | ||
180 | |||
181 | int flexcop_i2c_init(struct flexcop_device *fc) | ||
182 | { | ||
183 | int ret; | ||
184 | |||
185 | sema_init(&fc->i2c_sem,1); | ||
186 | |||
187 | memset(&fc->i2c_adap, 0, sizeof(struct i2c_adapter)); | ||
188 | strncpy(fc->i2c_adap.name, "B2C2 FlexCop device",I2C_NAME_SIZE); | ||
189 | |||
190 | i2c_set_adapdata(&fc->i2c_adap,fc); | ||
191 | |||
192 | fc->i2c_adap.class = I2C_CLASS_TV_DIGITAL; | ||
193 | fc->i2c_adap.algo = &flexcop_algo; | ||
194 | fc->i2c_adap.algo_data = NULL; | ||
195 | fc->i2c_adap.id = I2C_ALGO_BIT; | ||
196 | |||
197 | if ((ret = i2c_add_adapter(&fc->i2c_adap)) < 0) | ||
198 | return ret; | ||
199 | |||
200 | fc->init_state |= FC_STATE_I2C_INIT; | ||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | void flexcop_i2c_exit(struct flexcop_device *fc) | ||
205 | { | ||
206 | if (fc->init_state & FC_STATE_I2C_INIT) | ||
207 | i2c_del_adapter(&fc->i2c_adap); | ||
208 | |||
209 | fc->init_state &= ~FC_STATE_I2C_INIT; | ||
210 | } | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-misc.c b/drivers/media/dvb/b2c2/flexcop-misc.c new file mode 100644 index 000000000000..19e06da46774 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-misc.c | |||
@@ -0,0 +1,66 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-misc.c - miscellaneous functions. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | void flexcop_determine_revision(struct flexcop_device *fc) | ||
11 | { | ||
12 | flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204); | ||
13 | |||
14 | switch (v.misc_204.Rev_N_sig_revision_hi) { | ||
15 | case 0x2: | ||
16 | deb_info("found a FlexCopII.\n"); | ||
17 | fc->rev = FLEXCOP_II; | ||
18 | break; | ||
19 | case 0x3: | ||
20 | deb_info("found a FlexCopIIb.\n"); | ||
21 | fc->rev = FLEXCOP_IIB; | ||
22 | break; | ||
23 | case 0x0: | ||
24 | deb_info("found a FlexCopIII.\n"); | ||
25 | fc->rev = FLEXCOP_III; | ||
26 | break; | ||
27 | default: | ||
28 | err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi); | ||
29 | break; | ||
30 | } | ||
31 | |||
32 | if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps)) | ||
33 | deb_info("this FlexCop has the additional 32 hardware pid filter.\n"); | ||
34 | else | ||
35 | deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n"); | ||
36 | /* bus parts have to decide if hw pid filtering is used or not. */ | ||
37 | } | ||
38 | |||
39 | const char *flexcop_revision_names[] = { | ||
40 | "Unkown chip", | ||
41 | "FlexCopII", | ||
42 | "FlexCopIIb", | ||
43 | "FlexCopIII", | ||
44 | }; | ||
45 | |||
46 | const char *flexcop_device_names[] = { | ||
47 | "Unkown device", | ||
48 | "AirStar 2 DVB-T", | ||
49 | "AirStar 2 ATSC", | ||
50 | "SkyStar 2 DVB-S", | ||
51 | "SkyStar 2 DVB-S (old version)", | ||
52 | "CableStar 2 DVB-C", | ||
53 | }; | ||
54 | |||
55 | const char *flexcop_bus_names[] = { | ||
56 | "USB", | ||
57 | "PCI", | ||
58 | }; | ||
59 | |||
60 | void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const | ||
61 | char *suffix) | ||
62 | { | ||
63 | info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix, | ||
64 | flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type], | ||
65 | flexcop_revision_names[fc->rev],suffix); | ||
66 | } | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-pci.c b/drivers/media/dvb/b2c2/flexcop-pci.c new file mode 100644 index 000000000000..ed717c0073d5 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-pci.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-pci.c - covers the PCI part including DMA transfers. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | |||
9 | #define FC_LOG_PREFIX "flexcop-pci" | ||
10 | #include "flexcop-common.h" | ||
11 | |||
12 | static int enable_pid_filtering = 1; | ||
13 | module_param(enable_pid_filtering, int, 0444); | ||
14 | MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1"); | ||
15 | |||
16 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
17 | #define dprintk(level,args...) \ | ||
18 | do { if ((debug & level)) printk(args); } while (0) | ||
19 | #define DEBSTATUS "" | ||
20 | #else | ||
21 | #define dprintk(level,args...) | ||
22 | #define DEBSTATUS " (debugging is not enabled)" | ||
23 | #endif | ||
24 | |||
25 | #define deb_info(args...) dprintk(0x01,args) | ||
26 | #define deb_reg(args...) dprintk(0x02,args) | ||
27 | #define deb_ts(args...) dprintk(0x04,args) | ||
28 | #define deb_irq(args...) dprintk(0x08,args) | ||
29 | |||
30 | static int debug = 0; | ||
31 | module_param(debug, int, 0644); | ||
32 | MODULE_PARM_DESC(debug, "set debug level (1=info,2=regs,4=TS,8=irqdma (|-able))." DEBSTATUS); | ||
33 | |||
34 | #define DRIVER_VERSION "0.1" | ||
35 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver" | ||
36 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" | ||
37 | |||
38 | struct flexcop_pci { | ||
39 | struct pci_dev *pdev; | ||
40 | |||
41 | #define FC_PCI_INIT 0x01 | ||
42 | #define FC_PCI_DMA_INIT 0x02 | ||
43 | int init_state; | ||
44 | |||
45 | void __iomem *io_mem; | ||
46 | u32 irq; | ||
47 | /* buffersize (at least for DMA1, need to be % 188 == 0, | ||
48 | * this logic is required */ | ||
49 | #define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188) | ||
50 | #define FC_DEFAULT_DMA2_BUFSIZE (10 * 188) | ||
51 | struct flexcop_dma dma[2]; | ||
52 | |||
53 | int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */ | ||
54 | u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */ | ||
55 | int count; | ||
56 | |||
57 | spinlock_t irq_lock; | ||
58 | |||
59 | struct flexcop_device *fc_dev; | ||
60 | }; | ||
61 | |||
62 | static int lastwreg,lastwval,lastrreg,lastrval; | ||
63 | |||
64 | static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r) | ||
65 | { | ||
66 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
67 | flexcop_ibi_value v; | ||
68 | v.raw = readl(fc_pci->io_mem + r); | ||
69 | |||
70 | if (lastrreg != r || lastrval != v.raw) { | ||
71 | lastrreg = r; lastrval = v.raw; | ||
72 | deb_reg("new rd: %3x: %08x\n",r,v.raw); | ||
73 | } | ||
74 | |||
75 | return v; | ||
76 | } | ||
77 | |||
78 | static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v) | ||
79 | { | ||
80 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
81 | |||
82 | if (lastwreg != r || lastwval != v.raw) { | ||
83 | lastwreg = r; lastwval = v.raw; | ||
84 | deb_reg("new wr: %3x: %08x\n",r,v.raw); | ||
85 | } | ||
86 | |||
87 | writel(v.raw, fc_pci->io_mem + r); | ||
88 | return 0; | ||
89 | } | ||
90 | |||
91 | /* When PID filtering is turned on, we use the timer IRQ, because small amounts | ||
92 | * of data need to be passed to the user space instantly as well. When PID | ||
93 | * filtering is turned off, we use the page-change-IRQ */ | ||
94 | static irqreturn_t flexcop_pci_irq(int irq, void *dev_id, struct pt_regs *regs) | ||
95 | { | ||
96 | struct flexcop_pci *fc_pci = dev_id; | ||
97 | struct flexcop_device *fc = fc_pci->fc_dev; | ||
98 | flexcop_ibi_value v = fc->read_ibi_reg(fc,irq_20c); | ||
99 | irqreturn_t ret = IRQ_HANDLED; | ||
100 | |||
101 | spin_lock_irq(&fc_pci->irq_lock); | ||
102 | |||
103 | if (v.irq_20c.DMA1_IRQ_Status == 1) { | ||
104 | if (fc_pci->active_dma1_addr == 0) | ||
105 | flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188); | ||
106 | else | ||
107 | flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188); | ||
108 | |||
109 | deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr); | ||
110 | fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr; | ||
111 | } else if (v.irq_20c.DMA1_Timer_Status == 1) { | ||
112 | /* for the timer IRQ we only can use buffer dmx feeding, because we don't have | ||
113 | * complete TS packets when reading from the DMA memory */ | ||
114 | dma_addr_t cur_addr = | ||
115 | fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; | ||
116 | u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; | ||
117 | |||
118 | deb_irq("irq: %08x cur_addr: %08x: cur_pos: %08x, last_cur_pos: %08x ", | ||
119 | v.raw,cur_addr,cur_pos,fc_pci->last_dma1_cur_pos); | ||
120 | |||
121 | /* buffer end was reached, restarted from the beginning | ||
122 | * pass the data from last_cur_pos to the buffer end to the demux | ||
123 | */ | ||
124 | if (cur_pos < fc_pci->last_dma1_cur_pos) { | ||
125 | deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos); | ||
126 | flexcop_pass_dmx_data(fc_pci->fc_dev, | ||
127 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, | ||
128 | (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos); | ||
129 | fc_pci->last_dma1_cur_pos = 0; | ||
130 | fc_pci->count = 0; | ||
131 | } | ||
132 | |||
133 | if (cur_pos > fc_pci->last_dma1_cur_pos) { | ||
134 | deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos); | ||
135 | flexcop_pass_dmx_data(fc_pci->fc_dev, | ||
136 | fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos, | ||
137 | cur_pos - fc_pci->last_dma1_cur_pos); | ||
138 | } | ||
139 | deb_irq("\n"); | ||
140 | |||
141 | fc_pci->last_dma1_cur_pos = cur_pos; | ||
142 | } else | ||
143 | ret = IRQ_NONE; | ||
144 | |||
145 | spin_unlock_irq(&fc_pci->irq_lock); | ||
146 | |||
147 | /* packet count would be ideal for hw filtering, but it isn't working. Either | ||
148 | * the data book is wrong, or I'm unable to read it correctly */ | ||
149 | |||
150 | /* if (v.irq_20c.DMA1_Size_IRQ_Status == 1) { packet counter */ | ||
151 | |||
152 | return ret; | ||
153 | } | ||
154 | |||
155 | static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff) | ||
156 | { | ||
157 | struct flexcop_pci *fc_pci = fc->bus_specific; | ||
158 | if (onoff) { | ||
159 | flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1); | ||
160 | flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1); | ||
161 | flexcop_dma_config_timer(fc,FC_DMA_1,1); | ||
162 | |||
163 | if (fc_pci->fc_dev->pid_filtering) { | ||
164 | fc_pci->last_dma1_cur_pos = 0; | ||
165 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,1); | ||
166 | } else { | ||
167 | fc_pci->active_dma1_addr = 0; | ||
168 | flexcop_dma_control_size_irq(fc,FC_DMA_1,1); | ||
169 | } | ||
170 | |||
171 | /* flexcop_dma_config_packet_count(fc,FC_DMA_1,0xc0); | ||
172 | flexcop_dma_control_packet_irq(fc,FC_DMA_1,1); */ | ||
173 | |||
174 | deb_irq("irqs enabled\n"); | ||
175 | } else { | ||
176 | if (fc_pci->fc_dev->pid_filtering) | ||
177 | flexcop_dma_control_timer_irq(fc,FC_DMA_1,0); | ||
178 | else | ||
179 | flexcop_dma_control_size_irq(fc,FC_DMA_1,0); | ||
180 | |||
181 | // flexcop_dma_control_packet_irq(fc,FC_DMA_1,0); | ||
182 | deb_irq("irqs disabled\n"); | ||
183 | } | ||
184 | |||
185 | return 0; | ||
186 | } | ||
187 | |||
188 | static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci) | ||
189 | { | ||
190 | int ret; | ||
191 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0) | ||
192 | return ret; | ||
193 | |||
194 | if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) | ||
195 | goto dma1_free; | ||
196 | |||
197 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1); | ||
198 | flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2); | ||
199 | |||
200 | fc_pci->init_state |= FC_PCI_DMA_INIT; | ||
201 | goto success; | ||
202 | dma1_free: | ||
203 | flexcop_dma_free(&fc_pci->dma[0]); | ||
204 | |||
205 | success: | ||
206 | return ret; | ||
207 | } | ||
208 | |||
209 | static void flexcop_pci_dma_exit(struct flexcop_pci *fc_pci) | ||
210 | { | ||
211 | if (fc_pci->init_state & FC_PCI_DMA_INIT) { | ||
212 | flexcop_dma_free(&fc_pci->dma[0]); | ||
213 | flexcop_dma_free(&fc_pci->dma[1]); | ||
214 | } | ||
215 | fc_pci->init_state &= ~FC_PCI_DMA_INIT; | ||
216 | } | ||
217 | |||
218 | static int flexcop_pci_init(struct flexcop_pci *fc_pci) | ||
219 | { | ||
220 | int ret; | ||
221 | u8 card_rev; | ||
222 | |||
223 | pci_read_config_byte(fc_pci->pdev, PCI_CLASS_REVISION, &card_rev); | ||
224 | info("card revision %x", card_rev); | ||
225 | |||
226 | if ((ret = pci_enable_device(fc_pci->pdev)) != 0) | ||
227 | return ret; | ||
228 | |||
229 | pci_set_master(fc_pci->pdev); | ||
230 | |||
231 | /* enable interrupts */ | ||
232 | // pci_write_config_dword(pdev, 0x6c, 0x8000); | ||
233 | |||
234 | if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0) | ||
235 | goto err_pci_disable_device; | ||
236 | |||
237 | fc_pci->io_mem = pci_iomap(fc_pci->pdev, 0, 0x800); | ||
238 | |||
239 | if (!fc_pci->io_mem) { | ||
240 | err("cannot map io memory\n"); | ||
241 | ret = -EIO; | ||
242 | goto err_pci_release_regions; | ||
243 | } | ||
244 | |||
245 | pci_set_drvdata(fc_pci->pdev, fc_pci); | ||
246 | |||
247 | if ((ret = request_irq(fc_pci->pdev->irq, flexcop_pci_irq, | ||
248 | SA_SHIRQ, DRIVER_NAME, fc_pci)) != 0) | ||
249 | goto err_pci_iounmap; | ||
250 | |||
251 | spin_lock_init(&fc_pci->irq_lock); | ||
252 | |||
253 | fc_pci->init_state |= FC_PCI_INIT; | ||
254 | goto success; | ||
255 | |||
256 | err_pci_iounmap: | ||
257 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | ||
258 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
259 | err_pci_release_regions: | ||
260 | pci_release_regions(fc_pci->pdev); | ||
261 | err_pci_disable_device: | ||
262 | pci_disable_device(fc_pci->pdev); | ||
263 | |||
264 | success: | ||
265 | return ret; | ||
266 | } | ||
267 | |||
268 | static void flexcop_pci_exit(struct flexcop_pci *fc_pci) | ||
269 | { | ||
270 | if (fc_pci->init_state & FC_PCI_INIT) { | ||
271 | free_irq(fc_pci->pdev->irq, fc_pci); | ||
272 | pci_iounmap(fc_pci->pdev, fc_pci->io_mem); | ||
273 | pci_set_drvdata(fc_pci->pdev, NULL); | ||
274 | pci_release_regions(fc_pci->pdev); | ||
275 | pci_disable_device(fc_pci->pdev); | ||
276 | } | ||
277 | fc_pci->init_state &= ~FC_PCI_INIT; | ||
278 | } | ||
279 | |||
280 | |||
281 | static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
282 | { | ||
283 | struct flexcop_device *fc; | ||
284 | struct flexcop_pci *fc_pci; | ||
285 | int ret = -ENOMEM; | ||
286 | |||
287 | if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_pci))) == NULL) { | ||
288 | err("out of memory\n"); | ||
289 | return -ENOMEM; | ||
290 | } | ||
291 | |||
292 | /* general flexcop init */ | ||
293 | fc_pci = fc->bus_specific; | ||
294 | fc_pci->fc_dev = fc; | ||
295 | |||
296 | fc->read_ibi_reg = flexcop_pci_read_ibi_reg; | ||
297 | fc->write_ibi_reg = flexcop_pci_write_ibi_reg; | ||
298 | fc->i2c_request = flexcop_i2c_request; | ||
299 | fc->get_mac_addr = flexcop_eeprom_check_mac_addr; | ||
300 | |||
301 | fc->stream_control = flexcop_pci_stream_control; | ||
302 | |||
303 | if (enable_pid_filtering) | ||
304 | info("will use the HW PID filter."); | ||
305 | else | ||
306 | info("will pass the complete TS to the demuxer."); | ||
307 | |||
308 | fc->pid_filtering = enable_pid_filtering; | ||
309 | fc->bus_type = FC_PCI; | ||
310 | |||
311 | fc->dev = &pdev->dev; | ||
312 | fc->owner = THIS_MODULE; | ||
313 | |||
314 | /* bus specific part */ | ||
315 | fc_pci->pdev = pdev; | ||
316 | if ((ret = flexcop_pci_init(fc_pci)) != 0) | ||
317 | goto err_kfree; | ||
318 | |||
319 | /* init flexcop */ | ||
320 | if ((ret = flexcop_device_initialize(fc)) != 0) | ||
321 | goto err_pci_exit; | ||
322 | |||
323 | /* init dma */ | ||
324 | if ((ret = flexcop_pci_dma_init(fc_pci)) != 0) | ||
325 | goto err_fc_exit; | ||
326 | |||
327 | goto success; | ||
328 | err_fc_exit: | ||
329 | flexcop_device_exit(fc); | ||
330 | err_pci_exit: | ||
331 | flexcop_pci_exit(fc_pci); | ||
332 | err_kfree: | ||
333 | flexcop_device_kfree(fc); | ||
334 | success: | ||
335 | return ret; | ||
336 | } | ||
337 | |||
338 | /* in theory every _exit function should be called exactly two times, | ||
339 | * here and in the bail-out-part of the _init-function | ||
340 | */ | ||
341 | static void flexcop_pci_remove(struct pci_dev *pdev) | ||
342 | { | ||
343 | struct flexcop_pci *fc_pci = pci_get_drvdata(pdev); | ||
344 | |||
345 | flexcop_pci_dma_exit(fc_pci); | ||
346 | flexcop_device_exit(fc_pci->fc_dev); | ||
347 | flexcop_pci_exit(fc_pci); | ||
348 | flexcop_device_kfree(fc_pci->fc_dev); | ||
349 | } | ||
350 | |||
351 | static struct pci_device_id flexcop_pci_tbl[] = { | ||
352 | { PCI_DEVICE(0x13d0, 0x2103) }, | ||
353 | /* { PCI_DEVICE(0x13d0, 0x2200) }, PCI FlexCopIII ? */ | ||
354 | { }, | ||
355 | }; | ||
356 | |||
357 | MODULE_DEVICE_TABLE(pci, flexcop_pci_tbl); | ||
358 | |||
359 | static struct pci_driver flexcop_pci_driver = { | ||
360 | .name = "Technisat/B2C2 FlexCop II/IIb/III PCI", | ||
361 | .id_table = flexcop_pci_tbl, | ||
362 | .probe = flexcop_pci_probe, | ||
363 | .remove = flexcop_pci_remove, | ||
364 | }; | ||
365 | |||
366 | static int __init flexcop_pci_module_init(void) | ||
367 | { | ||
368 | return pci_register_driver(&flexcop_pci_driver); | ||
369 | } | ||
370 | |||
371 | static void __exit flexcop_pci_module_exit(void) | ||
372 | { | ||
373 | pci_unregister_driver(&flexcop_pci_driver); | ||
374 | } | ||
375 | |||
376 | module_init(flexcop_pci_module_init); | ||
377 | module_exit(flexcop_pci_module_exit); | ||
378 | |||
379 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
380 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
381 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-reg.h b/drivers/media/dvb/b2c2/flexcop-reg.h new file mode 100644 index 000000000000..5e131be55cb3 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-reg.h | |||
@@ -0,0 +1,701 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #ifndef __FLEXCOP_REG_H__ | ||
9 | #define __FLEXCOP_REG_H__ | ||
10 | |||
11 | |||
12 | typedef enum { | ||
13 | FLEXCOP_UNK = 0, | ||
14 | FLEXCOP_II, | ||
15 | FLEXCOP_IIB, | ||
16 | FLEXCOP_III, | ||
17 | } flexcop_revision_t; | ||
18 | |||
19 | extern const char *flexcop_revision_names[]; | ||
20 | |||
21 | typedef enum { | ||
22 | FC_UNK = 0, | ||
23 | FC_AIR_DVB, | ||
24 | FC_AIR_ATSC, | ||
25 | FC_SKY, | ||
26 | FC_SKY_OLD, | ||
27 | FC_CABLE, | ||
28 | } flexcop_device_type_t; | ||
29 | |||
30 | typedef enum { | ||
31 | FC_USB = 0, | ||
32 | FC_PCI, | ||
33 | } flexcop_bus_t; | ||
34 | |||
35 | extern const char *flexcop_device_names[]; | ||
36 | |||
37 | /* FlexCop IBI Registers */ | ||
38 | |||
39 | /* flexcop_ibi_reg - a huge union representing the register structure */ | ||
40 | typedef union { | ||
41 | u32 raw; | ||
42 | |||
43 | /* DMA 0x000 to 0x01c | ||
44 | * DMA1 0x000 to 0x00c | ||
45 | * DMA2 0x010 to 0x01c | ||
46 | */ | ||
47 | struct { | ||
48 | u32 dma_0start : 1; /* set: data will be delivered to dma1_address0 */ | ||
49 | u32 dma_0No_update : 1; /* set: dma1_cur_address will be updated, unset: no update */ | ||
50 | u32 dma_address0 :30; /* physical/virtual host memory address0 DMA */ | ||
51 | } dma_0x0; | ||
52 | |||
53 | struct { | ||
54 | u32 DMA_maxpackets : 8; /* (remapped) PCI DMA1 Packet Count Interrupt. This variable | ||
55 | is able to be read and written while bit(1) of register | ||
56 | 0x00c (remap_enable) is set. This variable represents | ||
57 | the number of packets that will be transmitted to the PCI | ||
58 | host using PCI DMA1 before an interrupt to the PCI is | ||
59 | asserted. This functionality may be enabled using bit(20) | ||
60 | of register 0x208. N=0 disables the IRQ. */ | ||
61 | u32 dma_addr_size :24; /* size of memory buffer in DWORDs (bytesize / 4) for DMA */ | ||
62 | } dma_0x4_remap; | ||
63 | |||
64 | struct { | ||
65 | u32 dma1timer : 7; /* reading PCI DMA1 timer ... when remap_enable is 0 */ | ||
66 | u32 unused : 1; | ||
67 | u32 dma_addr_size :24; | ||
68 | } dma_0x4_read; | ||
69 | |||
70 | struct { | ||
71 | u32 unused : 1; | ||
72 | u32 dmatimer : 7; /* writing PCI DMA1 timer ... when remap_enable is 0 */ | ||
73 | u32 dma_addr_size :24; | ||
74 | } dma_0x4_write; | ||
75 | |||
76 | struct { | ||
77 | u32 unused : 2; | ||
78 | u32 dma_cur_addr :30; /* current physical host memory address pointer for DMA */ | ||
79 | } dma_0x8; | ||
80 | |||
81 | struct { | ||
82 | u32 dma_1start : 1; /* set: data will be delivered to dma_address1, when dma_address0 is full */ | ||
83 | u32 remap_enable : 1; /* remap enable for 0x0x4(7:0) */ | ||
84 | u32 dma_address1 :30; /* Physical/virtual address 1 on DMA */ | ||
85 | } dma_0xc; | ||
86 | |||
87 | /* Two-wire Serial Master and Clock 0x100-0x110 */ | ||
88 | struct { | ||
89 | // u32 slave_transmitter : 1; /* ???*/ | ||
90 | u32 chipaddr : 7; /* two-line serial address of the target slave */ | ||
91 | u32 reserved1 : 1; | ||
92 | u32 baseaddr : 8; /* address of the location of the read/write operation */ | ||
93 | u32 data1_reg : 8; /* first byte in two-line serial read/write operation */ | ||
94 | u32 working_start : 1; /* when doing a write operation this indicator is 0 when ready | ||
95 | * set to 1 when doing a write operation */ | ||
96 | u32 twoWS_rw : 1; /* read/write indicator (1 = read, 0 write) */ | ||
97 | u32 total_bytes : 2; /* number of data bytes in each two-line serial transaction (0 = 1 byte, 11 = 4byte)*/ | ||
98 | u32 twoWS_port_reg : 2; /* port selection: 01 - Front End/Demod, 10 - EEPROM, 11 - Tuner */ | ||
99 | u32 no_base_addr_ack_error : 1; /* writing: write-req: frame is produced w/o baseaddr, read-req: read-cycles w/o | ||
100 | * preceding address assignment write frame | ||
101 | * ACK_ERROR = 1 when no ACK from slave in the last transaction */ | ||
102 | u32 st_done : 1; /* indicator for transaction is done */ | ||
103 | } tw_sm_c_100; | ||
104 | |||
105 | struct { | ||
106 | u32 data2_reg : 8; /* 2nd data byte */ | ||
107 | u32 data3_reg : 8; /* 3rd data byte */ | ||
108 | u32 data4_reg : 8; /* 4th data byte */ | ||
109 | u32 exlicit_stops : 1; /* when set, transactions are produced w/o trailing STOP flag, then send isolated STOP flags */ | ||
110 | u32 force_stop : 1; /* isolated stop flag */ | ||
111 | u32 unused : 6; | ||
112 | } tw_sm_c_104; | ||
113 | |||
114 | /* Clock. The register allows the FCIII to convert an incoming Master clock | ||
115 | * (MCLK) signal into a lower frequency clock through the use of a LowCounter | ||
116 | * (TLO) and a High- Counter (THI). The time counts for THI and TLO are | ||
117 | * measured in MCLK; each count represents 4 MCLK input clock cycles. | ||
118 | * | ||
119 | * The default output for port #1 is set for Front End Demod communication. (0x108) | ||
120 | * The default output for port #2 is set for EEPROM communication. (0x10c) | ||
121 | * The default output for port #3 is set for Tuner communication. (0x110) | ||
122 | */ | ||
123 | struct { | ||
124 | u32 thi1 : 6; /* Thi for port #1 (def: 100110b; 38) */ | ||
125 | u32 reserved1 : 2; | ||
126 | u32 tlo1 : 5; /* Tlo for port #1 (def: 11100b; 28) */ | ||
127 | u32 reserved2 :19; | ||
128 | } tw_sm_c_108; | ||
129 | |||
130 | struct { | ||
131 | u32 thi1 : 6; /* Thi for port #2 (def: 111001b; 57) */ | ||
132 | u32 reserved1 : 2; | ||
133 | u32 tlo1 : 5; /* Tlo for port #2 (def: 11100b; 28) */ | ||
134 | u32 reserved2 :19; | ||
135 | } tw_sm_c_10c; | ||
136 | |||
137 | struct { | ||
138 | u32 thi1 : 6; /* Thi for port #3 (def: 111001b; 57) */ | ||
139 | u32 reserved1 : 2; | ||
140 | u32 tlo1 : 5; /* Tlo for port #3 (def: 11100b; 28) */ | ||
141 | u32 reserved2 :19; | ||
142 | } tw_sm_c_110; | ||
143 | |||
144 | /* LNB Switch Frequency 0x200 | ||
145 | * Clock that creates the LNB switch tone. The default is set to have a fixed | ||
146 | * low output (not oscillating) to the LNB_CTL line. | ||
147 | */ | ||
148 | struct { | ||
149 | u32 LNB_CTLHighCount_sig :15; /* It is the number of pre-scaled clock cycles that will be low. */ | ||
150 | u32 LNB_CTLLowCount_sig :15; /* For example, to obtain a 22KHz output given a 45 Mhz Master | ||
151 | Clock signal (MCLK), set PreScalar=01 and LowCounter value to 0x1ff. */ | ||
152 | u32 LNB_CTLPrescaler_sig : 2; /* pre-scaler divides MCLK: 00 (no division), 01 by 2, 10 by 4, 11 by 12 */ | ||
153 | } lnb_switch_freq_200; | ||
154 | |||
155 | /* ACPI, Peripheral Reset, LNB Polarity | ||
156 | * ACPI power conservation mode, LNB polarity selection (low or high voltage), | ||
157 | * and peripheral reset. | ||
158 | */ | ||
159 | struct { | ||
160 | u32 ACPI1_sig : 1; /* turn of the power of tuner and LNB, not implemented in FCIII */ | ||
161 | u32 ACPI3_sig : 1; /* turn of power of the complete satelite receiver board (except FCIII) */ | ||
162 | u32 LNB_L_H_sig : 1; /* low or high voltage for LNB. (0 = low, 1 = high) */ | ||
163 | u32 Per_reset_sig : 1; /* misc. init reset (default: 1), to reset set to low and back to high */ | ||
164 | u32 reserved :20; | ||
165 | u32 Rev_N_sig_revision_hi : 4;/* 0xc in case of FCIII */ | ||
166 | u32 Rev_N_sig_reserved1 : 2; | ||
167 | u32 Rev_N_sig_caps : 1; /* if 1, FCIII has 32 PID- and MAC-filters and is capable of IP multicast */ | ||
168 | u32 Rev_N_sig_reserved2 : 1; | ||
169 | } misc_204; | ||
170 | |||
171 | /* Control and Status 0x208 to 0x21c */ | ||
172 | /* Gross enable and disable control */ | ||
173 | struct { | ||
174 | u32 Stream1_filter_sig : 1; /* Stream1 PID filtering */ | ||
175 | u32 Stream2_filter_sig : 1; /* Stream2 PID filtering */ | ||
176 | u32 PCR_filter_sig : 1; /* PCR PID filter */ | ||
177 | u32 PMT_filter_sig : 1; /* PMT PID filter */ | ||
178 | |||
179 | u32 EMM_filter_sig : 1; /* EMM PID filter */ | ||
180 | u32 ECM_filter_sig : 1; /* ECM PID filter */ | ||
181 | u32 Null_filter_sig : 1; /* Filters null packets, PID=0x1fff. */ | ||
182 | u32 Mask_filter_sig : 1; /* mask PID filter */ | ||
183 | |||
184 | u32 WAN_Enable_sig : 1; /* WAN output line through V8 memory space is activated. */ | ||
185 | u32 WAN_CA_Enable_sig : 1; /* not in FCIII */ | ||
186 | u32 CA_Enable_sig : 1; /* not in FCIII */ | ||
187 | u32 SMC_Enable_sig : 1; /* CI stream data (CAI) goes directly to the smart card intf (opposed IBI 0x600 or SC-cmd buf). */ | ||
188 | |||
189 | u32 Per_CA_Enable_sig : 1; /* not in FCIII */ | ||
190 | u32 Multi2_Enable_sig : 1; /* ? */ | ||
191 | u32 MAC_filter_Mode_sig : 1; /* (MAC_filter_enable) Globally enables MAC filters for Net PID filteres. */ | ||
192 | u32 Rcv_Data_sig : 1; /* PID filtering module enable. When this bit is a one, the PID filter will | ||
193 | examine and process packets according to all other (individual) PID | ||
194 | filtering controls. If it a zero, no packet processing of any kind will | ||
195 | take place. All data from the tuner will be thrown away. */ | ||
196 | |||
197 | u32 DMA1_IRQ_Enable_sig : 1; /* When set, a DWORD counter is enabled on PCI DMA1 that asserts the PCI | ||
198 | * interrupt after the specified count for filling the buffer. */ | ||
199 | u32 DMA1_Timer_Enable_sig : 1; /* When set, a timer is enabled on PCI DMA1 that asserts the PCI interrupt | ||
200 | after a specified amount of time. */ | ||
201 | u32 DMA2_IRQ_Enable_sig : 1; /* same as DMA1_IRQ_Enable_sig but for DMA2 */ | ||
202 | u32 DMA2_Timer_Enable_sig : 1; /* same as DMA1_Timer_Enable_sig but for DMA2 */ | ||
203 | |||
204 | u32 DMA1_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA1 that asserts the PCI interrupt. */ | ||
205 | u32 DMA2_Size_IRQ_Enable_sig : 1; /* When set, a packet count detector is enabled on PCI DMA2 that asserts the PCI interrupt. */ | ||
206 | u32 Mailbox_from_V8_Enable_sig: 1; /* When set, writes to the mailbox register produce an interrupt to the | ||
207 | PCI host to indicate that mailbox data is available. */ | ||
208 | |||
209 | u32 unused : 9; | ||
210 | } ctrl_208; | ||
211 | |||
212 | /* General status. When a PCI interrupt occurs, this register is read to | ||
213 | * discover the reason for the interrupt. | ||
214 | */ | ||
215 | struct { | ||
216 | u32 DMA1_IRQ_Status : 1; /* When set(1) the DMA1 counter had generated an IRQ. Read Only. */ | ||
217 | u32 DMA1_Timer_Status : 1; /* When set(1) the DMA1 timer had generated an IRQ. Read Only. */ | ||
218 | u32 DMA2_IRQ_Status : 1; /* When set(1) the DMA2 counter had generated an IRQ. Read Only. */ | ||
219 | u32 DMA2_Timer_Status : 1; /* When set(1) the DMA2 timer had generated an IRQ. Read Only. */ | ||
220 | u32 DMA1_Size_IRQ_Status : 1; /* (Read only). This register is read after an interrupt to */ | ||
221 | u32 DMA2_Size_IRQ_Status : 1; /* find out why we had an IRQ. Reading this register will clear this bit. Packet count*/ | ||
222 | u32 Mailbox_from_V8_Status_sig: 1; /* Same as above. Reading this register will clear this bit. */ | ||
223 | u32 Data_receiver_error : 1; /* 1 indicate an error in the receiver Front End (Tuner module) */ | ||
224 | u32 Continuity_error_flag : 1; /* 1 indicates a continuity error in the TS stream. */ | ||
225 | u32 LLC_SNAP_FLAG_set : 1; /* 1 indicates that the LCC_SNAP_FLAG was set. */ | ||
226 | u32 Transport_Error : 1; /* When set indicates that an unexpected packet was received. */ | ||
227 | u32 reserved :21; | ||
228 | } irq_20c; | ||
229 | |||
230 | |||
231 | /* Software reset register */ | ||
232 | struct { | ||
233 | u32 reset_blocks : 8; /* Enabled when Block_reset_enable = 0xB2 and 0x208 bits 15:8 = 0x00. | ||
234 | Each bit location represents a 0x100 block of registers. Writing | ||
235 | a one in a bit location resets that block of registers and the logic | ||
236 | that it controls. */ | ||
237 | u32 Block_reset_enable : 8; /* This variable is set to 0xB2 when the register is written. */ | ||
238 | u32 Special_controls :16; /* Asserts Reset_V8 => 0xC258; Turns on pci encryption => 0xC25A; | ||
239 | Turns off pci encryption => 0xC259 Note: pci_encryption default | ||
240 | at power-up is ON. */ | ||
241 | } sw_reset_210; | ||
242 | |||
243 | struct { | ||
244 | u32 vuart_oe_sig : 1; /* When clear, the V8 processor has sole control of the serial UART | ||
245 | (RS-232 Smart Card interface). When set, the IBI interface | ||
246 | defined by register 0x600 controls the serial UART. */ | ||
247 | u32 v2WS_oe_sig : 1; /* When clear, the V8 processor has direct control of the Two-line | ||
248 | Serial Master EEPROM target. When set, the Two-line Serial Master | ||
249 | EEPROM target interface is controlled by IBI register 0x100. */ | ||
250 | u32 halt_V8_sig : 1; /* When set, contiguous wait states are applied to the V8-space | ||
251 | bus masters. Once this signal is cleared, normal V8-space | ||
252 | operations resume. */ | ||
253 | u32 section_pkg_enable_sig: 1; /* When set, this signal enables the front end translation circuitry | ||
254 | to process section packed transport streams. */ | ||
255 | u32 s2p_sel_sig : 1; /* Serial to parallel conversion. When set, polarized transport data | ||
256 | within the FlexCop3 front end circuitry is converted from a serial | ||
257 | stream into parallel data before downstream processing otherwise | ||
258 | interprets the data. */ | ||
259 | u32 unused1 : 3; | ||
260 | u32 polarity_PS_CLK_sig: 1; /* This signal is used to invert the input polarity of the tranport | ||
261 | stream CLOCK signal before any processing occurs on the transport | ||
262 | stream within FlexCop3. */ | ||
263 | u32 polarity_PS_VALID_sig: 1; /* This signal is used to invert the input polarity of the tranport | ||
264 | stream VALID signal before any processing occurs on the transport | ||
265 | stream within FlexCop3. */ | ||
266 | u32 polarity_PS_SYNC_sig: 1; /* This signal is used to invert the input polarity of the tranport | ||
267 | stream SYNC signal before any processing occurs on the transport | ||
268 | stream within FlexCop3. */ | ||
269 | u32 polarity_PS_ERR_sig: 1; /* This signal is used to invert the input polarity of the tranport | ||
270 | stream ERROR signal before any processing occurs on the transport | ||
271 | stream within FlexCop3. */ | ||
272 | u32 unused2 :20; | ||
273 | } misc_214; | ||
274 | |||
275 | /* Mailbox from V8 to host */ | ||
276 | struct { | ||
277 | u32 Mailbox_from_V8 :32; /* When this register is written by either the V8 processor or by an | ||
278 | end host, an interrupt is generated to the PCI host to indicate | ||
279 | that mailbox data is available. Reading register 20c will clear | ||
280 | the IRQ. */ | ||
281 | } mbox_v8_to_host_218; | ||
282 | |||
283 | /* Mailbox from host to v8 Mailbox_to_V8 | ||
284 | * Mailbox_to_V8 mailbox storage register | ||
285 | * used to send messages from PCI to V8. Writing to this register will send an | ||
286 | * IRQ to the V8. Then it can read the data from here. Reading this register | ||
287 | * will clear the IRQ. If the V8 is halted and bit 31 of this register is set, | ||
288 | * then this register is used instead as a direct interface to access the | ||
289 | * V8space memory. | ||
290 | */ | ||
291 | struct { | ||
292 | u32 sysramaccess_data : 8; /* Data byte written or read from the specified address in V8 SysRAM. */ | ||
293 | u32 sysramaccess_addr :15; /* 15 bit address used to access V8 Sys-RAM. */ | ||
294 | u32 unused : 7; | ||
295 | u32 sysramaccess_write: 1; /* Write flag used to latch data into the V8 SysRAM. */ | ||
296 | u32 sysramaccess_busmuster: 1; /* Setting this bit when the V8 is halted at 0x214 Bit(2) allows | ||
297 | this IBI register interface to directly drive the V8-space memory. */ | ||
298 | } mbox_host_to_v8_21c; | ||
299 | |||
300 | |||
301 | /* PIDs, Translation Bit, SMC Filter Select 0x300 to 0x31c */ | ||
302 | struct { | ||
303 | u32 Stream1_PID :13; /* Primary use is receiving Net data, so these 13 bits normally | ||
304 | hold the PID value for the desired network stream. */ | ||
305 | u32 Stream1_trans : 1; /* When set, Net translation will take place for Net data ferried in TS packets. */ | ||
306 | u32 MAC_Multicast_filter : 1; /* When clear, multicast MAC filtering is not allowed for Stream1 and PID_n filters. */ | ||
307 | u32 debug_flag_pid_saved : 1; | ||
308 | u32 Stream2_PID :13; /* 13 bits for Stream 2 PID filter value. General use. */ | ||
309 | u32 Stream2_trans : 1; /* When set Tables/CAI translation will take place for the data ferried in | ||
310 | Stream2_PID TS packets. */ | ||
311 | u32 debug_flag_write_status00 : 1; | ||
312 | u32 debug_fifo_problem : 1; | ||
313 | } pid_filter_300; | ||
314 | |||
315 | struct { | ||
316 | u32 PCR_PID :13; /* PCR stream PID filter value. Primary use is Program Clock Reference stream filtering. */ | ||
317 | u32 PCR_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */ | ||
318 | u32 debug_overrun3 : 1; | ||
319 | u32 debug_overrun2 : 1; | ||
320 | u32 PMT_PID :13; /* stream PID filter value. Primary use is Program Management Table segment filtering. */ | ||
321 | u32 PMT_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */ | ||
322 | u32 reserved : 2; | ||
323 | } pid_filter_304; | ||
324 | |||
325 | struct { | ||
326 | u32 EMM_PID :13; /* EMM PID filter value. Primary use is Entitlement Management Messaging for | ||
327 | conditional access-related data. */ | ||
328 | u32 EMM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */ | ||
329 | u32 EMM_filter_4 : 1; /* When set will pass only EMM data possessing the same ID code as the | ||
330 | first four bytes (32 bits) of the end-user s 6-byte Smart Card ID number Select */ | ||
331 | u32 EMM_filter_6 : 1; /* When set will pass only EMM data possessing the same 6-byte code as the end-users | ||
332 | complete 6-byte Smart Card ID number. */ | ||
333 | u32 ECM_PID :13; /* ECM PID filter value. Primary use is Entitlement Control Messaging for conditional | ||
334 | access-related data. */ | ||
335 | u32 ECM_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */ | ||
336 | u32 reserved : 2; | ||
337 | } pid_filter_308; | ||
338 | |||
339 | struct { | ||
340 | u32 Group_PID :13; /* PID value for group filtering. */ | ||
341 | u32 Group_trans : 1; /* When set, Tables/CAI translation will take place for these packets. */ | ||
342 | u32 unused1 : 2; | ||
343 | u32 Group_mask :13; /* Mask value used in logical "and" equation that defines group filtering */ | ||
344 | u32 unused2 : 3; | ||
345 | } pid_filter_30c_ext_ind_0_7; | ||
346 | |||
347 | struct { | ||
348 | u32 net_master_read :17; | ||
349 | u32 unused :15; | ||
350 | } pid_filter_30c_ext_ind_1; | ||
351 | |||
352 | struct { | ||
353 | u32 net_master_write :17; | ||
354 | u32 unused :15; | ||
355 | } pid_filter_30c_ext_ind_2; | ||
356 | |||
357 | struct { | ||
358 | u32 next_net_master_write :17; | ||
359 | u32 unused :15; | ||
360 | } pid_filter_30c_ext_ind_3; | ||
361 | |||
362 | struct { | ||
363 | u32 unused1 : 1; | ||
364 | u32 state_write :10; | ||
365 | u32 reserved1 : 6; /* default: 000100 */ | ||
366 | u32 stack_read :10; | ||
367 | u32 reserved2 : 5; /* default: 00100 */ | ||
368 | } pid_filter_30c_ext_ind_4; | ||
369 | |||
370 | struct { | ||
371 | u32 stack_cnt :10; | ||
372 | u32 unused :22; | ||
373 | } pid_filter_30c_ext_ind_5; | ||
374 | |||
375 | struct { | ||
376 | u32 pid_fsm_save_reg0 : 2; | ||
377 | u32 pid_fsm_save_reg1 : 2; | ||
378 | u32 pid_fsm_save_reg2 : 2; | ||
379 | u32 pid_fsm_save_reg3 : 2; | ||
380 | u32 pid_fsm_save_reg4 : 2; | ||
381 | u32 pid_fsm_save_reg300 : 2; | ||
382 | u32 write_status1 : 2; | ||
383 | u32 write_status4 : 2; | ||
384 | u32 data_size_reg :12; | ||
385 | u32 unused : 4; | ||
386 | } pid_filter_30c_ext_ind_6; | ||
387 | |||
388 | struct { | ||
389 | u32 index_reg : 5; /* (Index pointer) Points at an internal PIDn register. A binary code | ||
390 | representing one of 32 internal PIDn registers as well as its | ||
391 | corresponding internal MAC_lown register. */ | ||
392 | u32 extra_index_reg : 3; /* This vector is used to select between sets of debug signals routed to register 0x30c. */ | ||
393 | u32 AB_select : 1; /* Used in conjunction with 0x31c. read/write to the MAC_highA or MAC_highB register | ||
394 | 0=MAC_highB register, 1=MAC_highA */ | ||
395 | u32 pass_alltables : 1; /* 1=Net packets are not filtered against the Network Table ID found in register 0x400. | ||
396 | All types of networks (DVB, ATSC, ISDB) are passed. */ | ||
397 | u32 unused :22; | ||
398 | } index_reg_310; | ||
399 | |||
400 | struct { | ||
401 | u32 PID :13; /* PID value */ | ||
402 | u32 PID_trans : 1; /* translation will take place for packets filtered */ | ||
403 | u32 PID_enable_bit : 1; /* When set this PID filter is enabled */ | ||
404 | u32 reserved :17; | ||
405 | } pid_n_reg_314; | ||
406 | |||
407 | struct { | ||
408 | u32 A4_byte : 8; | ||
409 | u32 A5_byte : 8; | ||
410 | u32 A6_byte : 8; | ||
411 | u32 Enable_bit : 1; /* enabled (1) or disabled (1) */ | ||
412 | u32 HighAB_bit : 1; /* use MAC_highA (1) or MAC_highB (0) as MSB */ | ||
413 | u32 reserved : 6; | ||
414 | } mac_low_reg_318; | ||
415 | |||
416 | struct { | ||
417 | u32 A1_byte : 8; | ||
418 | u32 A2_byte : 8; | ||
419 | u32 A3_byte : 8; | ||
420 | u32 reserved : 8; | ||
421 | } mac_high_reg_31c; | ||
422 | |||
423 | /* Table, SMCID,MACDestination Filters 0x400 to 0x41c */ | ||
424 | struct { | ||
425 | u32 reserved :16; | ||
426 | #define fc_data_Tag_ID_DVB 0x3e | ||
427 | #define fc_data_Tag_ID_ATSC 0x3f | ||
428 | #define fc_data_Tag_ID_IDSB 0x8b | ||
429 | u32 data_Tag_ID :16; | ||
430 | } data_tag_400; | ||
431 | |||
432 | struct { | ||
433 | u32 Card_IDbyte6 : 8; | ||
434 | u32 Card_IDbyte5 : 8; | ||
435 | u32 Card_IDbyte4 : 8; | ||
436 | u32 Card_IDbyte3 : 8; | ||
437 | } card_id_408; | ||
438 | |||
439 | struct { | ||
440 | u32 Card_IDbyte2 : 8; | ||
441 | u32 Card_IDbyte1 : 8; | ||
442 | } card_id_40c; | ||
443 | |||
444 | /* holding the unique mac address of the receiver which houses the FlexCopIII */ | ||
445 | struct { | ||
446 | u32 MAC1 : 8; | ||
447 | u32 MAC2 : 8; | ||
448 | u32 MAC3 : 8; | ||
449 | u32 MAC6 : 8; | ||
450 | } mac_address_418; | ||
451 | |||
452 | struct { | ||
453 | u32 MAC7 : 8; | ||
454 | u32 MAC8 : 8; | ||
455 | u32 reserved : 16; | ||
456 | } mac_address_41c; | ||
457 | |||
458 | struct { | ||
459 | u32 transmitter_data_byte : 8; | ||
460 | u32 ReceiveDataReady : 1; | ||
461 | u32 ReceiveByteFrameError: 1; | ||
462 | u32 txbuffempty : 1; | ||
463 | u32 reserved :21; | ||
464 | } ci_600; | ||
465 | |||
466 | struct { | ||
467 | u32 pi_d : 8; | ||
468 | u32 pi_ha :20; | ||
469 | u32 pi_rw : 1; | ||
470 | u32 pi_component_reg : 3; | ||
471 | } pi_604; | ||
472 | |||
473 | struct { | ||
474 | u32 serialReset : 1; | ||
475 | u32 oncecycle_read : 1; | ||
476 | u32 Timer_Read_req : 1; | ||
477 | u32 Timer_Load_req : 1; | ||
478 | u32 timer_data : 7; | ||
479 | u32 unused : 1; /* ??? not mentioned in data book */ | ||
480 | u32 Timer_addr : 5; | ||
481 | u32 reserved : 3; | ||
482 | u32 pcmcia_a_mod_pwr_n : 1; | ||
483 | u32 pcmcia_b_mod_pwr_n : 1; | ||
484 | u32 config_Done_stat : 1; | ||
485 | u32 config_Init_stat : 1; | ||
486 | u32 config_Prog_n : 1; | ||
487 | u32 config_wr_n : 1; | ||
488 | u32 config_cs_n : 1; | ||
489 | u32 config_cclk : 1; | ||
490 | u32 pi_CiMax_IRQ_n : 1; | ||
491 | u32 pi_timeout_status : 1; | ||
492 | u32 pi_wait_n : 1; | ||
493 | u32 pi_busy_n : 1; | ||
494 | } pi_608; | ||
495 | |||
496 | struct { | ||
497 | u32 PID :13; | ||
498 | u32 key_enable : 1; | ||
499 | #define fc_key_code_default 0x1 | ||
500 | #define fc_key_code_even 0x2 | ||
501 | #define fc_key_code_odd 0x3 | ||
502 | u32 key_code : 2; | ||
503 | u32 key_array_col : 3; | ||
504 | u32 key_array_row : 5; | ||
505 | u32 dvb_en : 1; /* 0=TS bypasses the Descrambler */ | ||
506 | u32 rw_flag : 1; | ||
507 | u32 reserved : 6; | ||
508 | } dvb_reg_60c; | ||
509 | |||
510 | /* SRAM and Output Destination 0x700 to 0x714 */ | ||
511 | struct { | ||
512 | u32 sram_addr :15; | ||
513 | u32 sram_rw : 1; /* 0=write, 1=read */ | ||
514 | u32 sram_data : 8; | ||
515 | u32 sc_xfer_bit : 1; | ||
516 | u32 reserved1 : 3; | ||
517 | u32 oe_pin_reg : 1; | ||
518 | u32 ce_pin_reg : 1; | ||
519 | u32 reserved2 : 1; | ||
520 | u32 start_sram_ibi : 1; | ||
521 | } sram_ctrl_reg_700; | ||
522 | |||
523 | struct { | ||
524 | u32 net_addr_read :16; | ||
525 | u32 net_addr_write :16; | ||
526 | } net_buf_reg_704; | ||
527 | |||
528 | struct { | ||
529 | u32 cai_read :11; | ||
530 | u32 reserved1 : 5; | ||
531 | u32 cai_write :11; | ||
532 | u32 reserved2 : 6; | ||
533 | u32 cai_cnt : 4; | ||
534 | } cai_buf_reg_708; | ||
535 | |||
536 | struct { | ||
537 | u32 cao_read :11; | ||
538 | u32 reserved1 : 5; | ||
539 | u32 cap_write :11; | ||
540 | u32 reserved2 : 6; | ||
541 | u32 cao_cnt : 4; | ||
542 | } cao_buf_reg_70c; | ||
543 | |||
544 | struct { | ||
545 | u32 media_read :11; | ||
546 | u32 reserved1 : 5; | ||
547 | u32 media_write :11; | ||
548 | u32 reserved2 : 6; | ||
549 | u32 media_cnt : 4; | ||
550 | } media_buf_reg_710; | ||
551 | |||
552 | struct { | ||
553 | u32 NET_Dest : 2; | ||
554 | u32 CAI_Dest : 2; | ||
555 | u32 CAO_Dest : 2; | ||
556 | u32 MEDIA_Dest : 2; | ||
557 | u32 net_ovflow_error : 1; | ||
558 | u32 media_ovflow_error : 1; | ||
559 | u32 cai_ovflow_error : 1; | ||
560 | u32 cao_ovflow_error : 1; | ||
561 | u32 ctrl_usb_wan : 1; | ||
562 | u32 ctrl_sramdma : 1; | ||
563 | u32 ctrl_maximumfill : 1; | ||
564 | u32 reserved :17; | ||
565 | } sram_dest_reg_714; | ||
566 | |||
567 | struct { | ||
568 | u32 net_cnt :12; | ||
569 | u32 reserved1 : 4; | ||
570 | u32 net_addr_read : 1; | ||
571 | u32 reserved2 : 3; | ||
572 | u32 net_addr_write : 1; | ||
573 | u32 reserved3 :11; | ||
574 | } net_buf_reg_718; | ||
575 | |||
576 | struct { | ||
577 | u32 wan_speed_sig : 2; | ||
578 | u32 reserved1 : 6; | ||
579 | u32 wan_wait_state : 8; | ||
580 | u32 sram_chip : 2; | ||
581 | u32 sram_memmap : 2; | ||
582 | u32 reserved2 : 4; | ||
583 | u32 wan_pkt_frame : 4; | ||
584 | u32 reserved3 : 4; | ||
585 | } wan_ctrl_reg_71c; | ||
586 | } flexcop_ibi_value; | ||
587 | |||
588 | extern flexcop_ibi_value ibi_zero; | ||
589 | |||
590 | typedef enum { | ||
591 | FC_I2C_PORT_DEMOD = 1, | ||
592 | FC_I2C_PORT_EEPROM = 2, | ||
593 | FC_I2C_PORT_TUNER = 3, | ||
594 | } flexcop_i2c_port_t; | ||
595 | |||
596 | typedef enum { | ||
597 | FC_WRITE = 0, | ||
598 | FC_READ = 1, | ||
599 | } flexcop_access_op_t; | ||
600 | |||
601 | typedef enum { | ||
602 | FC_SRAM_DEST_NET = 1, | ||
603 | FC_SRAM_DEST_CAI = 2, | ||
604 | FC_SRAM_DEST_CAO = 4, | ||
605 | FC_SRAM_DEST_MEDIA = 8 | ||
606 | } flexcop_sram_dest_t; | ||
607 | |||
608 | typedef enum { | ||
609 | FC_SRAM_DEST_TARGET_WAN_USB = 0, | ||
610 | FC_SRAM_DEST_TARGET_DMA1 = 1, | ||
611 | FC_SRAM_DEST_TARGET_DMA2 = 2, | ||
612 | FC_SRAM_DEST_TARGET_FC3_CA = 3 | ||
613 | } flexcop_sram_dest_target_t; | ||
614 | |||
615 | typedef enum { | ||
616 | FC_SRAM_2_32KB = 0, /* 64KB */ | ||
617 | FC_SRAM_1_32KB = 1, /* 32KB - default fow FCII */ | ||
618 | FC_SRAM_1_128KB = 2, /* 128KB */ | ||
619 | FC_SRAM_1_48KB = 3, /* 48KB - default for FCIII */ | ||
620 | } flexcop_sram_type_t; | ||
621 | |||
622 | typedef enum { | ||
623 | FC_WAN_SPEED_4MBITS = 0, | ||
624 | FC_WAN_SPEED_8MBITS = 1, | ||
625 | FC_WAN_SPEED_12MBITS = 2, | ||
626 | FC_WAN_SPEED_16MBITS = 3, | ||
627 | } flexcop_wan_speed_t; | ||
628 | |||
629 | typedef enum { | ||
630 | FC_DMA_1 = 1, | ||
631 | FC_DMA_2 = 2, | ||
632 | } flexcop_dma_index_t; | ||
633 | |||
634 | typedef enum { | ||
635 | FC_DMA_SUBADDR_0 = 1, | ||
636 | FC_DMA_SUBADDR_1 = 2, | ||
637 | } flexcop_dma_addr_index_t; | ||
638 | |||
639 | /* names of the particular registers */ | ||
640 | typedef enum { | ||
641 | dma1_000 = 0x000, | ||
642 | dma1_004 = 0x004, | ||
643 | dma1_008 = 0x008, | ||
644 | dma1_00c = 0x00c, | ||
645 | dma2_010 = 0x010, | ||
646 | dma2_014 = 0x014, | ||
647 | dma2_018 = 0x018, | ||
648 | dma2_01c = 0x01c, | ||
649 | |||
650 | tw_sm_c_100 = 0x100, | ||
651 | tw_sm_c_104 = 0x104, | ||
652 | tw_sm_c_108 = 0x108, | ||
653 | tw_sm_c_10c = 0x10c, | ||
654 | tw_sm_c_110 = 0x110, | ||
655 | |||
656 | lnb_switch_freq_200 = 0x200, | ||
657 | misc_204 = 0x204, | ||
658 | ctrl_208 = 0x208, | ||
659 | irq_20c = 0x20c, | ||
660 | sw_reset_210 = 0x210, | ||
661 | misc_214 = 0x214, | ||
662 | mbox_v8_to_host_218 = 0x218, | ||
663 | mbox_host_to_v8_21c = 0x21c, | ||
664 | |||
665 | pid_filter_300 = 0x300, | ||
666 | pid_filter_304 = 0x304, | ||
667 | pid_filter_308 = 0x308, | ||
668 | pid_filter_30c = 0x30c, | ||
669 | index_reg_310 = 0x310, | ||
670 | pid_n_reg_314 = 0x314, | ||
671 | mac_low_reg_318 = 0x318, | ||
672 | mac_high_reg_31c = 0x31c, | ||
673 | |||
674 | data_tag_400 = 0x400, | ||
675 | card_id_408 = 0x408, | ||
676 | card_id_40c = 0x40c, | ||
677 | mac_address_418 = 0x418, | ||
678 | mac_address_41c = 0x41c, | ||
679 | |||
680 | ci_600 = 0x600, | ||
681 | pi_604 = 0x604, | ||
682 | pi_608 = 0x608, | ||
683 | dvb_reg_60c = 0x60c, | ||
684 | |||
685 | sram_ctrl_reg_700 = 0x700, | ||
686 | net_buf_reg_704 = 0x704, | ||
687 | cai_buf_reg_708 = 0x708, | ||
688 | cao_buf_reg_70c = 0x70c, | ||
689 | media_buf_reg_710 = 0x710, | ||
690 | sram_dest_reg_714 = 0x714, | ||
691 | net_buf_reg_718 = 0x718, | ||
692 | wan_ctrl_reg_71c = 0x71c, | ||
693 | } flexcop_ibi_register; | ||
694 | |||
695 | #define flexcop_set_ibi_value(reg,attr,val) { \ | ||
696 | flexcop_ibi_value v = fc->read_ibi_reg(fc,reg); \ | ||
697 | v.reg.attr = val; \ | ||
698 | fc->write_ibi_reg(fc,reg,v); \ | ||
699 | } | ||
700 | |||
701 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-sram.c b/drivers/media/dvb/b2c2/flexcop-sram.c new file mode 100644 index 000000000000..01570ec80962 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-sram.c | |||
@@ -0,0 +1,403 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-sram.c - functions for controlling the SRAM. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #include "flexcop.h" | ||
9 | |||
10 | static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type) | ||
11 | { | ||
12 | flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type); | ||
13 | } | ||
14 | |||
15 | int flexcop_sram_init(struct flexcop_device *fc) | ||
16 | { | ||
17 | switch (fc->rev) { | ||
18 | case FLEXCOP_II: | ||
19 | case FLEXCOP_IIB: | ||
20 | flexcop_sram_set_chip(fc,FC_SRAM_1_32KB); | ||
21 | break; | ||
22 | case FLEXCOP_III: | ||
23 | flexcop_sram_set_chip(fc,FC_SRAM_1_48KB); | ||
24 | break; | ||
25 | default: | ||
26 | return -EINVAL; | ||
27 | } | ||
28 | return 0; | ||
29 | } | ||
30 | |||
31 | int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target) | ||
32 | { | ||
33 | flexcop_ibi_value v; | ||
34 | |||
35 | v = fc->read_ibi_reg(fc,sram_dest_reg_714); | ||
36 | |||
37 | if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) { | ||
38 | err("SRAM destination target to available on FlexCopII(b)\n"); | ||
39 | return -EINVAL; | ||
40 | } | ||
41 | |||
42 | deb_sram("sram dest: %x target: %x\n",dest, target); | ||
43 | |||
44 | if (dest & FC_SRAM_DEST_NET) | ||
45 | v.sram_dest_reg_714.NET_Dest = target; | ||
46 | if (dest & FC_SRAM_DEST_CAI) | ||
47 | v.sram_dest_reg_714.CAI_Dest = target; | ||
48 | if (dest & FC_SRAM_DEST_CAO) | ||
49 | v.sram_dest_reg_714.CAO_Dest = target; | ||
50 | if (dest & FC_SRAM_DEST_MEDIA) | ||
51 | v.sram_dest_reg_714.MEDIA_Dest = target; | ||
52 | |||
53 | fc->write_ibi_reg(fc,sram_dest_reg_714,v); | ||
54 | udelay(1000); /* TODO delay really necessary */ | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | EXPORT_SYMBOL(flexcop_sram_set_dest); | ||
59 | |||
60 | void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s) | ||
61 | { | ||
62 | flexcop_set_ibi_value(wan_ctrl_reg_71c,wan_speed_sig,s); | ||
63 | } | ||
64 | EXPORT_SYMBOL(flexcop_wan_set_speed); | ||
65 | |||
66 | void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill) | ||
67 | { | ||
68 | flexcop_ibi_value v = fc->read_ibi_reg(fc,sram_dest_reg_714); | ||
69 | v.sram_dest_reg_714.ctrl_usb_wan = usb_wan; | ||
70 | v.sram_dest_reg_714.ctrl_sramdma = sramdma; | ||
71 | v.sram_dest_reg_714.ctrl_maximumfill = maximumfill; | ||
72 | fc->write_ibi_reg(fc,sram_dest_reg_714,v); | ||
73 | } | ||
74 | EXPORT_SYMBOL(flexcop_sram_ctrl); | ||
75 | |||
76 | #if 0 | ||
77 | static void flexcop_sram_write(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len) | ||
78 | { | ||
79 | int i, retries; | ||
80 | u32 command; | ||
81 | |||
82 | for (i = 0; i < len; i++) { | ||
83 | command = bank | addr | 0x04000000 | (*buf << 0x10); | ||
84 | |||
85 | retries = 2; | ||
86 | |||
87 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | ||
88 | mdelay(1); | ||
89 | retries--; | ||
90 | }; | ||
91 | |||
92 | if (retries == 0) | ||
93 | printk("%s: SRAM timeout\n", __FUNCTION__); | ||
94 | |||
95 | write_reg_dw(adapter, 0x700, command); | ||
96 | |||
97 | buf++; | ||
98 | addr++; | ||
99 | } | ||
100 | } | ||
101 | |||
102 | static void flex_sram_read(struct adapter *adapter, u32 bank, u32 addr, u8 *buf, u32 len) | ||
103 | { | ||
104 | int i, retries; | ||
105 | u32 command, value; | ||
106 | |||
107 | for (i = 0; i < len; i++) { | ||
108 | command = bank | addr | 0x04008000; | ||
109 | |||
110 | retries = 10000; | ||
111 | |||
112 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | ||
113 | mdelay(1); | ||
114 | retries--; | ||
115 | }; | ||
116 | |||
117 | if (retries == 0) | ||
118 | printk("%s: SRAM timeout\n", __FUNCTION__); | ||
119 | |||
120 | write_reg_dw(adapter, 0x700, command); | ||
121 | |||
122 | retries = 10000; | ||
123 | |||
124 | while (((read_reg_dw(adapter, 0x700) & 0x80000000) != 0) && (retries > 0)) { | ||
125 | mdelay(1); | ||
126 | retries--; | ||
127 | }; | ||
128 | |||
129 | if (retries == 0) | ||
130 | printk("%s: SRAM timeout\n", __FUNCTION__); | ||
131 | |||
132 | value = read_reg_dw(adapter, 0x700) >> 0x10; | ||
133 | |||
134 | *buf = (value & 0xff); | ||
135 | |||
136 | addr++; | ||
137 | buf++; | ||
138 | } | ||
139 | } | ||
140 | |||
141 | static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) | ||
142 | { | ||
143 | u32 bank; | ||
144 | |||
145 | bank = 0; | ||
146 | |||
147 | if (adapter->dw_sram_type == 0x20000) { | ||
148 | bank = (addr & 0x18000) << 0x0d; | ||
149 | } | ||
150 | |||
151 | if (adapter->dw_sram_type == 0x00000) { | ||
152 | if ((addr >> 0x0f) == 0) | ||
153 | bank = 0x20000000; | ||
154 | else | ||
155 | bank = 0x10000000; | ||
156 | } | ||
157 | |||
158 | flex_sram_write(adapter, bank, addr & 0x7fff, buf, len); | ||
159 | } | ||
160 | |||
161 | static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len) | ||
162 | { | ||
163 | u32 bank; | ||
164 | |||
165 | bank = 0; | ||
166 | |||
167 | if (adapter->dw_sram_type == 0x20000) { | ||
168 | bank = (addr & 0x18000) << 0x0d; | ||
169 | } | ||
170 | |||
171 | if (adapter->dw_sram_type == 0x00000) { | ||
172 | if ((addr >> 0x0f) == 0) | ||
173 | bank = 0x20000000; | ||
174 | else | ||
175 | bank = 0x10000000; | ||
176 | } | ||
177 | |||
178 | flex_sram_read(adapter, bank, addr & 0x7fff, buf, len); | ||
179 | } | ||
180 | |||
181 | static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len) | ||
182 | { | ||
183 | u32 length; | ||
184 | |||
185 | while (len != 0) { | ||
186 | length = len; | ||
187 | |||
188 | // check if the address range belongs to the same | ||
189 | // 32K memory chip. If not, the data is read from | ||
190 | // one chip at a time. | ||
191 | if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { | ||
192 | length = (((addr >> 0x0f) + 1) << 0x0f) - addr; | ||
193 | } | ||
194 | |||
195 | sram_read_chunk(adapter, addr, buf, length); | ||
196 | |||
197 | addr = addr + length; | ||
198 | buf = buf + length; | ||
199 | len = len - length; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len) | ||
204 | { | ||
205 | u32 length; | ||
206 | |||
207 | while (len != 0) { | ||
208 | length = len; | ||
209 | |||
210 | // check if the address range belongs to the same | ||
211 | // 32K memory chip. If not, the data is written to | ||
212 | // one chip at a time. | ||
213 | if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) { | ||
214 | length = (((addr >> 0x0f) + 1) << 0x0f) - addr; | ||
215 | } | ||
216 | |||
217 | sram_write_chunk(adapter, addr, buf, length); | ||
218 | |||
219 | addr = addr + length; | ||
220 | buf = buf + length; | ||
221 | len = len - length; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static void sram_set_size(struct adapter *adapter, u32 mask) | ||
226 | { | ||
227 | write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c)))); | ||
228 | } | ||
229 | |||
230 | static void sram_init(struct adapter *adapter) | ||
231 | { | ||
232 | u32 tmp; | ||
233 | |||
234 | tmp = read_reg_dw(adapter, 0x71c); | ||
235 | |||
236 | write_reg_dw(adapter, 0x71c, 1); | ||
237 | |||
238 | if (read_reg_dw(adapter, 0x71c) != 0) { | ||
239 | write_reg_dw(adapter, 0x71c, tmp); | ||
240 | |||
241 | adapter->dw_sram_type = tmp & 0x30000; | ||
242 | |||
243 | ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); | ||
244 | |||
245 | } else { | ||
246 | |||
247 | adapter->dw_sram_type = 0x10000; | ||
248 | |||
249 | ddprintk("%s: dw_sram_type = %x\n", __FUNCTION__, adapter->dw_sram_type); | ||
250 | } | ||
251 | |||
252 | /* return value is never used? */ | ||
253 | /* return adapter->dw_sram_type; */ | ||
254 | } | ||
255 | |||
256 | static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr) | ||
257 | { | ||
258 | u8 tmp1, tmp2; | ||
259 | |||
260 | dprintk("%s: mask = %x, addr = %x\n", __FUNCTION__, mask, addr); | ||
261 | |||
262 | sram_set_size(adapter, mask); | ||
263 | sram_init(adapter); | ||
264 | |||
265 | tmp2 = 0xa5; | ||
266 | tmp1 = 0x4f; | ||
267 | |||
268 | sram_write(adapter, addr, &tmp2, 1); | ||
269 | sram_write(adapter, addr + 4, &tmp1, 1); | ||
270 | |||
271 | tmp2 = 0; | ||
272 | |||
273 | mdelay(20); | ||
274 | |||
275 | sram_read(adapter, addr, &tmp2, 1); | ||
276 | sram_read(adapter, addr, &tmp2, 1); | ||
277 | |||
278 | dprintk("%s: wrote 0xa5, read 0x%2x\n", __FUNCTION__, tmp2); | ||
279 | |||
280 | if (tmp2 != 0xa5) | ||
281 | return 0; | ||
282 | |||
283 | tmp2 = 0x5a; | ||
284 | tmp1 = 0xf4; | ||
285 | |||
286 | sram_write(adapter, addr, &tmp2, 1); | ||
287 | sram_write(adapter, addr + 4, &tmp1, 1); | ||
288 | |||
289 | tmp2 = 0; | ||
290 | |||
291 | mdelay(20); | ||
292 | |||
293 | sram_read(adapter, addr, &tmp2, 1); | ||
294 | sram_read(adapter, addr, &tmp2, 1); | ||
295 | |||
296 | dprintk("%s: wrote 0x5a, read 0x%2x\n", __FUNCTION__, tmp2); | ||
297 | |||
298 | if (tmp2 != 0x5a) | ||
299 | return 0; | ||
300 | |||
301 | return 1; | ||
302 | } | ||
303 | |||
304 | static u32 sram_length(struct adapter *adapter) | ||
305 | { | ||
306 | if (adapter->dw_sram_type == 0x10000) | ||
307 | return 32768; // 32K | ||
308 | if (adapter->dw_sram_type == 0x00000) | ||
309 | return 65536; // 64K | ||
310 | if (adapter->dw_sram_type == 0x20000) | ||
311 | return 131072; // 128K | ||
312 | |||
313 | return 32768; // 32K | ||
314 | } | ||
315 | |||
316 | /* FlexcopII can work with 32K, 64K or 128K of external SRAM memory. | ||
317 | - for 128K there are 4x32K chips at bank 0,1,2,3. | ||
318 | - for 64K there are 2x32K chips at bank 1,2. | ||
319 | - for 32K there is one 32K chip at bank 0. | ||
320 | |||
321 | FlexCop works only with one bank at a time. The bank is selected | ||
322 | by bits 28-29 of the 0x700 register. | ||
323 | |||
324 | bank 0 covers addresses 0x00000-0x07fff | ||
325 | bank 1 covers addresses 0x08000-0x0ffff | ||
326 | bank 2 covers addresses 0x10000-0x17fff | ||
327 | bank 3 covers addresses 0x18000-0x1ffff | ||
328 | */ | ||
329 | |||
330 | static int flexcop_sram_detect(struct flexcop_device *fc) | ||
331 | { | ||
332 | flexcop_ibi_value r208,r71c_0,vr71c_1; | ||
333 | |||
334 | r208 = fc->read_ibi_reg(fc, ctrl_208); | ||
335 | fc->write_ibi_reg(fc, ctrl_208, ibi_zero); | ||
336 | |||
337 | r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c); | ||
338 | |||
339 | write_reg_dw(adapter, 0x71c, 1); | ||
340 | |||
341 | tmp3 = read_reg_dw(adapter, 0x71c); | ||
342 | |||
343 | dprintk("%s: tmp3 = %x\n", __FUNCTION__, tmp3); | ||
344 | |||
345 | write_reg_dw(adapter, 0x71c, tmp2); | ||
346 | |||
347 | // check for internal SRAM ??? | ||
348 | tmp3--; | ||
349 | if (tmp3 != 0) { | ||
350 | sram_set_size(adapter, 0x10000); | ||
351 | sram_init(adapter); | ||
352 | write_reg_dw(adapter, 0x208, tmp); | ||
353 | |||
354 | dprintk("%s: sram size = 32K\n", __FUNCTION__); | ||
355 | |||
356 | return 32; | ||
357 | } | ||
358 | |||
359 | if (sram_test_location(adapter, 0x20000, 0x18000) != 0) { | ||
360 | sram_set_size(adapter, 0x20000); | ||
361 | sram_init(adapter); | ||
362 | write_reg_dw(adapter, 0x208, tmp); | ||
363 | |||
364 | dprintk("%s: sram size = 128K\n", __FUNCTION__); | ||
365 | |||
366 | return 128; | ||
367 | } | ||
368 | |||
369 | if (sram_test_location(adapter, 0x00000, 0x10000) != 0) { | ||
370 | sram_set_size(adapter, 0x00000); | ||
371 | sram_init(adapter); | ||
372 | write_reg_dw(adapter, 0x208, tmp); | ||
373 | |||
374 | dprintk("%s: sram size = 64K\n", __FUNCTION__); | ||
375 | |||
376 | return 64; | ||
377 | } | ||
378 | |||
379 | if (sram_test_location(adapter, 0x10000, 0x00000) != 0) { | ||
380 | sram_set_size(adapter, 0x10000); | ||
381 | sram_init(adapter); | ||
382 | write_reg_dw(adapter, 0x208, tmp); | ||
383 | |||
384 | dprintk("%s: sram size = 32K\n", __FUNCTION__); | ||
385 | |||
386 | return 32; | ||
387 | } | ||
388 | |||
389 | sram_set_size(adapter, 0x10000); | ||
390 | sram_init(adapter); | ||
391 | write_reg_dw(adapter, 0x208, tmp); | ||
392 | |||
393 | dprintk("%s: SRAM detection failed. Set to 32K \n", __FUNCTION__); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
398 | static void sll_detect_sram_size(struct adapter *adapter) | ||
399 | { | ||
400 | sram_detect_for_flex2(adapter); | ||
401 | } | ||
402 | |||
403 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.c b/drivers/media/dvb/b2c2/flexcop-usb.c new file mode 100644 index 000000000000..0113449abd15 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-usb.c | |||
@@ -0,0 +1,577 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop-usb.c - covers the USB part. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | |||
9 | #define FC_LOG_PREFIX "flexcop_usb" | ||
10 | #include "flexcop-usb.h" | ||
11 | #include "flexcop-common.h" | ||
12 | |||
13 | /* Version information */ | ||
14 | #define DRIVER_VERSION "0.1" | ||
15 | #define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV USB Driver" | ||
16 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>" | ||
17 | |||
18 | /* debug */ | ||
19 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
20 | #define dprintk(level,args...) \ | ||
21 | do { if ((debug & level)) { printk(args); } } while (0) | ||
22 | #define debug_dump(b,l,method) {\ | ||
23 | int i; \ | ||
24 | for (i = 0; i < l; i++) method("%02x ", b[i]); \ | ||
25 | method("\n");\ | ||
26 | } | ||
27 | |||
28 | #define DEBSTATUS "" | ||
29 | #else | ||
30 | #define dprintk(level,args...) | ||
31 | #define debug_dump(b,l,method) | ||
32 | #define DEBSTATUS " (debugging is not enabled)" | ||
33 | #endif | ||
34 | |||
35 | static int debug; | ||
36 | module_param(debug, int, 0644); | ||
37 | MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS); | ||
38 | #undef DEBSTATUS | ||
39 | |||
40 | #define deb_info(args...) dprintk(0x01,args) | ||
41 | #define deb_ts(args...) dprintk(0x02,args) | ||
42 | #define deb_ctrl(args...) dprintk(0x04,args) | ||
43 | #define deb_i2c(args...) dprintk(0x08,args) | ||
44 | #define deb_v8(args...) dprintk(0x10,args) | ||
45 | |||
46 | /* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits | ||
47 | * in the IBI address, to make the V8 code simpler. | ||
48 | * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used) | ||
49 | * in general: 0000 0HHH 000L LL00 | ||
50 | * IBI ADDRESS FORMAT: RHHH BLLL | ||
51 | * | ||
52 | * where R is the read(1)/write(0) bit, B is the busy bit | ||
53 | * and HHH and LLL are the two sets of three bits from the PCI address. | ||
54 | */ | ||
55 | #define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70)) | ||
56 | #define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4)) | ||
57 | |||
58 | /* | ||
59 | * DKT 020228 | ||
60 | * - forget about this VENDOR_BUFFER_SIZE, read and write register | ||
61 | * deal with DWORD or 4 bytes, that should be should from now on | ||
62 | * - from now on, we don't support anything older than firm 1.00 | ||
63 | * I eliminated the write register as a 2 trip of writing hi word and lo word | ||
64 | * and force this to write only 4 bytes at a time. | ||
65 | * NOTE: this should work with all the firmware from 1.00 and newer | ||
66 | */ | ||
67 | static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, u32 *val, u8 read) | ||
68 | { | ||
69 | struct flexcop_usb *fc_usb = fc->bus_specific; | ||
70 | u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG; | ||
71 | u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR; | ||
72 | u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0); | ||
73 | |||
74 | int len = usb_control_msg(fc_usb->udev, | ||
75 | read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT, | ||
76 | request, | ||
77 | request_type, /* 0xc0 read or 0x40 write*/ | ||
78 | wAddress, | ||
79 | 0, | ||
80 | val, | ||
81 | sizeof(u32), | ||
82 | B2C2_WAIT_FOR_OPERATION_RDW * HZ); | ||
83 | |||
84 | if (len != sizeof(u32)) { | ||
85 | err("error while %s dword from %d (%d).",read ? "reading" : "writing", | ||
86 | wAddress,wRegOffsPCI); | ||
87 | return -EIO; | ||
88 | } | ||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * DKT 010817 - add support for V8 memory read/write and flash update | ||
94 | */ | ||
95 | static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, | ||
96 | flexcop_usb_request_t req, u8 page, u16 wAddress, | ||
97 | u8 *pbBuffer,u32 buflen) | ||
98 | { | ||
99 | // u8 dwRequestType; | ||
100 | u8 request_type = USB_TYPE_VENDOR; | ||
101 | u16 wIndex; | ||
102 | int nWaitTime,pipe,len; | ||
103 | |||
104 | wIndex = page << 8; | ||
105 | |||
106 | switch (req) { | ||
107 | case B2C2_USB_READ_V8_MEM: | ||
108 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ; | ||
109 | request_type |= USB_DIR_IN; | ||
110 | // dwRequestType = (u8) RTYPE_READ_V8_MEMORY; | ||
111 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
112 | break; | ||
113 | case B2C2_USB_WRITE_V8_MEM: | ||
114 | wIndex |= pbBuffer[0]; | ||
115 | request_type |= USB_DIR_OUT; | ||
116 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE; | ||
117 | // dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY; | ||
118 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
119 | break; | ||
120 | case B2C2_USB_FLASH_BLOCK: | ||
121 | request_type |= USB_DIR_OUT; | ||
122 | nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH; | ||
123 | // dwRequestType = (u8) RTYPE_WRITE_V8_FLASH; | ||
124 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
125 | break; | ||
126 | default: | ||
127 | deb_info("unsupported request for v8_mem_req %x.\n",req); | ||
128 | return -EINVAL; | ||
129 | } | ||
130 | deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req, | ||
131 | wAddress,wIndex,buflen); | ||
132 | |||
133 | len = usb_control_msg(fc_usb->udev,pipe, | ||
134 | req, | ||
135 | request_type, | ||
136 | wAddress, | ||
137 | wIndex, | ||
138 | pbBuffer, | ||
139 | buflen, | ||
140 | nWaitTime * HZ); | ||
141 | |||
142 | debug_dump(pbBuffer,len,deb_v8); | ||
143 | |||
144 | return len == buflen ? 0 : -EIO; | ||
145 | } | ||
146 | |||
147 | #define bytes_left_to_read_on_page(paddr,buflen) \ | ||
148 | ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \ | ||
149 | ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK))) | ||
150 | |||
151 | static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req, | ||
152 | flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len) | ||
153 | { | ||
154 | int i,ret = 0; | ||
155 | u16 wMax; | ||
156 | u32 pagechunk = 0; | ||
157 | |||
158 | switch(req) { | ||
159 | case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break; | ||
160 | case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break; | ||
161 | case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break; | ||
162 | default: | ||
163 | return -EINVAL; | ||
164 | break; | ||
165 | } | ||
166 | for (i = 0; i < len;) { | ||
167 | pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len); | ||
168 | deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended)); | ||
169 | if ((ret = flexcop_usb_v8_memory_req(fc_usb,req, | ||
170 | page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */ | ||
171 | (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended), | ||
172 | &buf[i],pagechunk)) < 0) | ||
173 | return ret; | ||
174 | |||
175 | addr += pagechunk; | ||
176 | len -= pagechunk; | ||
177 | } | ||
178 | return 0; | ||
179 | } | ||
180 | |||
181 | static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended) | ||
182 | { | ||
183 | return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM, | ||
184 | V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6); | ||
185 | } | ||
186 | |||
187 | #if 0 | ||
188 | static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set, | ||
189 | flexcop_usb_utility_function_t func, u8 extra, u16 wIndex, | ||
190 | u16 buflen, u8 *pvBuffer) | ||
191 | { | ||
192 | u16 wValue; | ||
193 | u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR; | ||
194 | // u8 dwRequestType = (u8) RTYPE_GENERIC, | ||
195 | int nWaitTime = 2, | ||
196 | pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, | ||
197 | len; | ||
198 | |||
199 | wValue = (func << 8) | extra; | ||
200 | |||
201 | len = usb_control_msg(fc_usb->udev,pipe, | ||
202 | B2C2_USB_UTILITY, | ||
203 | request_type, | ||
204 | wValue, | ||
205 | wIndex, | ||
206 | pvBuffer, | ||
207 | buflen, | ||
208 | nWaitTime * HZ); | ||
209 | return len == buflen ? 0 : -EIO; | ||
210 | } | ||
211 | #endif | ||
212 | |||
213 | /* usb i2c stuff */ | ||
214 | static int flexcop_usb_i2c_req(struct flexcop_usb *fc_usb, | ||
215 | flexcop_usb_request_t req, flexcop_usb_i2c_function_t func, | ||
216 | flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u8 buflen) | ||
217 | { | ||
218 | u16 wValue, wIndex; | ||
219 | int nWaitTime,pipe,len; | ||
220 | // u8 dwRequestType; | ||
221 | u8 request_type = USB_TYPE_VENDOR; | ||
222 | |||
223 | switch (func) { | ||
224 | case USB_FUNC_I2C_WRITE: | ||
225 | case USB_FUNC_I2C_MULTIWRITE: | ||
226 | case USB_FUNC_I2C_REPEATWRITE: | ||
227 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
228 | case USB_FUNC_I2C_CHECKWRITE: | ||
229 | pipe = B2C2_USB_CTRL_PIPE_OUT; | ||
230 | nWaitTime = 2; | ||
231 | // dwRequestType = (u8) RTYPE_GENERIC; | ||
232 | request_type |= USB_DIR_OUT; | ||
233 | break; | ||
234 | case USB_FUNC_I2C_READ: | ||
235 | case USB_FUNC_I2C_REPEATREAD: | ||
236 | pipe = B2C2_USB_CTRL_PIPE_IN; | ||
237 | nWaitTime = 2; | ||
238 | // dwRequestType = (u8) RTYPE_GENERIC; | ||
239 | request_type |= USB_DIR_IN; | ||
240 | break; | ||
241 | default: | ||
242 | deb_info("unsupported function for i2c_req %x\n",func); | ||
243 | return -EINVAL; | ||
244 | } | ||
245 | wValue = (func << 8 ) | (port << 4); | ||
246 | wIndex = (chipaddr << 8 ) | addr; | ||
247 | |||
248 | deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req, | ||
249 | ((wValue && 0xff) << 8),wValue >> 8,((wIndex && 0xff) << 8),wIndex >> 8); | ||
250 | |||
251 | len = usb_control_msg(fc_usb->udev,pipe, | ||
252 | req, | ||
253 | request_type, | ||
254 | wValue, | ||
255 | wIndex, | ||
256 | buf, | ||
257 | buflen, | ||
258 | nWaitTime * HZ); | ||
259 | |||
260 | return len == buflen ? 0 : -EREMOTEIO; | ||
261 | } | ||
262 | |||
263 | /* actual bus specific access functions, make sure prototype are/will be equal to pci */ | ||
264 | static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg) | ||
265 | { | ||
266 | flexcop_ibi_value val; | ||
267 | val.raw = 0; | ||
268 | flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1); | ||
269 | return val; | ||
270 | } | ||
271 | |||
272 | static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val) | ||
273 | { | ||
274 | return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0); | ||
275 | } | ||
276 | |||
277 | static int flexcop_usb_i2c_request(struct flexcop_device *fc, flexcop_access_op_t op, | ||
278 | flexcop_i2c_port_t port, u8 chipaddr, u8 addr, u8 *buf, u16 len) | ||
279 | { | ||
280 | if (op == FC_READ) | ||
281 | return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_READ,port,chipaddr,addr,buf,len); | ||
282 | else | ||
283 | return flexcop_usb_i2c_req(fc->bus_specific,B2C2_USB_I2C_REQUEST,USB_FUNC_I2C_WRITE,port,chipaddr,addr,buf,len); | ||
284 | } | ||
285 | |||
286 | static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length) | ||
287 | { | ||
288 | u8 *b; | ||
289 | int l; | ||
290 | |||
291 | deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length); | ||
292 | |||
293 | if (fc_usb->tmp_buffer_length > 0) { | ||
294 | memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length); | ||
295 | fc_usb->tmp_buffer_length += buffer_length; | ||
296 | b = fc_usb->tmp_buffer; | ||
297 | l = fc_usb->tmp_buffer_length; | ||
298 | } else { | ||
299 | b=buffer; | ||
300 | l=buffer_length; | ||
301 | } | ||
302 | |||
303 | while (l >= 190) { | ||
304 | if (*b == 0xff) | ||
305 | switch (*(b+1) & 0x03) { | ||
306 | case 0x01: /* media packet */ | ||
307 | if ( *(b+2) == 0x47 ) | ||
308 | flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1); | ||
309 | else | ||
310 | deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) ); | ||
311 | |||
312 | b += 190; | ||
313 | l -= 190; | ||
314 | break; | ||
315 | default: | ||
316 | deb_ts("wrong packet type\n"); | ||
317 | l = 0; | ||
318 | break; | ||
319 | } | ||
320 | else { | ||
321 | deb_ts("wrong header\n"); | ||
322 | l = 0; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | if (l>0) | ||
327 | memcpy(fc_usb->tmp_buffer, b, l); | ||
328 | fc_usb->tmp_buffer_length = l; | ||
329 | } | ||
330 | |||
331 | static void flexcop_usb_urb_complete(struct urb *urb, struct pt_regs *ptregs) | ||
332 | { | ||
333 | struct flexcop_usb *fc_usb = urb->context; | ||
334 | int i; | ||
335 | |||
336 | if (urb->actual_length > 0) | ||
337 | deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length); | ||
338 | |||
339 | for (i = 0; i < urb->number_of_packets; i++) { | ||
340 | if (urb->iso_frame_desc[i].status < 0) { | ||
341 | err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status); | ||
342 | } else | ||
343 | if (urb->iso_frame_desc[i].actual_length > 0) { | ||
344 | deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length); | ||
345 | |||
346 | flexcop_usb_process_frame(fc_usb, | ||
347 | urb->transfer_buffer + urb->iso_frame_desc[i].offset, | ||
348 | urb->iso_frame_desc[i].actual_length); | ||
349 | } | ||
350 | urb->iso_frame_desc[i].status = 0; | ||
351 | urb->iso_frame_desc[i].actual_length = 0; | ||
352 | } | ||
353 | |||
354 | usb_submit_urb(urb,GFP_ATOMIC); | ||
355 | } | ||
356 | |||
357 | static int flexcop_usb_stream_control(struct flexcop_device *fc, int onoff) | ||
358 | { | ||
359 | /* submit/kill iso packets */ | ||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb) | ||
364 | { | ||
365 | int i; | ||
366 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) | ||
367 | if (fc_usb->iso_urb[i] != NULL) { | ||
368 | deb_ts("unlinking/killing urb no. %d\n",i); | ||
369 | usb_kill_urb(fc_usb->iso_urb[i]); | ||
370 | usb_free_urb(fc_usb->iso_urb[i]); | ||
371 | } | ||
372 | |||
373 | if (fc_usb->iso_buffer != NULL) | ||
374 | pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr); | ||
375 | } | ||
376 | |||
377 | static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb) | ||
378 | { | ||
379 | u16 frame_size = fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize; | ||
380 | int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret; | ||
381 | int buffer_offset = 0; | ||
382 | |||
383 | deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n", | ||
384 | B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize); | ||
385 | |||
386 | fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr); | ||
387 | if (fc_usb->iso_buffer == NULL) | ||
388 | return -ENOMEM; | ||
389 | memset(fc_usb->iso_buffer, 0, bufsize); | ||
390 | fc_usb->buffer_size = bufsize; | ||
391 | |||
392 | /* creating iso urbs */ | ||
393 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) | ||
394 | if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) { | ||
395 | ret = -ENOMEM; | ||
396 | goto urb_error; | ||
397 | } | ||
398 | /* initialising and submitting iso urbs */ | ||
399 | for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) { | ||
400 | int frame_offset = 0; | ||
401 | struct urb *urb = fc_usb->iso_urb[i]; | ||
402 | deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset); | ||
403 | |||
404 | urb->dev = fc_usb->udev; | ||
405 | urb->context = fc_usb; | ||
406 | urb->complete = flexcop_usb_urb_complete; | ||
407 | urb->pipe = B2C2_USB_DATA_PIPE; | ||
408 | urb->transfer_flags = URB_ISO_ASAP; | ||
409 | urb->interval = 1; | ||
410 | urb->number_of_packets = B2C2_USB_FRAMES_PER_ISO; | ||
411 | urb->transfer_buffer_length = frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
412 | urb->transfer_buffer = fc_usb->iso_buffer + buffer_offset; | ||
413 | |||
414 | buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO; | ||
415 | for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) { | ||
416 | deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset); | ||
417 | urb->iso_frame_desc[j].offset = frame_offset; | ||
418 | urb->iso_frame_desc[j].length = frame_size; | ||
419 | frame_offset += frame_size; | ||
420 | } | ||
421 | |||
422 | if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) { | ||
423 | err("submitting urb %d failed with %d.",i,ret); | ||
424 | goto urb_error; | ||
425 | } | ||
426 | deb_ts("submitted urb no. %d.\n",i); | ||
427 | } | ||
428 | |||
429 | /* SRAM */ | ||
430 | |||
431 | flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET | | ||
432 | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB); | ||
433 | flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS); | ||
434 | flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1); | ||
435 | |||
436 | ret = 0; | ||
437 | goto success; | ||
438 | urb_error: | ||
439 | flexcop_usb_transfer_exit(fc_usb); | ||
440 | success: | ||
441 | return ret; | ||
442 | } | ||
443 | |||
444 | static int flexcop_usb_init(struct flexcop_usb *fc_usb) | ||
445 | { | ||
446 | /* use the alternate setting with the larges buffer */ | ||
447 | usb_set_interface(fc_usb->udev,0,1); | ||
448 | switch (fc_usb->udev->speed) { | ||
449 | case USB_SPEED_LOW: | ||
450 | err("cannot handle USB speed because it is to sLOW."); | ||
451 | return -ENODEV; | ||
452 | break; | ||
453 | case USB_SPEED_FULL: | ||
454 | info("running at FULL speed."); | ||
455 | break; | ||
456 | case USB_SPEED_HIGH: | ||
457 | info("running at HIGH speed."); | ||
458 | break; | ||
459 | case USB_SPEED_UNKNOWN: /* fall through */ | ||
460 | default: | ||
461 | err("cannot handle USB speed because it is unkown."); | ||
462 | return -ENODEV; | ||
463 | } | ||
464 | usb_set_intfdata(fc_usb->uintf, fc_usb); | ||
465 | return 0; | ||
466 | } | ||
467 | |||
468 | static void flexcop_usb_exit(struct flexcop_usb *fc_usb) | ||
469 | { | ||
470 | usb_set_intfdata(fc_usb->uintf, NULL); | ||
471 | } | ||
472 | |||
473 | static int flexcop_usb_probe(struct usb_interface *intf, | ||
474 | const struct usb_device_id *id) | ||
475 | { | ||
476 | struct usb_device *udev = interface_to_usbdev(intf); | ||
477 | struct flexcop_usb *fc_usb = NULL; | ||
478 | struct flexcop_device *fc = NULL; | ||
479 | int ret; | ||
480 | |||
481 | if ((fc = flexcop_device_kmalloc(sizeof(struct flexcop_usb))) == NULL) { | ||
482 | err("out of memory\n"); | ||
483 | return -ENOMEM; | ||
484 | } | ||
485 | |||
486 | /* general flexcop init */ | ||
487 | fc_usb = fc->bus_specific; | ||
488 | fc_usb->fc_dev = fc; | ||
489 | |||
490 | fc->read_ibi_reg = flexcop_usb_read_ibi_reg; | ||
491 | fc->write_ibi_reg = flexcop_usb_write_ibi_reg; | ||
492 | fc->i2c_request = flexcop_usb_i2c_request; | ||
493 | fc->get_mac_addr = flexcop_usb_get_mac_addr; | ||
494 | |||
495 | fc->stream_control = flexcop_usb_stream_control; | ||
496 | |||
497 | fc->pid_filtering = 1; | ||
498 | fc->bus_type = FC_USB; | ||
499 | |||
500 | fc->dev = &udev->dev; | ||
501 | fc->owner = THIS_MODULE; | ||
502 | |||
503 | /* bus specific part */ | ||
504 | fc_usb->udev = udev; | ||
505 | fc_usb->uintf = intf; | ||
506 | if ((ret = flexcop_usb_init(fc_usb)) != 0) | ||
507 | goto err_kfree; | ||
508 | |||
509 | /* init flexcop */ | ||
510 | if ((ret = flexcop_device_initialize(fc)) != 0) | ||
511 | goto err_usb_exit; | ||
512 | |||
513 | /* xfer init */ | ||
514 | if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0) | ||
515 | goto err_fc_exit; | ||
516 | |||
517 | info("%s successfully initialized and connected.",DRIVER_NAME); | ||
518 | ret = 0; | ||
519 | goto success; | ||
520 | err_fc_exit: | ||
521 | flexcop_device_exit(fc); | ||
522 | err_usb_exit: | ||
523 | flexcop_usb_exit(fc_usb); | ||
524 | err_kfree: | ||
525 | flexcop_device_kfree(fc); | ||
526 | success: | ||
527 | return ret; | ||
528 | } | ||
529 | |||
530 | static void flexcop_usb_disconnect(struct usb_interface *intf) | ||
531 | { | ||
532 | struct flexcop_usb *fc_usb = usb_get_intfdata(intf); | ||
533 | flexcop_usb_transfer_exit(fc_usb); | ||
534 | flexcop_device_exit(fc_usb->fc_dev); | ||
535 | flexcop_usb_exit(fc_usb); | ||
536 | flexcop_device_kfree(fc_usb->fc_dev); | ||
537 | info("%s successfully deinitialized and disconnected.",DRIVER_NAME); | ||
538 | } | ||
539 | |||
540 | static struct usb_device_id flexcop_usb_table [] = { | ||
541 | { USB_DEVICE(0x0af7, 0x0101) }, | ||
542 | { } | ||
543 | }; | ||
544 | |||
545 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
546 | static struct usb_driver flexcop_usb_driver = { | ||
547 | .owner = THIS_MODULE, | ||
548 | .name = "Technisat/B2C2 FlexCop II/IIb/III USB", | ||
549 | .probe = flexcop_usb_probe, | ||
550 | .disconnect = flexcop_usb_disconnect, | ||
551 | .id_table = flexcop_usb_table, | ||
552 | }; | ||
553 | |||
554 | /* module stuff */ | ||
555 | static int __init flexcop_usb_module_init(void) | ||
556 | { | ||
557 | int result; | ||
558 | if ((result = usb_register(&flexcop_usb_driver))) { | ||
559 | err("usb_register failed. (%d)",result); | ||
560 | return result; | ||
561 | } | ||
562 | |||
563 | return 0; | ||
564 | } | ||
565 | |||
566 | static void __exit flexcop_usb_module_exit(void) | ||
567 | { | ||
568 | /* deregister this driver from the USB subsystem */ | ||
569 | usb_deregister(&flexcop_usb_driver); | ||
570 | } | ||
571 | |||
572 | module_init(flexcop_usb_module_init); | ||
573 | module_exit(flexcop_usb_module_exit); | ||
574 | |||
575 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
576 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
577 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop-usb.h b/drivers/media/dvb/b2c2/flexcop-usb.h new file mode 100644 index 000000000000..630e647a2caa --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop-usb.h | |||
@@ -0,0 +1,119 @@ | |||
1 | #ifndef __FLEXCOP_USB_H_INCLUDED__ | ||
2 | #define __FLEXCOP_USB_H_INCLUDED__ | ||
3 | |||
4 | #include <linux/usb.h> | ||
5 | |||
6 | /* transfer parameters */ | ||
7 | #define B2C2_USB_FRAMES_PER_ISO 4 | ||
8 | #define B2C2_USB_NUM_ISO_URB 4 | ||
9 | |||
10 | #define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0) | ||
11 | #define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0) | ||
12 | #define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81) | ||
13 | |||
14 | struct flexcop_usb { | ||
15 | struct usb_device *udev; | ||
16 | struct usb_interface *uintf; | ||
17 | |||
18 | u8 *iso_buffer; | ||
19 | int buffer_size; | ||
20 | dma_addr_t dma_addr; | ||
21 | struct urb *iso_urb[B2C2_USB_NUM_ISO_URB]; | ||
22 | |||
23 | struct flexcop_device *fc_dev; | ||
24 | |||
25 | u8 tmp_buffer[1023+190]; | ||
26 | int tmp_buffer_length; | ||
27 | }; | ||
28 | |||
29 | #if 0 | ||
30 | /* request types TODO What is its use?*/ | ||
31 | typedef enum { | ||
32 | |||
33 | /* something is wrong with this part | ||
34 | RTYPE_READ_DW = (1 << 6), | ||
35 | RTYPE_WRITE_DW_1 = (3 << 6), | ||
36 | RTYPE_READ_V8_MEMORY = (6 << 6), | ||
37 | RTYPE_WRITE_V8_MEMORY = (7 << 6), | ||
38 | RTYPE_WRITE_V8_FLASH = (8 << 6), | ||
39 | RTYPE_GENERIC = (9 << 6), | ||
40 | */ | ||
41 | } flexcop_usb_request_type_t; | ||
42 | #endif | ||
43 | |||
44 | /* request */ | ||
45 | typedef enum { | ||
46 | B2C2_USB_WRITE_V8_MEM = 0x04, | ||
47 | B2C2_USB_READ_V8_MEM = 0x05, | ||
48 | B2C2_USB_READ_REG = 0x08, | ||
49 | B2C2_USB_WRITE_REG = 0x0A, | ||
50 | /* B2C2_USB_WRITEREGLO = 0x0A, */ | ||
51 | B2C2_USB_WRITEREGHI = 0x0B, | ||
52 | B2C2_USB_FLASH_BLOCK = 0x10, | ||
53 | B2C2_USB_I2C_REQUEST = 0x11, | ||
54 | B2C2_USB_UTILITY = 0x12, | ||
55 | } flexcop_usb_request_t; | ||
56 | |||
57 | /* function definition for I2C_REQUEST */ | ||
58 | typedef enum { | ||
59 | USB_FUNC_I2C_WRITE = 0x01, | ||
60 | USB_FUNC_I2C_MULTIWRITE = 0x02, | ||
61 | USB_FUNC_I2C_READ = 0x03, | ||
62 | USB_FUNC_I2C_REPEATWRITE = 0x04, | ||
63 | USB_FUNC_GET_DESCRIPTOR = 0x05, | ||
64 | USB_FUNC_I2C_REPEATREAD = 0x06, | ||
65 | /* DKT 020208 - add this to support special case of DiSEqC */ | ||
66 | USB_FUNC_I2C_CHECKWRITE = 0x07, | ||
67 | USB_FUNC_I2C_CHECKRESULT = 0x08, | ||
68 | } flexcop_usb_i2c_function_t; | ||
69 | |||
70 | /* | ||
71 | * function definition for UTILITY request 0x12 | ||
72 | * DKT 020304 - new utility function | ||
73 | */ | ||
74 | typedef enum { | ||
75 | UTILITY_SET_FILTER = 0x01, | ||
76 | UTILITY_DATA_ENABLE = 0x02, | ||
77 | UTILITY_FLEX_MULTIWRITE = 0x03, | ||
78 | UTILITY_SET_BUFFER_SIZE = 0x04, | ||
79 | UTILITY_FLEX_OPERATOR = 0x05, | ||
80 | UTILITY_FLEX_RESET300_START = 0x06, | ||
81 | UTILITY_FLEX_RESET300_STOP = 0x07, | ||
82 | UTILITY_FLEX_RESET300 = 0x08, | ||
83 | UTILITY_SET_ISO_SIZE = 0x09, | ||
84 | UTILITY_DATA_RESET = 0x0A, | ||
85 | UTILITY_GET_DATA_STATUS = 0x10, | ||
86 | UTILITY_GET_V8_REG = 0x11, | ||
87 | /* DKT 020326 - add function for v1.14 */ | ||
88 | UTILITY_SRAM_WRITE = 0x12, | ||
89 | UTILITY_SRAM_READ = 0x13, | ||
90 | UTILITY_SRAM_TESTFILL = 0x14, | ||
91 | UTILITY_SRAM_TESTSET = 0x15, | ||
92 | UTILITY_SRAM_TESTVERIFY = 0x16, | ||
93 | } flexcop_usb_utility_function_t; | ||
94 | |||
95 | #define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */ | ||
96 | #define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */ | ||
97 | #define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */ | ||
98 | |||
99 | #define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */ | ||
100 | #define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */ | ||
101 | #define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */ | ||
102 | |||
103 | typedef enum { | ||
104 | V8_MEMORY_PAGE_DVB_CI = 0x20, | ||
105 | V8_MEMORY_PAGE_DVB_DS = 0x40, | ||
106 | V8_MEMORY_PAGE_MULTI2 = 0x60, | ||
107 | V8_MEMORY_PAGE_FLASH = 0x80 | ||
108 | } flexcop_usb_mem_page_t; | ||
109 | |||
110 | #define V8_MEMORY_EXTENDED (1 << 15) | ||
111 | |||
112 | #define USB_MEM_READ_MAX 32 | ||
113 | #define USB_MEM_WRITE_MAX 1 | ||
114 | #define USB_FLASH_MAX 8 | ||
115 | |||
116 | #define V8_MEMORY_PAGE_SIZE 0x8000 // 32K | ||
117 | #define V8_MEMORY_PAGE_MASK 0x7FFF | ||
118 | |||
119 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/flexcop.c b/drivers/media/dvb/b2c2/flexcop.c new file mode 100644 index 000000000000..8b5d14dd36e3 --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop.c | |||
@@ -0,0 +1,286 @@ | |||
1 | /* | ||
2 | * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de> | ||
5 | * | ||
6 | * based on the skystar2-driver | ||
7 | * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc | ||
8 | * | ||
9 | * Acknowledgements: | ||
10 | * John Jurrius from BBTI, Inc. for extensive support with | ||
11 | * code examples and data books | ||
12 | * | ||
13 | * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting) | ||
14 | * | ||
15 | * Contributions to the skystar2-driver have been done by | ||
16 | * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes) | ||
17 | * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code) | ||
18 | * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering) | ||
19 | * | ||
20 | * | ||
21 | * This program is free software; you can redistribute it and/or | ||
22 | * modify it under the terms of the GNU Lesser General Public License | ||
23 | * as published by the Free Software Foundation; either version 2.1 | ||
24 | * of the License, or (at your option) 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 | * | ||
31 | * You should have received a copy of the GNU Lesser General Public License | ||
32 | * along with this program; if not, write to the Free Software | ||
33 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
34 | */ | ||
35 | |||
36 | #include "flexcop.h" | ||
37 | |||
38 | #define DRIVER_NAME "B2C2 FlexcopII/II(b)/III digital TV receiver chip" | ||
39 | #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de" | ||
40 | |||
41 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
42 | #define DEBSTATUS "" | ||
43 | #else | ||
44 | #define DEBSTATUS " (debugging is not enabled)" | ||
45 | #endif | ||
46 | |||
47 | int b2c2_flexcop_debug; | ||
48 | module_param_named(debug, b2c2_flexcop_debug, int, 0644); | ||
49 | MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram (|-able))." DEBSTATUS); | ||
50 | #undef DEBSTATUS | ||
51 | |||
52 | /* global zero for ibi values */ | ||
53 | flexcop_ibi_value ibi_zero; | ||
54 | |||
55 | static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
56 | { | ||
57 | struct flexcop_device *fc = dvbdmxfeed->demux->priv; | ||
58 | return flexcop_pid_feed_control(fc,dvbdmxfeed,1); | ||
59 | } | ||
60 | |||
61 | static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed) | ||
62 | { | ||
63 | struct flexcop_device *fc = dvbdmxfeed->demux->priv; | ||
64 | return flexcop_pid_feed_control(fc,dvbdmxfeed,0); | ||
65 | } | ||
66 | |||
67 | static int flexcop_dvb_init(struct flexcop_device *fc) | ||
68 | { | ||
69 | int ret; | ||
70 | if ((ret = dvb_register_adapter(&fc->dvb_adapter,"FlexCop Digital TV device",fc->owner)) < 0) { | ||
71 | err("error registering DVB adapter"); | ||
72 | return ret; | ||
73 | } | ||
74 | fc->dvb_adapter.priv = fc; | ||
75 | |||
76 | fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING); | ||
77 | fc->demux.priv = fc; | ||
78 | |||
79 | fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED; | ||
80 | |||
81 | fc->demux.start_feed = flexcop_dvb_start_feed; | ||
82 | fc->demux.stop_feed = flexcop_dvb_stop_feed; | ||
83 | fc->demux.write_to_decoder = NULL; | ||
84 | |||
85 | if ((ret = dvb_dmx_init(&fc->demux)) < 0) { | ||
86 | err("dvb_dmx failed: error %d",ret); | ||
87 | goto err_dmx; | ||
88 | } | ||
89 | |||
90 | fc->hw_frontend.source = DMX_FRONTEND_0; | ||
91 | |||
92 | fc->dmxdev.filternum = fc->demux.feednum; | ||
93 | fc->dmxdev.demux = &fc->demux.dmx; | ||
94 | fc->dmxdev.capabilities = 0; | ||
95 | if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) { | ||
96 | err("dvb_dmxdev_init failed: error %d",ret); | ||
97 | goto err_dmx_dev; | ||
98 | } | ||
99 | |||
100 | if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { | ||
101 | err("adding hw_frontend to dmx failed: error %d",ret); | ||
102 | goto err_dmx_add_hw_frontend; | ||
103 | } | ||
104 | |||
105 | fc->mem_frontend.source = DMX_MEMORY_FE; | ||
106 | if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) { | ||
107 | err("adding mem_frontend to dmx failed: error %d",ret); | ||
108 | goto err_dmx_add_mem_frontend; | ||
109 | } | ||
110 | |||
111 | if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) { | ||
112 | err("connect frontend failed: error %d",ret); | ||
113 | goto err_connect_frontend; | ||
114 | } | ||
115 | |||
116 | dvb_net_init(&fc->dvb_adapter, &fc->dvbnet, &fc->demux.dmx); | ||
117 | |||
118 | fc->init_state |= FC_STATE_DVB_INIT; | ||
119 | goto success; | ||
120 | |||
121 | err_connect_frontend: | ||
122 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); | ||
123 | err_dmx_add_mem_frontend: | ||
124 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); | ||
125 | err_dmx_add_hw_frontend: | ||
126 | dvb_dmxdev_release(&fc->dmxdev); | ||
127 | err_dmx_dev: | ||
128 | dvb_dmx_release(&fc->demux); | ||
129 | err_dmx: | ||
130 | dvb_unregister_adapter(&fc->dvb_adapter); | ||
131 | return ret; | ||
132 | |||
133 | success: | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static void flexcop_dvb_exit(struct flexcop_device *fc) | ||
138 | { | ||
139 | if (fc->init_state & FC_STATE_DVB_INIT) { | ||
140 | dvb_net_release(&fc->dvbnet); | ||
141 | |||
142 | fc->demux.dmx.close(&fc->demux.dmx); | ||
143 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend); | ||
144 | fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend); | ||
145 | dvb_dmxdev_release(&fc->dmxdev); | ||
146 | dvb_dmx_release(&fc->demux); | ||
147 | dvb_unregister_adapter(&fc->dvb_adapter); | ||
148 | |||
149 | deb_info("deinitialized dvb stuff\n"); | ||
150 | } | ||
151 | fc->init_state &= ~FC_STATE_DVB_INIT; | ||
152 | } | ||
153 | |||
154 | /* these methods are necessary to achieve the long-term-goal of hiding the | ||
155 | * struct flexcop_device from the bus-parts */ | ||
156 | void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len) | ||
157 | { | ||
158 | dvb_dmx_swfilter(&fc->demux, buf, len); | ||
159 | } | ||
160 | EXPORT_SYMBOL(flexcop_pass_dmx_data); | ||
161 | |||
162 | void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no) | ||
163 | { | ||
164 | dvb_dmx_swfilter_packets(&fc->demux, buf, no); | ||
165 | } | ||
166 | EXPORT_SYMBOL(flexcop_pass_dmx_packets); | ||
167 | |||
168 | static void flexcop_reset(struct flexcop_device *fc) | ||
169 | { | ||
170 | flexcop_ibi_value v210,v204; | ||
171 | |||
172 | /* reset the flexcop itself */ | ||
173 | fc->write_ibi_reg(fc,ctrl_208,ibi_zero); | ||
174 | |||
175 | v210.raw = 0; | ||
176 | v210.sw_reset_210.reset_blocks = 0xff; | ||
177 | v210.sw_reset_210.Block_reset_enable = 0xb2; | ||
178 | fc->write_ibi_reg(fc,sw_reset_210,v210); | ||
179 | |||
180 | /* reset the periphical devices */ | ||
181 | |||
182 | v204 = fc->read_ibi_reg(fc,misc_204); | ||
183 | v204.misc_204.Per_reset_sig = 0; | ||
184 | fc->write_ibi_reg(fc,misc_204,v204); | ||
185 | v204.misc_204.Per_reset_sig = 1; | ||
186 | fc->write_ibi_reg(fc,misc_204,v204); | ||
187 | } | ||
188 | |||
189 | struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len) | ||
190 | { | ||
191 | void *bus; | ||
192 | struct flexcop_device *fc = kmalloc(sizeof(struct flexcop_device), GFP_KERNEL); | ||
193 | if (!fc) { | ||
194 | err("no memory"); | ||
195 | return NULL; | ||
196 | } | ||
197 | memset(fc, 0, sizeof(struct flexcop_device)); | ||
198 | |||
199 | bus = kmalloc(bus_specific_len, GFP_KERNEL); | ||
200 | if (!bus) { | ||
201 | err("no memory"); | ||
202 | kfree(fc); | ||
203 | return NULL; | ||
204 | } | ||
205 | memset(bus, 0, bus_specific_len); | ||
206 | |||
207 | fc->bus_specific = bus; | ||
208 | |||
209 | return fc; | ||
210 | } | ||
211 | EXPORT_SYMBOL(flexcop_device_kmalloc); | ||
212 | |||
213 | void flexcop_device_kfree(struct flexcop_device *fc) | ||
214 | { | ||
215 | kfree(fc->bus_specific); | ||
216 | kfree(fc); | ||
217 | } | ||
218 | EXPORT_SYMBOL(flexcop_device_kfree); | ||
219 | |||
220 | int flexcop_device_initialize(struct flexcop_device *fc) | ||
221 | { | ||
222 | int ret; | ||
223 | ibi_zero.raw = 0; | ||
224 | |||
225 | flexcop_reset(fc); | ||
226 | flexcop_determine_revision(fc); | ||
227 | flexcop_sram_init(fc); | ||
228 | flexcop_hw_filter_init(fc); | ||
229 | |||
230 | flexcop_smc_ctrl(fc, 0); | ||
231 | |||
232 | if ((ret = flexcop_dvb_init(fc))) | ||
233 | goto error; | ||
234 | |||
235 | /* do the MAC address reading after initializing the dvb_adapter */ | ||
236 | if (fc->get_mac_addr(fc, 0) == 0) { | ||
237 | u8 *b = fc->dvb_adapter.proposed_mac; | ||
238 | info("MAC address = %02x:%02x:%02x:%02x:%02x:%02x", b[0],b[1],b[2],b[3],b[4],b[5]); | ||
239 | flexcop_set_mac_filter(fc,b); | ||
240 | flexcop_mac_filter_ctrl(fc,1); | ||
241 | } else | ||
242 | warn("reading of MAC address failed.\n"); | ||
243 | |||
244 | |||
245 | if ((ret = flexcop_i2c_init(fc))) | ||
246 | goto error; | ||
247 | |||
248 | if ((ret = flexcop_frontend_init(fc))) | ||
249 | goto error; | ||
250 | |||
251 | flexcop_device_name(fc,"initialization of","complete"); | ||
252 | |||
253 | ret = 0; | ||
254 | goto success; | ||
255 | error: | ||
256 | flexcop_device_exit(fc); | ||
257 | success: | ||
258 | return ret; | ||
259 | } | ||
260 | EXPORT_SYMBOL(flexcop_device_initialize); | ||
261 | |||
262 | void flexcop_device_exit(struct flexcop_device *fc) | ||
263 | { | ||
264 | flexcop_frontend_exit(fc); | ||
265 | flexcop_i2c_exit(fc); | ||
266 | flexcop_dvb_exit(fc); | ||
267 | } | ||
268 | EXPORT_SYMBOL(flexcop_device_exit); | ||
269 | |||
270 | static int flexcop_module_init(void) | ||
271 | { | ||
272 | info(DRIVER_NAME " loaded successfully"); | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static void flexcop_module_cleanup(void) | ||
277 | { | ||
278 | info(DRIVER_NAME " unloaded successfully"); | ||
279 | } | ||
280 | |||
281 | module_init(flexcop_module_init); | ||
282 | module_exit(flexcop_module_cleanup); | ||
283 | |||
284 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
285 | MODULE_DESCRIPTION(DRIVER_NAME); | ||
286 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/b2c2/flexcop.h b/drivers/media/dvb/b2c2/flexcop.h new file mode 100644 index 000000000000..caa343a97bdc --- /dev/null +++ b/drivers/media/dvb/b2c2/flexcop.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III | ||
3 | * | ||
4 | * flexcop.h - private header file for all flexcop-chip-source files. | ||
5 | * | ||
6 | * see flexcop.c for copyright information. | ||
7 | */ | ||
8 | #ifndef __FLEXCOP_H__ | ||
9 | #define __FLEXCOP_H___ | ||
10 | |||
11 | #define FC_LOG_PREFIX "b2c2-flexcop" | ||
12 | #include "flexcop-common.h" | ||
13 | |||
14 | extern int b2c2_flexcop_debug; | ||
15 | |||
16 | /* debug */ | ||
17 | #ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG | ||
18 | #define dprintk(level,args...) \ | ||
19 | do { if ((b2c2_flexcop_debug & level)) printk(args); } while (0) | ||
20 | #else | ||
21 | #define dprintk(level,args...) | ||
22 | #endif | ||
23 | |||
24 | #define deb_info(args...) dprintk(0x01,args) | ||
25 | #define deb_tuner(args...) dprintk(0x02,args) | ||
26 | #define deb_i2c(args...) dprintk(0x04,args) | ||
27 | #define deb_ts(args...) dprintk(0x08,args) | ||
28 | #define deb_sram(args...) dprintk(0x10,args) | ||
29 | |||
30 | #endif | ||
diff --git a/drivers/media/dvb/b2c2/skystar2.c b/drivers/media/dvb/b2c2/skystar2.c index 336c178fcd5f..acbc4c34f72a 100644 --- a/drivers/media/dvb/b2c2/skystar2.c +++ b/drivers/media/dvb/b2c2/skystar2.c | |||
@@ -97,7 +97,7 @@ struct adapter { | |||
97 | u8 mac_addr[8]; | 97 | u8 mac_addr[8]; |
98 | u32 dw_sram_type; | 98 | u32 dw_sram_type; |
99 | 99 | ||
100 | struct dvb_adapter *dvb_adapter; | 100 | struct dvb_adapter dvb_adapter; |
101 | struct dvb_demux demux; | 101 | struct dvb_demux demux; |
102 | struct dmxdev dmxdev; | 102 | struct dmxdev dmxdev; |
103 | struct dmx_frontend hw_frontend; | 103 | struct dmx_frontend hw_frontend; |
@@ -2461,7 +2461,7 @@ static void frontend_init(struct adapter *skystar2) | |||
2461 | skystar2->pdev->subsystem_vendor, | 2461 | skystar2->pdev->subsystem_vendor, |
2462 | skystar2->pdev->subsystem_device); | 2462 | skystar2->pdev->subsystem_device); |
2463 | } else { | 2463 | } else { |
2464 | if (dvb_register_frontend(skystar2->dvb_adapter, skystar2->fe)) { | 2464 | if (dvb_register_frontend(&skystar2->dvb_adapter, skystar2->fe)) { |
2465 | printk("skystar2: Frontend registration failed!\n"); | 2465 | printk("skystar2: Frontend registration failed!\n"); |
2466 | if (skystar2->fe->ops->release) | 2466 | if (skystar2->fe->ops->release) |
2467 | skystar2->fe->ops->release(skystar2->fe); | 2467 | skystar2->fe->ops->release(skystar2->fe); |
@@ -2486,17 +2486,17 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2486 | if (ret < 0) | 2486 | if (ret < 0) |
2487 | goto out; | 2487 | goto out; |
2488 | 2488 | ||
2489 | ret = dvb_register_adapter(&dvb_adapter, skystar2_pci_driver.name, | 2489 | adapter = pci_get_drvdata(pdev); |
2490 | dvb_adapter = &adapter->dvb_adapter; | ||
2491 | |||
2492 | ret = dvb_register_adapter(dvb_adapter, skystar2_pci_driver.name, | ||
2490 | THIS_MODULE); | 2493 | THIS_MODULE); |
2491 | if (ret < 0) { | 2494 | if (ret < 0) { |
2492 | printk("%s: Error registering DVB adapter\n", __FUNCTION__); | 2495 | printk("%s: Error registering DVB adapter\n", __FUNCTION__); |
2493 | goto err_halt; | 2496 | goto err_halt; |
2494 | } | 2497 | } |
2495 | 2498 | ||
2496 | adapter = pci_get_drvdata(pdev); | ||
2497 | |||
2498 | dvb_adapter->priv = adapter; | 2499 | dvb_adapter->priv = adapter; |
2499 | adapter->dvb_adapter = dvb_adapter; | ||
2500 | 2500 | ||
2501 | 2501 | ||
2502 | init_MUTEX(&adapter->i2c_sem); | 2502 | init_MUTEX(&adapter->i2c_sem); |
@@ -2541,7 +2541,7 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2541 | adapter->dmxdev.demux = dmx; | 2541 | adapter->dmxdev.demux = dmx; |
2542 | adapter->dmxdev.capabilities = 0; | 2542 | adapter->dmxdev.capabilities = 0; |
2543 | 2543 | ||
2544 | ret = dvb_dmxdev_init(&adapter->dmxdev, adapter->dvb_adapter); | 2544 | ret = dvb_dmxdev_init(&adapter->dmxdev, &adapter->dvb_adapter); |
2545 | if (ret < 0) | 2545 | if (ret < 0) |
2546 | goto err_dmx_release; | 2546 | goto err_dmx_release; |
2547 | 2547 | ||
@@ -2559,7 +2559,7 @@ static int skystar2_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2559 | if (ret < 0) | 2559 | if (ret < 0) |
2560 | goto err_remove_mem_frontend; | 2560 | goto err_remove_mem_frontend; |
2561 | 2561 | ||
2562 | dvb_net_init(adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx); | 2562 | dvb_net_init(&adapter->dvb_adapter, &adapter->dvbnet, &dvbdemux->dmx); |
2563 | 2563 | ||
2564 | frontend_init(adapter); | 2564 | frontend_init(adapter); |
2565 | out: | 2565 | out: |
@@ -2576,7 +2576,7 @@ err_dmx_release: | |||
2576 | err_i2c_del: | 2576 | err_i2c_del: |
2577 | i2c_del_adapter(&adapter->i2c_adap); | 2577 | i2c_del_adapter(&adapter->i2c_adap); |
2578 | err_dvb_unregister: | 2578 | err_dvb_unregister: |
2579 | dvb_unregister_adapter(adapter->dvb_adapter); | 2579 | dvb_unregister_adapter(&adapter->dvb_adapter); |
2580 | err_halt: | 2580 | err_halt: |
2581 | driver_halt(pdev); | 2581 | driver_halt(pdev); |
2582 | goto out; | 2582 | goto out; |
@@ -2605,7 +2605,7 @@ static void skystar2_remove(struct pci_dev *pdev) | |||
2605 | if (adapter->fe != NULL) | 2605 | if (adapter->fe != NULL) |
2606 | dvb_unregister_frontend(adapter->fe); | 2606 | dvb_unregister_frontend(adapter->fe); |
2607 | 2607 | ||
2608 | dvb_unregister_adapter(adapter->dvb_adapter); | 2608 | dvb_unregister_adapter(&adapter->dvb_adapter); |
2609 | 2609 | ||
2610 | i2c_del_adapter(&adapter->i2c_adap); | 2610 | i2c_del_adapter(&adapter->i2c_adap); |
2611 | 2611 | ||
diff --git a/drivers/media/dvb/bt8xx/Kconfig b/drivers/media/dvb/bt8xx/Kconfig index e7d11e0667a8..b12545f093f8 100644 --- a/drivers/media/dvb/bt8xx/Kconfig +++ b/drivers/media/dvb/bt8xx/Kconfig | |||
@@ -11,9 +11,8 @@ config DVB_BT8XX | |||
11 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and | 11 | the Nebula cards, the Pinnacle PCTV cards, the Twinhan DST cards and |
12 | pcHDTV HD2000 cards. | 12 | pcHDTV HD2000 cards. |
13 | 13 | ||
14 | Since these cards have no MPEG decoder onboard, they transmit | 14 | Since these cards have no MPEG decoder onboard, they transmit |
15 | only compressed MPEG data over the PCI bus, so you need | 15 | only compressed MPEG data over the PCI bus, so you need |
16 | an external software decoder to watch TV on your computer. | 16 | an external software decoder to watch TV on your computer. |
17 | 17 | ||
18 | Say Y if you own such a device and want to use it. | 18 | Say Y if you own such a device and want to use it. |
19 | |||
diff --git a/drivers/media/dvb/bt8xx/Makefile b/drivers/media/dvb/bt8xx/Makefile index 9da8604b9e18..d188e4c670b5 100644 --- a/drivers/media/dvb/bt8xx/Makefile +++ b/drivers/media/dvb/bt8xx/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | 1 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o dst_ca.o | |
2 | obj-$(CONFIG_DVB_BT8XX) += bt878.o dvb-bt8xx.o dst.o | ||
3 | 2 | ||
4 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends | 3 | EXTRA_CFLAGS = -Idrivers/media/dvb/dvb-core/ -Idrivers/media/video -Idrivers/media/dvb/frontends |
5 | |||
diff --git a/drivers/media/dvb/bt8xx/bt878.c b/drivers/media/dvb/bt8xx/bt878.c index 213ff7902024..3c5a8e273c4a 100644 --- a/drivers/media/dvb/bt8xx/bt878.c +++ b/drivers/media/dvb/bt8xx/bt878.c | |||
@@ -4,27 +4,27 @@ | |||
4 | * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> | 4 | * Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> |
5 | * | 5 | * |
6 | * large parts based on the bttv driver | 6 | * large parts based on the bttv driver |
7 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@thp.uni-koeln.de) | 7 | * Copyright (C) 1996,97,98 Ralph Metzler (rjkm@metzlerbros.de) |
8 | * & Marcus Metzler (mocm@thp.uni-koeln.de) | 8 | * & Marcus Metzler (mocm@metzlerbros.de) |
9 | * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> | 9 | * (c) 1999,2000 Gerd Knorr <kraxel@goldbach.in-berlin.de> |
10 | * | 10 | * |
11 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License | 12 | * modify it under the terms of the GNU General Public License |
13 | * as published by the Free Software Foundation; either version 2 | 13 | * as published by the Free Software Foundation; either version 2 |
14 | * of the License, or (at your option) any later version. | 14 | * of the License, or (at your option) any later version. |
15 | * | 15 | * |
16 | 16 | ||
17 | * This program is distributed in the hope that it will be useful, | 17 | * This program is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | * GNU General Public License for more details. | 20 | * GNU General Public License for more details. |
21 | * | 21 | * |
22 | 22 | ||
23 | * You should have received a copy of the GNU General Public License | 23 | * You should have received a copy of the GNU General Public License |
24 | * along with this program; if not, write to the Free Software | 24 | * along with this program; if not, write to the Free Software |
25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 25 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
26 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html | 26 | * Or, point your browser to http://www.gnu.org/copyleft/gpl.html |
27 | * | 27 | * |
28 | */ | 28 | */ |
29 | 29 | ||
30 | #include <linux/module.h> | 30 | #include <linux/module.h> |
@@ -58,7 +58,7 @@ module_param_named(verbose, bt878_verbose, int, 0444); | |||
58 | MODULE_PARM_DESC(verbose, | 58 | MODULE_PARM_DESC(verbose, |
59 | "verbose startup messages, default is 1 (yes)"); | 59 | "verbose startup messages, default is 1 (yes)"); |
60 | module_param_named(debug, bt878_debug, int, 0644); | 60 | module_param_named(debug, bt878_debug, int, 0644); |
61 | MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off)."); | 61 | MODULE_PARM_DESC(debug, "Turn on/off debugging, default is 0 (off)."); |
62 | 62 | ||
63 | int bt878_num; | 63 | int bt878_num; |
64 | struct bt878 bt878[BT878_MAX]; | 64 | struct bt878 bt878[BT878_MAX]; |
@@ -128,21 +128,21 @@ static int bt878_mem_alloc(struct bt878 *bt) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | /* RISC instructions */ | 130 | /* RISC instructions */ |
131 | #define RISC_WRITE (0x01 << 28) | 131 | #define RISC_WRITE (0x01 << 28) |
132 | #define RISC_JUMP (0x07 << 28) | 132 | #define RISC_JUMP (0x07 << 28) |
133 | #define RISC_SYNC (0x08 << 28) | 133 | #define RISC_SYNC (0x08 << 28) |
134 | 134 | ||
135 | /* RISC bits */ | 135 | /* RISC bits */ |
136 | #define RISC_WR_SOL (1 << 27) | 136 | #define RISC_WR_SOL (1 << 27) |
137 | #define RISC_WR_EOL (1 << 26) | 137 | #define RISC_WR_EOL (1 << 26) |
138 | #define RISC_IRQ (1 << 24) | 138 | #define RISC_IRQ (1 << 24) |
139 | #define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16)) | 139 | #define RISC_STATUS(status) ((((~status) & 0x0F) << 20) | ((status & 0x0F) << 16)) |
140 | #define RISC_SYNC_RESYNC (1 << 15) | 140 | #define RISC_SYNC_RESYNC (1 << 15) |
141 | #define RISC_SYNC_FM1 0x06 | 141 | #define RISC_SYNC_FM1 0x06 |
142 | #define RISC_SYNC_VRO 0x0C | 142 | #define RISC_SYNC_VRO 0x0C |
143 | 143 | ||
144 | #define RISC_FLUSH() bt->risc_pos = 0 | 144 | #define RISC_FLUSH() bt->risc_pos = 0 |
145 | #define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) | 145 | #define RISC_INSTR(instr) bt->risc_cpu[bt->risc_pos++] = cpu_to_le32(instr) |
146 | 146 | ||
147 | static int bt878_make_risc(struct bt878 *bt) | 147 | static int bt878_make_risc(struct bt878 *bt) |
148 | { | 148 | { |
@@ -173,7 +173,7 @@ static void bt878_risc_program(struct bt878 *bt, u32 op_sync_orin) | |||
173 | RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); | 173 | RISC_INSTR(RISC_SYNC | RISC_SYNC_FM1 | op_sync_orin); |
174 | RISC_INSTR(0); | 174 | RISC_INSTR(0); |
175 | 175 | ||
176 | dprintk("bt878: risc len lines %u, bytes per line %u\n", | 176 | dprintk("bt878: risc len lines %u, bytes per line %u\n", |
177 | bt->line_count, bt->line_bytes); | 177 | bt->line_count, bt->line_bytes); |
178 | for (line = 0; line < bt->line_count; line++) { | 178 | for (line = 0; line < bt->line_count; line++) { |
179 | // At the beginning of every block we issue an IRQ with previous (finished) block number set | 179 | // At the beginning of every block we issue an IRQ with previous (finished) block number set |
@@ -228,14 +228,14 @@ void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, | |||
228 | * Hacked for DST to: | 228 | * Hacked for DST to: |
229 | * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI | 229 | * SCERR | OCERR | FDSR | FTRGT | FBUS | RISCI |
230 | */ | 230 | */ |
231 | int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | | 231 | int_mask = BT878_ASCERR | BT878_AOCERR | BT878_APABORT | |
232 | BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | | 232 | BT878_ARIPERR | BT878_APPERR | BT878_AFDSR | BT878_AFTRGT | |
233 | BT878_AFBUS | BT878_ARISCI; | 233 | BT878_AFBUS | BT878_ARISCI; |
234 | 234 | ||
235 | 235 | ||
236 | /* ignore pesky bits */ | 236 | /* ignore pesky bits */ |
237 | int_mask &= ~irq_err_ignore; | 237 | int_mask &= ~irq_err_ignore; |
238 | 238 | ||
239 | btwrite(int_mask, BT878_AINT_MASK); | 239 | btwrite(int_mask, BT878_AINT_MASK); |
240 | btwrite(controlreg, BT878_AGPIO_DMA_CTL); | 240 | btwrite(controlreg, BT878_AGPIO_DMA_CTL); |
241 | } | 241 | } |
@@ -461,9 +461,9 @@ static int __devinit bt878_probe(struct pci_dev *dev, | |||
461 | pci_set_drvdata(dev, bt); | 461 | pci_set_drvdata(dev, bt); |
462 | 462 | ||
463 | /* if(init_bt878(btv) < 0) { | 463 | /* if(init_bt878(btv) < 0) { |
464 | bt878_remove(dev); | 464 | bt878_remove(dev); |
465 | return -EIO; | 465 | return -EIO; |
466 | } | 466 | } |
467 | */ | 467 | */ |
468 | 468 | ||
469 | if ((result = bt878_mem_alloc(bt))) { | 469 | if ((result = bt878_mem_alloc(bt))) { |
@@ -536,10 +536,10 @@ static struct pci_device_id bt878_pci_tbl[] __devinitdata = { | |||
536 | MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); | 536 | MODULE_DEVICE_TABLE(pci, bt878_pci_tbl); |
537 | 537 | ||
538 | static struct pci_driver bt878_pci_driver = { | 538 | static struct pci_driver bt878_pci_driver = { |
539 | .name = "bt878", | 539 | .name = "bt878", |
540 | .id_table = bt878_pci_tbl, | 540 | .id_table = bt878_pci_tbl, |
541 | .probe = bt878_probe, | 541 | .probe = bt878_probe, |
542 | .remove = bt878_remove, | 542 | .remove = bt878_remove, |
543 | }; | 543 | }; |
544 | 544 | ||
545 | static int bt878_pci_driver_registered = 0; | 545 | static int bt878_pci_driver_registered = 0; |
@@ -558,7 +558,7 @@ static int bt878_init_module(void) | |||
558 | (BT878_VERSION_CODE >> 8) & 0xff, | 558 | (BT878_VERSION_CODE >> 8) & 0xff, |
559 | BT878_VERSION_CODE & 0xff); | 559 | BT878_VERSION_CODE & 0xff); |
560 | /* | 560 | /* |
561 | bt878_check_chipset(); | 561 | bt878_check_chipset(); |
562 | */ | 562 | */ |
563 | /* later we register inside of bt878_find_audio_dma() | 563 | /* later we register inside of bt878_find_audio_dma() |
564 | * because we may want to ignore certain cards */ | 564 | * because we may want to ignore certain cards */ |
diff --git a/drivers/media/dvb/bt8xx/bt878.h b/drivers/media/dvb/bt8xx/bt878.h index e1b9809d1b08..837623f7fcdf 100644 --- a/drivers/media/dvb/bt8xx/bt878.h +++ b/drivers/media/dvb/bt8xx/bt878.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | bt878.h - Bt878 audio module (register offsets) | 2 | bt878.h - Bt878 audio module (register offsets) |
3 | 3 | ||
4 | Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> | 4 | Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@t-online.de> |
@@ -120,14 +120,14 @@ struct bt878 { | |||
120 | u32 risc_pos; | 120 | u32 risc_pos; |
121 | 121 | ||
122 | struct tasklet_struct tasklet; | 122 | struct tasklet_struct tasklet; |
123 | int shutdown; | 123 | int shutdown; |
124 | }; | 124 | }; |
125 | 125 | ||
126 | extern struct bt878 bt878[BT878_MAX]; | 126 | extern struct bt878 bt878[BT878_MAX]; |
127 | 127 | ||
128 | void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, | 128 | void bt878_start(struct bt878 *bt, u32 controlreg, u32 op_sync_orin, |
129 | u32 irq_err_ignore); | 129 | u32 irq_err_ignore); |
130 | void bt878_stop(struct bt878 *bt); | 130 | void bt878_stop(struct bt878 *bt); |
131 | 131 | ||
132 | #if defined(__powerpc__) /* big-endian */ | 132 | #if defined(__powerpc__) /* big-endian */ |
133 | extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val) | 133 | extern __inline__ void io_st_le32(volatile unsigned __iomem *addr, unsigned val) |
diff --git a/drivers/media/dvb/bt8xx/dst.c b/drivers/media/dvb/bt8xx/dst.c index eac83768dfd0..d047e349d706 100644 --- a/drivers/media/dvb/bt8xx/dst.c +++ b/drivers/media/dvb/bt8xx/dst.c | |||
@@ -1,25 +1,25 @@ | |||
1 | /* | 1 | /* |
2 | Frontend-driver for TwinHan DST Frontend | ||
3 | 2 | ||
4 | Copyright (C) 2003 Jamie Honan | 3 | Frontend/Card driver for TwinHan DST Frontend |
4 | Copyright (C) 2003 Jamie Honan | ||
5 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
5 | 6 | ||
6 | This program is free software; you can redistribute it and/or modify | 7 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by | 8 | 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 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. | 10 | (at your option) any later version. |
10 | 11 | ||
11 | This program is distributed in the hope that it will be useful, | 12 | This program is distributed in the hope that it will be useful, |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | 15 | GNU General Public License for more details. | |
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | 16 | ||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | */ | 20 | */ |
22 | 21 | ||
22 | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
@@ -31,59 +31,22 @@ | |||
31 | 31 | ||
32 | #include "dvb_frontend.h" | 32 | #include "dvb_frontend.h" |
33 | #include "dst_priv.h" | 33 | #include "dst_priv.h" |
34 | #include "dst.h" | 34 | #include "dst_common.h" |
35 | |||
36 | struct dst_state { | ||
37 | |||
38 | struct i2c_adapter* i2c; | ||
39 | |||
40 | struct bt878* bt; | ||
41 | |||
42 | struct dvb_frontend_ops ops; | ||
43 | |||
44 | /* configuration settings */ | ||
45 | const struct dst_config* config; | ||
46 | |||
47 | struct dvb_frontend frontend; | ||
48 | |||
49 | /* private demodulator data */ | ||
50 | u8 tx_tuna[10]; | ||
51 | u8 rx_tuna[10]; | ||
52 | u8 rxbuffer[10]; | ||
53 | u8 diseq_flags; | ||
54 | u8 dst_type; | ||
55 | u32 type_flags; | ||
56 | u32 frequency; /* intermediate frequency in kHz for QPSK */ | ||
57 | fe_spectral_inversion_t inversion; | ||
58 | u32 symbol_rate; /* symbol rate in Symbols per second */ | ||
59 | fe_code_rate_t fec; | ||
60 | fe_sec_voltage_t voltage; | ||
61 | fe_sec_tone_mode_t tone; | ||
62 | u32 decode_freq; | ||
63 | u8 decode_lock; | ||
64 | u16 decode_strength; | ||
65 | u16 decode_snr; | ||
66 | unsigned long cur_jiff; | ||
67 | u8 k22; | ||
68 | fe_bandwidth_t bandwidth; | ||
69 | }; | ||
70 | 35 | ||
71 | static unsigned int dst_verbose = 0; | ||
72 | module_param(dst_verbose, int, 0644); | ||
73 | MODULE_PARM_DESC(dst_verbose, "verbose startup messages, default is 1 (yes)"); | ||
74 | static unsigned int dst_debug = 0; | ||
75 | module_param(dst_debug, int, 0644); | ||
76 | MODULE_PARM_DESC(dst_debug, "debug messages, default is 0 (no)"); | ||
77 | 36 | ||
78 | #define dprintk if (dst_debug) printk | 37 | static unsigned int verbose = 1; |
38 | module_param(verbose, int, 0644); | ||
39 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
79 | 40 | ||
80 | #define DST_TYPE_IS_SAT 0 | 41 | static unsigned int debug = 1; |
81 | #define DST_TYPE_IS_TERR 1 | 42 | module_param(debug, int, 0644); |
82 | #define DST_TYPE_IS_CABLE 2 | 43 | MODULE_PARM_DESC(debug, "debug messages, default is 0 (yes)"); |
83 | 44 | ||
84 | #define DST_TYPE_HAS_NEWTUNE 1 | 45 | static unsigned int dst_addons; |
85 | #define DST_TYPE_HAS_TS204 2 | 46 | module_param(dst_addons, int, 0644); |
86 | #define DST_TYPE_HAS_SYMDIV 4 | 47 | MODULE_PARM_DESC(dst_addons, "CA daughterboard, default is 0 (No addons)"); |
48 | |||
49 | #define dprintk if (debug) printk | ||
87 | 50 | ||
88 | #define HAS_LOCK 1 | 51 | #define HAS_LOCK 1 |
89 | #define ATTEMPT_TUNE 2 | 52 | #define ATTEMPT_TUNE 2 |
@@ -97,7 +60,7 @@ static void dst_packsize(struct dst_state* state, int psize) | |||
97 | bt878_device_control(state->bt, DST_IG_TS, &bits); | 60 | bt878_device_control(state->bt, DST_IG_TS, &bits); |
98 | } | 61 | } |
99 | 62 | ||
100 | static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh) | 63 | int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay) |
101 | { | 64 | { |
102 | union dst_gpio_packet enb; | 65 | union dst_gpio_packet enb; |
103 | union dst_gpio_packet bits; | 66 | union dst_gpio_packet bits; |
@@ -105,26 +68,33 @@ static int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhig | |||
105 | 68 | ||
106 | enb.enb.mask = mask; | 69 | enb.enb.mask = mask; |
107 | enb.enb.enable = enbb; | 70 | enb.enb.enable = enbb; |
71 | if (verbose > 4) | ||
72 | dprintk("%s: mask=[%04x], enbb=[%04x], outhigh=[%04x]\n", __FUNCTION__, mask, enbb, outhigh); | ||
73 | |||
108 | if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { | 74 | if ((err = bt878_device_control(state->bt, DST_IG_ENABLE, &enb)) < 0) { |
109 | dprintk("%s: dst_gpio_enb error (err == %i, mask == 0x%02x, enb == 0x%02x)\n", __FUNCTION__, err, mask, enbb); | 75 | dprintk("%s: dst_gpio_enb error (err == %i, mask == %02x, enb == %02x)\n", __FUNCTION__, err, mask, enbb); |
110 | return -EREMOTEIO; | 76 | return -EREMOTEIO; |
111 | } | 77 | } |
112 | 78 | udelay(1000); | |
113 | /* because complete disabling means no output, no need to do output packet */ | 79 | /* because complete disabling means no output, no need to do output packet */ |
114 | if (enbb == 0) | 80 | if (enbb == 0) |
115 | return 0; | 81 | return 0; |
116 | 82 | ||
83 | if (delay) | ||
84 | msleep(10); | ||
85 | |||
117 | bits.outp.mask = enbb; | 86 | bits.outp.mask = enbb; |
118 | bits.outp.highvals = outhigh; | 87 | bits.outp.highvals = outhigh; |
119 | 88 | ||
120 | if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { | 89 | if ((err = bt878_device_control(state->bt, DST_IG_WRITE, &bits)) < 0) { |
121 | dprintk("%s: dst_gpio_outb error (err == %i, enbb == 0x%02x, outhigh == 0x%02x)\n", __FUNCTION__, err, enbb, outhigh); | 90 | dprintk("%s: dst_gpio_outb error (err == %i, enbb == %02x, outhigh == %02x)\n", __FUNCTION__, err, enbb, outhigh); |
122 | return -EREMOTEIO; | 91 | return -EREMOTEIO; |
123 | } | 92 | } |
124 | return 0; | 93 | return 0; |
125 | } | 94 | } |
95 | EXPORT_SYMBOL(dst_gpio_outb); | ||
126 | 96 | ||
127 | static int dst_gpio_inb(struct dst_state *state, u8 * result) | 97 | int dst_gpio_inb(struct dst_state *state, u8 * result) |
128 | { | 98 | { |
129 | union dst_gpio_packet rd_packet; | 99 | union dst_gpio_packet rd_packet; |
130 | int err; | 100 | int err; |
@@ -139,143 +109,225 @@ static int dst_gpio_inb(struct dst_state *state, u8 * result) | |||
139 | *result = (u8) rd_packet.rd.value; | 109 | *result = (u8) rd_packet.rd.value; |
140 | return 0; | 110 | return 0; |
141 | } | 111 | } |
112 | EXPORT_SYMBOL(dst_gpio_inb); | ||
142 | 113 | ||
143 | #define DST_I2C_ENABLE 1 | 114 | int rdc_reset_state(struct dst_state *state) |
144 | #define DST_8820 2 | ||
145 | |||
146 | static int dst_reset8820(struct dst_state *state) | ||
147 | { | 115 | { |
148 | int retval; | 116 | if (verbose > 1) |
149 | /* pull 8820 gpio pin low, wait, high, wait, then low */ | 117 | dprintk("%s: Resetting state machine\n", __FUNCTION__); |
150 | // dprintk ("%s: reset 8820\n", __FUNCTION__); | 118 | |
151 | retval = dst_gpio_outb(state, DST_8820, DST_8820, 0); | 119 | if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, 0, NO_DELAY) < 0) { |
152 | if (retval < 0) | 120 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); |
153 | return retval; | 121 | return -1; |
122 | } | ||
123 | |||
154 | msleep(10); | 124 | msleep(10); |
155 | retval = dst_gpio_outb(state, DST_8820, DST_8820, DST_8820); | 125 | |
156 | if (retval < 0) | 126 | if (dst_gpio_outb(state, RDC_8820_INT, RDC_8820_INT, RDC_8820_INT, NO_DELAY) < 0) { |
157 | return retval; | 127 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); |
158 | /* wait for more feedback on what works here * | 128 | msleep(10); |
159 | msleep(10); | 129 | return -1; |
160 | retval = dst_gpio_outb(dst, DST_8820, DST_8820, 0); | 130 | } |
161 | if (retval < 0) | 131 | |
162 | return retval; | ||
163 | */ | ||
164 | return 0; | 132 | return 0; |
165 | } | 133 | } |
134 | EXPORT_SYMBOL(rdc_reset_state); | ||
166 | 135 | ||
167 | static int dst_i2c_enable(struct dst_state *state) | 136 | int rdc_8820_reset(struct dst_state *state) |
168 | { | 137 | { |
169 | int retval; | 138 | if (verbose > 1) |
170 | /* pull I2C enable gpio pin low, wait */ | 139 | dprintk("%s: Resetting DST\n", __FUNCTION__); |
171 | // dprintk ("%s: i2c enable\n", __FUNCTION__); | 140 | |
172 | retval = dst_gpio_outb(state, ~0, DST_I2C_ENABLE, 0); | 141 | if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, 0, NO_DELAY) < 0) { |
173 | if (retval < 0) | 142 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); |
174 | return retval; | 143 | return -1; |
175 | // dprintk ("%s: i2c enable delay\n", __FUNCTION__); | 144 | } |
176 | msleep(33); | 145 | udelay(1000); |
146 | if (dst_gpio_outb(state, RDC_8820_RESET, RDC_8820_RESET, RDC_8820_RESET, DELAY) < 0) { | ||
147 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); | ||
148 | return -1; | ||
149 | } | ||
150 | |||
177 | return 0; | 151 | return 0; |
178 | } | 152 | } |
153 | EXPORT_SYMBOL(rdc_8820_reset); | ||
179 | 154 | ||
180 | static int dst_i2c_disable(struct dst_state *state) | 155 | int dst_pio_enable(struct dst_state *state) |
181 | { | 156 | { |
182 | int retval; | 157 | if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_ENABLE, 0, NO_DELAY) < 0) { |
183 | /* release I2C enable gpio pin, wait */ | 158 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); |
184 | // dprintk ("%s: i2c disable\n", __FUNCTION__); | 159 | return -1; |
185 | retval = dst_gpio_outb(state, ~0, 0, 0); | 160 | } |
186 | if (retval < 0) | 161 | udelay(1000); |
187 | return retval; | 162 | return 0; |
188 | // dprintk ("%s: i2c disable delay\n", __FUNCTION__); | 163 | } |
189 | msleep(33); | 164 | EXPORT_SYMBOL(dst_pio_enable); |
165 | |||
166 | int dst_pio_disable(struct dst_state *state) | ||
167 | { | ||
168 | if (dst_gpio_outb(state, ~0, RDC_8820_PIO_0_DISABLE, RDC_8820_PIO_0_DISABLE, NO_DELAY) < 0) { | ||
169 | dprintk("%s: dst_gpio_outb ERROR !\n", __FUNCTION__); | ||
170 | return -1; | ||
171 | } | ||
172 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
173 | udelay(1000); | ||
174 | |||
190 | return 0; | 175 | return 0; |
191 | } | 176 | } |
177 | EXPORT_SYMBOL(dst_pio_disable); | ||
192 | 178 | ||
193 | static int dst_wait_dst_ready(struct dst_state *state) | 179 | int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode) |
194 | { | 180 | { |
195 | u8 reply; | 181 | u8 reply; |
196 | int retval; | ||
197 | int i; | 182 | int i; |
183 | |||
198 | for (i = 0; i < 200; i++) { | 184 | for (i = 0; i < 200; i++) { |
199 | retval = dst_gpio_inb(state, &reply); | 185 | if (dst_gpio_inb(state, &reply) < 0) { |
200 | if (retval < 0) | 186 | dprintk("%s: dst_gpio_inb ERROR !\n", __FUNCTION__); |
201 | return retval; | 187 | return -1; |
202 | if ((reply & DST_I2C_ENABLE) == 0) { | 188 | } |
203 | dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); | 189 | |
190 | if ((reply & RDC_8820_PIO_0_ENABLE) == 0) { | ||
191 | if (verbose > 4) | ||
192 | dprintk("%s: dst wait ready after %d\n", __FUNCTION__, i); | ||
204 | return 1; | 193 | return 1; |
205 | } | 194 | } |
206 | msleep(10); | 195 | msleep(10); |
207 | } | 196 | } |
208 | dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); | 197 | if (verbose > 1) |
198 | dprintk("%s: dst wait NOT ready after %d\n", __FUNCTION__, i); | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | EXPORT_SYMBOL(dst_wait_dst_ready); | ||
203 | |||
204 | int dst_error_recovery(struct dst_state *state) | ||
205 | { | ||
206 | dprintk("%s: Trying to return from previous errors...\n", __FUNCTION__); | ||
207 | dst_pio_disable(state); | ||
208 | msleep(10); | ||
209 | dst_pio_enable(state); | ||
210 | msleep(10); | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | EXPORT_SYMBOL(dst_error_recovery); | ||
215 | |||
216 | int dst_error_bailout(struct dst_state *state) | ||
217 | { | ||
218 | dprintk("%s: Trying to bailout from previous error...\n", __FUNCTION__); | ||
219 | rdc_8820_reset(state); | ||
220 | dst_pio_disable(state); | ||
221 | msleep(10); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | EXPORT_SYMBOL(dst_error_bailout); | ||
226 | |||
227 | |||
228 | int dst_comm_init(struct dst_state* state) | ||
229 | { | ||
230 | if (verbose > 1) | ||
231 | dprintk ("%s: Initializing DST..\n", __FUNCTION__); | ||
232 | if ((dst_pio_enable(state)) < 0) { | ||
233 | dprintk("%s: PIO Enable Failed.\n", __FUNCTION__); | ||
234 | return -1; | ||
235 | } | ||
236 | if ((rdc_reset_state(state)) < 0) { | ||
237 | dprintk("%s: RDC 8820 State RESET Failed.\n", __FUNCTION__); | ||
238 | return -1; | ||
239 | } | ||
240 | if (state->type_flags & DST_TYPE_HAS_FW_1) | ||
241 | msleep(100); | ||
242 | else | ||
243 | msleep(5); | ||
244 | |||
209 | return 0; | 245 | return 0; |
210 | } | 246 | } |
247 | EXPORT_SYMBOL(dst_comm_init); | ||
211 | 248 | ||
212 | static int write_dst(struct dst_state *state, u8 * data, u8 len) | 249 | |
250 | int write_dst(struct dst_state *state, u8 *data, u8 len) | ||
213 | { | 251 | { |
214 | struct i2c_msg msg = { | 252 | struct i2c_msg msg = { |
215 | .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len | 253 | .addr = state->config->demod_address,.flags = 0,.buf = data,.len = len |
216 | }; | 254 | }; |
255 | |||
217 | int err; | 256 | int err; |
218 | int cnt; | 257 | int cnt; |
219 | 258 | if (debug && (verbose > 4)) { | |
220 | if (dst_debug && dst_verbose) { | ||
221 | u8 i; | 259 | u8 i; |
222 | dprintk("%s writing", __FUNCTION__); | 260 | if (verbose > 4) { |
223 | for (i = 0; i < len; i++) { | 261 | dprintk("%s writing", __FUNCTION__); |
224 | dprintk(" 0x%02x", data[i]); | 262 | for (i = 0; i < len; i++) |
263 | dprintk(" %02x", data[i]); | ||
264 | dprintk("\n"); | ||
225 | } | 265 | } |
226 | dprintk("\n"); | ||
227 | } | 266 | } |
228 | msleep(30); | 267 | for (cnt = 0; cnt < 2; cnt++) { |
229 | for (cnt = 0; cnt < 4; cnt++) { | ||
230 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { | 268 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { |
231 | dprintk("%s: write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); | 269 | dprintk("%s: _write_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, data[0]); |
232 | dst_i2c_disable(state); | 270 | dst_error_recovery(state); |
233 | msleep(500); | ||
234 | dst_i2c_enable(state); | ||
235 | msleep(500); | ||
236 | continue; | 271 | continue; |
237 | } else | 272 | } else |
238 | break; | 273 | break; |
239 | } | 274 | } |
240 | if (cnt >= 4) | 275 | |
241 | return -EREMOTEIO; | 276 | if (cnt >= 2) { |
277 | if (verbose > 1) | ||
278 | printk("%s: RDC 8820 RESET...\n", __FUNCTION__); | ||
279 | dst_error_bailout(state); | ||
280 | |||
281 | return -1; | ||
282 | } | ||
283 | |||
242 | return 0; | 284 | return 0; |
243 | } | 285 | } |
286 | EXPORT_SYMBOL(write_dst); | ||
244 | 287 | ||
245 | static int read_dst(struct dst_state *state, u8 * ret, u8 len) | 288 | int read_dst(struct dst_state *state, u8 * ret, u8 len) |
246 | { | 289 | { |
247 | struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; | 290 | struct i2c_msg msg = {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = ret,.len = len }; |
248 | int err; | 291 | int err; |
249 | int cnt; | 292 | int cnt; |
250 | 293 | ||
251 | for (cnt = 0; cnt < 4; cnt++) { | 294 | for (cnt = 0; cnt < 2; cnt++) { |
252 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { | 295 | if ((err = i2c_transfer(state->i2c, &msg, 1)) < 0) { |
296 | |||
253 | dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); | 297 | dprintk("%s: read_dst error (err == %i, len == 0x%02x, b0 == 0x%02x)\n", __FUNCTION__, err, len, ret[0]); |
254 | dst_i2c_disable(state); | 298 | dst_error_recovery(state); |
255 | dst_i2c_enable(state); | 299 | |
256 | continue; | 300 | continue; |
257 | } else | 301 | } else |
258 | break; | 302 | break; |
259 | } | 303 | } |
260 | if (cnt >= 4) | 304 | if (cnt >= 2) { |
261 | return -EREMOTEIO; | 305 | if (verbose > 1) |
262 | dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); | 306 | printk("%s: RDC 8820 RESET...\n", __FUNCTION__); |
263 | if (dst_debug && dst_verbose) { | 307 | dst_error_bailout(state); |
308 | |||
309 | return -1; | ||
310 | } | ||
311 | if (debug && (verbose > 4)) { | ||
312 | dprintk("%s reply is 0x%x\n", __FUNCTION__, ret[0]); | ||
264 | for (err = 1; err < len; err++) | 313 | for (err = 1; err < len; err++) |
265 | dprintk(" 0x%x", ret[err]); | 314 | dprintk(" 0x%x", ret[err]); |
266 | if (err > 1) | 315 | if (err > 1) |
267 | dprintk("\n"); | 316 | dprintk("\n"); |
268 | } | 317 | } |
318 | |||
269 | return 0; | 319 | return 0; |
270 | } | 320 | } |
321 | EXPORT_SYMBOL(read_dst); | ||
271 | 322 | ||
272 | static int dst_set_freq(struct dst_state *state, u32 freq) | 323 | static int dst_set_freq(struct dst_state *state, u32 freq) |
273 | { | 324 | { |
274 | u8 *val; | 325 | u8 *val; |
275 | 326 | ||
276 | state->frequency = freq; | 327 | state->frequency = freq; |
328 | if (debug > 4) | ||
329 | dprintk("%s: set Frequency %u\n", __FUNCTION__, freq); | ||
277 | 330 | ||
278 | // dprintk("%s: set frequency %u\n", __FUNCTION__, freq); | ||
279 | if (state->dst_type == DST_TYPE_IS_SAT) { | 331 | if (state->dst_type == DST_TYPE_IS_SAT) { |
280 | freq = freq / 1000; | 332 | freq = freq / 1000; |
281 | if (freq < 950 || freq > 2150) | 333 | if (freq < 950 || freq > 2150) |
@@ -398,7 +450,8 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate) | |||
398 | if (state->dst_type == DST_TYPE_IS_TERR) { | 450 | if (state->dst_type == DST_TYPE_IS_TERR) { |
399 | return 0; | 451 | return 0; |
400 | } | 452 | } |
401 | // dprintk("%s: set srate %u\n", __FUNCTION__, srate); | 453 | if (debug > 4) |
454 | dprintk("%s: set symrate %u\n", __FUNCTION__, srate); | ||
402 | srate /= 1000; | 455 | srate /= 1000; |
403 | val = &state->tx_tuna[0]; | 456 | val = &state->tx_tuna[0]; |
404 | 457 | ||
@@ -407,7 +460,10 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate) | |||
407 | sval <<= 20; | 460 | sval <<= 20; |
408 | do_div(sval, 88000); | 461 | do_div(sval, 88000); |
409 | symcalc = (u32) sval; | 462 | symcalc = (u32) sval; |
410 | // dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc); | 463 | |
464 | if (debug > 4) | ||
465 | dprintk("%s: set symcalc %u\n", __FUNCTION__, symcalc); | ||
466 | |||
411 | val[5] = (u8) (symcalc >> 12); | 467 | val[5] = (u8) (symcalc >> 12); |
412 | val[6] = (u8) (symcalc >> 4); | 468 | val[6] = (u8) (symcalc >> 4); |
413 | val[7] = (u8) (symcalc << 4); | 469 | val[7] = (u8) (symcalc << 4); |
@@ -422,7 +478,7 @@ static int dst_set_symbolrate(struct dst_state* state, u32 srate) | |||
422 | return 0; | 478 | return 0; |
423 | } | 479 | } |
424 | 480 | ||
425 | static u8 dst_check_sum(u8 * buf, u32 len) | 481 | u8 dst_check_sum(u8 * buf, u32 len) |
426 | { | 482 | { |
427 | u32 i; | 483 | u32 i; |
428 | u8 val = 0; | 484 | u8 val = 0; |
@@ -433,28 +489,7 @@ static u8 dst_check_sum(u8 * buf, u32 len) | |||
433 | } | 489 | } |
434 | return ((~val) + 1); | 490 | return ((~val) + 1); |
435 | } | 491 | } |
436 | 492 | EXPORT_SYMBOL(dst_check_sum); | |
437 | struct dst_types { | ||
438 | char *mstr; | ||
439 | int offs; | ||
440 | u8 dst_type; | ||
441 | u32 type_flags; | ||
442 | }; | ||
443 | |||
444 | static struct dst_types dst_tlist[] = { | ||
445 | {"DST-020", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV}, | ||
446 | {"DST-030", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE}, | ||
447 | {"DST-03T", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204}, | ||
448 | {"DST-MOT", 0, DST_TYPE_IS_SAT, DST_TYPE_HAS_SYMDIV}, | ||
449 | {"DST-CI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE}, | ||
450 | {"DSTMCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE}, | ||
451 | {"DSTFCI", 1, DST_TYPE_IS_SAT, DST_TYPE_HAS_NEWTUNE}, | ||
452 | {"DCTNEW", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE}, | ||
453 | {"DCT-CI", 1, DST_TYPE_IS_CABLE, DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_TS204}, | ||
454 | {"DTTDIG", 1, DST_TYPE_IS_TERR, 0} | ||
455 | }; | ||
456 | |||
457 | /* DCTNEW and DCT-CI are guesses */ | ||
458 | 493 | ||
459 | static void dst_type_flags_print(u32 type_flags) | 494 | static void dst_type_flags_print(u32 type_flags) |
460 | { | 495 | { |
@@ -465,93 +500,270 @@ static void dst_type_flags_print(u32 type_flags) | |||
465 | printk(" 0x%x ts204", DST_TYPE_HAS_TS204); | 500 | printk(" 0x%x ts204", DST_TYPE_HAS_TS204); |
466 | if (type_flags & DST_TYPE_HAS_SYMDIV) | 501 | if (type_flags & DST_TYPE_HAS_SYMDIV) |
467 | printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); | 502 | printk(" 0x%x symdiv", DST_TYPE_HAS_SYMDIV); |
503 | if (type_flags & DST_TYPE_HAS_FW_1) | ||
504 | printk(" 0x%x firmware version = 1", DST_TYPE_HAS_FW_1); | ||
505 | if (type_flags & DST_TYPE_HAS_FW_2) | ||
506 | printk(" 0x%x firmware version = 2", DST_TYPE_HAS_FW_2); | ||
507 | if (type_flags & DST_TYPE_HAS_FW_3) | ||
508 | printk(" 0x%x firmware version = 3", DST_TYPE_HAS_FW_3); | ||
509 | // if ((type_flags & DST_TYPE_HAS_FW_BUILD) && new_fw) | ||
510 | |||
468 | printk("\n"); | 511 | printk("\n"); |
469 | } | 512 | } |
470 | 513 | ||
471 | static int dst_type_print(u8 type) | 514 | |
515 | static int dst_type_print (u8 type) | ||
472 | { | 516 | { |
473 | char *otype; | 517 | char *otype; |
474 | switch (type) { | 518 | switch (type) { |
475 | case DST_TYPE_IS_SAT: | 519 | case DST_TYPE_IS_SAT: |
476 | otype = "satellite"; | 520 | otype = "satellite"; |
477 | break; | 521 | break; |
522 | |||
478 | case DST_TYPE_IS_TERR: | 523 | case DST_TYPE_IS_TERR: |
479 | otype = "terrestrial"; | 524 | otype = "terrestrial"; |
480 | break; | 525 | break; |
526 | |||
481 | case DST_TYPE_IS_CABLE: | 527 | case DST_TYPE_IS_CABLE: |
482 | otype = "cable"; | 528 | otype = "cable"; |
483 | break; | 529 | break; |
530 | |||
484 | default: | 531 | default: |
485 | printk("%s: invalid dst type %d\n", __FUNCTION__, type); | 532 | printk("%s: invalid dst type %d\n", __FUNCTION__, type); |
486 | return -EINVAL; | 533 | return -EINVAL; |
487 | } | 534 | } |
488 | printk("DST type : %s\n", otype); | 535 | printk("DST type : %s\n", otype); |
536 | |||
489 | return 0; | 537 | return 0; |
490 | } | 538 | } |
491 | 539 | ||
492 | static int dst_check_ci(struct dst_state *state) | 540 | /* |
541 | Known cards list | ||
542 | Satellite | ||
543 | ------------------- | ||
544 | 200103A | ||
545 | VP-1020 DST-MOT LG(old), TS=188 | ||
546 | |||
547 | VP-1020 DST-03T LG(new), TS=204 | ||
548 | VP-1022 DST-03T LG(new), TS=204 | ||
549 | VP-1025 DST-03T LG(new), TS=204 | ||
550 | |||
551 | VP-1030 DSTMCI, LG(new), TS=188 | ||
552 | VP-1032 DSTMCI, LG(new), TS=188 | ||
553 | |||
554 | Cable | ||
555 | ------------------- | ||
556 | VP-2030 DCT-CI, Samsung, TS=204 | ||
557 | VP-2021 DCT-CI, Unknown, TS=204 | ||
558 | VP-2031 DCT-CI, Philips, TS=188 | ||
559 | VP-2040 DCT-CI, Philips, TS=188, with CA daughter board | ||
560 | VP-2040 DCT-CI, Philips, TS=204, without CA daughter board | ||
561 | |||
562 | Terrestrial | ||
563 | ------------------- | ||
564 | VP-3050 DTTNXT TS=188 | ||
565 | VP-3040 DTT-CI, Philips, TS=188 | ||
566 | VP-3040 DTT-CI, Philips, TS=204 | ||
567 | |||
568 | ATSC | ||
569 | ------------------- | ||
570 | VP-3220 ATSCDI, TS=188 | ||
571 | VP-3250 ATSCAD, TS=188 | ||
572 | |||
573 | */ | ||
574 | |||
575 | struct dst_types dst_tlist[] = { | ||
576 | { | ||
577 | .device_id = "200103A", | ||
578 | .offset = 0, | ||
579 | .dst_type = DST_TYPE_IS_SAT, | ||
580 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | ||
581 | .dst_feature = 0 | ||
582 | }, /* obsolete */ | ||
583 | |||
584 | { | ||
585 | .device_id = "DST-020", | ||
586 | .offset = 0, | ||
587 | .dst_type = DST_TYPE_IS_SAT, | ||
588 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | ||
589 | .dst_feature = 0 | ||
590 | }, /* obsolete */ | ||
591 | |||
592 | { | ||
593 | .device_id = "DST-030", | ||
594 | .offset = 0, | ||
595 | .dst_type = DST_TYPE_IS_SAT, | ||
596 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | ||
597 | .dst_feature = 0 | ||
598 | }, /* obsolete */ | ||
599 | |||
600 | { | ||
601 | .device_id = "DST-03T", | ||
602 | .offset = 0, | ||
603 | .dst_type = DST_TYPE_IS_SAT, | ||
604 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2, | ||
605 | .dst_feature = DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | DST_TYPE_HAS_DISEQC5 | ||
606 | | DST_TYPE_HAS_MAC | DST_TYPE_HAS_MOTO | ||
607 | }, | ||
608 | |||
609 | { | ||
610 | .device_id = "DST-MOT", | ||
611 | .offset = 0, | ||
612 | .dst_type = DST_TYPE_IS_SAT, | ||
613 | .type_flags = DST_TYPE_HAS_SYMDIV | DST_TYPE_HAS_FW_1, | ||
614 | .dst_feature = 0 | ||
615 | }, /* obsolete */ | ||
616 | |||
617 | { | ||
618 | .device_id = "DST-CI", | ||
619 | .offset = 1, | ||
620 | .dst_type = DST_TYPE_IS_SAT, | ||
621 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | ||
622 | .dst_feature = DST_TYPE_HAS_CA | ||
623 | }, /* An OEM board */ | ||
624 | |||
625 | { | ||
626 | .device_id = "DSTMCI", | ||
627 | .offset = 1, | ||
628 | .dst_type = DST_TYPE_IS_SAT, | ||
629 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, | ||
630 | .dst_feature = DST_TYPE_HAS_CA | DST_TYPE_HAS_DISEQC3 | DST_TYPE_HAS_DISEQC4 | ||
631 | | DST_TYPE_HAS_MOTO | DST_TYPE_HAS_MAC | ||
632 | }, | ||
633 | |||
634 | { | ||
635 | .device_id = "DSTFCI", | ||
636 | .offset = 1, | ||
637 | .dst_type = DST_TYPE_IS_SAT, | ||
638 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1, | ||
639 | .dst_feature = 0 | ||
640 | }, /* unknown to vendor */ | ||
641 | |||
642 | { | ||
643 | .device_id = "DCT-CI", | ||
644 | .offset = 1, | ||
645 | .dst_type = DST_TYPE_IS_CABLE, | ||
646 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_1 | ||
647 | | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, | ||
648 | .dst_feature = DST_TYPE_HAS_CA | ||
649 | }, | ||
650 | |||
651 | { | ||
652 | .device_id = "DCTNEW", | ||
653 | .offset = 1, | ||
654 | .dst_type = DST_TYPE_IS_CABLE, | ||
655 | .type_flags = DST_TYPE_HAS_NEWTUNE | DST_TYPE_HAS_FW_3, | ||
656 | .dst_feature = 0 | ||
657 | }, | ||
658 | |||
659 | { | ||
660 | .device_id = "DTT-CI", | ||
661 | .offset = 1, | ||
662 | .dst_type = DST_TYPE_IS_TERR, | ||
663 | .type_flags = DST_TYPE_HAS_TS204 | DST_TYPE_HAS_FW_2 | DST_TYPE_HAS_FW_BUILD, | ||
664 | .dst_feature = 0 | ||
665 | }, | ||
666 | |||
667 | { | ||
668 | .device_id = "DTTDIG", | ||
669 | .offset = 1, | ||
670 | .dst_type = DST_TYPE_IS_TERR, | ||
671 | .type_flags = DST_TYPE_HAS_FW_2, | ||
672 | .dst_feature = 0 | ||
673 | }, | ||
674 | |||
675 | { | ||
676 | .device_id = "DTTNXT", | ||
677 | .offset = 1, | ||
678 | .dst_type = DST_TYPE_IS_TERR, | ||
679 | .type_flags = DST_TYPE_HAS_FW_2, | ||
680 | .dst_feature = DST_TYPE_HAS_ANALOG | ||
681 | }, | ||
682 | |||
683 | { | ||
684 | .device_id = "ATSCDI", | ||
685 | .offset = 1, | ||
686 | .dst_type = DST_TYPE_IS_ATSC, | ||
687 | .type_flags = DST_TYPE_HAS_FW_2, | ||
688 | .dst_feature = 0 | ||
689 | }, | ||
690 | |||
691 | { | ||
692 | .device_id = "ATSCAD", | ||
693 | .offset = 1, | ||
694 | .dst_type = DST_TYPE_IS_ATSC, | ||
695 | .type_flags = DST_TYPE_HAS_FW_2, | ||
696 | .dst_feature = 0 | ||
697 | }, | ||
698 | |||
699 | { } | ||
700 | |||
701 | }; | ||
702 | |||
703 | |||
704 | static int dst_get_device_id(struct dst_state *state) | ||
493 | { | 705 | { |
494 | u8 txbuf[8]; | 706 | u8 reply; |
495 | u8 rxbuf[8]; | 707 | |
496 | int retval; | ||
497 | int i; | 708 | int i; |
498 | struct dst_types *dsp; | 709 | struct dst_types *p_dst_type; |
499 | u8 use_dst_type; | 710 | u8 use_dst_type = 0; |
500 | u32 use_type_flags; | 711 | u32 use_type_flags = 0; |
501 | 712 | ||
502 | memset(txbuf, 0, sizeof(txbuf)); | 713 | static u8 device_type[8] = {0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; |
503 | txbuf[1] = 6; | ||
504 | txbuf[7] = dst_check_sum(txbuf, 7); | ||
505 | 714 | ||
506 | dst_i2c_enable(state); | 715 | device_type[7] = dst_check_sum(device_type, 7); |
507 | dst_reset8820(state); | 716 | |
508 | retval = write_dst(state, txbuf, 8); | 717 | if (write_dst(state, device_type, FIXED_COMM)) |
509 | if (retval < 0) { | 718 | return -1; /* Write failed */ |
510 | dst_i2c_disable(state); | 719 | |
511 | dprintk("%s: write not successful, maybe no card?\n", __FUNCTION__); | 720 | if ((dst_pio_disable(state)) < 0) |
512 | return retval; | 721 | return -1; |
513 | } | 722 | |
514 | msleep(3); | 723 | if (read_dst(state, &reply, GET_ACK)) |
515 | retval = read_dst(state, rxbuf, 1); | 724 | return -1; /* Read failure */ |
516 | dst_i2c_disable(state); | 725 | |
517 | if (retval < 0) { | 726 | if (reply != ACK) { |
518 | dprintk("%s: read not successful, maybe no card?\n", __FUNCTION__); | 727 | dprintk("%s: Write not Acknowledged! [Reply=0x%02x]\n", __FUNCTION__, reply); |
519 | return retval; | 728 | return -1; /* Unack'd write */ |
520 | } | ||
521 | if (rxbuf[0] != 0xff) { | ||
522 | dprintk("%s: write reply not 0xff, not ci (%02x)\n", __FUNCTION__, rxbuf[0]); | ||
523 | return retval; | ||
524 | } | ||
525 | if (!dst_wait_dst_ready(state)) | ||
526 | return 0; | ||
527 | // dst_i2c_enable(i2c); Dimitri | ||
528 | retval = read_dst(state, rxbuf, 8); | ||
529 | dst_i2c_disable(state); | ||
530 | if (retval < 0) { | ||
531 | dprintk("%s: read not successful\n", __FUNCTION__); | ||
532 | return retval; | ||
533 | } | 729 | } |
534 | if (rxbuf[7] != dst_check_sum(rxbuf, 7)) { | 730 | |
535 | dprintk("%s: checksum failure\n", __FUNCTION__); | 731 | if (!dst_wait_dst_ready(state, DEVICE_INIT)) |
536 | return retval; | 732 | return -1; /* DST not ready yet */ |
733 | |||
734 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) | ||
735 | return -1; | ||
736 | |||
737 | dst_pio_disable(state); | ||
738 | |||
739 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | ||
740 | dprintk("%s: Checksum failure! \n", __FUNCTION__); | ||
741 | return -1; /* Checksum failure */ | ||
537 | } | 742 | } |
538 | rxbuf[7] = '\0'; | 743 | |
539 | for (i = 0, dsp = &dst_tlist[0]; i < sizeof(dst_tlist) / sizeof(dst_tlist[0]); i++, dsp++) { | 744 | state->rxbuffer[7] = '\0'; |
540 | if (!strncmp(&rxbuf[dsp->offs], dsp->mstr, strlen(dsp->mstr))) { | 745 | |
541 | use_type_flags = dsp->type_flags; | 746 | for (i = 0, p_dst_type = dst_tlist; i < ARRAY_SIZE (dst_tlist); i++, p_dst_type++) { |
542 | use_dst_type = dsp->dst_type; | 747 | if (!strncmp (&state->rxbuffer[p_dst_type->offset], p_dst_type->device_id, strlen (p_dst_type->device_id))) { |
543 | printk("%s: recognize %s\n", __FUNCTION__, dsp->mstr); | 748 | use_type_flags = p_dst_type->type_flags; |
749 | use_dst_type = p_dst_type->dst_type; | ||
750 | |||
751 | /* Card capabilities */ | ||
752 | state->dst_hw_cap = p_dst_type->dst_feature; | ||
753 | printk ("%s: Recognise [%s]\n", __FUNCTION__, p_dst_type->device_id); | ||
754 | |||
544 | break; | 755 | break; |
545 | } | 756 | } |
546 | } | 757 | } |
547 | if (i >= sizeof(dst_tlist) / sizeof(dst_tlist[0])) { | 758 | |
548 | printk("%s: unable to recognize %s or %s\n", __FUNCTION__, &rxbuf[0], &rxbuf[1]); | 759 | if (i >= sizeof (dst_tlist) / sizeof (dst_tlist [0])) { |
549 | printk("%s please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); | 760 | printk("%s: Unable to recognize %s or %s\n", __FUNCTION__, &state->rxbuffer[0], &state->rxbuffer[1]); |
761 | printk("%s: please email linux-dvb@linuxtv.org with this type in\n", __FUNCTION__); | ||
550 | use_dst_type = DST_TYPE_IS_SAT; | 762 | use_dst_type = DST_TYPE_IS_SAT; |
551 | use_type_flags = DST_TYPE_HAS_SYMDIV; | 763 | use_type_flags = DST_TYPE_HAS_SYMDIV; |
552 | } | 764 | } |
553 | dst_type_print(use_dst_type); | ||
554 | 765 | ||
766 | dst_type_print(use_dst_type); | ||
555 | state->type_flags = use_type_flags; | 767 | state->type_flags = use_type_flags; |
556 | state->dst_type = use_dst_type; | 768 | state->dst_type = use_dst_type; |
557 | dst_type_flags_print(state->type_flags); | 769 | dst_type_flags_print(state->type_flags); |
@@ -559,50 +771,102 @@ static int dst_check_ci(struct dst_state *state) | |||
559 | if (state->type_flags & DST_TYPE_HAS_TS204) { | 771 | if (state->type_flags & DST_TYPE_HAS_TS204) { |
560 | dst_packsize(state, 204); | 772 | dst_packsize(state, 204); |
561 | } | 773 | } |
774 | |||
562 | return 0; | 775 | return 0; |
563 | } | 776 | } |
564 | 777 | ||
565 | static int dst_command(struct dst_state* state, u8 * data, u8 len) | 778 | static int dst_probe(struct dst_state *state) |
779 | { | ||
780 | if ((rdc_8820_reset(state)) < 0) { | ||
781 | dprintk("%s: RDC 8820 RESET Failed.\n", __FUNCTION__); | ||
782 | return -1; | ||
783 | } | ||
784 | if (dst_addons & DST_TYPE_HAS_CA) | ||
785 | msleep(4000); | ||
786 | else | ||
787 | msleep(100); | ||
788 | |||
789 | if ((dst_comm_init(state)) < 0) { | ||
790 | dprintk("%s: DST Initialization Failed.\n", __FUNCTION__); | ||
791 | return -1; | ||
792 | } | ||
793 | msleep(100); | ||
794 | if (dst_get_device_id(state) < 0) { | ||
795 | dprintk("%s: unknown device.\n", __FUNCTION__); | ||
796 | return -1; | ||
797 | } | ||
798 | |||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | int dst_command(struct dst_state* state, u8 * data, u8 len) | ||
566 | { | 803 | { |
567 | int retval; | ||
568 | u8 reply; | 804 | u8 reply; |
805 | if ((dst_comm_init(state)) < 0) { | ||
806 | dprintk("%s: DST Communication Initialization Failed.\n", __FUNCTION__); | ||
807 | return -1; | ||
808 | } | ||
569 | 809 | ||
570 | dst_i2c_enable(state); | 810 | if (write_dst(state, data, len)) { |
571 | dst_reset8820(state); | 811 | if (verbose > 1) |
572 | retval = write_dst(state, data, len); | 812 | dprintk("%s: Tring to recover.. \n", __FUNCTION__); |
573 | if (retval < 0) { | 813 | if ((dst_error_recovery(state)) < 0) { |
574 | dst_i2c_disable(state); | 814 | dprintk("%s: Recovery Failed.\n", __FUNCTION__); |
575 | dprintk("%s: write not successful\n", __FUNCTION__); | 815 | return -1; |
576 | return retval; | 816 | } |
817 | return -1; | ||
577 | } | 818 | } |
578 | msleep(33); | 819 | if ((dst_pio_disable(state)) < 0) { |
579 | retval = read_dst(state, &reply, 1); | 820 | dprintk("%s: PIO Disable Failed.\n", __FUNCTION__); |
580 | dst_i2c_disable(state); | 821 | return -1; |
581 | if (retval < 0) { | ||
582 | dprintk("%s: read verify not successful\n", __FUNCTION__); | ||
583 | return retval; | ||
584 | } | 822 | } |
585 | if (reply != 0xff) { | 823 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
586 | dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); | 824 | udelay(3000); |
587 | return 0; | 825 | |
826 | if (read_dst(state, &reply, GET_ACK)) { | ||
827 | if (verbose > 1) | ||
828 | dprintk("%s: Trying to recover.. \n", __FUNCTION__); | ||
829 | if ((dst_error_recovery(state)) < 0) { | ||
830 | dprintk("%s: Recovery Failed.\n", __FUNCTION__); | ||
831 | return -1; | ||
832 | } | ||
833 | return -1; | ||
834 | } | ||
835 | |||
836 | if (reply != ACK) { | ||
837 | dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); | ||
838 | return -1; | ||
588 | } | 839 | } |
589 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) | 840 | if (len >= 2 && data[0] == 0 && (data[1] == 1 || data[1] == 3)) |
590 | return 0; | 841 | return 0; |
591 | if (!dst_wait_dst_ready(state)) | 842 | |
592 | return 0; | 843 | // udelay(3000); |
593 | // dst_i2c_enable(i2c); Per dimitri | 844 | if (state->type_flags & DST_TYPE_HAS_FW_1) |
594 | retval = read_dst(state, state->rxbuffer, 8); | 845 | udelay(3000); |
595 | dst_i2c_disable(state); | 846 | else |
596 | if (retval < 0) { | 847 | udelay(2000); |
597 | dprintk("%s: read not successful\n", __FUNCTION__); | 848 | |
598 | return 0; | 849 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
850 | return -1; | ||
851 | |||
852 | if (read_dst(state, state->rxbuffer, FIXED_COMM)) { | ||
853 | if (verbose > 1) | ||
854 | dprintk("%s: Trying to recover.. \n", __FUNCTION__); | ||
855 | if ((dst_error_recovery(state)) < 0) { | ||
856 | dprintk("%s: Recovery failed.\n", __FUNCTION__); | ||
857 | return -1; | ||
858 | } | ||
859 | return -1; | ||
599 | } | 860 | } |
861 | |||
600 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { | 862 | if (state->rxbuffer[7] != dst_check_sum(state->rxbuffer, 7)) { |
601 | dprintk("%s: checksum failure\n", __FUNCTION__); | 863 | dprintk("%s: checksum failure\n", __FUNCTION__); |
602 | return 0; | 864 | return -1; |
603 | } | 865 | } |
866 | |||
604 | return 0; | 867 | return 0; |
605 | } | 868 | } |
869 | EXPORT_SYMBOL(dst_command); | ||
606 | 870 | ||
607 | static int dst_get_signal(struct dst_state* state) | 871 | static int dst_get_signal(struct dst_state* state) |
608 | { | 872 | { |
@@ -646,11 +910,17 @@ static int dst_tone_power_cmd(struct dst_state* state) | |||
646 | paket[4] = 0; | 910 | paket[4] = 0; |
647 | else | 911 | else |
648 | paket[4] = 1; | 912 | paket[4] = 1; |
913 | |||
649 | if (state->tone == SEC_TONE_ON) | 914 | if (state->tone == SEC_TONE_ON) |
650 | paket[2] = state->k22; | 915 | paket[2] = 0x02; |
651 | else | 916 | else |
652 | paket[2] = 0; | 917 | paket[2] = 0; |
653 | paket[7] = dst_check_sum(&paket[0], 7); | 918 | if (state->minicmd == SEC_MINI_A) |
919 | paket[3] = 0x02; | ||
920 | else | ||
921 | paket[3] = 0; | ||
922 | |||
923 | paket[7] = dst_check_sum (paket, 7); | ||
654 | dst_command(state, paket, 8); | 924 | dst_command(state, paket, 8); |
655 | return 0; | 925 | return 0; |
656 | } | 926 | } |
@@ -658,21 +928,26 @@ static int dst_tone_power_cmd(struct dst_state* state) | |||
658 | static int dst_get_tuna(struct dst_state* state) | 928 | static int dst_get_tuna(struct dst_state* state) |
659 | { | 929 | { |
660 | int retval; | 930 | int retval; |
931 | |||
661 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) | 932 | if ((state->diseq_flags & ATTEMPT_TUNE) == 0) |
662 | return 0; | 933 | return 0; |
934 | |||
663 | state->diseq_flags &= ~(HAS_LOCK); | 935 | state->diseq_flags &= ~(HAS_LOCK); |
664 | if (!dst_wait_dst_ready(state)) | 936 | if (!dst_wait_dst_ready(state, NO_DELAY)) |
665 | return 0; | 937 | return 0; |
938 | |||
666 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 939 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
667 | /* how to get variable length reply ???? */ | 940 | /* how to get variable length reply ???? */ |
668 | retval = read_dst(state, state->rx_tuna, 10); | 941 | retval = read_dst(state, state->rx_tuna, 10); |
669 | } else { | 942 | } else { |
670 | retval = read_dst(state, &state->rx_tuna[2], 8); | 943 | retval = read_dst(state, &state->rx_tuna[2], FIXED_COMM); |
671 | } | 944 | } |
945 | |||
672 | if (retval < 0) { | 946 | if (retval < 0) { |
673 | dprintk("%s: read not successful\n", __FUNCTION__); | 947 | dprintk("%s: read not successful\n", __FUNCTION__); |
674 | return 0; | 948 | return 0; |
675 | } | 949 | } |
950 | |||
676 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 951 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
677 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { | 952 | if (state->rx_tuna[9] != dst_check_sum(&state->rx_tuna[0], 9)) { |
678 | dprintk("%s: checksum failure?\n", __FUNCTION__); | 953 | dprintk("%s: checksum failure?\n", __FUNCTION__); |
@@ -709,7 +984,9 @@ static int dst_write_tuna(struct dvb_frontend* fe) | |||
709 | int retval; | 984 | int retval; |
710 | u8 reply; | 985 | u8 reply; |
711 | 986 | ||
712 | dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags); | 987 | if (debug > 4) |
988 | dprintk("%s: type_flags 0x%x \n", __FUNCTION__, state->type_flags); | ||
989 | |||
713 | state->decode_freq = 0; | 990 | state->decode_freq = 0; |
714 | state->decode_lock = state->decode_strength = state->decode_snr = 0; | 991 | state->decode_lock = state->decode_strength = state->decode_snr = 0; |
715 | if (state->dst_type == DST_TYPE_IS_SAT) { | 992 | if (state->dst_type == DST_TYPE_IS_SAT) { |
@@ -717,32 +994,41 @@ static int dst_write_tuna(struct dvb_frontend* fe) | |||
717 | dst_set_voltage(fe, SEC_VOLTAGE_13); | 994 | dst_set_voltage(fe, SEC_VOLTAGE_13); |
718 | } | 995 | } |
719 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); | 996 | state->diseq_flags &= ~(HAS_LOCK | ATTEMPT_TUNE); |
720 | dst_i2c_enable(state); | 997 | |
998 | if ((dst_comm_init(state)) < 0) { | ||
999 | dprintk("%s: DST Communication initialization failed.\n", __FUNCTION__); | ||
1000 | return -1; | ||
1001 | } | ||
1002 | |||
721 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { | 1003 | if (state->type_flags & DST_TYPE_HAS_NEWTUNE) { |
722 | dst_reset8820(state); | ||
723 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); | 1004 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[0], 9); |
724 | retval = write_dst(state, &state->tx_tuna[0], 10); | 1005 | retval = write_dst(state, &state->tx_tuna[0], 10); |
1006 | |||
725 | } else { | 1007 | } else { |
726 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); | 1008 | state->tx_tuna[9] = dst_check_sum(&state->tx_tuna[2], 7); |
727 | retval = write_dst(state, &state->tx_tuna[2], 8); | 1009 | retval = write_dst(state, &state->tx_tuna[2], FIXED_COMM); |
728 | } | 1010 | } |
729 | if (retval < 0) { | 1011 | if (retval < 0) { |
730 | dst_i2c_disable(state); | 1012 | dst_pio_disable(state); |
731 | dprintk("%s: write not successful\n", __FUNCTION__); | 1013 | dprintk("%s: write not successful\n", __FUNCTION__); |
732 | return retval; | 1014 | return retval; |
733 | } | 1015 | } |
734 | msleep(3); | 1016 | |
735 | retval = read_dst(state, &reply, 1); | 1017 | if ((dst_pio_disable(state)) < 0) { |
736 | dst_i2c_disable(state); | 1018 | dprintk("%s: DST PIO disable failed !\n", __FUNCTION__); |
737 | if (retval < 0) { | 1019 | return -1; |
738 | dprintk("%s: read verify not successful\n", __FUNCTION__); | 1020 | } |
739 | return retval; | 1021 | |
1022 | if ((read_dst(state, &reply, GET_ACK) < 0)) { | ||
1023 | dprintk("%s: read verify not successful.\n", __FUNCTION__); | ||
1024 | return -1; | ||
740 | } | 1025 | } |
741 | if (reply != 0xff) { | 1026 | if (reply != ACK) { |
742 | dprintk("%s: write reply not 0xff 0x%02x \n", __FUNCTION__, reply); | 1027 | dprintk("%s: write not acknowledged 0x%02x \n", __FUNCTION__, reply); |
743 | return 0; | 1028 | return 0; |
744 | } | 1029 | } |
745 | state->diseq_flags |= ATTEMPT_TUNE; | 1030 | state->diseq_flags |= ATTEMPT_TUNE; |
1031 | |||
746 | return dst_get_tuna(state); | 1032 | return dst_get_tuna(state); |
747 | } | 1033 | } |
748 | 1034 | ||
@@ -796,22 +1082,25 @@ static int dst_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | |||
796 | need_cmd = 1; | 1082 | need_cmd = 1; |
797 | state->diseq_flags |= HAS_POWER; | 1083 | state->diseq_flags |= HAS_POWER; |
798 | break; | 1084 | break; |
1085 | |||
799 | case SEC_VOLTAGE_18: | 1086 | case SEC_VOLTAGE_18: |
800 | if ((state->diseq_flags & HAS_POWER) == 0) | 1087 | if ((state->diseq_flags & HAS_POWER) == 0) |
801 | need_cmd = 1; | 1088 | need_cmd = 1; |
802 | state->diseq_flags |= HAS_POWER; | 1089 | state->diseq_flags |= HAS_POWER; |
803 | val[8] |= 0x40; | 1090 | val[8] |= 0x40; |
804 | break; | 1091 | break; |
1092 | |||
805 | case SEC_VOLTAGE_OFF: | 1093 | case SEC_VOLTAGE_OFF: |
806 | need_cmd = 1; | 1094 | need_cmd = 1; |
807 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); | 1095 | state->diseq_flags &= ~(HAS_POWER | HAS_LOCK | ATTEMPT_TUNE); |
808 | break; | 1096 | break; |
1097 | |||
809 | default: | 1098 | default: |
810 | return -EINVAL; | 1099 | return -EINVAL; |
811 | } | 1100 | } |
812 | if (need_cmd) { | 1101 | if (need_cmd) |
813 | dst_tone_power_cmd(state); | 1102 | dst_tone_power_cmd(state); |
814 | } | 1103 | |
815 | return 0; | 1104 | return 0; |
816 | } | 1105 | } |
817 | 1106 | ||
@@ -832,13 +1121,16 @@ static int dst_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
832 | switch (tone) { | 1121 | switch (tone) { |
833 | case SEC_TONE_OFF: | 1122 | case SEC_TONE_OFF: |
834 | break; | 1123 | break; |
1124 | |||
835 | case SEC_TONE_ON: | 1125 | case SEC_TONE_ON: |
836 | val[8] |= 1; | 1126 | val[8] |= 1; |
837 | break; | 1127 | break; |
1128 | |||
838 | default: | 1129 | default: |
839 | return -EINVAL; | 1130 | return -EINVAL; |
840 | } | 1131 | } |
841 | dst_tone_power_cmd(state); | 1132 | dst_tone_power_cmd(state); |
1133 | |||
842 | return 0; | 1134 | return 0; |
843 | } | 1135 | } |
844 | 1136 | ||
@@ -913,10 +1205,16 @@ static int dst_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
913 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; | 1205 | struct dst_state* state = (struct dst_state*) fe->demodulator_priv; |
914 | 1206 | ||
915 | dst_set_freq(state, p->frequency); | 1207 | dst_set_freq(state, p->frequency); |
1208 | if (verbose > 4) | ||
1209 | dprintk("Set Frequency = [%d]\n", p->frequency); | ||
1210 | |||
916 | dst_set_inversion(state, p->inversion); | 1211 | dst_set_inversion(state, p->inversion); |
917 | if (state->dst_type == DST_TYPE_IS_SAT) { | 1212 | if (state->dst_type == DST_TYPE_IS_SAT) { |
918 | dst_set_fec(state, p->u.qpsk.fec_inner); | 1213 | dst_set_fec(state, p->u.qpsk.fec_inner); |
919 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); | 1214 | dst_set_symbolrate(state, p->u.qpsk.symbol_rate); |
1215 | if (verbose > 4) | ||
1216 | dprintk("Set Symbolrate = [%d]\n", p->u.qpsk.symbol_rate); | ||
1217 | |||
920 | } else if (state->dst_type == DST_TYPE_IS_TERR) { | 1218 | } else if (state->dst_type == DST_TYPE_IS_TERR) { |
921 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); | 1219 | dst_set_bandwidth(state, p->u.ofdm.bandwidth); |
922 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { | 1220 | } else if (state->dst_type == DST_TYPE_IS_CABLE) { |
@@ -958,50 +1256,47 @@ static struct dvb_frontend_ops dst_dvbt_ops; | |||
958 | static struct dvb_frontend_ops dst_dvbs_ops; | 1256 | static struct dvb_frontend_ops dst_dvbs_ops; |
959 | static struct dvb_frontend_ops dst_dvbc_ops; | 1257 | static struct dvb_frontend_ops dst_dvbc_ops; |
960 | 1258 | ||
961 | struct dvb_frontend* dst_attach(const struct dst_config* config, | 1259 | struct dst_state* dst_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter) |
962 | struct i2c_adapter* i2c, | ||
963 | struct bt878 *bt) | ||
964 | { | 1260 | { |
965 | struct dst_state* state = NULL; | ||
966 | |||
967 | /* allocate memory for the internal state */ | ||
968 | state = (struct dst_state*) kmalloc(sizeof(struct dst_state), GFP_KERNEL); | ||
969 | if (state == NULL) goto error; | ||
970 | 1261 | ||
971 | /* setup the state */ | 1262 | /* check if the ASIC is there */ |
972 | state->config = config; | 1263 | if (dst_probe(state) < 0) { |
973 | state->i2c = i2c; | 1264 | if (state) |
974 | state->bt = bt; | 1265 | kfree(state); |
975 | |||
976 | /* check if the demod is there */ | ||
977 | if (dst_check_ci(state) < 0) goto error; | ||
978 | 1266 | ||
1267 | return NULL; | ||
1268 | } | ||
979 | /* determine settings based on type */ | 1269 | /* determine settings based on type */ |
980 | switch (state->dst_type) { | 1270 | switch (state->dst_type) { |
981 | case DST_TYPE_IS_TERR: | 1271 | case DST_TYPE_IS_TERR: |
982 | memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); | 1272 | memcpy(&state->ops, &dst_dvbt_ops, sizeof(struct dvb_frontend_ops)); |
983 | break; | 1273 | break; |
1274 | |||
984 | case DST_TYPE_IS_CABLE: | 1275 | case DST_TYPE_IS_CABLE: |
985 | memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); | 1276 | memcpy(&state->ops, &dst_dvbc_ops, sizeof(struct dvb_frontend_ops)); |
986 | break; | 1277 | break; |
1278 | |||
987 | case DST_TYPE_IS_SAT: | 1279 | case DST_TYPE_IS_SAT: |
988 | memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); | 1280 | memcpy(&state->ops, &dst_dvbs_ops, sizeof(struct dvb_frontend_ops)); |
989 | break; | 1281 | break; |
1282 | |||
990 | default: | 1283 | default: |
991 | printk("dst: unknown frontend type. please report to the LinuxTV.org DVB mailinglist.\n"); | 1284 | printk("%s: unknown DST type. please report to the LinuxTV.org DVB mailinglist.\n", __FUNCTION__); |
992 | goto error; | 1285 | if (state) |
1286 | kfree(state); | ||
1287 | |||
1288 | return NULL; | ||
993 | } | 1289 | } |
994 | 1290 | ||
995 | /* create dvb_frontend */ | 1291 | /* create dvb_frontend */ |
996 | state->frontend.ops = &state->ops; | 1292 | state->frontend.ops = &state->ops; |
997 | state->frontend.demodulator_priv = state; | 1293 | state->frontend.demodulator_priv = state; |
998 | return &state->frontend; | ||
999 | 1294 | ||
1000 | error: | 1295 | return state; /* Manu (DST is a card not a frontend) */ |
1001 | kfree(state); | ||
1002 | return NULL; | ||
1003 | } | 1296 | } |
1004 | 1297 | ||
1298 | EXPORT_SYMBOL(dst_attach); | ||
1299 | |||
1005 | static struct dvb_frontend_ops dst_dvbt_ops = { | 1300 | static struct dvb_frontend_ops dst_dvbt_ops = { |
1006 | 1301 | ||
1007 | .info = { | 1302 | .info = { |
@@ -1051,6 +1346,7 @@ static struct dvb_frontend_ops dst_dvbs_ops = { | |||
1051 | .read_signal_strength = dst_read_signal_strength, | 1346 | .read_signal_strength = dst_read_signal_strength, |
1052 | .read_snr = dst_read_snr, | 1347 | .read_snr = dst_read_snr, |
1053 | 1348 | ||
1349 | .diseqc_send_burst = dst_set_tone, | ||
1054 | .diseqc_send_master_cmd = dst_set_diseqc, | 1350 | .diseqc_send_master_cmd = dst_set_diseqc, |
1055 | .set_voltage = dst_set_voltage, | 1351 | .set_voltage = dst_set_voltage, |
1056 | .set_tone = dst_set_tone, | 1352 | .set_tone = dst_set_tone, |
@@ -1082,8 +1378,7 @@ static struct dvb_frontend_ops dst_dvbc_ops = { | |||
1082 | .read_snr = dst_read_snr, | 1378 | .read_snr = dst_read_snr, |
1083 | }; | 1379 | }; |
1084 | 1380 | ||
1381 | |||
1085 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); | 1382 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo Frontend driver"); |
1086 | MODULE_AUTHOR("Jamie Honan"); | 1383 | MODULE_AUTHOR("Jamie Honan, Manu Abraham"); |
1087 | MODULE_LICENSE("GPL"); | 1384 | MODULE_LICENSE("GPL"); |
1088 | |||
1089 | EXPORT_SYMBOL(dst_attach); | ||
diff --git a/drivers/media/dvb/bt8xx/dst.h b/drivers/media/dvb/bt8xx/dst.h deleted file mode 100644 index bcb418c5c121..000000000000 --- a/drivers/media/dvb/bt8xx/dst.h +++ /dev/null | |||
@@ -1,40 +0,0 @@ | |||
1 | /* | ||
2 | Frontend-driver for TwinHan DST Frontend | ||
3 | |||
4 | Copyright (C) 2003 Jamie Honan | ||
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 | |||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | |||
21 | */ | ||
22 | |||
23 | #ifndef DST_H | ||
24 | #define DST_H | ||
25 | |||
26 | #include <linux/dvb/frontend.h> | ||
27 | #include <linux/device.h> | ||
28 | #include "bt878.h" | ||
29 | |||
30 | struct dst_config | ||
31 | { | ||
32 | /* the demodulator's i2c address */ | ||
33 | u8 demod_address; | ||
34 | }; | ||
35 | |||
36 | extern struct dvb_frontend* dst_attach(const struct dst_config* config, | ||
37 | struct i2c_adapter* i2c, | ||
38 | struct bt878 *bt); | ||
39 | |||
40 | #endif // DST_H | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.c b/drivers/media/dvb/bt8xx/dst_ca.c new file mode 100644 index 000000000000..d781504cc2fa --- /dev/null +++ b/drivers/media/dvb/bt8xx/dst_ca.c | |||
@@ -0,0 +1,861 @@ | |||
1 | /* | ||
2 | CA-driver for TwinHan DST Frontend/Card | ||
3 | |||
4 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
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 | |||
23 | #include <linux/kernel.h> | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/string.h> | ||
27 | |||
28 | #include <linux/dvb/ca.h> | ||
29 | #include "dvbdev.h" | ||
30 | #include "dvb_frontend.h" | ||
31 | |||
32 | #include "dst_ca.h" | ||
33 | #include "dst_common.h" | ||
34 | |||
35 | static unsigned int verbose = 1; | ||
36 | module_param(verbose, int, 0644); | ||
37 | MODULE_PARM_DESC(verbose, "verbose startup messages, default is 1 (yes)"); | ||
38 | |||
39 | static unsigned int debug = 1; | ||
40 | module_param(debug, int, 0644); | ||
41 | MODULE_PARM_DESC(debug, "debug messages, default is 1 (yes)"); | ||
42 | |||
43 | #define dprintk if (debug) printk | ||
44 | |||
45 | /* Need some more work */ | ||
46 | static int ca_set_slot_descr(void) | ||
47 | { | ||
48 | /* We could make this more graceful ? */ | ||
49 | return -EOPNOTSUPP; | ||
50 | } | ||
51 | |||
52 | /* Need some more work */ | ||
53 | static int ca_set_pid(void) | ||
54 | { | ||
55 | /* We could make this more graceful ? */ | ||
56 | return -EOPNOTSUPP; | ||
57 | } | ||
58 | |||
59 | |||
60 | static int put_checksum(u8 *check_string, int length) | ||
61 | { | ||
62 | u8 i = 0, checksum = 0; | ||
63 | |||
64 | if (verbose > 3) { | ||
65 | dprintk("%s: ========================= Checksum calculation ===========================\n", __FUNCTION__); | ||
66 | dprintk("%s: String Length=[0x%02x]\n", __FUNCTION__, length); | ||
67 | |||
68 | dprintk("%s: String=[", __FUNCTION__); | ||
69 | } | ||
70 | while (i < length) { | ||
71 | if (verbose > 3) | ||
72 | dprintk(" %02x", check_string[i]); | ||
73 | checksum += check_string[i]; | ||
74 | i++; | ||
75 | } | ||
76 | if (verbose > 3) { | ||
77 | dprintk(" ]\n"); | ||
78 | dprintk("%s: Sum=[%02x]\n", __FUNCTION__, checksum); | ||
79 | } | ||
80 | check_string[length] = ~checksum + 1; | ||
81 | if (verbose > 3) { | ||
82 | dprintk("%s: Checksum=[%02x]\n", __FUNCTION__, check_string[length]); | ||
83 | dprintk("%s: ==========================================================================\n", __FUNCTION__); | ||
84 | } | ||
85 | |||
86 | return 0; | ||
87 | } | ||
88 | |||
89 | static int dst_ci_command(struct dst_state* state, u8 * data, u8 *ca_string, u8 len, int read) | ||
90 | { | ||
91 | u8 reply; | ||
92 | |||
93 | dst_comm_init(state); | ||
94 | msleep(65); | ||
95 | |||
96 | if (write_dst(state, data, len)) { | ||
97 | dprintk("%s: Write not successful, trying to recover\n", __FUNCTION__); | ||
98 | dst_error_recovery(state); | ||
99 | return -1; | ||
100 | } | ||
101 | |||
102 | if ((dst_pio_disable(state)) < 0) { | ||
103 | dprintk("%s: DST PIO disable failed.\n", __FUNCTION__); | ||
104 | return -1; | ||
105 | } | ||
106 | |||
107 | if (read_dst(state, &reply, GET_ACK) < 0) { | ||
108 | dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); | ||
109 | dst_error_recovery(state); | ||
110 | return -1; | ||
111 | } | ||
112 | |||
113 | if (read) { | ||
114 | if (! dst_wait_dst_ready(state, LONG_DELAY)) { | ||
115 | dprintk("%s: 8820 not ready\n", __FUNCTION__); | ||
116 | return -1; | ||
117 | } | ||
118 | |||
119 | if (read_dst(state, ca_string, 128) < 0) { /* Try to make this dynamic */ | ||
120 | dprintk("%s: Read not successful, trying to recover\n", __FUNCTION__); | ||
121 | dst_error_recovery(state); | ||
122 | return -1; | ||
123 | } | ||
124 | } | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | |||
130 | static int dst_put_ci(struct dst_state *state, u8 *data, int len, u8 *ca_string, int read) | ||
131 | { | ||
132 | u8 dst_ca_comm_err = 0; | ||
133 | |||
134 | while (dst_ca_comm_err < RETRIES) { | ||
135 | dst_comm_init(state); | ||
136 | if (verbose > 2) | ||
137 | dprintk("%s: Put Command\n", __FUNCTION__); | ||
138 | if (dst_ci_command(state, data, ca_string, len, read)) { // If error | ||
139 | dst_error_recovery(state); | ||
140 | dst_ca_comm_err++; // work required here. | ||
141 | } | ||
142 | break; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | |||
149 | |||
150 | static int ca_get_app_info(struct dst_state *state) | ||
151 | { | ||
152 | static u8 command[8] = {0x07, 0x40, 0x01, 0x00, 0x01, 0x00, 0x00, 0xff}; | ||
153 | |||
154 | put_checksum(&command[0], command[0]); | ||
155 | if ((dst_put_ci(state, command, sizeof(command), state->messages, GET_REPLY)) < 0) { | ||
156 | dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); | ||
157 | return -1; | ||
158 | } | ||
159 | if (verbose > 1) { | ||
160 | dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); | ||
161 | |||
162 | dprintk("%s: ================================ CI Module Application Info ======================================\n", __FUNCTION__); | ||
163 | dprintk("%s: Application Type=[%d], Application Vendor=[%d], Vendor Code=[%d]\n%s: Application info=[%s]\n", | ||
164 | __FUNCTION__, state->messages[7], (state->messages[8] << 8) | state->messages[9], | ||
165 | (state->messages[10] << 8) | state->messages[11], __FUNCTION__, (char *)(&state->messages[12])); | ||
166 | dprintk("%s: ==================================================================================================\n", __FUNCTION__); | ||
167 | } | ||
168 | |||
169 | return 0; | ||
170 | } | ||
171 | |||
172 | static int ca_get_slot_caps(struct dst_state *state, struct ca_caps *p_ca_caps, void *arg) | ||
173 | { | ||
174 | int i; | ||
175 | u8 slot_cap[256]; | ||
176 | static u8 slot_command[8] = {0x07, 0x40, 0x02, 0x00, 0x02, 0x00, 0x00, 0xff}; | ||
177 | |||
178 | put_checksum(&slot_command[0], slot_command[0]); | ||
179 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_cap, GET_REPLY)) < 0) { | ||
180 | dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); | ||
181 | return -1; | ||
182 | } | ||
183 | if (verbose > 1) | ||
184 | dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); | ||
185 | |||
186 | /* Will implement the rest soon */ | ||
187 | |||
188 | if (verbose > 1) { | ||
189 | dprintk("%s: Slot cap = [%d]\n", __FUNCTION__, slot_cap[7]); | ||
190 | dprintk("===================================\n"); | ||
191 | for (i = 0; i < 8; i++) | ||
192 | dprintk(" %d", slot_cap[i]); | ||
193 | dprintk("\n"); | ||
194 | } | ||
195 | |||
196 | p_ca_caps->slot_num = 1; | ||
197 | p_ca_caps->slot_type = 1; | ||
198 | p_ca_caps->descr_num = slot_cap[7]; | ||
199 | p_ca_caps->descr_type = 1; | ||
200 | |||
201 | |||
202 | if (copy_to_user((struct ca_caps *)arg, p_ca_caps, sizeof (struct ca_caps))) { | ||
203 | return -EFAULT; | ||
204 | } | ||
205 | |||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | /* Need some more work */ | ||
210 | static int ca_get_slot_descr(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | ||
211 | { | ||
212 | return -EOPNOTSUPP; | ||
213 | } | ||
214 | |||
215 | |||
216 | static int ca_get_slot_info(struct dst_state *state, struct ca_slot_info *p_ca_slot_info, void *arg) | ||
217 | { | ||
218 | int i; | ||
219 | static u8 slot_command[8] = {0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}; | ||
220 | |||
221 | u8 *slot_info = state->rxbuffer; | ||
222 | |||
223 | put_checksum(&slot_command[0], 7); | ||
224 | if ((dst_put_ci(state, slot_command, sizeof (slot_command), slot_info, GET_REPLY)) < 0) { | ||
225 | dprintk("%s: -->dst_put_ci FAILED !\n", __FUNCTION__); | ||
226 | return -1; | ||
227 | } | ||
228 | if (verbose > 1) | ||
229 | dprintk("%s: -->dst_put_ci SUCCESS !\n", __FUNCTION__); | ||
230 | |||
231 | /* Will implement the rest soon */ | ||
232 | |||
233 | if (verbose > 1) { | ||
234 | dprintk("%s: Slot info = [%d]\n", __FUNCTION__, slot_info[3]); | ||
235 | dprintk("===================================\n"); | ||
236 | for (i = 0; i < 8; i++) | ||
237 | dprintk(" %d", slot_info[i]); | ||
238 | dprintk("\n"); | ||
239 | } | ||
240 | |||
241 | if (slot_info[4] & 0x80) { | ||
242 | p_ca_slot_info->flags = CA_CI_MODULE_PRESENT; | ||
243 | p_ca_slot_info->num = 1; | ||
244 | p_ca_slot_info->type = CA_CI; | ||
245 | } | ||
246 | else if (slot_info[4] & 0x40) { | ||
247 | p_ca_slot_info->flags = CA_CI_MODULE_READY; | ||
248 | p_ca_slot_info->num = 1; | ||
249 | p_ca_slot_info->type = CA_CI; | ||
250 | } | ||
251 | else { | ||
252 | p_ca_slot_info->flags = 0; | ||
253 | } | ||
254 | |||
255 | if (copy_to_user((struct ca_slot_info *)arg, p_ca_slot_info, sizeof (struct ca_slot_info))) { | ||
256 | return -EFAULT; | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | |||
263 | |||
264 | |||
265 | static int ca_get_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | ||
266 | { | ||
267 | u8 i = 0; | ||
268 | u32 command = 0; | ||
269 | |||
270 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | ||
271 | return -EFAULT; | ||
272 | |||
273 | |||
274 | if (p_ca_message->msg) { | ||
275 | if (verbose > 3) | ||
276 | dprintk("Message = [%02x %02x %02x]\n", p_ca_message->msg[0], p_ca_message->msg[1], p_ca_message->msg[2]); | ||
277 | |||
278 | for (i = 0; i < 3; i++) { | ||
279 | command = command | p_ca_message->msg[i]; | ||
280 | if (i < 2) | ||
281 | command = command << 8; | ||
282 | } | ||
283 | if (verbose > 3) | ||
284 | dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command); | ||
285 | |||
286 | switch (command) { | ||
287 | case CA_APP_INFO: | ||
288 | memcpy(p_ca_message->msg, state->messages, 128); | ||
289 | if (copy_to_user((void *)arg, p_ca_message, sizeof (struct ca_msg)) ) | ||
290 | return -EFAULT; | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | static int handle_en50221_tag(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) | ||
299 | { | ||
300 | if (state->dst_hw_cap & DST_TYPE_HAS_SESSION) { | ||
301 | hw_buffer->msg[2] = p_ca_message->msg[1]; /* MSB */ | ||
302 | hw_buffer->msg[3] = p_ca_message->msg[2]; /* LSB */ | ||
303 | } | ||
304 | else { | ||
305 | hw_buffer->msg[2] = 0x03; | ||
306 | hw_buffer->msg[3] = 0x00; | ||
307 | } | ||
308 | return 0; | ||
309 | } | ||
310 | |||
311 | static int debug_8820_buffer(struct ca_msg *hw_buffer) | ||
312 | { | ||
313 | unsigned int i; | ||
314 | |||
315 | dprintk("%s:Debug=[", __FUNCTION__); | ||
316 | for (i = 0; i < (hw_buffer->msg[0] + 1); i++) | ||
317 | dprintk(" %02x", hw_buffer->msg[i]); | ||
318 | dprintk("]\n"); | ||
319 | |||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static int write_to_8820(struct dst_state *state, struct ca_msg *hw_buffer, u8 reply) | ||
324 | { | ||
325 | if ((dst_put_ci(state, hw_buffer->msg, (hw_buffer->length + 1), hw_buffer->msg, reply)) < 0) { | ||
326 | dprintk("%s: DST-CI Command failed.\n", __FUNCTION__); | ||
327 | dprintk("%s: Resetting DST.\n", __FUNCTION__); | ||
328 | rdc_reset_state(state); | ||
329 | return -1; | ||
330 | } | ||
331 | if (verbose > 2) | ||
332 | dprintk("%s: DST-CI Command succes.\n", __FUNCTION__); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | |||
338 | static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) | ||
339 | { | ||
340 | u32 hw_offset, buf_offset, i, k; | ||
341 | u32 program_info_length = 0, es_info_length = 0, length = 0, words = 0; | ||
342 | u8 found_prog_ca_desc = 0, found_stream_ca_desc = 0, error_condition = 0, hw_buffer_length = 0; | ||
343 | |||
344 | if (verbose > 3) | ||
345 | dprintk("%s, p_ca_message length %d (0x%x)\n", __FUNCTION__,p_ca_message->length,p_ca_message->length ); | ||
346 | |||
347 | handle_en50221_tag(state, p_ca_message, hw_buffer); /* EN50221 tag */ | ||
348 | |||
349 | /* Handle the length field (variable) */ | ||
350 | if (!(p_ca_message->msg[3] & 0x80)) { /* Length = 1 */ | ||
351 | length = p_ca_message->msg[3] & 0x7f; | ||
352 | words = 0; /* domi's suggestion */ | ||
353 | } | ||
354 | else { /* Length = words */ | ||
355 | words = p_ca_message->msg[3] & 0x7f; | ||
356 | for (i = 0; i < words; i++) { | ||
357 | length = length << 8; | ||
358 | length = length | p_ca_message->msg[4 + i]; | ||
359 | } | ||
360 | } | ||
361 | if (verbose > 4) { | ||
362 | dprintk("%s:Length=[%d (0x%x)], Words=[%d]\n", __FUNCTION__, length,length, words); | ||
363 | |||
364 | /* Debug Input string */ | ||
365 | for (i = 0; i < length; i++) | ||
366 | dprintk(" %02x", p_ca_message->msg[i]); | ||
367 | dprintk("]\n"); | ||
368 | } | ||
369 | |||
370 | hw_offset = 7; | ||
371 | buf_offset = words + 4; | ||
372 | |||
373 | /* Program Header */ | ||
374 | if (verbose > 4) | ||
375 | dprintk("\n%s:Program Header=[", __FUNCTION__); | ||
376 | for (i = 0; i < 6; i++) { | ||
377 | hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; | ||
378 | if (verbose > 4) | ||
379 | dprintk(" %02x", p_ca_message->msg[buf_offset]); | ||
380 | hw_offset++, buf_offset++, hw_buffer_length++; | ||
381 | } | ||
382 | if (verbose > 4) | ||
383 | dprintk("]\n"); | ||
384 | |||
385 | program_info_length = 0; | ||
386 | program_info_length = (((program_info_length | p_ca_message->msg[words + 8]) & 0x0f) << 8) | p_ca_message->msg[words + 9]; | ||
387 | if (verbose > 4) | ||
388 | dprintk("%s:Program info Length=[%d][%02x], hw_offset=[%d], buf_offset=[%d] \n", | ||
389 | __FUNCTION__, program_info_length, program_info_length, hw_offset, buf_offset); | ||
390 | |||
391 | if (program_info_length && (program_info_length < 256)) { /* If program_info_length */ | ||
392 | hw_buffer->msg[11] = hw_buffer->msg[11] & 0x0f; /* req only 4 bits */ | ||
393 | hw_buffer->msg[12] = hw_buffer->msg[12] + 1; /* increment! ASIC bug! */ | ||
394 | |||
395 | if (p_ca_message->msg[buf_offset + 1] == 0x09) { /* Check CA descriptor */ | ||
396 | found_prog_ca_desc = 1; | ||
397 | if (verbose > 4) | ||
398 | dprintk("%s: Found CA descriptor @ Program level\n", __FUNCTION__); | ||
399 | } | ||
400 | |||
401 | if (found_prog_ca_desc) { /* Command only if CA descriptor */ | ||
402 | hw_buffer->msg[13] = p_ca_message->msg[buf_offset]; /* CA PMT command ID */ | ||
403 | hw_offset++, buf_offset++, hw_buffer_length++; | ||
404 | } | ||
405 | |||
406 | /* Program descriptors */ | ||
407 | if (verbose > 4) { | ||
408 | dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset); | ||
409 | dprintk("%s:Program descriptors=[", __FUNCTION__); | ||
410 | } | ||
411 | while (program_info_length && !error_condition) { /* Copy prog descriptors */ | ||
412 | if (program_info_length > p_ca_message->length) { /* Error situation */ | ||
413 | dprintk ("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d]\n", | ||
414 | __FUNCTION__, __LINE__, program_info_length); | ||
415 | dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); | ||
416 | error_condition = 1; | ||
417 | break; | ||
418 | } | ||
419 | |||
420 | hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; | ||
421 | dprintk(" %02x", p_ca_message->msg[buf_offset]); | ||
422 | hw_offset++, buf_offset++, hw_buffer_length++, program_info_length--; | ||
423 | } | ||
424 | if (verbose > 4) { | ||
425 | dprintk("]\n"); | ||
426 | dprintk("%s:**********>buf_offset=[%d], hw_offset=[%d]\n", __FUNCTION__, buf_offset, hw_offset); | ||
427 | } | ||
428 | if (found_prog_ca_desc) { | ||
429 | if (!reply) { | ||
430 | hw_buffer->msg[13] = 0x01; /* OK descrambling */ | ||
431 | if (verbose > 1) | ||
432 | dprintk("CA PMT Command = OK Descrambling\n"); | ||
433 | } | ||
434 | else { | ||
435 | hw_buffer->msg[13] = 0x02; /* Ok MMI */ | ||
436 | if (verbose > 1) | ||
437 | dprintk("CA PMT Command = Ok MMI\n"); | ||
438 | } | ||
439 | if (query) { | ||
440 | hw_buffer->msg[13] = 0x03; /* Query */ | ||
441 | if (verbose > 1) | ||
442 | dprintk("CA PMT Command = CA PMT query\n"); | ||
443 | } | ||
444 | } | ||
445 | } | ||
446 | else { | ||
447 | hw_buffer->msg[11] = hw_buffer->msg[11] & 0xf0; /* Don't write to ASIC */ | ||
448 | hw_buffer->msg[12] = hw_buffer->msg[12] = 0x00; | ||
449 | } | ||
450 | if (verbose > 4) | ||
451 | dprintk("%s:**********>p_ca_message->length=[%d], buf_offset=[%d], hw_offset=[%d]\n", | ||
452 | __FUNCTION__, p_ca_message->length, buf_offset, hw_offset); | ||
453 | |||
454 | while ((buf_offset < p_ca_message->length) && !error_condition) { | ||
455 | /* Bail out in case of an indefinite loop */ | ||
456 | if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) { | ||
457 | dprintk("%s:\"WARNING\" Length error, line=[%d], prog_info_length=[%d], buf_offset=[%d]\n", | ||
458 | __FUNCTION__, __LINE__, program_info_length, buf_offset); | ||
459 | |||
460 | dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); | ||
461 | error_condition = 1; | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Stream Header */ | ||
466 | |||
467 | for (k = 0; k < 5; k++) { | ||
468 | hw_buffer->msg[hw_offset + k] = p_ca_message->msg[buf_offset + k]; | ||
469 | } | ||
470 | |||
471 | es_info_length = 0; | ||
472 | es_info_length = (es_info_length | (p_ca_message->msg[buf_offset + 3] & 0x0f)) << 8 | p_ca_message->msg[buf_offset + 4]; | ||
473 | |||
474 | if (verbose > 4) { | ||
475 | dprintk("\n%s:----->Stream header=[%02x %02x %02x %02x %02x]\n", __FUNCTION__, | ||
476 | p_ca_message->msg[buf_offset + 0], p_ca_message->msg[buf_offset + 1], | ||
477 | p_ca_message->msg[buf_offset + 2], p_ca_message->msg[buf_offset + 3], | ||
478 | p_ca_message->msg[buf_offset + 4]); | ||
479 | |||
480 | dprintk("%s:----->Stream type=[%02x], es length=[%d (0x%x)], Chars=[%02x] [%02x], buf_offset=[%d]\n", __FUNCTION__, | ||
481 | p_ca_message->msg[buf_offset + 0], es_info_length, es_info_length, | ||
482 | p_ca_message->msg[buf_offset + 3], p_ca_message->msg[buf_offset + 4], buf_offset); | ||
483 | } | ||
484 | |||
485 | hw_buffer->msg[hw_offset + 3] &= 0x0f; /* req only 4 bits */ | ||
486 | |||
487 | if (found_prog_ca_desc) { | ||
488 | hw_buffer->msg[hw_offset + 3] = 0x00; | ||
489 | hw_buffer->msg[hw_offset + 4] = 0x00; | ||
490 | } | ||
491 | |||
492 | hw_offset += 5, buf_offset += 5, hw_buffer_length += 5; | ||
493 | |||
494 | /* Check for CA descriptor */ | ||
495 | if (p_ca_message->msg[buf_offset + 1] == 0x09) { | ||
496 | if (verbose > 4) | ||
497 | dprintk("%s:Found CA descriptor @ Stream level\n", __FUNCTION__); | ||
498 | found_stream_ca_desc = 1; | ||
499 | } | ||
500 | |||
501 | /* ES descriptors */ | ||
502 | |||
503 | if (es_info_length && !error_condition && !found_prog_ca_desc && found_stream_ca_desc) { | ||
504 | // if (!ca_pmt_done) { | ||
505 | hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; /* CA PMT cmd(es) */ | ||
506 | if (verbose > 4) | ||
507 | printk("%s:----->CA PMT Command ID=[%02x]\n", __FUNCTION__, p_ca_message->msg[buf_offset]); | ||
508 | // hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--, ca_pmt_done = 1; | ||
509 | hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--; | ||
510 | // } | ||
511 | if (verbose > 4) | ||
512 | dprintk("%s:----->ES descriptors=[", __FUNCTION__); | ||
513 | |||
514 | while (es_info_length && !error_condition) { /* ES descriptors */ | ||
515 | if ((es_info_length > p_ca_message->length) || (buf_offset > p_ca_message->length)) { | ||
516 | if (verbose > 4) { | ||
517 | dprintk("%s:\"WARNING\" ES Length error, line=[%d], es_info_length=[%d], buf_offset=[%d]\n", | ||
518 | __FUNCTION__, __LINE__, es_info_length, buf_offset); | ||
519 | |||
520 | dprintk("%s:\"WARNING\" Bailing out of possible loop\n", __FUNCTION__); | ||
521 | } | ||
522 | error_condition = 1; | ||
523 | break; | ||
524 | } | ||
525 | |||
526 | hw_buffer->msg[hw_offset] = p_ca_message->msg[buf_offset]; | ||
527 | if (verbose > 3) | ||
528 | dprintk("%02x ", hw_buffer->msg[hw_offset]); | ||
529 | hw_offset++, buf_offset++, hw_buffer_length++, es_info_length--; | ||
530 | } | ||
531 | found_stream_ca_desc = 0; /* unset for new streams */ | ||
532 | dprintk("]\n"); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | /* MCU Magic words */ | ||
537 | |||
538 | hw_buffer_length += 7; | ||
539 | hw_buffer->msg[0] = hw_buffer_length; | ||
540 | hw_buffer->msg[1] = 64; | ||
541 | hw_buffer->msg[4] = 3; | ||
542 | hw_buffer->msg[5] = hw_buffer->msg[0] - 7; | ||
543 | hw_buffer->msg[6] = 0; | ||
544 | |||
545 | |||
546 | /* Fix length */ | ||
547 | hw_buffer->length = hw_buffer->msg[0]; | ||
548 | |||
549 | put_checksum(&hw_buffer->msg[0], hw_buffer->msg[0]); | ||
550 | /* Do the actual write */ | ||
551 | if (verbose > 4) { | ||
552 | dprintk("%s:======================DEBUGGING================================\n", __FUNCTION__); | ||
553 | dprintk("%s: Actual Length=[%d]\n", __FUNCTION__, hw_buffer_length); | ||
554 | } | ||
555 | /* Only for debugging! */ | ||
556 | if (verbose > 2) | ||
557 | debug_8820_buffer(hw_buffer); | ||
558 | if (verbose > 3) | ||
559 | dprintk("%s: Reply = [%d]\n", __FUNCTION__, reply); | ||
560 | write_to_8820(state, hw_buffer, reply); | ||
561 | |||
562 | return 0; | ||
563 | } | ||
564 | |||
565 | /* Board supports CA PMT reply ? */ | ||
566 | static int dst_check_ca_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer) | ||
567 | { | ||
568 | int ca_pmt_reply_test = 0; | ||
569 | |||
570 | /* Do test board */ | ||
571 | /* Not there yet but soon */ | ||
572 | |||
573 | |||
574 | /* CA PMT Reply capable */ | ||
575 | if (ca_pmt_reply_test) { | ||
576 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 1, GET_REPLY)) < 0) { | ||
577 | dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); | ||
578 | return -1; | ||
579 | } | ||
580 | |||
581 | /* Process CA PMT Reply */ | ||
582 | /* will implement soon */ | ||
583 | dprintk("%s: Not there yet\n", __FUNCTION__); | ||
584 | } | ||
585 | /* CA PMT Reply not capable */ | ||
586 | if (!ca_pmt_reply_test) { | ||
587 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, NO_REPLY)) < 0) { | ||
588 | dprintk("%s: ca_set_pmt.. failed !\n", __FUNCTION__); | ||
589 | return -1; | ||
590 | } | ||
591 | if (verbose > 3) | ||
592 | dprintk("%s: ca_set_pmt.. success !\n", __FUNCTION__); | ||
593 | /* put a dummy message */ | ||
594 | |||
595 | } | ||
596 | return 0; | ||
597 | } | ||
598 | |||
599 | static int ca_send_message(struct dst_state *state, struct ca_msg *p_ca_message, void *arg) | ||
600 | { | ||
601 | int i = 0; | ||
602 | unsigned int ca_message_header_len; | ||
603 | |||
604 | u32 command = 0; | ||
605 | struct ca_msg *hw_buffer; | ||
606 | |||
607 | if ((hw_buffer = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | ||
608 | printk("%s: Memory allocation failure\n", __FUNCTION__); | ||
609 | return -ENOMEM; | ||
610 | } | ||
611 | if (verbose > 3) | ||
612 | dprintk("%s\n", __FUNCTION__); | ||
613 | |||
614 | if (copy_from_user(p_ca_message, (void *)arg, sizeof (struct ca_msg))) | ||
615 | return -EFAULT; | ||
616 | |||
617 | if (p_ca_message->msg) { | ||
618 | ca_message_header_len = p_ca_message->length; /* Restore it back when you are done */ | ||
619 | /* EN50221 tag */ | ||
620 | command = 0; | ||
621 | |||
622 | for (i = 0; i < 3; i++) { | ||
623 | command = command | p_ca_message->msg[i]; | ||
624 | if (i < 2) | ||
625 | command = command << 8; | ||
626 | } | ||
627 | if (verbose > 3) | ||
628 | dprintk("%s:Command=[0x%x]\n", __FUNCTION__, command); | ||
629 | |||
630 | switch (command) { | ||
631 | case CA_PMT: | ||
632 | if (verbose > 3) | ||
633 | dprintk("Command = SEND_CA_PMT\n"); | ||
634 | if ((ca_set_pmt(state, p_ca_message, hw_buffer, 0, 0)) < 0) { | ||
635 | dprintk("%s: -->CA_PMT Failed !\n", __FUNCTION__); | ||
636 | return -1; | ||
637 | } | ||
638 | if (verbose > 3) | ||
639 | dprintk("%s: -->CA_PMT Success !\n", __FUNCTION__); | ||
640 | // retval = dummy_set_pmt(state, p_ca_message, hw_buffer, 0, 0); | ||
641 | |||
642 | break; | ||
643 | |||
644 | case CA_PMT_REPLY: | ||
645 | if (verbose > 3) | ||
646 | dprintk("Command = CA_PMT_REPLY\n"); | ||
647 | /* Have to handle the 2 basic types of cards here */ | ||
648 | if ((dst_check_ca_pmt(state, p_ca_message, hw_buffer)) < 0) { | ||
649 | dprintk("%s: -->CA_PMT_REPLY Failed !\n", __FUNCTION__); | ||
650 | return -1; | ||
651 | } | ||
652 | if (verbose > 3) | ||
653 | dprintk("%s: -->CA_PMT_REPLY Success !\n", __FUNCTION__); | ||
654 | |||
655 | /* Certain boards do behave different ? */ | ||
656 | // retval = ca_set_pmt(state, p_ca_message, hw_buffer, 1, 1); | ||
657 | |||
658 | case CA_APP_INFO_ENQUIRY: // only for debugging | ||
659 | if (verbose > 3) | ||
660 | dprintk("%s: Getting Cam Application information\n", __FUNCTION__); | ||
661 | |||
662 | if ((ca_get_app_info(state)) < 0) { | ||
663 | dprintk("%s: -->CA_APP_INFO_ENQUIRY Failed !\n", __FUNCTION__); | ||
664 | return -1; | ||
665 | } | ||
666 | if (verbose > 3) | ||
667 | printk("%s: -->CA_APP_INFO_ENQUIRY Success !\n", __FUNCTION__); | ||
668 | |||
669 | break; | ||
670 | } | ||
671 | } | ||
672 | return 0; | ||
673 | } | ||
674 | |||
675 | static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) | ||
676 | { | ||
677 | struct dvb_device* dvbdev = (struct dvb_device*) file->private_data; | ||
678 | struct dst_state* state = (struct dst_state*) dvbdev->priv; | ||
679 | struct ca_slot_info *p_ca_slot_info; | ||
680 | struct ca_caps *p_ca_caps; | ||
681 | struct ca_msg *p_ca_message; | ||
682 | |||
683 | if ((p_ca_message = (struct ca_msg *) kmalloc(sizeof (struct ca_msg), GFP_KERNEL)) == NULL) { | ||
684 | printk("%s: Memory allocation failure\n", __FUNCTION__); | ||
685 | return -ENOMEM; | ||
686 | } | ||
687 | |||
688 | if ((p_ca_slot_info = (struct ca_slot_info *) kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL)) == NULL) { | ||
689 | printk("%s: Memory allocation failure\n", __FUNCTION__); | ||
690 | return -ENOMEM; | ||
691 | } | ||
692 | |||
693 | if ((p_ca_caps = (struct ca_caps *) kmalloc(sizeof (struct ca_caps), GFP_KERNEL)) == NULL) { | ||
694 | printk("%s: Memory allocation failure\n", __FUNCTION__); | ||
695 | return -ENOMEM; | ||
696 | } | ||
697 | |||
698 | /* We have now only the standard ioctl's, the driver is upposed to handle internals. */ | ||
699 | switch (cmd) { | ||
700 | case CA_SEND_MSG: | ||
701 | if (verbose > 1) | ||
702 | dprintk("%s: Sending message\n", __FUNCTION__); | ||
703 | if ((ca_send_message(state, p_ca_message, arg)) < 0) { | ||
704 | dprintk("%s: -->CA_SEND_MSG Failed !\n", __FUNCTION__); | ||
705 | return -1; | ||
706 | } | ||
707 | |||
708 | break; | ||
709 | |||
710 | case CA_GET_MSG: | ||
711 | if (verbose > 1) | ||
712 | dprintk("%s: Getting message\n", __FUNCTION__); | ||
713 | if ((ca_get_message(state, p_ca_message, arg)) < 0) { | ||
714 | dprintk("%s: -->CA_GET_MSG Failed !\n", __FUNCTION__); | ||
715 | return -1; | ||
716 | } | ||
717 | if (verbose > 1) | ||
718 | dprintk("%s: -->CA_GET_MSG Success !\n", __FUNCTION__); | ||
719 | |||
720 | break; | ||
721 | |||
722 | case CA_RESET: | ||
723 | if (verbose > 1) | ||
724 | dprintk("%s: Resetting DST\n", __FUNCTION__); | ||
725 | dst_error_bailout(state); | ||
726 | msleep(4000); | ||
727 | |||
728 | break; | ||
729 | |||
730 | case CA_GET_SLOT_INFO: | ||
731 | if (verbose > 1) | ||
732 | dprintk("%s: Getting Slot info\n", __FUNCTION__); | ||
733 | if ((ca_get_slot_info(state, p_ca_slot_info, arg)) < 0) { | ||
734 | dprintk("%s: -->CA_GET_SLOT_INFO Failed !\n", __FUNCTION__); | ||
735 | return -1; | ||
736 | } | ||
737 | if (verbose > 1) | ||
738 | dprintk("%s: -->CA_GET_SLOT_INFO Success !\n", __FUNCTION__); | ||
739 | |||
740 | break; | ||
741 | |||
742 | case CA_GET_CAP: | ||
743 | if (verbose > 1) | ||
744 | dprintk("%s: Getting Slot capabilities\n", __FUNCTION__); | ||
745 | if ((ca_get_slot_caps(state, p_ca_caps, arg)) < 0) { | ||
746 | dprintk("%s: -->CA_GET_CAP Failed !\n", __FUNCTION__); | ||
747 | return -1; | ||
748 | } | ||
749 | if (verbose > 1) | ||
750 | dprintk("%s: -->CA_GET_CAP Success !\n", __FUNCTION__); | ||
751 | |||
752 | break; | ||
753 | |||
754 | case CA_GET_DESCR_INFO: | ||
755 | if (verbose > 1) | ||
756 | dprintk("%s: Getting descrambler description\n", __FUNCTION__); | ||
757 | if ((ca_get_slot_descr(state, p_ca_message, arg)) < 0) { | ||
758 | dprintk("%s: -->CA_GET_DESCR_INFO Failed !\n", __FUNCTION__); | ||
759 | return -1; | ||
760 | } | ||
761 | if (verbose > 1) | ||
762 | dprintk("%s: -->CA_GET_DESCR_INFO Success !\n", __FUNCTION__); | ||
763 | |||
764 | break; | ||
765 | |||
766 | case CA_SET_DESCR: | ||
767 | if (verbose > 1) | ||
768 | dprintk("%s: Setting descrambler\n", __FUNCTION__); | ||
769 | if ((ca_set_slot_descr()) < 0) { | ||
770 | dprintk("%s: -->CA_SET_DESCR Failed !\n", __FUNCTION__); | ||
771 | return -1; | ||
772 | } | ||
773 | if (verbose > 1) | ||
774 | dprintk("%s: -->CA_SET_DESCR Success !\n", __FUNCTION__); | ||
775 | |||
776 | break; | ||
777 | |||
778 | case CA_SET_PID: | ||
779 | if (verbose > 1) | ||
780 | dprintk("%s: Setting PID\n", __FUNCTION__); | ||
781 | if ((ca_set_pid()) < 0) { | ||
782 | dprintk("%s: -->CA_SET_PID Failed !\n", __FUNCTION__); | ||
783 | return -1; | ||
784 | } | ||
785 | if (verbose > 1) | ||
786 | dprintk("%s: -->CA_SET_PID Success !\n", __FUNCTION__); | ||
787 | |||
788 | default: | ||
789 | return -EOPNOTSUPP; | ||
790 | }; | ||
791 | |||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | static int dst_ca_open(struct inode *inode, struct file *file) | ||
796 | { | ||
797 | if (verbose > 4) | ||
798 | dprintk("%s:Device opened [%p]\n", __FUNCTION__, file); | ||
799 | try_module_get(THIS_MODULE); | ||
800 | |||
801 | return 0; | ||
802 | } | ||
803 | |||
804 | static int dst_ca_release(struct inode *inode, struct file *file) | ||
805 | { | ||
806 | if (verbose > 4) | ||
807 | dprintk("%s:Device closed.\n", __FUNCTION__); | ||
808 | module_put(THIS_MODULE); | ||
809 | |||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static int dst_ca_read(struct file *file, char __user * buffer, size_t length, loff_t * offset) | ||
814 | { | ||
815 | int bytes_read = 0; | ||
816 | |||
817 | if (verbose > 4) | ||
818 | dprintk("%s:Device read.\n", __FUNCTION__); | ||
819 | |||
820 | return bytes_read; | ||
821 | } | ||
822 | |||
823 | static int dst_ca_write(struct file *file, const char __user * buffer, size_t length, loff_t * offset) | ||
824 | { | ||
825 | if (verbose > 4) | ||
826 | dprintk("%s:Device write.\n", __FUNCTION__); | ||
827 | |||
828 | return 0; | ||
829 | } | ||
830 | |||
831 | static struct file_operations dst_ca_fops = { | ||
832 | .owner = THIS_MODULE, | ||
833 | .ioctl = (void *)dst_ca_ioctl, | ||
834 | .open = dst_ca_open, | ||
835 | .release = dst_ca_release, | ||
836 | .read = dst_ca_read, | ||
837 | .write = dst_ca_write | ||
838 | }; | ||
839 | |||
840 | static struct dvb_device dvbdev_ca = { | ||
841 | .priv = NULL, | ||
842 | .users = 1, | ||
843 | .readers = 1, | ||
844 | .writers = 1, | ||
845 | .fops = &dst_ca_fops | ||
846 | }; | ||
847 | |||
848 | int dst_ca_attach(struct dst_state *dst, struct dvb_adapter *dvb_adapter) | ||
849 | { | ||
850 | struct dvb_device *dvbdev; | ||
851 | if (verbose > 4) | ||
852 | dprintk("%s:registering DST-CA device\n", __FUNCTION__); | ||
853 | dvb_register_device(dvb_adapter, &dvbdev, &dvbdev_ca, dst, DVB_DEVICE_CA); | ||
854 | return 0; | ||
855 | } | ||
856 | |||
857 | EXPORT_SYMBOL(dst_ca_attach); | ||
858 | |||
859 | MODULE_DESCRIPTION("DST DVB-S/T/C Combo CA driver"); | ||
860 | MODULE_AUTHOR("Manu Abraham"); | ||
861 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/media/dvb/bt8xx/dst_ca.h b/drivers/media/dvb/bt8xx/dst_ca.h new file mode 100644 index 000000000000..59cd0ddd6d8e --- /dev/null +++ b/drivers/media/dvb/bt8xx/dst_ca.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | CA-driver for TwinHan DST Frontend/Card | ||
3 | |||
4 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.com) | ||
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 | #ifndef _DST_CA_H_ | ||
22 | #define _DST_CA_H_ | ||
23 | |||
24 | #define RETRIES 5 | ||
25 | |||
26 | |||
27 | #define CA_APP_INFO_ENQUIRY 0x9f8020 | ||
28 | #define CA_APP_INFO 0x9f8021 | ||
29 | #define CA_ENTER_MENU 0x9f8022 | ||
30 | #define CA_INFO_ENQUIRY 0x9f8030 | ||
31 | #define CA_INFO 0x9f8031 | ||
32 | #define CA_PMT 0x9f8032 | ||
33 | #define CA_PMT_REPLY 0x9f8033 | ||
34 | |||
35 | #define CA_CLOSE_MMI 0x9f8800 | ||
36 | #define CA_DISPLAY_CONTROL 0x9f8801 | ||
37 | #define CA_DISPLAY_REPLY 0x9f8802 | ||
38 | #define CA_TEXT_LAST 0x9f8803 | ||
39 | #define CA_TEXT_MORE 0x9f8804 | ||
40 | #define CA_KEYPAD_CONTROL 0x9f8805 | ||
41 | #define CA_KEYPRESS 0x9f8806 | ||
42 | |||
43 | #define CA_ENQUIRY 0x9f8807 | ||
44 | #define CA_ANSWER 0x9f8808 | ||
45 | #define CA_MENU_LAST 0x9f8809 | ||
46 | #define CA_MENU_MORE 0x9f880a | ||
47 | #define CA_MENU_ANSWER 0x9f880b | ||
48 | #define CA_LIST_LAST 0x9f880c | ||
49 | #define CA_LIST_MORE 0x9f880d | ||
50 | |||
51 | |||
52 | struct dst_ca_private { | ||
53 | struct dst_state *dst; | ||
54 | struct dvb_device *dvbdev; | ||
55 | }; | ||
56 | |||
57 | |||
58 | #endif | ||
diff --git a/drivers/media/dvb/bt8xx/dst_common.h b/drivers/media/dvb/bt8xx/dst_common.h new file mode 100644 index 000000000000..0b3da29245fb --- /dev/null +++ b/drivers/media/dvb/bt8xx/dst_common.h | |||
@@ -0,0 +1,153 @@ | |||
1 | /* | ||
2 | Frontend-driver for TwinHan DST Frontend | ||
3 | |||
4 | Copyright (C) 2003 Jamie Honan | ||
5 | Copyright (C) 2004, 2005 Manu Abraham (manu@kromtek.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 as published by | ||
9 | the Free Software Foundation; either version 2 of the License, or | ||
10 | (at your option) any later version. | ||
11 | |||
12 | This program is distributed in the hope that it will be useful, | ||
13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | GNU General Public License for more details. | ||
16 | |||
17 | You should have received a copy of the GNU General Public License | ||
18 | along with this program; if not, write to the Free Software | ||
19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
20 | */ | ||
21 | |||
22 | #ifndef DST_COMMON_H | ||
23 | #define DST_COMMON_H | ||
24 | |||
25 | #include <linux/dvb/frontend.h> | ||
26 | #include <linux/device.h> | ||
27 | #include "bt878.h" | ||
28 | |||
29 | #include "dst_ca.h" | ||
30 | |||
31 | |||
32 | #define NO_DELAY 0 | ||
33 | #define LONG_DELAY 1 | ||
34 | #define DEVICE_INIT 2 | ||
35 | |||
36 | #define DELAY 1 | ||
37 | |||
38 | #define DST_TYPE_IS_SAT 0 | ||
39 | #define DST_TYPE_IS_TERR 1 | ||
40 | #define DST_TYPE_IS_CABLE 2 | ||
41 | #define DST_TYPE_IS_ATSC 3 | ||
42 | |||
43 | #define DST_TYPE_HAS_NEWTUNE 1 | ||
44 | #define DST_TYPE_HAS_TS204 2 | ||
45 | #define DST_TYPE_HAS_SYMDIV 4 | ||
46 | #define DST_TYPE_HAS_FW_1 8 | ||
47 | #define DST_TYPE_HAS_FW_2 16 | ||
48 | #define DST_TYPE_HAS_FW_3 32 | ||
49 | #define DST_TYPE_HAS_FW_BUILD 64 | ||
50 | |||
51 | /* Card capability list */ | ||
52 | |||
53 | #define DST_TYPE_HAS_MAC 1 | ||
54 | #define DST_TYPE_HAS_DISEQC3 2 | ||
55 | #define DST_TYPE_HAS_DISEQC4 4 | ||
56 | #define DST_TYPE_HAS_DISEQC5 8 | ||
57 | #define DST_TYPE_HAS_MOTO 16 | ||
58 | #define DST_TYPE_HAS_CA 32 | ||
59 | #define DST_TYPE_HAS_ANALOG 64 /* Analog inputs */ | ||
60 | #define DST_TYPE_HAS_SESSION 128 | ||
61 | |||
62 | |||
63 | #define RDC_8820_PIO_0_DISABLE 0 | ||
64 | #define RDC_8820_PIO_0_ENABLE 1 | ||
65 | #define RDC_8820_INT 2 | ||
66 | #define RDC_8820_RESET 4 | ||
67 | |||
68 | /* DST Communication */ | ||
69 | #define GET_REPLY 1 | ||
70 | #define NO_REPLY 0 | ||
71 | |||
72 | #define GET_ACK 1 | ||
73 | #define FIXED_COMM 8 | ||
74 | |||
75 | #define ACK 0xff | ||
76 | |||
77 | struct dst_state { | ||
78 | |||
79 | struct i2c_adapter* i2c; | ||
80 | |||
81 | struct bt878* bt; | ||
82 | |||
83 | struct dvb_frontend_ops ops; | ||
84 | |||
85 | /* configuration settings */ | ||
86 | const struct dst_config* config; | ||
87 | |||
88 | struct dvb_frontend frontend; | ||
89 | |||
90 | /* private ASIC data */ | ||
91 | u8 tx_tuna[10]; | ||
92 | u8 rx_tuna[10]; | ||
93 | u8 rxbuffer[10]; | ||
94 | u8 diseq_flags; | ||
95 | u8 dst_type; | ||
96 | u32 type_flags; | ||
97 | u32 frequency; /* intermediate frequency in kHz for QPSK */ | ||
98 | fe_spectral_inversion_t inversion; | ||
99 | u32 symbol_rate; /* symbol rate in Symbols per second */ | ||
100 | fe_code_rate_t fec; | ||
101 | fe_sec_voltage_t voltage; | ||
102 | fe_sec_tone_mode_t tone; | ||
103 | u32 decode_freq; | ||
104 | u8 decode_lock; | ||
105 | u16 decode_strength; | ||
106 | u16 decode_snr; | ||
107 | unsigned long cur_jiff; | ||
108 | u8 k22; | ||
109 | fe_bandwidth_t bandwidth; | ||
110 | u32 dst_hw_cap; | ||
111 | u8 dst_fw_version; | ||
112 | fe_sec_mini_cmd_t minicmd; | ||
113 | u8 messages[256]; | ||
114 | }; | ||
115 | |||
116 | struct dst_types { | ||
117 | char *device_id; | ||
118 | int offset; | ||
119 | u8 dst_type; | ||
120 | u32 type_flags; | ||
121 | u32 dst_feature; | ||
122 | }; | ||
123 | |||
124 | |||
125 | |||
126 | struct dst_config | ||
127 | { | ||
128 | /* the ASIC i2c address */ | ||
129 | u8 demod_address; | ||
130 | }; | ||
131 | |||
132 | |||
133 | int rdc_reset_state(struct dst_state *state); | ||
134 | int rdc_8820_reset(struct dst_state *state); | ||
135 | |||
136 | int dst_wait_dst_ready(struct dst_state *state, u8 delay_mode); | ||
137 | int dst_pio_enable(struct dst_state *state); | ||
138 | int dst_pio_disable(struct dst_state *state); | ||
139 | int dst_error_recovery(struct dst_state* state); | ||
140 | int dst_error_bailout(struct dst_state *state); | ||
141 | int dst_comm_init(struct dst_state* state); | ||
142 | |||
143 | int write_dst(struct dst_state *state, u8 * data, u8 len); | ||
144 | int read_dst(struct dst_state *state, u8 * ret, u8 len); | ||
145 | u8 dst_check_sum(u8 * buf, u32 len); | ||
146 | struct dst_state* dst_attach(struct dst_state* state, struct dvb_adapter *dvb_adapter); | ||
147 | int dst_ca_attach(struct dst_state *state, struct dvb_adapter *dvb_adapter); | ||
148 | int dst_gpio_outb(struct dst_state* state, u32 mask, u32 enbb, u32 outhigh, int delay); | ||
149 | |||
150 | int dst_command(struct dst_state* state, u8 * data, u8 len); | ||
151 | |||
152 | |||
153 | #endif // DST_COMMON_H | ||
diff --git a/drivers/media/dvb/bt8xx/dst_priv.h b/drivers/media/dvb/bt8xx/dst_priv.h index 80488aa628b4..3974a4c6ebe7 100644 --- a/drivers/media/dvb/bt8xx/dst_priv.h +++ b/drivers/media/dvb/bt8xx/dst_priv.h | |||
@@ -33,4 +33,3 @@ union dst_gpio_packet { | |||
33 | struct bt878; | 33 | struct bt878; |
34 | 34 | ||
35 | int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); | 35 | int bt878_device_control(struct bt878 *bt, unsigned int cmd, union dst_gpio_packet *mp); |
36 | |||
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.c b/drivers/media/dvb/bt8xx/dvb-bt8xx.c index b735397f59aa..6f857c6091f3 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.c +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.c | |||
@@ -142,7 +142,7 @@ static int thomson_dtt7579_demod_init(struct dvb_frontend* fe) | |||
142 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); | 142 | mt352_write(fe, mt352_adc_ctl_1_cfg, sizeof(mt352_adc_ctl_1_cfg)); |
143 | 143 | ||
144 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); | 144 | mt352_write(fe, mt352_agc_cfg, sizeof(mt352_agc_cfg)); |
145 | mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); | 145 | mt352_write(fe, mt352_gpp_ctl_cfg, sizeof(mt352_gpp_ctl_cfg)); |
146 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); | 146 | mt352_write(fe, mt352_capt_range_cfg, sizeof(mt352_capt_range_cfg)); |
147 | 147 | ||
148 | return 0; | 148 | return 0; |
@@ -161,7 +161,7 @@ static int thomson_dtt7579_pll_set(struct dvb_frontend* fe, struct dvb_frontend_ | |||
161 | else if (params->frequency < 771000000) cp = 0xbc; | 161 | else if (params->frequency < 771000000) cp = 0xbc; |
162 | else cp = 0xf4; | 162 | else cp = 0xf4; |
163 | 163 | ||
164 | if (params->frequency == 0) bs = 0x03; | 164 | if (params->frequency == 0) bs = 0x03; |
165 | else if (params->frequency < 443250000) bs = 0x02; | 165 | else if (params->frequency < 443250000) bs = 0x02; |
166 | else bs = 0x08; | 166 | else bs = 0x08; |
167 | 167 | ||
@@ -190,44 +190,44 @@ static int cx24108_pll_set(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
190 | 190 | ||
191 | 191 | ||
192 | u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, | 192 | u32 osci[]={950000,1019000,1075000,1178000,1296000,1432000, |
193 | 1576000,1718000,1856000,2036000,2150000}; | 193 | 1576000,1718000,1856000,2036000,2150000}; |
194 | u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, | 194 | u32 bandsel[]={0,0x00020000,0x00040000,0x00100800,0x00101000, |
195 | 0x00102000,0x00104000,0x00108000,0x00110000, | 195 | 0x00102000,0x00104000,0x00108000,0x00110000, |
196 | 0x00120000,0x00140000}; | 196 | 0x00120000,0x00140000}; |
197 | 197 | ||
198 | #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ | 198 | #define XTAL 1011100 /* Hz, really 1.0111 MHz and a /10 prescaler */ |
199 | printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); | 199 | printk("cx24108 debug: entering SetTunerFreq, freq=%d\n",freq); |
200 | 200 | ||
201 | /* This is really the bit driving the tuner chip cx24108 */ | 201 | /* This is really the bit driving the tuner chip cx24108 */ |
202 | 202 | ||
203 | if(freq<950000) freq=950000; /* kHz */ | 203 | if(freq<950000) freq=950000; /* kHz */ |
204 | if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ | 204 | if(freq>2150000) freq=2150000; /* satellite IF is 950..2150MHz */ |
205 | 205 | ||
206 | /* decide which VCO to use for the input frequency */ | 206 | /* decide which VCO to use for the input frequency */ |
207 | for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); | 207 | for(i=1;(i<sizeof(osci)/sizeof(osci[0]))&&(osci[i]<freq);i++); |
208 | printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); | 208 | printk("cx24108 debug: select vco #%d (f=%d)\n",i,freq); |
209 | band=bandsel[i]; | 209 | band=bandsel[i]; |
210 | /* the gain values must be set by SetSymbolrate */ | 210 | /* the gain values must be set by SetSymbolrate */ |
211 | /* compute the pll divider needed, from Conexant data sheet, | 211 | /* compute the pll divider needed, from Conexant data sheet, |
212 | resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, | 212 | resolved for (n*32+a), remember f(vco) is f(receive) *2 or *4, |
213 | depending on the divider bit. It is set to /4 on the 2 lowest | 213 | depending on the divider bit. It is set to /4 on the 2 lowest |
214 | bands */ | 214 | bands */ |
215 | n=((i<=2?2:1)*freq*10L)/(XTAL/100); | 215 | n=((i<=2?2:1)*freq*10L)/(XTAL/100); |
216 | a=n%32; n/=32; if(a==0) n--; | 216 | a=n%32; n/=32; if(a==0) n--; |
217 | pump=(freq<(osci[i-1]+osci[i])/2); | 217 | pump=(freq<(osci[i-1]+osci[i])/2); |
218 | pll=0xf8000000| | 218 | pll=0xf8000000| |
219 | ((pump?1:2)<<(14+11))| | 219 | ((pump?1:2)<<(14+11))| |
220 | ((n&0x1ff)<<(5+11))| | 220 | ((n&0x1ff)<<(5+11))| |
221 | ((a&0x1f)<<11); | 221 | ((a&0x1f)<<11); |
222 | /* everything is shifted left 11 bits to left-align the bits in the | 222 | /* everything is shifted left 11 bits to left-align the bits in the |
223 | 32bit word. Output to the tuner goes MSB-aligned, after all */ | 223 | 32bit word. Output to the tuner goes MSB-aligned, after all */ |
224 | printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); | 224 | printk("cx24108 debug: pump=%d, n=%d, a=%d\n",pump,n,a); |
225 | cx24110_pll_write(fe,band); | 225 | cx24110_pll_write(fe,band); |
226 | /* set vga and vca to their widest-band settings, as a precaution. | 226 | /* set vga and vca to their widest-band settings, as a precaution. |
227 | SetSymbolrate might not be called to set this up */ | 227 | SetSymbolrate might not be called to set this up */ |
228 | cx24110_pll_write(fe,0x500c0000); | 228 | cx24110_pll_write(fe,0x500c0000); |
229 | cx24110_pll_write(fe,0x83f1f800); | 229 | cx24110_pll_write(fe,0x83f1f800); |
230 | cx24110_pll_write(fe,pll); | 230 | cx24110_pll_write(fe,pll); |
231 | /* writereg(client,0x56,0x7f);*/ | 231 | /* writereg(client,0x56,0x7f);*/ |
232 | 232 | ||
233 | return 0; | 233 | return 0; |
@@ -299,7 +299,7 @@ static int advbt771_samsung_tdtc9251dh0_demod_init(struct dvb_frontend* fe) | |||
299 | static u8 mt352_reset [] = { 0x50, 0x80 }; | 299 | static u8 mt352_reset [] = { 0x50, 0x80 }; |
300 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | 300 | static u8 mt352_adc_ctl_1_cfg [] = { 0x8E, 0x40 }; |
301 | static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, | 301 | static u8 mt352_agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, |
302 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | 302 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; |
303 | static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; | 303 | static u8 mt352_av771_extra[] = { 0xB5, 0x7A }; |
304 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; | 304 | static u8 mt352_capt_range_cfg[] = { 0x75, 0x32 }; |
305 | 305 | ||
@@ -463,6 +463,9 @@ static struct nxt6000_config vp3021_alps_tded4_config = { | |||
463 | 463 | ||
464 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | 464 | static void frontend_init(struct dvb_bt8xx_card *card, u32 type) |
465 | { | 465 | { |
466 | int ret; | ||
467 | struct dst_state* state = NULL; | ||
468 | |||
466 | switch(type) { | 469 | switch(type) { |
467 | #ifdef BTTV_DVICO_DVBT_LITE | 470 | #ifdef BTTV_DVICO_DVBT_LITE |
468 | case BTTV_DVICO_DVBT_LITE: | 471 | case BTTV_DVICO_DVBT_LITE: |
@@ -503,7 +506,25 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
503 | break; | 506 | break; |
504 | 507 | ||
505 | case BTTV_TWINHAN_DST: | 508 | case BTTV_TWINHAN_DST: |
506 | card->fe = dst_attach(&dst_config, card->i2c_adapter, card->bt); | 509 | /* DST is not a frontend driver !!! */ |
510 | state = (struct dst_state *) kmalloc(sizeof (struct dst_state), GFP_KERNEL); | ||
511 | /* Setup the Card */ | ||
512 | state->config = &dst_config; | ||
513 | state->i2c = card->i2c_adapter; | ||
514 | state->bt = card->bt; | ||
515 | |||
516 | /* DST is not a frontend, attaching the ASIC */ | ||
517 | if ((dst_attach(state, &card->dvb_adapter)) == NULL) { | ||
518 | printk("%s: Could not find a Twinhan DST.\n", __FUNCTION__); | ||
519 | break; | ||
520 | } | ||
521 | card->fe = &state->frontend; | ||
522 | |||
523 | /* Attach other DST peripherals if any */ | ||
524 | /* Conditional Access device */ | ||
525 | if (state->dst_hw_cap & DST_TYPE_HAS_CA) { | ||
526 | ret = dst_ca_attach(state, &card->dvb_adapter); | ||
527 | } | ||
507 | if (card->fe != NULL) { | 528 | if (card->fe != NULL) { |
508 | break; | 529 | break; |
509 | } | 530 | } |
@@ -531,7 +552,7 @@ static void frontend_init(struct dvb_bt8xx_card *card, u32 type) | |||
531 | card->bt->dev->subsystem_vendor, | 552 | card->bt->dev->subsystem_vendor, |
532 | card->bt->dev->subsystem_device); | 553 | card->bt->dev->subsystem_device); |
533 | } else { | 554 | } else { |
534 | if (dvb_register_frontend(card->dvb_adapter, card->fe)) { | 555 | if (dvb_register_frontend(&card->dvb_adapter, card->fe)) { |
535 | printk("dvb-bt8xx: Frontend registration failed!\n"); | 556 | printk("dvb-bt8xx: Frontend registration failed!\n"); |
536 | if (card->fe->ops->release) | 557 | if (card->fe->ops->release) |
537 | card->fe->ops->release(card->fe); | 558 | card->fe->ops->release(card->fe); |
@@ -550,7 +571,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
550 | return result; | 571 | return result; |
551 | 572 | ||
552 | } | 573 | } |
553 | card->dvb_adapter->priv = card; | 574 | card->dvb_adapter.priv = card; |
554 | 575 | ||
555 | card->bt->adapter = card->i2c_adapter; | 576 | card->bt->adapter = card->i2c_adapter; |
556 | 577 | ||
@@ -568,7 +589,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
568 | if ((result = dvb_dmx_init(&card->demux)) < 0) { | 589 | if ((result = dvb_dmx_init(&card->demux)) < 0) { |
569 | printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); | 590 | printk("dvb_bt8xx: dvb_dmx_init failed (errno = %d)\n", result); |
570 | 591 | ||
571 | dvb_unregister_adapter(card->dvb_adapter); | 592 | dvb_unregister_adapter(&card->dvb_adapter); |
572 | return result; | 593 | return result; |
573 | } | 594 | } |
574 | 595 | ||
@@ -576,11 +597,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
576 | card->dmxdev.demux = &card->demux.dmx; | 597 | card->dmxdev.demux = &card->demux.dmx; |
577 | card->dmxdev.capabilities = 0; | 598 | card->dmxdev.capabilities = 0; |
578 | 599 | ||
579 | if ((result = dvb_dmxdev_init(&card->dmxdev, card->dvb_adapter)) < 0) { | 600 | if ((result = dvb_dmxdev_init(&card->dmxdev, &card->dvb_adapter)) < 0) { |
580 | printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); | 601 | printk("dvb_bt8xx: dvb_dmxdev_init failed (errno = %d)\n", result); |
581 | 602 | ||
582 | dvb_dmx_release(&card->demux); | 603 | dvb_dmx_release(&card->demux); |
583 | dvb_unregister_adapter(card->dvb_adapter); | 604 | dvb_unregister_adapter(&card->dvb_adapter); |
584 | return result; | 605 | return result; |
585 | } | 606 | } |
586 | 607 | ||
@@ -591,7 +612,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
591 | 612 | ||
592 | dvb_dmxdev_release(&card->dmxdev); | 613 | dvb_dmxdev_release(&card->dmxdev); |
593 | dvb_dmx_release(&card->demux); | 614 | dvb_dmx_release(&card->demux); |
594 | dvb_unregister_adapter(card->dvb_adapter); | 615 | dvb_unregister_adapter(&card->dvb_adapter); |
595 | return result; | 616 | return result; |
596 | } | 617 | } |
597 | 618 | ||
@@ -603,7 +624,7 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
603 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); | 624 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); |
604 | dvb_dmxdev_release(&card->dmxdev); | 625 | dvb_dmxdev_release(&card->dmxdev); |
605 | dvb_dmx_release(&card->demux); | 626 | dvb_dmx_release(&card->demux); |
606 | dvb_unregister_adapter(card->dvb_adapter); | 627 | dvb_unregister_adapter(&card->dvb_adapter); |
607 | return result; | 628 | return result; |
608 | } | 629 | } |
609 | 630 | ||
@@ -614,11 +635,11 @@ static int __init dvb_bt8xx_load_card(struct dvb_bt8xx_card *card, u32 type) | |||
614 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); | 635 | card->demux.dmx.remove_frontend(&card->demux.dmx, &card->fe_hw); |
615 | dvb_dmxdev_release(&card->dmxdev); | 636 | dvb_dmxdev_release(&card->dmxdev); |
616 | dvb_dmx_release(&card->demux); | 637 | dvb_dmx_release(&card->demux); |
617 | dvb_unregister_adapter(card->dvb_adapter); | 638 | dvb_unregister_adapter(&card->dvb_adapter); |
618 | return result; | 639 | return result; |
619 | } | 640 | } |
620 | 641 | ||
621 | dvb_net_init(card->dvb_adapter, &card->dvbnet, &card->demux.dmx); | 642 | dvb_net_init(&card->dvb_adapter, &card->dvbnet, &card->demux.dmx); |
622 | 643 | ||
623 | tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); | 644 | tasklet_init(&card->bt->tasklet, dvb_bt8xx_task, (unsigned long) card); |
624 | 645 | ||
@@ -648,7 +669,7 @@ static int dvb_bt8xx_probe(struct device *dev) | |||
648 | case BTTV_PINNACLESAT: | 669 | case BTTV_PINNACLESAT: |
649 | card->gpio_mode = 0x0400c060; | 670 | card->gpio_mode = 0x0400c060; |
650 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, | 671 | /* should be: BT878_A_GAIN=0,BT878_A_PWRDN,BT878_DA_DPM,BT878_DA_SBR, |
651 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ | 672 | BT878_DA_IOM=1,BT878_DA_APP to enable serial highspeed mode. */ |
652 | card->op_sync_orin = 0; | 673 | card->op_sync_orin = 0; |
653 | card->irq_err_ignore = 0; | 674 | card->irq_err_ignore = 0; |
654 | break; | 675 | break; |
@@ -759,7 +780,7 @@ static int dvb_bt8xx_remove(struct device *dev) | |||
759 | dvb_dmxdev_release(&card->dmxdev); | 780 | dvb_dmxdev_release(&card->dmxdev); |
760 | dvb_dmx_release(&card->demux); | 781 | dvb_dmx_release(&card->demux); |
761 | if (card->fe) dvb_unregister_frontend(card->fe); | 782 | if (card->fe) dvb_unregister_frontend(card->fe); |
762 | dvb_unregister_adapter(card->dvb_adapter); | 783 | dvb_unregister_adapter(&card->dvb_adapter); |
763 | 784 | ||
764 | kfree(card); | 785 | kfree(card); |
765 | 786 | ||
diff --git a/drivers/media/dvb/bt8xx/dvb-bt8xx.h b/drivers/media/dvb/bt8xx/dvb-bt8xx.h index 80ef189f930f..2923b3b0dd3c 100644 --- a/drivers/media/dvb/bt8xx/dvb-bt8xx.h +++ b/drivers/media/dvb/bt8xx/dvb-bt8xx.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include "bttv.h" | 31 | #include "bttv.h" |
32 | #include "mt352.h" | 32 | #include "mt352.h" |
33 | #include "sp887x.h" | 33 | #include "sp887x.h" |
34 | #include "dst.h" | 34 | #include "dst_common.h" |
35 | #include "nxt6000.h" | 35 | #include "nxt6000.h" |
36 | #include "cx24110.h" | 36 | #include "cx24110.h" |
37 | #include "or51211.h" | 37 | #include "or51211.h" |
@@ -40,7 +40,7 @@ struct dvb_bt8xx_card { | |||
40 | struct semaphore lock; | 40 | struct semaphore lock; |
41 | int nfeeds; | 41 | int nfeeds; |
42 | char card_name[32]; | 42 | char card_name[32]; |
43 | struct dvb_adapter *dvb_adapter; | 43 | struct dvb_adapter dvb_adapter; |
44 | struct bt878 *bt; | 44 | struct bt878 *bt; |
45 | unsigned int bttv_nr; | 45 | unsigned int bttv_nr; |
46 | struct dvb_demux demux; | 46 | struct dvb_demux demux; |
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index 28d4d926de3e..96c57fde95a0 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c | |||
@@ -119,7 +119,7 @@ struct cinergyt2 { | |||
119 | struct dvb_demux demux; | 119 | struct dvb_demux demux; |
120 | struct usb_device *udev; | 120 | struct usb_device *udev; |
121 | struct semaphore sem; | 121 | struct semaphore sem; |
122 | struct dvb_adapter *adapter; | 122 | struct dvb_adapter adapter; |
123 | struct dvb_device *fedev; | 123 | struct dvb_device *fedev; |
124 | struct dmxdev dmxdev; | 124 | struct dmxdev dmxdev; |
125 | struct dvb_net dvbnet; | 125 | struct dvb_net dvbnet; |
@@ -813,15 +813,15 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
813 | cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx; | 813 | cinergyt2->dmxdev.demux = &cinergyt2->demux.dmx; |
814 | cinergyt2->dmxdev.capabilities = 0; | 814 | cinergyt2->dmxdev.capabilities = 0; |
815 | 815 | ||
816 | if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, cinergyt2->adapter)) < 0) { | 816 | if ((err = dvb_dmxdev_init(&cinergyt2->dmxdev, &cinergyt2->adapter)) < 0) { |
817 | dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err); | 817 | dprintk(1, "dvb_dmxdev_init() failed (err = %d)\n", err); |
818 | goto bailout; | 818 | goto bailout; |
819 | } | 819 | } |
820 | 820 | ||
821 | if (dvb_net_init(cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx)) | 821 | if (dvb_net_init(&cinergyt2->adapter, &cinergyt2->dvbnet, &cinergyt2->demux.dmx)) |
822 | dprintk(1, "dvb_net_init() failed!\n"); | 822 | dprintk(1, "dvb_net_init() failed!\n"); |
823 | 823 | ||
824 | dvb_register_device(cinergyt2->adapter, &cinergyt2->fedev, | 824 | dvb_register_device(&cinergyt2->adapter, &cinergyt2->fedev, |
825 | &cinergyt2_fe_template, cinergyt2, | 825 | &cinergyt2_fe_template, cinergyt2, |
826 | DVB_DEVICE_FRONTEND); | 826 | DVB_DEVICE_FRONTEND); |
827 | 827 | ||
@@ -848,7 +848,7 @@ static int cinergyt2_probe (struct usb_interface *intf, | |||
848 | bailout: | 848 | bailout: |
849 | dvb_dmxdev_release(&cinergyt2->dmxdev); | 849 | dvb_dmxdev_release(&cinergyt2->dmxdev); |
850 | dvb_dmx_release(&cinergyt2->demux); | 850 | dvb_dmx_release(&cinergyt2->demux); |
851 | dvb_unregister_adapter (cinergyt2->adapter); | 851 | dvb_unregister_adapter (&cinergyt2->adapter); |
852 | cinergyt2_free_stream_urbs (cinergyt2); | 852 | cinergyt2_free_stream_urbs (cinergyt2); |
853 | kfree(cinergyt2); | 853 | kfree(cinergyt2); |
854 | return -ENOMEM; | 854 | return -ENOMEM; |
@@ -872,7 +872,7 @@ static void cinergyt2_disconnect (struct usb_interface *intf) | |||
872 | dvb_dmxdev_release(&cinergyt2->dmxdev); | 872 | dvb_dmxdev_release(&cinergyt2->dmxdev); |
873 | dvb_dmx_release(&cinergyt2->demux); | 873 | dvb_dmx_release(&cinergyt2->demux); |
874 | dvb_unregister_device(cinergyt2->fedev); | 874 | dvb_unregister_device(cinergyt2->fedev); |
875 | dvb_unregister_adapter(cinergyt2->adapter); | 875 | dvb_unregister_adapter(&cinergyt2->adapter); |
876 | 876 | ||
877 | cinergyt2_free_stream_urbs(cinergyt2); | 877 | cinergyt2_free_stream_urbs(cinergyt2); |
878 | up(&cinergyt2->sem); | 878 | up(&cinergyt2->sem); |
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c index 04e54ec093f0..400b439e804e 100644 --- a/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c +++ b/drivers/media/dvb/dibusb/dvb-dibusb-dvb.c | |||
@@ -131,7 +131,7 @@ int dibusb_dvb_init(struct usb_dibusb *dib) | |||
131 | deb_info("dvb_register_adapter failed: error %d", ret); | 131 | deb_info("dvb_register_adapter failed: error %d", ret); |
132 | goto err; | 132 | goto err; |
133 | } | 133 | } |
134 | dib->adapter->priv = dib; | 134 | dib->adapter.priv = dib; |
135 | 135 | ||
136 | /* i2c is done in dibusb_i2c_init */ | 136 | /* i2c is done in dibusb_i2c_init */ |
137 | 137 | ||
@@ -151,18 +151,18 @@ int dibusb_dvb_init(struct usb_dibusb *dib) | |||
151 | dib->dmxdev.filternum = dib->demux.filternum; | 151 | dib->dmxdev.filternum = dib->demux.filternum; |
152 | dib->dmxdev.demux = &dib->demux.dmx; | 152 | dib->dmxdev.demux = &dib->demux.dmx; |
153 | dib->dmxdev.capabilities = 0; | 153 | dib->dmxdev.capabilities = 0; |
154 | if ((ret = dvb_dmxdev_init(&dib->dmxdev, dib->adapter)) < 0) { | 154 | if ((ret = dvb_dmxdev_init(&dib->dmxdev, &dib->adapter)) < 0) { |
155 | err("dvb_dmxdev_init failed: error %d",ret); | 155 | err("dvb_dmxdev_init failed: error %d",ret); |
156 | goto err_dmx_dev; | 156 | goto err_dmx_dev; |
157 | } | 157 | } |
158 | 158 | ||
159 | dvb_net_init(dib->adapter, &dib->dvb_net, &dib->demux.dmx); | 159 | dvb_net_init(&dib->adapter, &dib->dvb_net, &dib->demux.dmx); |
160 | 160 | ||
161 | goto success; | 161 | goto success; |
162 | err_dmx_dev: | 162 | err_dmx_dev: |
163 | dvb_dmx_release(&dib->demux); | 163 | dvb_dmx_release(&dib->demux); |
164 | err_dmx: | 164 | err_dmx: |
165 | dvb_unregister_adapter(dib->adapter); | 165 | dvb_unregister_adapter(&dib->adapter); |
166 | err: | 166 | err: |
167 | return ret; | 167 | return ret; |
168 | success: | 168 | success: |
@@ -179,7 +179,7 @@ int dibusb_dvb_exit(struct usb_dibusb *dib) | |||
179 | dib->demux.dmx.close(&dib->demux.dmx); | 179 | dib->demux.dmx.close(&dib->demux.dmx); |
180 | dvb_dmxdev_release(&dib->dmxdev); | 180 | dvb_dmxdev_release(&dib->dmxdev); |
181 | dvb_dmx_release(&dib->demux); | 181 | dvb_dmx_release(&dib->demux); |
182 | dvb_unregister_adapter(dib->adapter); | 182 | dvb_unregister_adapter(&dib->adapter); |
183 | } | 183 | } |
184 | return 0; | 184 | return 0; |
185 | } | 185 | } |
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c index 2ed89488c7c4..5a71b88797d9 100644 --- a/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c +++ b/drivers/media/dvb/dibusb/dvb-dibusb-fe-i2c.c | |||
@@ -183,7 +183,7 @@ int dibusb_fe_init(struct usb_dibusb* dib) | |||
183 | dib->dibdev->name); | 183 | dib->dibdev->name); |
184 | return -ENODEV; | 184 | return -ENODEV; |
185 | } else { | 185 | } else { |
186 | if (dvb_register_frontend(dib->adapter, dib->fe)) { | 186 | if (dvb_register_frontend(&dib->adapter, dib->fe)) { |
187 | err("Frontend registration failed."); | 187 | err("Frontend registration failed."); |
188 | if (dib->fe->ops->release) | 188 | if (dib->fe->ops->release) |
189 | dib->fe->ops->release(dib->fe); | 189 | dib->fe->ops->release(dib->fe); |
@@ -206,7 +206,7 @@ int dibusb_i2c_init(struct usb_dibusb *dib) | |||
206 | { | 206 | { |
207 | int ret = 0; | 207 | int ret = 0; |
208 | 208 | ||
209 | dib->adapter->priv = dib; | 209 | dib->adapter.priv = dib; |
210 | 210 | ||
211 | strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE); | 211 | strncpy(dib->i2c_adap.name,dib->dibdev->name,I2C_NAME_SIZE); |
212 | #ifdef I2C_ADAP_CLASS_TV_DIGITAL | 212 | #ifdef I2C_ADAP_CLASS_TV_DIGITAL |
diff --git a/drivers/media/dvb/dibusb/dvb-dibusb.h b/drivers/media/dvb/dibusb/dvb-dibusb.h index 52cd35dd9d83..c965b64fb1ab 100644 --- a/drivers/media/dvb/dibusb/dvb-dibusb.h +++ b/drivers/media/dvb/dibusb/dvb-dibusb.h | |||
@@ -181,7 +181,7 @@ struct usb_dibusb { | |||
181 | struct semaphore i2c_sem; | 181 | struct semaphore i2c_sem; |
182 | 182 | ||
183 | /* dvb */ | 183 | /* dvb */ |
184 | struct dvb_adapter *adapter; | 184 | struct dvb_adapter adapter; |
185 | struct dmxdev dmxdev; | 185 | struct dmxdev dmxdev; |
186 | struct dvb_demux demux; | 186 | struct dvb_demux demux; |
187 | struct dvb_net dvb_net; | 187 | struct dvb_net dvb_net; |
diff --git a/drivers/media/dvb/dvb-core/dmxdev.c b/drivers/media/dvb/dvb-core/dmxdev.c index 1863f1dfb00c..c225de7ffd82 100644 --- a/drivers/media/dvb/dvb-core/dmxdev.c +++ b/drivers/media/dvb/dvb-core/dmxdev.c | |||
@@ -175,8 +175,8 @@ static inline void dvb_dmxdev_dvr_state_set(struct dmxdev_dvr *dmxdevdvr, int st | |||
175 | 175 | ||
176 | static int dvb_dvr_open(struct inode *inode, struct file *file) | 176 | static int dvb_dvr_open(struct inode *inode, struct file *file) |
177 | { | 177 | { |
178 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 178 | struct dvb_device *dvbdev = file->private_data; |
179 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 179 | struct dmxdev *dmxdev = dvbdev->priv; |
180 | struct dmx_frontend *front; | 180 | struct dmx_frontend *front; |
181 | 181 | ||
182 | dprintk ("function : %s\n", __FUNCTION__); | 182 | dprintk ("function : %s\n", __FUNCTION__); |
@@ -224,8 +224,8 @@ static int dvb_dvr_open(struct inode *inode, struct file *file) | |||
224 | 224 | ||
225 | static int dvb_dvr_release(struct inode *inode, struct file *file) | 225 | static int dvb_dvr_release(struct inode *inode, struct file *file) |
226 | { | 226 | { |
227 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 227 | struct dvb_device *dvbdev = file->private_data; |
228 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 228 | struct dmxdev *dmxdev = dvbdev->priv; |
229 | 229 | ||
230 | if (down_interruptible (&dmxdev->mutex)) | 230 | if (down_interruptible (&dmxdev->mutex)) |
231 | return -ERESTARTSYS; | 231 | return -ERESTARTSYS; |
@@ -252,8 +252,8 @@ static int dvb_dvr_release(struct inode *inode, struct file *file) | |||
252 | static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, | 252 | static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, |
253 | size_t count, loff_t *ppos) | 253 | size_t count, loff_t *ppos) |
254 | { | 254 | { |
255 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 255 | struct dvb_device *dvbdev = file->private_data; |
256 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 256 | struct dmxdev *dmxdev = dvbdev->priv; |
257 | int ret; | 257 | int ret; |
258 | 258 | ||
259 | if (!dmxdev->demux->write) | 259 | if (!dmxdev->demux->write) |
@@ -270,8 +270,8 @@ static ssize_t dvb_dvr_write(struct file *file, const char __user *buf, | |||
270 | static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, | 270 | static ssize_t dvb_dvr_read(struct file *file, char __user *buf, size_t count, |
271 | loff_t *ppos) | 271 | loff_t *ppos) |
272 | { | 272 | { |
273 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 273 | struct dvb_device *dvbdev = file->private_data; |
274 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 274 | struct dmxdev *dmxdev = dvbdev->priv; |
275 | int ret; | 275 | int ret; |
276 | 276 | ||
277 | //down(&dmxdev->mutex); | 277 | //down(&dmxdev->mutex); |
@@ -345,7 +345,7 @@ static int dvb_dmxdev_section_callback(const u8 *buffer1, size_t buffer1_len, | |||
345 | const u8 *buffer2, size_t buffer2_len, | 345 | const u8 *buffer2, size_t buffer2_len, |
346 | struct dmx_section_filter *filter, enum dmx_success success) | 346 | struct dmx_section_filter *filter, enum dmx_success success) |
347 | { | 347 | { |
348 | struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) filter->priv; | 348 | struct dmxdev_filter *dmxdevfilter = filter->priv; |
349 | int ret; | 349 | int ret; |
350 | 350 | ||
351 | if (dmxdevfilter->buffer.error) { | 351 | if (dmxdevfilter->buffer.error) { |
@@ -381,7 +381,7 @@ static int dvb_dmxdev_ts_callback(const u8 *buffer1, size_t buffer1_len, | |||
381 | const u8 *buffer2, size_t buffer2_len, | 381 | const u8 *buffer2, size_t buffer2_len, |
382 | struct dmx_ts_feed *feed, enum dmx_success success) | 382 | struct dmx_ts_feed *feed, enum dmx_success success) |
383 | { | 383 | { |
384 | struct dmxdev_filter *dmxdevfilter=(struct dmxdev_filter *) feed->priv; | 384 | struct dmxdev_filter *dmxdevfilter = feed->priv; |
385 | struct dmxdev_buffer *buffer; | 385 | struct dmxdev_buffer *buffer; |
386 | int ret; | 386 | int ret; |
387 | 387 | ||
@@ -684,8 +684,8 @@ static int dvb_dmxdev_filter_start(struct dmxdev_filter *filter) | |||
684 | 684 | ||
685 | static int dvb_demux_open(struct inode *inode, struct file *file) | 685 | static int dvb_demux_open(struct inode *inode, struct file *file) |
686 | { | 686 | { |
687 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 687 | struct dvb_device *dvbdev = file->private_data; |
688 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 688 | struct dmxdev *dmxdev = dvbdev->priv; |
689 | int i; | 689 | int i; |
690 | struct dmxdev_filter *dmxdevfilter; | 690 | struct dmxdev_filter *dmxdevfilter; |
691 | 691 | ||
@@ -1013,8 +1013,8 @@ static struct dvb_device dvbdev_demux = { | |||
1013 | static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, | 1013 | static int dvb_dvr_do_ioctl(struct inode *inode, struct file *file, |
1014 | unsigned int cmd, void *parg) | 1014 | unsigned int cmd, void *parg) |
1015 | { | 1015 | { |
1016 | struct dvb_device *dvbdev=(struct dvb_device *) file->private_data; | 1016 | struct dvb_device *dvbdev = file->private_data; |
1017 | struct dmxdev *dmxdev=(struct dmxdev *) dvbdev->priv; | 1017 | struct dmxdev *dmxdev = dvbdev->priv; |
1018 | 1018 | ||
1019 | int ret=0; | 1019 | int ret=0; |
1020 | 1020 | ||
@@ -1044,8 +1044,8 @@ static int dvb_dvr_ioctl(struct inode *inode, struct file *file, | |||
1044 | 1044 | ||
1045 | static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) | 1045 | static unsigned int dvb_dvr_poll (struct file *file, poll_table *wait) |
1046 | { | 1046 | { |
1047 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1047 | struct dvb_device *dvbdev = file->private_data; |
1048 | struct dmxdev *dmxdev = (struct dmxdev *) dvbdev->priv; | 1048 | struct dmxdev *dmxdev = dvbdev->priv; |
1049 | unsigned int mask = 0; | 1049 | unsigned int mask = 0; |
1050 | 1050 | ||
1051 | dprintk ("function : %s\n", __FUNCTION__); | 1051 | dprintk ("function : %s\n", __FUNCTION__); |
diff --git a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c index c1ea89f2880c..0eb9aa711fb0 100644 --- a/drivers/media/dvb/dvb-core/dvb_ca_en50221.c +++ b/drivers/media/dvb/dvb-core/dvb_ca_en50221.c | |||
@@ -829,7 +829,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_camready_irq); | |||
829 | */ | 829 | */ |
830 | void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) | 830 | void dvb_ca_en50221_camchange_irq(struct dvb_ca_en50221 *pubca, int slot, int change_type) |
831 | { | 831 | { |
832 | struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private; | 832 | struct dvb_ca_private *ca = pubca->private; |
833 | 833 | ||
834 | dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type); | 834 | dprintk("CAMCHANGE IRQ slot:%i change_type:%i\n", slot, change_type); |
835 | 835 | ||
@@ -857,7 +857,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_frda_irq); | |||
857 | */ | 857 | */ |
858 | void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) | 858 | void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) |
859 | { | 859 | { |
860 | struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private; | 860 | struct dvb_ca_private *ca = pubca->private; |
861 | 861 | ||
862 | dprintk("CAMREADY IRQ slot:%i\n", slot); | 862 | dprintk("CAMREADY IRQ slot:%i\n", slot); |
863 | 863 | ||
@@ -876,7 +876,7 @@ void dvb_ca_en50221_camready_irq(struct dvb_ca_en50221 *pubca, int slot) | |||
876 | */ | 876 | */ |
877 | void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) | 877 | void dvb_ca_en50221_frda_irq(struct dvb_ca_en50221 *pubca, int slot) |
878 | { | 878 | { |
879 | struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private; | 879 | struct dvb_ca_private *ca = pubca->private; |
880 | int flags; | 880 | int flags; |
881 | 881 | ||
882 | dprintk("FR/DA IRQ slot:%i\n", slot); | 882 | dprintk("FR/DA IRQ slot:%i\n", slot); |
@@ -993,7 +993,7 @@ static void dvb_ca_en50221_thread_update_delay(struct dvb_ca_private *ca) | |||
993 | */ | 993 | */ |
994 | static int dvb_ca_en50221_thread(void *data) | 994 | static int dvb_ca_en50221_thread(void *data) |
995 | { | 995 | { |
996 | struct dvb_ca_private *ca = (struct dvb_ca_private *) data; | 996 | struct dvb_ca_private *ca = data; |
997 | char name[15]; | 997 | char name[15]; |
998 | int slot; | 998 | int slot; |
999 | int flags; | 999 | int flags; |
@@ -1202,8 +1202,8 @@ static int dvb_ca_en50221_thread(void *data) | |||
1202 | static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, | 1202 | static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, |
1203 | unsigned int cmd, void *parg) | 1203 | unsigned int cmd, void *parg) |
1204 | { | 1204 | { |
1205 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1205 | struct dvb_device *dvbdev = file->private_data; |
1206 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1206 | struct dvb_ca_private *ca = dvbdev->priv; |
1207 | int err = 0; | 1207 | int err = 0; |
1208 | int slot; | 1208 | int slot; |
1209 | 1209 | ||
@@ -1225,7 +1225,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, | |||
1225 | break; | 1225 | break; |
1226 | 1226 | ||
1227 | case CA_GET_CAP: { | 1227 | case CA_GET_CAP: { |
1228 | struct ca_caps *caps = (struct ca_caps *) parg; | 1228 | struct ca_caps *caps = parg; |
1229 | 1229 | ||
1230 | caps->slot_num = ca->slot_count; | 1230 | caps->slot_num = ca->slot_count; |
1231 | caps->slot_type = CA_CI_LINK; | 1231 | caps->slot_type = CA_CI_LINK; |
@@ -1235,7 +1235,7 @@ static int dvb_ca_en50221_io_do_ioctl(struct inode *inode, struct file *file, | |||
1235 | } | 1235 | } |
1236 | 1236 | ||
1237 | case CA_GET_SLOT_INFO: { | 1237 | case CA_GET_SLOT_INFO: { |
1238 | struct ca_slot_info *info = (struct ca_slot_info *) parg; | 1238 | struct ca_slot_info *info = parg; |
1239 | 1239 | ||
1240 | if ((info->num > ca->slot_count) || (info->num < 0)) | 1240 | if ((info->num > ca->slot_count) || (info->num < 0)) |
1241 | return -EINVAL; | 1241 | return -EINVAL; |
@@ -1291,8 +1291,8 @@ static int dvb_ca_en50221_io_ioctl(struct inode *inode, struct file *file, | |||
1291 | static ssize_t dvb_ca_en50221_io_write(struct file *file, | 1291 | static ssize_t dvb_ca_en50221_io_write(struct file *file, |
1292 | const char __user * buf, size_t count, loff_t * ppos) | 1292 | const char __user * buf, size_t count, loff_t * ppos) |
1293 | { | 1293 | { |
1294 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1294 | struct dvb_device *dvbdev = file->private_data; |
1295 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1295 | struct dvb_ca_private *ca = dvbdev->priv; |
1296 | u8 slot, connection_id; | 1296 | u8 slot, connection_id; |
1297 | int status; | 1297 | int status; |
1298 | char fragbuf[HOST_LINK_BUF_SIZE]; | 1298 | char fragbuf[HOST_LINK_BUF_SIZE]; |
@@ -1428,8 +1428,8 @@ static int dvb_ca_en50221_io_read_condition(struct dvb_ca_private *ca, int *resu | |||
1428 | static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, | 1428 | static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, |
1429 | size_t count, loff_t * ppos) | 1429 | size_t count, loff_t * ppos) |
1430 | { | 1430 | { |
1431 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1431 | struct dvb_device *dvbdev = file->private_data; |
1432 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1432 | struct dvb_ca_private *ca = dvbdev->priv; |
1433 | int status; | 1433 | int status; |
1434 | int result = 0; | 1434 | int result = 0; |
1435 | u8 hdr[2]; | 1435 | u8 hdr[2]; |
@@ -1526,8 +1526,8 @@ static ssize_t dvb_ca_en50221_io_read(struct file *file, char __user * buf, | |||
1526 | */ | 1526 | */ |
1527 | static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) | 1527 | static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) |
1528 | { | 1528 | { |
1529 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1529 | struct dvb_device *dvbdev = file->private_data; |
1530 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1530 | struct dvb_ca_private *ca = dvbdev->priv; |
1531 | int err; | 1531 | int err; |
1532 | int i; | 1532 | int i; |
1533 | 1533 | ||
@@ -1569,8 +1569,8 @@ static int dvb_ca_en50221_io_open(struct inode *inode, struct file *file) | |||
1569 | */ | 1569 | */ |
1570 | static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) | 1570 | static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) |
1571 | { | 1571 | { |
1572 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1572 | struct dvb_device *dvbdev = file->private_data; |
1573 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1573 | struct dvb_ca_private *ca = dvbdev->priv; |
1574 | int err = 0; | 1574 | int err = 0; |
1575 | 1575 | ||
1576 | dprintk("%s\n", __FUNCTION__); | 1576 | dprintk("%s\n", __FUNCTION__); |
@@ -1597,8 +1597,8 @@ static int dvb_ca_en50221_io_release(struct inode *inode, struct file *file) | |||
1597 | */ | 1597 | */ |
1598 | static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) | 1598 | static unsigned int dvb_ca_en50221_io_poll(struct file *file, poll_table * wait) |
1599 | { | 1599 | { |
1600 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1600 | struct dvb_device *dvbdev = file->private_data; |
1601 | struct dvb_ca_private *ca = (struct dvb_ca_private *) dvbdev->priv; | 1601 | struct dvb_ca_private *ca = dvbdev->priv; |
1602 | unsigned int mask = 0; | 1602 | unsigned int mask = 0; |
1603 | int slot; | 1603 | int slot; |
1604 | int result = 0; | 1604 | int result = 0; |
@@ -1750,7 +1750,7 @@ EXPORT_SYMBOL(dvb_ca_en50221_release); | |||
1750 | */ | 1750 | */ |
1751 | void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) | 1751 | void dvb_ca_en50221_release(struct dvb_ca_en50221 *pubca) |
1752 | { | 1752 | { |
1753 | struct dvb_ca_private *ca = (struct dvb_ca_private *) pubca->private; | 1753 | struct dvb_ca_private *ca = pubca->private; |
1754 | int i; | 1754 | int i; |
1755 | 1755 | ||
1756 | dprintk("%s\n", __FUNCTION__); | 1756 | dprintk("%s\n", __FUNCTION__); |
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index 59a9adfae1eb..d19301d90a09 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c | |||
@@ -48,7 +48,7 @@ static int dvb_override_tune_delay; | |||
48 | static int dvb_powerdown_on_sleep = 1; | 48 | static int dvb_powerdown_on_sleep = 1; |
49 | 49 | ||
50 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); | 50 | module_param_named(frontend_debug, dvb_frontend_debug, int, 0644); |
51 | MODULE_PARM_DESC(dvb_frontend_debug, "Turn on/off frontend core debugging (default:off)."); | 51 | MODULE_PARM_DESC(frontend_debug, "Turn on/off frontend core debugging (default:off)."); |
52 | module_param(dvb_shutdown_timeout, int, 0444); | 52 | module_param(dvb_shutdown_timeout, int, 0444); |
53 | MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); | 53 | MODULE_PARM_DESC(dvb_shutdown_timeout, "wait <shutdown_timeout> seconds after close() before suspending hardware"); |
54 | module_param(dvb_force_auto_inversion, int, 0444); | 54 | module_param(dvb_force_auto_inversion, int, 0444); |
@@ -117,7 +117,7 @@ struct dvb_frontend_private { | |||
117 | 117 | ||
118 | static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) | 118 | static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) |
119 | { | 119 | { |
120 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 120 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
121 | struct dvb_fe_events *events = &fepriv->events; | 121 | struct dvb_fe_events *events = &fepriv->events; |
122 | struct dvb_frontend_event *e; | 122 | struct dvb_frontend_event *e; |
123 | int wp; | 123 | int wp; |
@@ -155,7 +155,7 @@ static void dvb_frontend_add_event(struct dvb_frontend *fe, fe_status_t status) | |||
155 | static int dvb_frontend_get_event(struct dvb_frontend *fe, | 155 | static int dvb_frontend_get_event(struct dvb_frontend *fe, |
156 | struct dvb_frontend_event *event, int flags) | 156 | struct dvb_frontend_event *event, int flags) |
157 | { | 157 | { |
158 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 158 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
159 | struct dvb_fe_events *events = &fepriv->events; | 159 | struct dvb_fe_events *events = &fepriv->events; |
160 | 160 | ||
161 | dprintk ("%s\n", __FUNCTION__); | 161 | dprintk ("%s\n", __FUNCTION__); |
@@ -234,7 +234,7 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | |||
234 | { | 234 | { |
235 | int autoinversion; | 235 | int autoinversion; |
236 | int ready = 0; | 236 | int ready = 0; |
237 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 237 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
238 | int original_inversion = fepriv->parameters.inversion; | 238 | int original_inversion = fepriv->parameters.inversion; |
239 | u32 original_frequency = fepriv->parameters.frequency; | 239 | u32 original_frequency = fepriv->parameters.frequency; |
240 | 240 | ||
@@ -321,7 +321,7 @@ static int dvb_frontend_autotune(struct dvb_frontend *fe, int check_wrapped) | |||
321 | 321 | ||
322 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | 322 | static int dvb_frontend_is_exiting(struct dvb_frontend *fe) |
323 | { | 323 | { |
324 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 324 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
325 | 325 | ||
326 | if (fepriv->exit) | 326 | if (fepriv->exit) |
327 | return 1; | 327 | return 1; |
@@ -335,7 +335,7 @@ static int dvb_frontend_is_exiting(struct dvb_frontend *fe) | |||
335 | 335 | ||
336 | static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) | 336 | static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) |
337 | { | 337 | { |
338 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 338 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
339 | 339 | ||
340 | if (fepriv->wakeup) { | 340 | if (fepriv->wakeup) { |
341 | fepriv->wakeup = 0; | 341 | fepriv->wakeup = 0; |
@@ -346,7 +346,7 @@ static int dvb_frontend_should_wakeup(struct dvb_frontend *fe) | |||
346 | 346 | ||
347 | static void dvb_frontend_wakeup(struct dvb_frontend *fe) | 347 | static void dvb_frontend_wakeup(struct dvb_frontend *fe) |
348 | { | 348 | { |
349 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 349 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
350 | 350 | ||
351 | fepriv->wakeup = 1; | 351 | fepriv->wakeup = 1; |
352 | wake_up_interruptible(&fepriv->wait_queue); | 352 | wake_up_interruptible(&fepriv->wait_queue); |
@@ -357,8 +357,8 @@ static void dvb_frontend_wakeup(struct dvb_frontend *fe) | |||
357 | */ | 357 | */ |
358 | static int dvb_frontend_thread(void *data) | 358 | static int dvb_frontend_thread(void *data) |
359 | { | 359 | { |
360 | struct dvb_frontend *fe = (struct dvb_frontend *) data; | 360 | struct dvb_frontend *fe = data; |
361 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 361 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
362 | unsigned long timeout; | 362 | unsigned long timeout; |
363 | char name [15]; | 363 | char name [15]; |
364 | int quality = 0, delay = 3*HZ; | 364 | int quality = 0, delay = 3*HZ; |
@@ -520,7 +520,7 @@ static int dvb_frontend_thread(void *data) | |||
520 | static void dvb_frontend_stop(struct dvb_frontend *fe) | 520 | static void dvb_frontend_stop(struct dvb_frontend *fe) |
521 | { | 521 | { |
522 | unsigned long ret; | 522 | unsigned long ret; |
523 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 523 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
524 | 524 | ||
525 | dprintk ("%s\n", __FUNCTION__); | 525 | dprintk ("%s\n", __FUNCTION__); |
526 | 526 | ||
@@ -559,7 +559,7 @@ static void dvb_frontend_stop(struct dvb_frontend *fe) | |||
559 | static int dvb_frontend_start(struct dvb_frontend *fe) | 559 | static int dvb_frontend_start(struct dvb_frontend *fe) |
560 | { | 560 | { |
561 | int ret; | 561 | int ret; |
562 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 562 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
563 | 563 | ||
564 | dprintk ("%s\n", __FUNCTION__); | 564 | dprintk ("%s\n", __FUNCTION__); |
565 | 565 | ||
@@ -597,7 +597,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
597 | { | 597 | { |
598 | struct dvb_device *dvbdev = file->private_data; | 598 | struct dvb_device *dvbdev = file->private_data; |
599 | struct dvb_frontend *fe = dvbdev->priv; | 599 | struct dvb_frontend *fe = dvbdev->priv; |
600 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 600 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
601 | int err = -EOPNOTSUPP; | 601 | int err = -EOPNOTSUPP; |
602 | 602 | ||
603 | dprintk ("%s\n", __FUNCTION__); | 603 | dprintk ("%s\n", __FUNCTION__); |
@@ -615,7 +615,7 @@ static int dvb_frontend_ioctl(struct inode *inode, struct file *file, | |||
615 | 615 | ||
616 | switch (cmd) { | 616 | switch (cmd) { |
617 | case FE_GET_INFO: { | 617 | case FE_GET_INFO: { |
618 | struct dvb_frontend_info* info = (struct dvb_frontend_info*) parg; | 618 | struct dvb_frontend_info* info = parg; |
619 | memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); | 619 | memcpy(info, &fe->ops->info, sizeof(struct dvb_frontend_info)); |
620 | 620 | ||
621 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't | 621 | /* Force the CAN_INVERSION_AUTO bit on. If the frontend doesn't |
@@ -793,7 +793,7 @@ static unsigned int dvb_frontend_poll(struct file *file, struct poll_table_struc | |||
793 | { | 793 | { |
794 | struct dvb_device *dvbdev = file->private_data; | 794 | struct dvb_device *dvbdev = file->private_data; |
795 | struct dvb_frontend *fe = dvbdev->priv; | 795 | struct dvb_frontend *fe = dvbdev->priv; |
796 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 796 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
797 | 797 | ||
798 | dprintk ("%s\n", __FUNCTION__); | 798 | dprintk ("%s\n", __FUNCTION__); |
799 | 799 | ||
@@ -809,7 +809,7 @@ static int dvb_frontend_open(struct inode *inode, struct file *file) | |||
809 | { | 809 | { |
810 | struct dvb_device *dvbdev = file->private_data; | 810 | struct dvb_device *dvbdev = file->private_data; |
811 | struct dvb_frontend *fe = dvbdev->priv; | 811 | struct dvb_frontend *fe = dvbdev->priv; |
812 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 812 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
813 | int ret; | 813 | int ret; |
814 | 814 | ||
815 | dprintk ("%s\n", __FUNCTION__); | 815 | dprintk ("%s\n", __FUNCTION__); |
@@ -833,7 +833,7 @@ static int dvb_frontend_release(struct inode *inode, struct file *file) | |||
833 | { | 833 | { |
834 | struct dvb_device *dvbdev = file->private_data; | 834 | struct dvb_device *dvbdev = file->private_data; |
835 | struct dvb_frontend *fe = dvbdev->priv; | 835 | struct dvb_frontend *fe = dvbdev->priv; |
836 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 836 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
837 | 837 | ||
838 | dprintk ("%s\n", __FUNCTION__); | 838 | dprintk ("%s\n", __FUNCTION__); |
839 | 839 | ||
@@ -873,7 +873,7 @@ int dvb_register_frontend(struct dvb_adapter* dvb, | |||
873 | up(&frontend_mutex); | 873 | up(&frontend_mutex); |
874 | return -ENOMEM; | 874 | return -ENOMEM; |
875 | } | 875 | } |
876 | fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 876 | fepriv = fe->frontend_priv; |
877 | memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private)); | 877 | memset(fe->frontend_priv, 0, sizeof(struct dvb_frontend_private)); |
878 | 878 | ||
879 | init_MUTEX (&fepriv->sem); | 879 | init_MUTEX (&fepriv->sem); |
@@ -897,7 +897,7 @@ EXPORT_SYMBOL(dvb_register_frontend); | |||
897 | 897 | ||
898 | int dvb_unregister_frontend(struct dvb_frontend* fe) | 898 | int dvb_unregister_frontend(struct dvb_frontend* fe) |
899 | { | 899 | { |
900 | struct dvb_frontend_private *fepriv = (struct dvb_frontend_private*) fe->frontend_priv; | 900 | struct dvb_frontend_private *fepriv = fe->frontend_priv; |
901 | dprintk ("%s\n", __FUNCTION__); | 901 | dprintk ("%s\n", __FUNCTION__); |
902 | 902 | ||
903 | down (&frontend_mutex); | 903 | down (&frontend_mutex); |
diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index 44892e7abd3d..6a968c346a36 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c | |||
@@ -315,7 +315,7 @@ static inline void reset_ule( struct dvb_net_priv *p ) | |||
315 | */ | 315 | */ |
316 | static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) | 316 | static void dvb_net_ule( struct net_device *dev, const u8 *buf, size_t buf_len ) |
317 | { | 317 | { |
318 | struct dvb_net_priv *priv = (struct dvb_net_priv *)dev->priv; | 318 | struct dvb_net_priv *priv = dev->priv; |
319 | unsigned long skipped = 0L; | 319 | unsigned long skipped = 0L; |
320 | u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1; | 320 | u8 *ts, *ts_end, *from_where = NULL, ts_remain = 0, how_much = 0, new_ts = 1; |
321 | struct ethhdr *ethh = NULL; | 321 | struct ethhdr *ethh = NULL; |
@@ -709,7 +709,7 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, | |||
709 | const u8 *buffer2, size_t buffer2_len, | 709 | const u8 *buffer2, size_t buffer2_len, |
710 | struct dmx_ts_feed *feed, enum dmx_success success) | 710 | struct dmx_ts_feed *feed, enum dmx_success success) |
711 | { | 711 | { |
712 | struct net_device *dev = (struct net_device *)feed->priv; | 712 | struct net_device *dev = feed->priv; |
713 | 713 | ||
714 | if (buffer2 != 0) | 714 | if (buffer2 != 0) |
715 | printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2); | 715 | printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2); |
@@ -727,6 +727,7 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) | |||
727 | u8 *eth; | 727 | u8 *eth; |
728 | struct sk_buff *skb; | 728 | struct sk_buff *skb; |
729 | struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats); | 729 | struct net_device_stats *stats = &(((struct dvb_net_priv *) dev->priv)->stats); |
730 | int snap = 0; | ||
730 | 731 | ||
731 | /* note: pkt_len includes a 32bit checksum */ | 732 | /* note: pkt_len includes a 32bit checksum */ |
732 | if (pkt_len < 16) { | 733 | if (pkt_len < 16) { |
@@ -750,9 +751,12 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) | |||
750 | return; | 751 | return; |
751 | } | 752 | } |
752 | if (pkt[5] & 0x02) { | 753 | if (pkt[5] & 0x02) { |
753 | //FIXME: handle LLC/SNAP | 754 | /* handle LLC/SNAP, see rfc-1042 */ |
754 | stats->rx_dropped++; | 755 | if (pkt_len < 24 || memcmp(&pkt[12], "\xaa\xaa\x03\0\0\0", 6)) { |
755 | return; | 756 | stats->rx_dropped++; |
757 | return; | ||
758 | } | ||
759 | snap = 8; | ||
756 | } | 760 | } |
757 | if (pkt[7]) { | 761 | if (pkt[7]) { |
758 | /* FIXME: assemble datagram from multiple sections */ | 762 | /* FIXME: assemble datagram from multiple sections */ |
@@ -762,9 +766,9 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) | |||
762 | } | 766 | } |
763 | 767 | ||
764 | /* we have 14 byte ethernet header (ip header follows); | 768 | /* we have 14 byte ethernet header (ip header follows); |
765 | * 12 byte MPE header; 4 byte checksum; + 2 byte alignment | 769 | * 12 byte MPE header; 4 byte checksum; + 2 byte alignment, 8 byte LLC/SNAP |
766 | */ | 770 | */ |
767 | if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2))) { | 771 | if (!(skb = dev_alloc_skb(pkt_len - 4 - 12 + 14 + 2 - snap))) { |
768 | //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); | 772 | //printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name); |
769 | stats->rx_dropped++; | 773 | stats->rx_dropped++; |
770 | return; | 774 | return; |
@@ -773,8 +777,8 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) | |||
773 | skb->dev = dev; | 777 | skb->dev = dev; |
774 | 778 | ||
775 | /* copy L3 payload */ | 779 | /* copy L3 payload */ |
776 | eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14); | 780 | eth = (u8 *) skb_put(skb, pkt_len - 12 - 4 + 14 - snap); |
777 | memcpy(eth + 14, pkt + 12, pkt_len - 12 - 4); | 781 | memcpy(eth + 14, pkt + 12 + snap, pkt_len - 12 - 4 - snap); |
778 | 782 | ||
779 | /* create ethernet header: */ | 783 | /* create ethernet header: */ |
780 | eth[0]=pkt[0x0b]; | 784 | eth[0]=pkt[0x0b]; |
@@ -786,8 +790,21 @@ static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) | |||
786 | 790 | ||
787 | eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0; | 791 | eth[6]=eth[7]=eth[8]=eth[9]=eth[10]=eth[11]=0; |
788 | 792 | ||
789 | eth[12] = 0x08; /* ETH_P_IP */ | 793 | if (snap) { |
790 | eth[13] = 0x00; | 794 | eth[12] = pkt[18]; |
795 | eth[13] = pkt[19]; | ||
796 | } else { | ||
797 | /* protocol numbers are from rfc-1700 or | ||
798 | * http://www.iana.org/assignments/ethernet-numbers | ||
799 | */ | ||
800 | if (pkt[12] >> 4 == 6) { /* version field from IP header */ | ||
801 | eth[12] = 0x86; /* IPv6 */ | ||
802 | eth[13] = 0xdd; | ||
803 | } else { | ||
804 | eth[12] = 0x08; /* IPv4 */ | ||
805 | eth[13] = 0x00; | ||
806 | } | ||
807 | } | ||
791 | 808 | ||
792 | skb->protocol = dvb_net_eth_type_trans(skb, dev); | 809 | skb->protocol = dvb_net_eth_type_trans(skb, dev); |
793 | 810 | ||
@@ -801,7 +818,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, | |||
801 | struct dmx_section_filter *filter, | 818 | struct dmx_section_filter *filter, |
802 | enum dmx_success success) | 819 | enum dmx_success success) |
803 | { | 820 | { |
804 | struct net_device *dev=(struct net_device *) filter->priv; | 821 | struct net_device *dev = filter->priv; |
805 | 822 | ||
806 | /** | 823 | /** |
807 | * we rely on the DVB API definition where exactly one complete | 824 | * we rely on the DVB API definition where exactly one complete |
@@ -826,7 +843,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev, | |||
826 | struct dmx_section_filter **secfilter, | 843 | struct dmx_section_filter **secfilter, |
827 | u8 *mac, u8 *mac_mask) | 844 | u8 *mac, u8 *mac_mask) |
828 | { | 845 | { |
829 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 846 | struct dvb_net_priv *priv = dev->priv; |
830 | int ret; | 847 | int ret; |
831 | 848 | ||
832 | *secfilter=NULL; | 849 | *secfilter=NULL; |
@@ -870,7 +887,7 @@ static int dvb_net_filter_sec_set(struct net_device *dev, | |||
870 | static int dvb_net_feed_start(struct net_device *dev) | 887 | static int dvb_net_feed_start(struct net_device *dev) |
871 | { | 888 | { |
872 | int ret, i; | 889 | int ret, i; |
873 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 890 | struct dvb_net_priv *priv = dev->priv; |
874 | struct dmx_demux *demux = priv->demux; | 891 | struct dmx_demux *demux = priv->demux; |
875 | unsigned char *mac = (unsigned char *) dev->dev_addr; | 892 | unsigned char *mac = (unsigned char *) dev->dev_addr; |
876 | 893 | ||
@@ -965,7 +982,7 @@ static int dvb_net_feed_start(struct net_device *dev) | |||
965 | 982 | ||
966 | static int dvb_net_feed_stop(struct net_device *dev) | 983 | static int dvb_net_feed_stop(struct net_device *dev) |
967 | { | 984 | { |
968 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 985 | struct dvb_net_priv *priv = dev->priv; |
969 | int i; | 986 | int i; |
970 | 987 | ||
971 | dprintk("%s\n", __FUNCTION__); | 988 | dprintk("%s\n", __FUNCTION__); |
@@ -1016,7 +1033,7 @@ static int dvb_net_feed_stop(struct net_device *dev) | |||
1016 | 1033 | ||
1017 | static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) | 1034 | static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) |
1018 | { | 1035 | { |
1019 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1036 | struct dvb_net_priv *priv = dev->priv; |
1020 | 1037 | ||
1021 | if (priv->multi_num == DVB_NET_MULTICAST_MAX) | 1038 | if (priv->multi_num == DVB_NET_MULTICAST_MAX) |
1022 | return -ENOMEM; | 1039 | return -ENOMEM; |
@@ -1031,7 +1048,7 @@ static int dvb_set_mc_filter (struct net_device *dev, struct dev_mc_list *mc) | |||
1031 | static void wq_set_multicast_list (void *data) | 1048 | static void wq_set_multicast_list (void *data) |
1032 | { | 1049 | { |
1033 | struct net_device *dev = data; | 1050 | struct net_device *dev = data; |
1034 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1051 | struct dvb_net_priv *priv = dev->priv; |
1035 | 1052 | ||
1036 | dvb_net_feed_stop(dev); | 1053 | dvb_net_feed_stop(dev); |
1037 | 1054 | ||
@@ -1066,7 +1083,7 @@ static void wq_set_multicast_list (void *data) | |||
1066 | 1083 | ||
1067 | static void dvb_net_set_multicast_list (struct net_device *dev) | 1084 | static void dvb_net_set_multicast_list (struct net_device *dev) |
1068 | { | 1085 | { |
1069 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1086 | struct dvb_net_priv *priv = dev->priv; |
1070 | schedule_work(&priv->set_multicast_list_wq); | 1087 | schedule_work(&priv->set_multicast_list_wq); |
1071 | } | 1088 | } |
1072 | 1089 | ||
@@ -1084,7 +1101,7 @@ static void wq_restart_net_feed (void *data) | |||
1084 | 1101 | ||
1085 | static int dvb_net_set_mac (struct net_device *dev, void *p) | 1102 | static int dvb_net_set_mac (struct net_device *dev, void *p) |
1086 | { | 1103 | { |
1087 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1104 | struct dvb_net_priv *priv = dev->priv; |
1088 | struct sockaddr *addr=p; | 1105 | struct sockaddr *addr=p; |
1089 | 1106 | ||
1090 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); | 1107 | memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); |
@@ -1098,7 +1115,7 @@ static int dvb_net_set_mac (struct net_device *dev, void *p) | |||
1098 | 1115 | ||
1099 | static int dvb_net_open(struct net_device *dev) | 1116 | static int dvb_net_open(struct net_device *dev) |
1100 | { | 1117 | { |
1101 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1118 | struct dvb_net_priv *priv = dev->priv; |
1102 | 1119 | ||
1103 | priv->in_use++; | 1120 | priv->in_use++; |
1104 | dvb_net_feed_start(dev); | 1121 | dvb_net_feed_start(dev); |
@@ -1108,7 +1125,7 @@ static int dvb_net_open(struct net_device *dev) | |||
1108 | 1125 | ||
1109 | static int dvb_net_stop(struct net_device *dev) | 1126 | static int dvb_net_stop(struct net_device *dev) |
1110 | { | 1127 | { |
1111 | struct dvb_net_priv *priv = (struct dvb_net_priv*) dev->priv; | 1128 | struct dvb_net_priv *priv = dev->priv; |
1112 | 1129 | ||
1113 | priv->in_use--; | 1130 | priv->in_use--; |
1114 | return dvb_net_feed_stop(dev); | 1131 | return dvb_net_feed_stop(dev); |
@@ -1228,8 +1245,8 @@ static int dvb_net_remove_if(struct dvb_net *dvbnet, unsigned int num) | |||
1228 | static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | 1245 | static int dvb_net_do_ioctl(struct inode *inode, struct file *file, |
1229 | unsigned int cmd, void *parg) | 1246 | unsigned int cmd, void *parg) |
1230 | { | 1247 | { |
1231 | struct dvb_device *dvbdev = (struct dvb_device *) file->private_data; | 1248 | struct dvb_device *dvbdev = file->private_data; |
1232 | struct dvb_net *dvbnet = (struct dvb_net *) dvbdev->priv; | 1249 | struct dvb_net *dvbnet = dvbdev->priv; |
1233 | 1250 | ||
1234 | if (((file->f_flags&O_ACCMODE)==O_RDONLY)) | 1251 | if (((file->f_flags&O_ACCMODE)==O_RDONLY)) |
1235 | return -EPERM; | 1252 | return -EPERM; |
@@ -1237,7 +1254,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1237 | switch (cmd) { | 1254 | switch (cmd) { |
1238 | case NET_ADD_IF: | 1255 | case NET_ADD_IF: |
1239 | { | 1256 | { |
1240 | struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg; | 1257 | struct dvb_net_if *dvbnetif = parg; |
1241 | int result; | 1258 | int result; |
1242 | 1259 | ||
1243 | if (!capable(CAP_SYS_ADMIN)) | 1260 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1258,7 +1275,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1258 | { | 1275 | { |
1259 | struct net_device *netdev; | 1276 | struct net_device *netdev; |
1260 | struct dvb_net_priv *priv_data; | 1277 | struct dvb_net_priv *priv_data; |
1261 | struct dvb_net_if *dvbnetif=(struct dvb_net_if *)parg; | 1278 | struct dvb_net_if *dvbnetif = parg; |
1262 | 1279 | ||
1263 | if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || | 1280 | if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || |
1264 | !dvbnet->state[dvbnetif->if_num]) | 1281 | !dvbnet->state[dvbnetif->if_num]) |
@@ -1266,7 +1283,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1266 | 1283 | ||
1267 | netdev = dvbnet->device[dvbnetif->if_num]; | 1284 | netdev = dvbnet->device[dvbnetif->if_num]; |
1268 | 1285 | ||
1269 | priv_data=(struct dvb_net_priv*)netdev->priv; | 1286 | priv_data = netdev->priv; |
1270 | dvbnetif->pid=priv_data->pid; | 1287 | dvbnetif->pid=priv_data->pid; |
1271 | dvbnetif->feedtype=priv_data->feedtype; | 1288 | dvbnetif->feedtype=priv_data->feedtype; |
1272 | break; | 1289 | break; |
@@ -1288,7 +1305,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1288 | /* binary compatiblity cruft */ | 1305 | /* binary compatiblity cruft */ |
1289 | case __NET_ADD_IF_OLD: | 1306 | case __NET_ADD_IF_OLD: |
1290 | { | 1307 | { |
1291 | struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg; | 1308 | struct __dvb_net_if_old *dvbnetif = parg; |
1292 | int result; | 1309 | int result; |
1293 | 1310 | ||
1294 | if (!capable(CAP_SYS_ADMIN)) | 1311 | if (!capable(CAP_SYS_ADMIN)) |
@@ -1309,7 +1326,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1309 | { | 1326 | { |
1310 | struct net_device *netdev; | 1327 | struct net_device *netdev; |
1311 | struct dvb_net_priv *priv_data; | 1328 | struct dvb_net_priv *priv_data; |
1312 | struct __dvb_net_if_old *dvbnetif=(struct __dvb_net_if_old *)parg; | 1329 | struct __dvb_net_if_old *dvbnetif = parg; |
1313 | 1330 | ||
1314 | if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || | 1331 | if (dvbnetif->if_num >= DVB_NET_DEVICES_MAX || |
1315 | !dvbnet->state[dvbnetif->if_num]) | 1332 | !dvbnet->state[dvbnetif->if_num]) |
@@ -1317,7 +1334,7 @@ static int dvb_net_do_ioctl(struct inode *inode, struct file *file, | |||
1317 | 1334 | ||
1318 | netdev = dvbnet->device[dvbnetif->if_num]; | 1335 | netdev = dvbnet->device[dvbnetif->if_num]; |
1319 | 1336 | ||
1320 | priv_data=(struct dvb_net_priv*)netdev->priv; | 1337 | priv_data = netdev->priv; |
1321 | dvbnetif->pid=priv_data->pid; | 1338 | dvbnetif->pid=priv_data->pid; |
1322 | break; | 1339 | break; |
1323 | } | 1340 | } |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c index cf4ffe38fda3..9d9662f4b8e6 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.c +++ b/drivers/media/dvb/dvb-core/dvbdev.c | |||
@@ -286,9 +286,8 @@ skip: | |||
286 | } | 286 | } |
287 | 287 | ||
288 | 288 | ||
289 | int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct module *module) | 289 | int dvb_register_adapter(struct dvb_adapter *adap, const char *name, struct module *module) |
290 | { | 290 | { |
291 | struct dvb_adapter *adap; | ||
292 | int num; | 291 | int num; |
293 | 292 | ||
294 | if (down_interruptible (&dvbdev_register_lock)) | 293 | if (down_interruptible (&dvbdev_register_lock)) |
@@ -299,11 +298,6 @@ int dvb_register_adapter(struct dvb_adapter **padap, const char *name, struct mo | |||
299 | return -ENFILE; | 298 | return -ENFILE; |
300 | } | 299 | } |
301 | 300 | ||
302 | if (!(*padap = adap = kmalloc(sizeof(struct dvb_adapter), GFP_KERNEL))) { | ||
303 | up(&dvbdev_register_lock); | ||
304 | return -ENOMEM; | ||
305 | } | ||
306 | |||
307 | memset (adap, 0, sizeof(struct dvb_adapter)); | 301 | memset (adap, 0, sizeof(struct dvb_adapter)); |
308 | INIT_LIST_HEAD (&adap->device_list); | 302 | INIT_LIST_HEAD (&adap->device_list); |
309 | 303 | ||
@@ -331,7 +325,6 @@ int dvb_unregister_adapter(struct dvb_adapter *adap) | |||
331 | return -ERESTARTSYS; | 325 | return -ERESTARTSYS; |
332 | list_del (&adap->list_head); | 326 | list_del (&adap->list_head); |
333 | up (&dvbdev_register_lock); | 327 | up (&dvbdev_register_lock); |
334 | kfree (adap); | ||
335 | return 0; | 328 | return 0; |
336 | } | 329 | } |
337 | EXPORT_SYMBOL(dvb_unregister_adapter); | 330 | EXPORT_SYMBOL(dvb_unregister_adapter); |
diff --git a/drivers/media/dvb/dvb-core/dvbdev.h b/drivers/media/dvb/dvb-core/dvbdev.h index 184edba3caa7..a251867f30f1 100644 --- a/drivers/media/dvb/dvb-core/dvbdev.h +++ b/drivers/media/dvb/dvb-core/dvbdev.h | |||
@@ -76,7 +76,7 @@ struct dvb_device { | |||
76 | }; | 76 | }; |
77 | 77 | ||
78 | 78 | ||
79 | extern int dvb_register_adapter (struct dvb_adapter **padap, const char *name, struct module *module); | 79 | extern int dvb_register_adapter (struct dvb_adapter *adap, const char *name, struct module *module); |
80 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); | 80 | extern int dvb_unregister_adapter (struct dvb_adapter *adap); |
81 | 81 | ||
82 | extern int dvb_register_device (struct dvb_adapter *adap, | 82 | extern int dvb_register_device (struct dvb_adapter *adap, |
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index 0bfd4df17d08..75fb556ec01f 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -12,10 +12,10 @@ config DVB_STV0299 | |||
12 | 12 | ||
13 | config DVB_CX24110 | 13 | config DVB_CX24110 |
14 | tristate "Conexant CX24110 based" | 14 | tristate "Conexant CX24110 based" |
15 | depends on DVB_CORE | 15 | depends on DVB_CORE |
16 | help | 16 | help |
17 | A DVB-S tuner module. Say Y when you want to support this frontend. | 17 | A DVB-S tuner module. Say Y when you want to support this frontend. |
18 | 18 | ||
19 | config DVB_TDA8083 | 19 | config DVB_TDA8083 |
20 | tristate "Philips TDA8083 based" | 20 | tristate "Philips TDA8083 based" |
21 | depends on DVB_CORE | 21 | depends on DVB_CORE |
@@ -127,8 +127,8 @@ comment "DVB-C (cable) frontends" | |||
127 | config DVB_ATMEL_AT76C651 | 127 | config DVB_ATMEL_AT76C651 |
128 | tristate "Atmel AT76C651 based" | 128 | tristate "Atmel AT76C651 based" |
129 | depends on DVB_CORE | 129 | depends on DVB_CORE |
130 | help | 130 | help |
131 | A DVB-C tuner module. Say Y when you want to support this frontend. | 131 | A DVB-C tuner module. Say Y when you want to support this frontend. |
132 | 132 | ||
133 | config DVB_VES1820 | 133 | config DVB_VES1820 |
134 | tristate "VLSI VES1820 based" | 134 | tristate "VLSI VES1820 based" |
@@ -158,10 +158,6 @@ config DVB_NXT2002 | |||
158 | help | 158 | help |
159 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 159 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
160 | 160 | ||
161 | config DVB_OR51132 | ||
162 | tristate "OR51132 based (pcHDTV)" | ||
163 | depends on DVB_CORE | ||
164 | |||
165 | config DVB_OR51211 | 161 | config DVB_OR51211 |
166 | tristate "or51211 based (pcHDTV HD2000 card)" | 162 | tristate "or51211 based (pcHDTV HD2000 card)" |
167 | depends on DVB_CORE | 163 | depends on DVB_CORE |
@@ -169,4 +165,12 @@ config DVB_OR51211 | |||
169 | help | 165 | help |
170 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. | 166 | An ATSC 8VSB tuner module. Say Y when you want to support this frontend. |
171 | 167 | ||
168 | config DVB_OR51132 | ||
169 | tristate "OR51132 based (pcHDTV HD3000 card)" | ||
170 | depends on DVB_CORE | ||
171 | select FW_LOADER | ||
172 | help | ||
173 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | ||
174 | to support this frontend. | ||
175 | |||
172 | endmenu | 176 | endmenu |
diff --git a/drivers/media/dvb/frontends/at76c651.c b/drivers/media/dvb/frontends/at76c651.c index ce2eaa1640e8..72a2b5455b0b 100644 --- a/drivers/media/dvb/frontends/at76c651.c +++ b/drivers/media/dvb/frontends/at76c651.c | |||
@@ -259,7 +259,7 @@ static int at76c651_set_parameters(struct dvb_frontend* fe, | |||
259 | struct dvb_frontend_parameters *p) | 259 | struct dvb_frontend_parameters *p) |
260 | { | 260 | { |
261 | int ret; | 261 | int ret; |
262 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 262 | struct at76c651_state* state = fe->demodulator_priv; |
263 | 263 | ||
264 | at76c651_writereg(state, 0x0c, 0xc3); | 264 | at76c651_writereg(state, 0x0c, 0xc3); |
265 | state->config->pll_set(fe, p); | 265 | state->config->pll_set(fe, p); |
@@ -276,7 +276,7 @@ static int at76c651_set_parameters(struct dvb_frontend* fe, | |||
276 | 276 | ||
277 | static int at76c651_set_defaults(struct dvb_frontend* fe) | 277 | static int at76c651_set_defaults(struct dvb_frontend* fe) |
278 | { | 278 | { |
279 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 279 | struct at76c651_state* state = fe->demodulator_priv; |
280 | 280 | ||
281 | at76c651_set_symbol_rate(state, 6900000); | 281 | at76c651_set_symbol_rate(state, 6900000); |
282 | at76c651_set_qam(state, QAM_64); | 282 | at76c651_set_qam(state, QAM_64); |
@@ -294,7 +294,7 @@ static int at76c651_set_defaults(struct dvb_frontend* fe) | |||
294 | 294 | ||
295 | static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) | 295 | static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) |
296 | { | 296 | { |
297 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 297 | struct at76c651_state* state = fe->demodulator_priv; |
298 | u8 sync; | 298 | u8 sync; |
299 | 299 | ||
300 | /* | 300 | /* |
@@ -319,7 +319,7 @@ static int at76c651_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
319 | 319 | ||
320 | static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) | 320 | static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) |
321 | { | 321 | { |
322 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 322 | struct at76c651_state* state = fe->demodulator_priv; |
323 | 323 | ||
324 | *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16; | 324 | *ber = (at76c651_readreg(state, 0x81) & 0x0F) << 16; |
325 | *ber |= at76c651_readreg(state, 0x82) << 8; | 325 | *ber |= at76c651_readreg(state, 0x82) << 8; |
@@ -331,7 +331,7 @@ static int at76c651_read_ber(struct dvb_frontend* fe, u32* ber) | |||
331 | 331 | ||
332 | static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 332 | static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
333 | { | 333 | { |
334 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 334 | struct at76c651_state* state = fe->demodulator_priv; |
335 | 335 | ||
336 | u8 gain = ~at76c651_readreg(state, 0x91); | 336 | u8 gain = ~at76c651_readreg(state, 0x91); |
337 | *strength = (gain << 8) | gain; | 337 | *strength = (gain << 8) | gain; |
@@ -341,7 +341,7 @@ static int at76c651_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
341 | 341 | ||
342 | static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) | 342 | static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) |
343 | { | 343 | { |
344 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 344 | struct at76c651_state* state = fe->demodulator_priv; |
345 | 345 | ||
346 | *snr = 0xFFFF - | 346 | *snr = 0xFFFF - |
347 | ((at76c651_readreg(state, 0x8F) << 8) | | 347 | ((at76c651_readreg(state, 0x8F) << 8) | |
@@ -352,7 +352,7 @@ static int at76c651_read_snr(struct dvb_frontend* fe, u16* snr) | |||
352 | 352 | ||
353 | static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 353 | static int at76c651_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
354 | { | 354 | { |
355 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 355 | struct at76c651_state* state = fe->demodulator_priv; |
356 | 356 | ||
357 | *ucblocks = at76c651_readreg(state, 0x82); | 357 | *ucblocks = at76c651_readreg(state, 0x82); |
358 | 358 | ||
@@ -369,7 +369,7 @@ static int at76c651_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte | |||
369 | 369 | ||
370 | static void at76c651_release(struct dvb_frontend* fe) | 370 | static void at76c651_release(struct dvb_frontend* fe) |
371 | { | 371 | { |
372 | struct at76c651_state* state = (struct at76c651_state*) fe->demodulator_priv; | 372 | struct at76c651_state* state = fe->demodulator_priv; |
373 | kfree(state); | 373 | kfree(state); |
374 | } | 374 | } |
375 | 375 | ||
@@ -381,7 +381,7 @@ struct dvb_frontend* at76c651_attach(const struct at76c651_config* config, | |||
381 | struct at76c651_state* state = NULL; | 381 | struct at76c651_state* state = NULL; |
382 | 382 | ||
383 | /* allocate memory for the internal state */ | 383 | /* allocate memory for the internal state */ |
384 | state = (struct at76c651_state*) kmalloc(sizeof(struct at76c651_state), GFP_KERNEL); | 384 | state = kmalloc(sizeof(struct at76c651_state), GFP_KERNEL); |
385 | if (state == NULL) goto error; | 385 | if (state == NULL) goto error; |
386 | 386 | ||
387 | /* setup the state */ | 387 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/cx22700.c b/drivers/media/dvb/frontends/cx22700.c index a212279042b8..0c2ed4438618 100644 --- a/drivers/media/dvb/frontends/cx22700.c +++ b/drivers/media/dvb/frontends/cx22700.c | |||
@@ -232,7 +232,7 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet | |||
232 | 232 | ||
233 | static int cx22700_init (struct dvb_frontend* fe) | 233 | static int cx22700_init (struct dvb_frontend* fe) |
234 | 234 | ||
235 | { struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 235 | { struct cx22700_state* state = fe->demodulator_priv; |
236 | int i; | 236 | int i; |
237 | 237 | ||
238 | dprintk("cx22700_init: init chip\n"); | 238 | dprintk("cx22700_init: init chip\n"); |
@@ -258,7 +258,7 @@ static int cx22700_init (struct dvb_frontend* fe) | |||
258 | 258 | ||
259 | static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) | 259 | static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) |
260 | { | 260 | { |
261 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 261 | struct cx22700_state* state = fe->demodulator_priv; |
262 | 262 | ||
263 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) | 263 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) |
264 | | (cx22700_readreg (state, 0x0e) << 1); | 264 | | (cx22700_readreg (state, 0x0e) << 1); |
@@ -286,7 +286,7 @@ static int cx22700_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
286 | 286 | ||
287 | static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber) | 287 | static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber) |
288 | { | 288 | { |
289 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 289 | struct cx22700_state* state = fe->demodulator_priv; |
290 | 290 | ||
291 | *ber = cx22700_readreg (state, 0x0c) & 0x7f; | 291 | *ber = cx22700_readreg (state, 0x0c) & 0x7f; |
292 | cx22700_writereg (state, 0x0c, 0x00); | 292 | cx22700_writereg (state, 0x0c, 0x00); |
@@ -296,7 +296,7 @@ static int cx22700_read_ber(struct dvb_frontend* fe, u32* ber) | |||
296 | 296 | ||
297 | static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 297 | static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) |
298 | { | 298 | { |
299 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 299 | struct cx22700_state* state = fe->demodulator_priv; |
300 | 300 | ||
301 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) | 301 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) |
302 | | (cx22700_readreg (state, 0x0e) << 1); | 302 | | (cx22700_readreg (state, 0x0e) << 1); |
@@ -307,7 +307,7 @@ static int cx22700_read_signal_strength(struct dvb_frontend* fe, u16* signal_str | |||
307 | 307 | ||
308 | static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr) | 308 | static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr) |
309 | { | 309 | { |
310 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 310 | struct cx22700_state* state = fe->demodulator_priv; |
311 | 311 | ||
312 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) | 312 | u16 rs_ber = (cx22700_readreg (state, 0x0d) << 9) |
313 | | (cx22700_readreg (state, 0x0e) << 1); | 313 | | (cx22700_readreg (state, 0x0e) << 1); |
@@ -318,7 +318,7 @@ static int cx22700_read_snr(struct dvb_frontend* fe, u16* snr) | |||
318 | 318 | ||
319 | static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 319 | static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
320 | { | 320 | { |
321 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 321 | struct cx22700_state* state = fe->demodulator_priv; |
322 | 322 | ||
323 | *ucblocks = cx22700_readreg (state, 0x0f); | 323 | *ucblocks = cx22700_readreg (state, 0x0f); |
324 | cx22700_writereg (state, 0x0f, 0x00); | 324 | cx22700_writereg (state, 0x0f, 0x00); |
@@ -328,7 +328,7 @@ static int cx22700_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
328 | 328 | ||
329 | static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 329 | static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
330 | { | 330 | { |
331 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 331 | struct cx22700_state* state = fe->demodulator_priv; |
332 | 332 | ||
333 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ | 333 | cx22700_writereg (state, 0x00, 0x02); /* XXX CHECKME: soft reset*/ |
334 | cx22700_writereg (state, 0x00, 0x00); | 334 | cx22700_writereg (state, 0x00, 0x00); |
@@ -346,7 +346,7 @@ static int cx22700_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
346 | 346 | ||
347 | static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 347 | static int cx22700_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
348 | { | 348 | { |
349 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 349 | struct cx22700_state* state = fe->demodulator_priv; |
350 | u8 reg09 = cx22700_readreg (state, 0x09); | 350 | u8 reg09 = cx22700_readreg (state, 0x09); |
351 | 351 | ||
352 | p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; | 352 | p->inversion = reg09 & 0x1 ? INVERSION_ON : INVERSION_OFF; |
@@ -363,7 +363,7 @@ static int cx22700_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten | |||
363 | 363 | ||
364 | static void cx22700_release(struct dvb_frontend* fe) | 364 | static void cx22700_release(struct dvb_frontend* fe) |
365 | { | 365 | { |
366 | struct cx22700_state* state = (struct cx22700_state*) fe->demodulator_priv; | 366 | struct cx22700_state* state = fe->demodulator_priv; |
367 | kfree(state); | 367 | kfree(state); |
368 | } | 368 | } |
369 | 369 | ||
@@ -375,7 +375,7 @@ struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, | |||
375 | struct cx22700_state* state = NULL; | 375 | struct cx22700_state* state = NULL; |
376 | 376 | ||
377 | /* allocate memory for the internal state */ | 377 | /* allocate memory for the internal state */ |
378 | state = (struct cx22700_state*) kmalloc(sizeof(struct cx22700_state), GFP_KERNEL); | 378 | state = kmalloc(sizeof(struct cx22700_state), GFP_KERNEL); |
379 | if (state == NULL) goto error; | 379 | if (state == NULL) goto error; |
380 | 380 | ||
381 | /* setup the state */ | 381 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c index 011860ce36cc..f4aa44136c7c 100644 --- a/drivers/media/dvb/frontends/cx22702.c +++ b/drivers/media/dvb/frontends/cx22702.c | |||
@@ -200,7 +200,7 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet | |||
200 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 200 | static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
201 | { | 201 | { |
202 | u8 val; | 202 | u8 val; |
203 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 203 | struct cx22702_state* state = fe->demodulator_priv; |
204 | 204 | ||
205 | /* set PLL */ | 205 | /* set PLL */ |
206 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); | 206 | cx22702_writereg (state, 0x0D, cx22702_readreg(state,0x0D) &0xfe); |
@@ -338,7 +338,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet | |||
338 | static int cx22702_init (struct dvb_frontend* fe) | 338 | static int cx22702_init (struct dvb_frontend* fe) |
339 | { | 339 | { |
340 | int i; | 340 | int i; |
341 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 341 | struct cx22702_state* state = fe->demodulator_priv; |
342 | 342 | ||
343 | cx22702_writereg (state, 0x00, 0x02); | 343 | cx22702_writereg (state, 0x00, 0x02); |
344 | 344 | ||
@@ -360,7 +360,7 @@ static int cx22702_init (struct dvb_frontend* fe) | |||
360 | 360 | ||
361 | static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) | 361 | static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) |
362 | { | 362 | { |
363 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 363 | struct cx22702_state* state = fe->demodulator_priv; |
364 | u8 reg0A; | 364 | u8 reg0A; |
365 | u8 reg23; | 365 | u8 reg23; |
366 | 366 | ||
@@ -389,7 +389,7 @@ static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
389 | 389 | ||
390 | static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) | 390 | static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) |
391 | { | 391 | { |
392 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 392 | struct cx22702_state* state = fe->demodulator_priv; |
393 | 393 | ||
394 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 394 | if(cx22702_readreg (state, 0xE4) & 0x02) { |
395 | /* Realtime statistics */ | 395 | /* Realtime statistics */ |
@@ -406,7 +406,7 @@ static int cx22702_read_ber(struct dvb_frontend* fe, u32* ber) | |||
406 | 406 | ||
407 | static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 407 | static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) |
408 | { | 408 | { |
409 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 409 | struct cx22702_state* state = fe->demodulator_priv; |
410 | 410 | ||
411 | *signal_strength = cx22702_readreg (state, 0x23); | 411 | *signal_strength = cx22702_readreg (state, 0x23); |
412 | 412 | ||
@@ -415,7 +415,7 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str | |||
415 | 415 | ||
416 | static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) | 416 | static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) |
417 | { | 417 | { |
418 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 418 | struct cx22702_state* state = fe->demodulator_priv; |
419 | 419 | ||
420 | u16 rs_ber=0; | 420 | u16 rs_ber=0; |
421 | if(cx22702_readreg (state, 0xE4) & 0x02) { | 421 | if(cx22702_readreg (state, 0xE4) & 0x02) { |
@@ -434,7 +434,7 @@ static int cx22702_read_snr(struct dvb_frontend* fe, u16* snr) | |||
434 | 434 | ||
435 | static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 435 | static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
436 | { | 436 | { |
437 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 437 | struct cx22702_state* state = fe->demodulator_priv; |
438 | 438 | ||
439 | u8 _ucblocks; | 439 | u8 _ucblocks; |
440 | 440 | ||
@@ -449,7 +449,7 @@ static int cx22702_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
449 | 449 | ||
450 | static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 450 | static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
451 | { | 451 | { |
452 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 452 | struct cx22702_state* state = fe->demodulator_priv; |
453 | 453 | ||
454 | u8 reg0C = cx22702_readreg (state, 0x0C); | 454 | u8 reg0C = cx22702_readreg (state, 0x0C); |
455 | 455 | ||
@@ -459,7 +459,7 @@ static int cx22702_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
459 | 459 | ||
460 | static void cx22702_release(struct dvb_frontend* fe) | 460 | static void cx22702_release(struct dvb_frontend* fe) |
461 | { | 461 | { |
462 | struct cx22702_state* state = (struct cx22702_state*) fe->demodulator_priv; | 462 | struct cx22702_state* state = fe->demodulator_priv; |
463 | kfree(state); | 463 | kfree(state); |
464 | } | 464 | } |
465 | 465 | ||
@@ -471,7 +471,7 @@ struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, | |||
471 | struct cx22702_state* state = NULL; | 471 | struct cx22702_state* state = NULL; |
472 | 472 | ||
473 | /* allocate memory for the internal state */ | 473 | /* allocate memory for the internal state */ |
474 | state = (struct cx22702_state*) kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); | 474 | state = kmalloc(sizeof(struct cx22702_state), GFP_KERNEL); |
475 | if (state == NULL) goto error; | 475 | if (state == NULL) goto error; |
476 | 476 | ||
477 | /* setup the state */ | 477 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c index ae16112a0653..8222b88cb486 100644 --- a/drivers/media/dvb/frontends/cx24110.c +++ b/drivers/media/dvb/frontends/cx24110.c | |||
@@ -315,7 +315,7 @@ dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate); | |||
315 | 315 | ||
316 | int cx24110_pll_write (struct dvb_frontend* fe, u32 data) | 316 | int cx24110_pll_write (struct dvb_frontend* fe, u32 data) |
317 | { | 317 | { |
318 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 318 | struct cx24110_state *state = fe->demodulator_priv; |
319 | 319 | ||
320 | /* tuner data is 21 bits long, must be left-aligned in data */ | 320 | /* tuner data is 21 bits long, must be left-aligned in data */ |
321 | /* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ | 321 | /* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ |
@@ -356,7 +356,7 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data) | |||
356 | 356 | ||
357 | static int cx24110_initfe(struct dvb_frontend* fe) | 357 | static int cx24110_initfe(struct dvb_frontend* fe) |
358 | { | 358 | { |
359 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 359 | struct cx24110_state *state = fe->demodulator_priv; |
360 | /* fixme (low): error handling */ | 360 | /* fixme (low): error handling */ |
361 | int i; | 361 | int i; |
362 | 362 | ||
@@ -373,7 +373,7 @@ static int cx24110_initfe(struct dvb_frontend* fe) | |||
373 | 373 | ||
374 | static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 374 | static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
375 | { | 375 | { |
376 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 376 | struct cx24110_state *state = fe->demodulator_priv; |
377 | 377 | ||
378 | switch (voltage) { | 378 | switch (voltage) { |
379 | case SEC_VOLTAGE_13: | 379 | case SEC_VOLTAGE_13: |
@@ -385,8 +385,7 @@ static int cx24110_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
385 | }; | 385 | }; |
386 | } | 386 | } |
387 | 387 | ||
388 | static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, | 388 | static int cx24110_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
389 | fe_sec_mini_cmd_t burst) | ||
390 | { | 389 | { |
391 | int rv, bit, i; | 390 | int rv, bit, i; |
392 | struct cx24110_state *state = fe->demodulator_priv; | 391 | struct cx24110_state *state = fe->demodulator_priv; |
@@ -413,7 +412,7 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, | |||
413 | struct dvb_diseqc_master_cmd *cmd) | 412 | struct dvb_diseqc_master_cmd *cmd) |
414 | { | 413 | { |
415 | int i, rv; | 414 | int i, rv; |
416 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 415 | struct cx24110_state *state = fe->demodulator_priv; |
417 | 416 | ||
418 | for (i = 0; i < cmd->msg_len; i++) | 417 | for (i = 0; i < cmd->msg_len; i++) |
419 | cx24110_writereg(state, 0x79 + i, cmd->msg[i]); | 418 | cx24110_writereg(state, 0x79 + i, cmd->msg[i]); |
@@ -432,7 +431,7 @@ static int cx24110_send_diseqc_msg(struct dvb_frontend* fe, | |||
432 | 431 | ||
433 | static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) | 432 | static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) |
434 | { | 433 | { |
435 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 434 | struct cx24110_state *state = fe->demodulator_priv; |
436 | 435 | ||
437 | int sync = cx24110_readreg (state, 0x55); | 436 | int sync = cx24110_readreg (state, 0x55); |
438 | 437 | ||
@@ -460,7 +459,7 @@ static int cx24110_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
460 | 459 | ||
461 | static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber) | 460 | static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber) |
462 | { | 461 | { |
463 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 462 | struct cx24110_state *state = fe->demodulator_priv; |
464 | 463 | ||
465 | /* fixme (maybe): value range is 16 bit. Scale? */ | 464 | /* fixme (maybe): value range is 16 bit. Scale? */ |
466 | if(cx24110_readreg(state,0x24)&0x10) { | 465 | if(cx24110_readreg(state,0x24)&0x10) { |
@@ -478,7 +477,7 @@ static int cx24110_read_ber(struct dvb_frontend* fe, u32* ber) | |||
478 | 477 | ||
479 | static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 478 | static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) |
480 | { | 479 | { |
481 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 480 | struct cx24110_state *state = fe->demodulator_priv; |
482 | 481 | ||
483 | /* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */ | 482 | /* no provision in hardware. Read the frontend AGC accumulator. No idea how to scale this, but I know it is 2s complement */ |
484 | u8 signal = cx24110_readreg (state, 0x27)+128; | 483 | u8 signal = cx24110_readreg (state, 0x27)+128; |
@@ -489,7 +488,7 @@ static int cx24110_read_signal_strength(struct dvb_frontend* fe, u16* signal_str | |||
489 | 488 | ||
490 | static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) | 489 | static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) |
491 | { | 490 | { |
492 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 491 | struct cx24110_state *state = fe->demodulator_priv; |
493 | 492 | ||
494 | /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */ | 493 | /* no provision in hardware. Can be computed from the Es/N0 estimator, but I don't know how. */ |
495 | if(cx24110_readreg(state,0x6a)&0x80) { | 494 | if(cx24110_readreg(state,0x6a)&0x80) { |
@@ -505,7 +504,7 @@ static int cx24110_read_snr(struct dvb_frontend* fe, u16* snr) | |||
505 | 504 | ||
506 | static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 505 | static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
507 | { | 506 | { |
508 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 507 | struct cx24110_state *state = fe->demodulator_priv; |
509 | u32 lastbyer; | 508 | u32 lastbyer; |
510 | 509 | ||
511 | if(cx24110_readreg(state,0x10)&0x40) { | 510 | if(cx24110_readreg(state,0x10)&0x40) { |
@@ -527,7 +526,7 @@ static int cx24110_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
527 | 526 | ||
528 | static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 527 | static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
529 | { | 528 | { |
530 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 529 | struct cx24110_state *state = fe->demodulator_priv; |
531 | 530 | ||
532 | state->config->pll_set(fe, p); | 531 | state->config->pll_set(fe, p); |
533 | cx24110_set_inversion (state, p->inversion); | 532 | cx24110_set_inversion (state, p->inversion); |
@@ -540,7 +539,7 @@ static int cx24110_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
540 | 539 | ||
541 | static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 540 | static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
542 | { | 541 | { |
543 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 542 | struct cx24110_state *state = fe->demodulator_priv; |
544 | s32 afc; unsigned sclk; | 543 | s32 afc; unsigned sclk; |
545 | 544 | ||
546 | /* cannot read back tuner settings (freq). Need to have some private storage */ | 545 | /* cannot read back tuner settings (freq). Need to have some private storage */ |
@@ -567,14 +566,14 @@ static int cx24110_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
567 | 566 | ||
568 | static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 567 | static int cx24110_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
569 | { | 568 | { |
570 | struct cx24110_state *state = (struct cx24110_state*) fe->demodulator_priv; | 569 | struct cx24110_state *state = fe->demodulator_priv; |
571 | 570 | ||
572 | return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0)); | 571 | return cx24110_writereg(state,0x76,(cx24110_readreg(state,0x76)&~0x10)|(((tone==SEC_TONE_ON))?0x10:0)); |
573 | } | 572 | } |
574 | 573 | ||
575 | static void cx24110_release(struct dvb_frontend* fe) | 574 | static void cx24110_release(struct dvb_frontend* fe) |
576 | { | 575 | { |
577 | struct cx24110_state* state = (struct cx24110_state*) fe->demodulator_priv; | 576 | struct cx24110_state* state = fe->demodulator_priv; |
578 | kfree(state); | 577 | kfree(state); |
579 | } | 578 | } |
580 | 579 | ||
@@ -587,7 +586,7 @@ struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, | |||
587 | int ret; | 586 | int ret; |
588 | 587 | ||
589 | /* allocate memory for the internal state */ | 588 | /* allocate memory for the internal state */ |
590 | state = (struct cx24110_state*) kmalloc(sizeof(struct cx24110_state), GFP_KERNEL); | 589 | state = kmalloc(sizeof(struct cx24110_state), GFP_KERNEL); |
591 | if (state == NULL) goto error; | 590 | if (state == NULL) goto error; |
592 | 591 | ||
593 | /* setup the state */ | 592 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c index a853d12a26f1..6f52d649e97e 100644 --- a/drivers/media/dvb/frontends/dib3000mb.c +++ b/drivers/media/dvb/frontends/dib3000mb.c | |||
@@ -56,12 +56,12 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, | |||
56 | static int dib3000mb_set_frontend(struct dvb_frontend* fe, | 56 | static int dib3000mb_set_frontend(struct dvb_frontend* fe, |
57 | struct dvb_frontend_parameters *fep, int tuner) | 57 | struct dvb_frontend_parameters *fep, int tuner) |
58 | { | 58 | { |
59 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 59 | struct dib3000_state* state = fe->demodulator_priv; |
60 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 60 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; |
61 | fe_code_rate_t fe_cr = FEC_NONE; | 61 | fe_code_rate_t fe_cr = FEC_NONE; |
62 | int search_state, seq; | 62 | int search_state, seq; |
63 | 63 | ||
64 | if (tuner) { | 64 | if (tuner && state->config.pll_addr && state->config.pll_set) { |
65 | dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); | 65 | dib3000mb_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); |
66 | state->config.pll_set(fe, fep, NULL); | 66 | state->config.pll_set(fe, fep, NULL); |
67 | dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); | 67 | dib3000mb_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); |
@@ -317,7 +317,7 @@ static int dib3000mb_set_frontend(struct dvb_frontend* fe, | |||
317 | 317 | ||
318 | static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) | 318 | static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) |
319 | { | 319 | { |
320 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 320 | struct dib3000_state* state = fe->demodulator_priv; |
321 | 321 | ||
322 | deb_info("dib3000mb is getting up.\n"); | 322 | deb_info("dib3000mb is getting up.\n"); |
323 | wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); | 323 | wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_UP); |
@@ -401,7 +401,7 @@ static int dib3000mb_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
401 | static int dib3000mb_get_frontend(struct dvb_frontend* fe, | 401 | static int dib3000mb_get_frontend(struct dvb_frontend* fe, |
402 | struct dvb_frontend_parameters *fep) | 402 | struct dvb_frontend_parameters *fep) |
403 | { | 403 | { |
404 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 404 | struct dib3000_state* state = fe->demodulator_priv; |
405 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 405 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; |
406 | fe_code_rate_t *cr; | 406 | fe_code_rate_t *cr; |
407 | u16 tps_val; | 407 | u16 tps_val; |
@@ -562,7 +562,7 @@ static int dib3000mb_get_frontend(struct dvb_frontend* fe, | |||
562 | 562 | ||
563 | static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) | 563 | static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) |
564 | { | 564 | { |
565 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 565 | struct dib3000_state* state = fe->demodulator_priv; |
566 | 566 | ||
567 | *stat = 0; | 567 | *stat = 0; |
568 | 568 | ||
@@ -594,7 +594,7 @@ static int dib3000mb_read_status(struct dvb_frontend* fe, fe_status_t *stat) | |||
594 | 594 | ||
595 | static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) | 595 | static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) |
596 | { | 596 | { |
597 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 597 | struct dib3000_state* state = fe->demodulator_priv; |
598 | 598 | ||
599 | *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); | 599 | *ber = ((rd(DIB3000MB_REG_BER_MSB) << 16) | rd(DIB3000MB_REG_BER_LSB)); |
600 | return 0; | 600 | return 0; |
@@ -603,7 +603,7 @@ static int dib3000mb_read_ber(struct dvb_frontend* fe, u32 *ber) | |||
603 | /* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ | 603 | /* see dib3000-watch dvb-apps for exact calcuations of signal_strength and snr */ |
604 | static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) | 604 | static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength) |
605 | { | 605 | { |
606 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 606 | struct dib3000_state* state = fe->demodulator_priv; |
607 | 607 | ||
608 | *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; | 608 | *strength = rd(DIB3000MB_REG_SIGNAL_POWER) * 0xffff / 0x170; |
609 | return 0; | 609 | return 0; |
@@ -611,7 +611,7 @@ static int dib3000mb_read_signal_strength(struct dvb_frontend* fe, u16 *strength | |||
611 | 611 | ||
612 | static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) | 612 | static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) |
613 | { | 613 | { |
614 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 614 | struct dib3000_state* state = fe->demodulator_priv; |
615 | short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); | 615 | short sigpow = rd(DIB3000MB_REG_SIGNAL_POWER); |
616 | int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | | 616 | int icipow = ((rd(DIB3000MB_REG_NOISE_POWER_MSB) & 0xff) << 16) | |
617 | rd(DIB3000MB_REG_NOISE_POWER_LSB); | 617 | rd(DIB3000MB_REG_NOISE_POWER_LSB); |
@@ -621,7 +621,7 @@ static int dib3000mb_read_snr(struct dvb_frontend* fe, u16 *snr) | |||
621 | 621 | ||
622 | static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | 622 | static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) |
623 | { | 623 | { |
624 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 624 | struct dib3000_state* state = fe->demodulator_priv; |
625 | 625 | ||
626 | *unc = rd(DIB3000MB_REG_UNC); | 626 | *unc = rd(DIB3000MB_REG_UNC); |
627 | return 0; | 627 | return 0; |
@@ -629,7 +629,7 @@ static int dib3000mb_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | |||
629 | 629 | ||
630 | static int dib3000mb_sleep(struct dvb_frontend* fe) | 630 | static int dib3000mb_sleep(struct dvb_frontend* fe) |
631 | { | 631 | { |
632 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 632 | struct dib3000_state* state = fe->demodulator_priv; |
633 | deb_info("dib3000mb is going to bed.\n"); | 633 | deb_info("dib3000mb is going to bed.\n"); |
634 | wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); | 634 | wr(DIB3000MB_REG_POWER_CONTROL, DIB3000MB_POWER_DOWN); |
635 | return 0; | 635 | return 0; |
@@ -656,7 +656,7 @@ static int dib3000mb_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_ | |||
656 | 656 | ||
657 | static void dib3000mb_release(struct dvb_frontend* fe) | 657 | static void dib3000mb_release(struct dvb_frontend* fe) |
658 | { | 658 | { |
659 | struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; | 659 | struct dib3000_state *state = fe->demodulator_priv; |
660 | kfree(state); | 660 | kfree(state); |
661 | } | 661 | } |
662 | 662 | ||
@@ -671,7 +671,7 @@ static int dib3000mb_pid_control(struct dvb_frontend *fe,int index, int pid,int | |||
671 | 671 | ||
672 | static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) | 672 | static int dib3000mb_fifo_control(struct dvb_frontend *fe, int onoff) |
673 | { | 673 | { |
674 | struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; | 674 | struct dib3000_state *state = fe->demodulator_priv; |
675 | 675 | ||
676 | deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); | 676 | deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); |
677 | if (onoff) { | 677 | if (onoff) { |
@@ -692,7 +692,7 @@ static int dib3000mb_pid_parse(struct dvb_frontend *fe, int onoff) | |||
692 | 692 | ||
693 | static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) | 693 | static int dib3000mb_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) |
694 | { | 694 | { |
695 | struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; | 695 | struct dib3000_state *state = fe->demodulator_priv; |
696 | if (onoff) { | 696 | if (onoff) { |
697 | wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); | 697 | wr(DIB3000MB_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); |
698 | } else { | 698 | } else { |
@@ -709,7 +709,7 @@ struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, | |||
709 | struct dib3000_state* state = NULL; | 709 | struct dib3000_state* state = NULL; |
710 | 710 | ||
711 | /* allocate memory for the internal state */ | 711 | /* allocate memory for the internal state */ |
712 | state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL); | 712 | state = kmalloc(sizeof(struct dib3000_state), GFP_KERNEL); |
713 | if (state == NULL) | 713 | if (state == NULL) |
714 | goto error; | 714 | goto error; |
715 | memset(state,0,sizeof(struct dib3000_state)); | 715 | memset(state,0,sizeof(struct dib3000_state)); |
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c index 4a31c05eaecd..888f10a5e96b 100644 --- a/drivers/media/dvb/frontends/dib3000mc.c +++ b/drivers/media/dvb/frontends/dib3000mc.c | |||
@@ -297,7 +297,7 @@ static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_fro | |||
297 | static int dib3000mc_get_frontend(struct dvb_frontend* fe, | 297 | static int dib3000mc_get_frontend(struct dvb_frontend* fe, |
298 | struct dvb_frontend_parameters *fep) | 298 | struct dvb_frontend_parameters *fep) |
299 | { | 299 | { |
300 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 300 | struct dib3000_state* state = fe->demodulator_priv; |
301 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 301 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; |
302 | fe_code_rate_t *cr; | 302 | fe_code_rate_t *cr; |
303 | u16 tps_val,cr_val; | 303 | u16 tps_val,cr_val; |
@@ -458,12 +458,12 @@ static int dib3000mc_get_frontend(struct dvb_frontend* fe, | |||
458 | static int dib3000mc_set_frontend(struct dvb_frontend* fe, | 458 | static int dib3000mc_set_frontend(struct dvb_frontend* fe, |
459 | struct dvb_frontend_parameters *fep, int tuner) | 459 | struct dvb_frontend_parameters *fep, int tuner) |
460 | { | 460 | { |
461 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 461 | struct dib3000_state* state = fe->demodulator_priv; |
462 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; | 462 | struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; |
463 | int search_state,auto_val; | 463 | int search_state,auto_val; |
464 | u16 val; | 464 | u16 val; |
465 | 465 | ||
466 | if (tuner) { /* initial call from dvb */ | 466 | if (tuner && state->config.pll_addr && state->config.pll_set) { /* initial call from dvb */ |
467 | dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); | 467 | dib3000mc_tuner_pass_ctrl(fe,1,state->config.pll_addr(fe)); |
468 | state->config.pll_set(fe,fep,NULL); | 468 | state->config.pll_set(fe,fep,NULL); |
469 | dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); | 469 | dib3000mc_tuner_pass_ctrl(fe,0,state->config.pll_addr(fe)); |
@@ -659,7 +659,7 @@ static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) | |||
659 | } | 659 | } |
660 | static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) | 660 | static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) |
661 | { | 661 | { |
662 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 662 | struct dib3000_state* state = fe->demodulator_priv; |
663 | u16 lock = rd(DIB3000MC_REG_LOCKING); | 663 | u16 lock = rd(DIB3000MC_REG_LOCKING); |
664 | 664 | ||
665 | *stat = 0; | 665 | *stat = 0; |
@@ -679,14 +679,14 @@ static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) | |||
679 | 679 | ||
680 | static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) | 680 | static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) |
681 | { | 681 | { |
682 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 682 | struct dib3000_state* state = fe->demodulator_priv; |
683 | *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); | 683 | *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); |
684 | return 0; | 684 | return 0; |
685 | } | 685 | } |
686 | 686 | ||
687 | static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | 687 | static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) |
688 | { | 688 | { |
689 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 689 | struct dib3000_state* state = fe->demodulator_priv; |
690 | 690 | ||
691 | *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT); | 691 | *unc = rd(DIB3000MC_REG_PACKET_ERROR_COUNT); |
692 | return 0; | 692 | return 0; |
@@ -695,7 +695,7 @@ static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) | |||
695 | /* see dib3000mb.c for calculation comments */ | 695 | /* see dib3000mb.c for calculation comments */ |
696 | static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength) | 696 | static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength) |
697 | { | 697 | { |
698 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 698 | struct dib3000_state* state = fe->demodulator_priv; |
699 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); | 699 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); |
700 | *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); | 700 | *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); |
701 | 701 | ||
@@ -706,7 +706,7 @@ static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength | |||
706 | /* see dib3000mb.c for calculation comments */ | 706 | /* see dib3000mb.c for calculation comments */ |
707 | static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) | 707 | static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) |
708 | { | 708 | { |
709 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 709 | struct dib3000_state* state = fe->demodulator_priv; |
710 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), | 710 | u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), |
711 | val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); | 711 | val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); |
712 | u16 sig,noise; | 712 | u16 sig,noise; |
@@ -726,7 +726,7 @@ static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr) | |||
726 | 726 | ||
727 | static int dib3000mc_sleep(struct dvb_frontend* fe) | 727 | static int dib3000mc_sleep(struct dvb_frontend* fe) |
728 | { | 728 | { |
729 | struct dib3000_state* state = (struct dib3000_state*) fe->demodulator_priv; | 729 | struct dib3000_state* state = fe->demodulator_priv; |
730 | 730 | ||
731 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); | 731 | set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); |
732 | wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); | 732 | wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); |
@@ -756,7 +756,7 @@ static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_ | |||
756 | 756 | ||
757 | static void dib3000mc_release(struct dvb_frontend* fe) | 757 | static void dib3000mc_release(struct dvb_frontend* fe) |
758 | { | 758 | { |
759 | struct dib3000_state *state = (struct dib3000_state *) fe->demodulator_priv; | 759 | struct dib3000_state *state = fe->demodulator_priv; |
760 | kfree(state); | 760 | kfree(state); |
761 | } | 761 | } |
762 | 762 | ||
@@ -771,7 +771,7 @@ static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int | |||
771 | 771 | ||
772 | static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) | 772 | static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) |
773 | { | 773 | { |
774 | struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; | 774 | struct dib3000_state *state = fe->demodulator_priv; |
775 | u16 tmp = rd(DIB3000MC_REG_SMO_MODE); | 775 | u16 tmp = rd(DIB3000MC_REG_SMO_MODE); |
776 | 776 | ||
777 | deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); | 777 | deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling"); |
@@ -803,7 +803,7 @@ static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) | |||
803 | 803 | ||
804 | static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) | 804 | static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) |
805 | { | 805 | { |
806 | struct dib3000_state *state = (struct dib3000_state*) fe->demodulator_priv; | 806 | struct dib3000_state *state = fe->demodulator_priv; |
807 | if (onoff) { | 807 | if (onoff) { |
808 | wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); | 808 | wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr)); |
809 | } else { | 809 | } else { |
@@ -844,7 +844,7 @@ struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, | |||
844 | u16 devid; | 844 | u16 devid; |
845 | 845 | ||
846 | /* allocate memory for the internal state */ | 846 | /* allocate memory for the internal state */ |
847 | state = (struct dib3000_state*) kmalloc(sizeof(struct dib3000_state), GFP_KERNEL); | 847 | state = kmalloc(sizeof(struct dib3000_state), GFP_KERNEL); |
848 | if (state == NULL) | 848 | if (state == NULL) |
849 | goto error; | 849 | goto error; |
850 | memset(state,0,sizeof(struct dib3000_state)); | 850 | memset(state,0,sizeof(struct dib3000_state)); |
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h index 016c794a5677..c4c3c56c4a81 100644 --- a/drivers/media/dvb/frontends/dvb-pll.h +++ b/drivers/media/dvb/frontends/dvb-pll.h | |||
@@ -2,6 +2,9 @@ | |||
2 | * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $ | 2 | * $Id: dvb-pll.h,v 1.2 2005/02/10 11:43:41 kraxel Exp $ |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #ifndef __DVB_PLL_H__ | ||
6 | #define __DVB_PLL_H__ | ||
7 | |||
5 | struct dvb_pll_desc { | 8 | struct dvb_pll_desc { |
6 | char *name; | 9 | char *name; |
7 | u32 min; | 10 | u32 min; |
@@ -26,9 +29,4 @@ extern struct dvb_pll_desc dvb_pll_unknown_1; | |||
26 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, | 29 | int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, |
27 | u32 freq, int bandwidth); | 30 | u32 freq, int bandwidth); |
28 | 31 | ||
29 | /* | 32 | #endif |
30 | * Local variables: | ||
31 | * c-basic-offset: 8 | ||
32 | * compile-command: "make DVB=1" | ||
33 | * End: | ||
34 | */ | ||
diff --git a/drivers/media/dvb/frontends/dvb_dummy_fe.c b/drivers/media/dvb/frontends/dvb_dummy_fe.c index c05a9b05600c..cff93b9d8ab2 100644 --- a/drivers/media/dvb/frontends/dvb_dummy_fe.c +++ b/drivers/media/dvb/frontends/dvb_dummy_fe.c | |||
@@ -100,7 +100,7 @@ static int dvb_dummy_fe_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t vo | |||
100 | 100 | ||
101 | static void dvb_dummy_fe_release(struct dvb_frontend* fe) | 101 | static void dvb_dummy_fe_release(struct dvb_frontend* fe) |
102 | { | 102 | { |
103 | struct dvb_dummy_fe_state* state = (struct dvb_dummy_fe_state*) fe->demodulator_priv; | 103 | struct dvb_dummy_fe_state* state = fe->demodulator_priv; |
104 | kfree(state); | 104 | kfree(state); |
105 | } | 105 | } |
106 | 106 | ||
@@ -111,7 +111,7 @@ struct dvb_frontend* dvb_dummy_fe_ofdm_attach(void) | |||
111 | struct dvb_dummy_fe_state* state = NULL; | 111 | struct dvb_dummy_fe_state* state = NULL; |
112 | 112 | ||
113 | /* allocate memory for the internal state */ | 113 | /* allocate memory for the internal state */ |
114 | state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 114 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
115 | if (state == NULL) goto error; | 115 | if (state == NULL) goto error; |
116 | 116 | ||
117 | /* setup the state */ | 117 | /* setup the state */ |
@@ -134,7 +134,7 @@ struct dvb_frontend* dvb_dummy_fe_qpsk_attach() | |||
134 | struct dvb_dummy_fe_state* state = NULL; | 134 | struct dvb_dummy_fe_state* state = NULL; |
135 | 135 | ||
136 | /* allocate memory for the internal state */ | 136 | /* allocate memory for the internal state */ |
137 | state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 137 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
138 | if (state == NULL) goto error; | 138 | if (state == NULL) goto error; |
139 | 139 | ||
140 | /* setup the state */ | 140 | /* setup the state */ |
@@ -157,7 +157,7 @@ struct dvb_frontend* dvb_dummy_fe_qam_attach() | |||
157 | struct dvb_dummy_fe_state* state = NULL; | 157 | struct dvb_dummy_fe_state* state = NULL; |
158 | 158 | ||
159 | /* allocate memory for the internal state */ | 159 | /* allocate memory for the internal state */ |
160 | state = (struct dvb_dummy_fe_state*) kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); | 160 | state = kmalloc(sizeof(struct dvb_dummy_fe_state), GFP_KERNEL); |
161 | if (state == NULL) goto error; | 161 | if (state == NULL) goto error; |
162 | 162 | ||
163 | /* setup the state */ | 163 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/l64781.c b/drivers/media/dvb/frontends/l64781.c index 9ac95de9834d..031a1ddc7d11 100644 --- a/drivers/media/dvb/frontends/l64781.c +++ b/drivers/media/dvb/frontends/l64781.c | |||
@@ -121,7 +121,7 @@ static int reset_and_configure (struct l64781_state* state) | |||
121 | 121 | ||
122 | static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param) | 122 | static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_parameters *param) |
123 | { | 123 | { |
124 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 124 | struct l64781_state* state = fe->demodulator_priv; |
125 | /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ | 125 | /* The coderates for FEC_NONE, FEC_4_5 and FEC_FEC_6_7 are arbitrary */ |
126 | static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 }; | 126 | static const u8 fec_tab[] = { 7, 0, 1, 2, 9, 3, 10, 4 }; |
127 | /* QPSK, QAM_16, QAM_64 */ | 127 | /* QPSK, QAM_16, QAM_64 */ |
@@ -234,7 +234,7 @@ static int apply_frontend_param (struct dvb_frontend* fe, struct dvb_frontend_pa | |||
234 | 234 | ||
235 | static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param) | 235 | static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* param) |
236 | { | 236 | { |
237 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 237 | struct l64781_state* state = fe->demodulator_priv; |
238 | int tmp; | 238 | int tmp; |
239 | 239 | ||
240 | 240 | ||
@@ -352,7 +352,7 @@ static int get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters* | |||
352 | 352 | ||
353 | static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) | 353 | static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) |
354 | { | 354 | { |
355 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 355 | struct l64781_state* state = fe->demodulator_priv; |
356 | int sync = l64781_readreg (state, 0x32); | 356 | int sync = l64781_readreg (state, 0x32); |
357 | int gain = l64781_readreg (state, 0x0e); | 357 | int gain = l64781_readreg (state, 0x0e); |
358 | 358 | ||
@@ -381,7 +381,7 @@ static int l64781_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
381 | 381 | ||
382 | static int l64781_read_ber(struct dvb_frontend* fe, u32* ber) | 382 | static int l64781_read_ber(struct dvb_frontend* fe, u32* ber) |
383 | { | 383 | { |
384 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 384 | struct l64781_state* state = fe->demodulator_priv; |
385 | 385 | ||
386 | /* XXX FIXME: set up counting period (reg 0x26...0x28) | 386 | /* XXX FIXME: set up counting period (reg 0x26...0x28) |
387 | */ | 387 | */ |
@@ -393,7 +393,7 @@ static int l64781_read_ber(struct dvb_frontend* fe, u32* ber) | |||
393 | 393 | ||
394 | static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | 394 | static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) |
395 | { | 395 | { |
396 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 396 | struct l64781_state* state = fe->demodulator_priv; |
397 | 397 | ||
398 | u8 gain = l64781_readreg (state, 0x0e); | 398 | u8 gain = l64781_readreg (state, 0x0e); |
399 | *signal_strength = (gain << 8) | gain; | 399 | *signal_strength = (gain << 8) | gain; |
@@ -403,7 +403,7 @@ static int l64781_read_signal_strength(struct dvb_frontend* fe, u16* signal_stre | |||
403 | 403 | ||
404 | static int l64781_read_snr(struct dvb_frontend* fe, u16* snr) | 404 | static int l64781_read_snr(struct dvb_frontend* fe, u16* snr) |
405 | { | 405 | { |
406 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 406 | struct l64781_state* state = fe->demodulator_priv; |
407 | 407 | ||
408 | u8 avg_quality = 0xff - l64781_readreg (state, 0x33); | 408 | u8 avg_quality = 0xff - l64781_readreg (state, 0x33); |
409 | *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/ | 409 | *snr = (avg_quality << 8) | avg_quality; /* not exact, but...*/ |
@@ -413,7 +413,7 @@ static int l64781_read_snr(struct dvb_frontend* fe, u16* snr) | |||
413 | 413 | ||
414 | static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 414 | static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
415 | { | 415 | { |
416 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 416 | struct l64781_state* state = fe->demodulator_priv; |
417 | 417 | ||
418 | *ucblocks = l64781_readreg (state, 0x37) | 418 | *ucblocks = l64781_readreg (state, 0x37) |
419 | | (l64781_readreg (state, 0x38) << 8); | 419 | | (l64781_readreg (state, 0x38) << 8); |
@@ -423,7 +423,7 @@ static int l64781_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
423 | 423 | ||
424 | static int l64781_sleep(struct dvb_frontend* fe) | 424 | static int l64781_sleep(struct dvb_frontend* fe) |
425 | { | 425 | { |
426 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 426 | struct l64781_state* state = fe->demodulator_priv; |
427 | 427 | ||
428 | /* Power down */ | 428 | /* Power down */ |
429 | return l64781_writereg (state, 0x3e, 0x5a); | 429 | return l64781_writereg (state, 0x3e, 0x5a); |
@@ -431,7 +431,7 @@ static int l64781_sleep(struct dvb_frontend* fe) | |||
431 | 431 | ||
432 | static int l64781_init(struct dvb_frontend* fe) | 432 | static int l64781_init(struct dvb_frontend* fe) |
433 | { | 433 | { |
434 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 434 | struct l64781_state* state = fe->demodulator_priv; |
435 | 435 | ||
436 | reset_and_configure (state); | 436 | reset_and_configure (state); |
437 | 437 | ||
@@ -484,7 +484,7 @@ static int l64781_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend | |||
484 | 484 | ||
485 | static void l64781_release(struct dvb_frontend* fe) | 485 | static void l64781_release(struct dvb_frontend* fe) |
486 | { | 486 | { |
487 | struct l64781_state* state = (struct l64781_state*) fe->demodulator_priv; | 487 | struct l64781_state* state = fe->demodulator_priv; |
488 | kfree(state); | 488 | kfree(state); |
489 | } | 489 | } |
490 | 490 | ||
@@ -501,7 +501,7 @@ struct dvb_frontend* l64781_attach(const struct l64781_config* config, | |||
501 | { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; | 501 | { .addr = config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } }; |
502 | 502 | ||
503 | /* allocate memory for the internal state */ | 503 | /* allocate memory for the internal state */ |
504 | state = (struct l64781_state*) kmalloc(sizeof(struct l64781_state), GFP_KERNEL); | 504 | state = kmalloc(sizeof(struct l64781_state), GFP_KERNEL); |
505 | if (state == NULL) goto error; | 505 | if (state == NULL) goto error; |
506 | 506 | ||
507 | /* setup the state */ | 507 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/mt312.c b/drivers/media/dvb/frontends/mt312.c index 176a22e3441b..e455aecd76b2 100644 --- a/drivers/media/dvb/frontends/mt312.c +++ b/drivers/media/dvb/frontends/mt312.c | |||
@@ -226,7 +226,7 @@ static int mt312_get_code_rate(struct mt312_state* state, fe_code_rate_t *cr) | |||
226 | 226 | ||
227 | static int mt312_initfe(struct dvb_frontend* fe) | 227 | static int mt312_initfe(struct dvb_frontend* fe) |
228 | { | 228 | { |
229 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 229 | struct mt312_state *state = fe->demodulator_priv; |
230 | int ret; | 230 | int ret; |
231 | u8 buf[2]; | 231 | u8 buf[2]; |
232 | 232 | ||
@@ -287,7 +287,7 @@ static int mt312_initfe(struct dvb_frontend* fe) | |||
287 | static int mt312_send_master_cmd(struct dvb_frontend* fe, | 287 | static int mt312_send_master_cmd(struct dvb_frontend* fe, |
288 | struct dvb_diseqc_master_cmd *c) | 288 | struct dvb_diseqc_master_cmd *c) |
289 | { | 289 | { |
290 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 290 | struct mt312_state *state = fe->demodulator_priv; |
291 | int ret; | 291 | int ret; |
292 | u8 diseqc_mode; | 292 | u8 diseqc_mode; |
293 | 293 | ||
@@ -318,7 +318,7 @@ static int mt312_send_master_cmd(struct dvb_frontend* fe, | |||
318 | 318 | ||
319 | static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c) | 319 | static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c) |
320 | { | 320 | { |
321 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 321 | struct mt312_state *state = fe->demodulator_priv; |
322 | const u8 mini_tab[2] = { 0x02, 0x03 }; | 322 | const u8 mini_tab[2] = { 0x02, 0x03 }; |
323 | 323 | ||
324 | int ret; | 324 | int ret; |
@@ -340,7 +340,7 @@ static int mt312_send_burst(struct dvb_frontend* fe, const fe_sec_mini_cmd_t c) | |||
340 | 340 | ||
341 | static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t) | 341 | static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t) |
342 | { | 342 | { |
343 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 343 | struct mt312_state *state = fe->demodulator_priv; |
344 | const u8 tone_tab[2] = { 0x01, 0x00 }; | 344 | const u8 tone_tab[2] = { 0x01, 0x00 }; |
345 | 345 | ||
346 | int ret; | 346 | int ret; |
@@ -362,7 +362,7 @@ static int mt312_set_tone(struct dvb_frontend* fe, const fe_sec_tone_mode_t t) | |||
362 | 362 | ||
363 | static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v) | 363 | static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v) |
364 | { | 364 | { |
365 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 365 | struct mt312_state *state = fe->demodulator_priv; |
366 | const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; | 366 | const u8 volt_tab[3] = { 0x00, 0x40, 0x00 }; |
367 | 367 | ||
368 | if (v > SEC_VOLTAGE_OFF) | 368 | if (v > SEC_VOLTAGE_OFF) |
@@ -373,7 +373,7 @@ static int mt312_set_voltage(struct dvb_frontend* fe, const fe_sec_voltage_t v) | |||
373 | 373 | ||
374 | static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s) | 374 | static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s) |
375 | { | 375 | { |
376 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 376 | struct mt312_state *state = fe->demodulator_priv; |
377 | int ret; | 377 | int ret; |
378 | u8 status[3]; | 378 | u8 status[3]; |
379 | 379 | ||
@@ -400,7 +400,7 @@ static int mt312_read_status(struct dvb_frontend* fe, fe_status_t *s) | |||
400 | 400 | ||
401 | static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber) | 401 | static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber) |
402 | { | 402 | { |
403 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 403 | struct mt312_state *state = fe->demodulator_priv; |
404 | int ret; | 404 | int ret; |
405 | u8 buf[3]; | 405 | u8 buf[3]; |
406 | 406 | ||
@@ -414,7 +414,7 @@ static int mt312_read_ber(struct dvb_frontend* fe, u32 *ber) | |||
414 | 414 | ||
415 | static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength) | 415 | static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_strength) |
416 | { | 416 | { |
417 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 417 | struct mt312_state *state = fe->demodulator_priv; |
418 | int ret; | 418 | int ret; |
419 | u8 buf[3]; | 419 | u8 buf[3]; |
420 | u16 agc; | 420 | u16 agc; |
@@ -435,7 +435,7 @@ static int mt312_read_signal_strength(struct dvb_frontend* fe, u16 *signal_stren | |||
435 | 435 | ||
436 | static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr) | 436 | static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr) |
437 | { | 437 | { |
438 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 438 | struct mt312_state *state = fe->demodulator_priv; |
439 | int ret; | 439 | int ret; |
440 | u8 buf[2]; | 440 | u8 buf[2]; |
441 | 441 | ||
@@ -449,7 +449,7 @@ static int mt312_read_snr(struct dvb_frontend* fe, u16 *snr) | |||
449 | 449 | ||
450 | static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc) | 450 | static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc) |
451 | { | 451 | { |
452 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 452 | struct mt312_state *state = fe->demodulator_priv; |
453 | int ret; | 453 | int ret; |
454 | u8 buf[2]; | 454 | u8 buf[2]; |
455 | 455 | ||
@@ -464,7 +464,7 @@ static int mt312_read_ucblocks(struct dvb_frontend* fe, u32 *ubc) | |||
464 | static int mt312_set_frontend(struct dvb_frontend* fe, | 464 | static int mt312_set_frontend(struct dvb_frontend* fe, |
465 | struct dvb_frontend_parameters *p) | 465 | struct dvb_frontend_parameters *p) |
466 | { | 466 | { |
467 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 467 | struct mt312_state *state = fe->demodulator_priv; |
468 | int ret; | 468 | int ret; |
469 | u8 buf[5], config_val; | 469 | u8 buf[5], config_val; |
470 | u16 sr; | 470 | u16 sr; |
@@ -560,7 +560,7 @@ static int mt312_set_frontend(struct dvb_frontend* fe, | |||
560 | static int mt312_get_frontend(struct dvb_frontend* fe, | 560 | static int mt312_get_frontend(struct dvb_frontend* fe, |
561 | struct dvb_frontend_parameters *p) | 561 | struct dvb_frontend_parameters *p) |
562 | { | 562 | { |
563 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 563 | struct mt312_state *state = fe->demodulator_priv; |
564 | int ret; | 564 | int ret; |
565 | 565 | ||
566 | if ((ret = mt312_get_inversion(state, &p->inversion)) < 0) | 566 | if ((ret = mt312_get_inversion(state, &p->inversion)) < 0) |
@@ -577,7 +577,7 @@ static int mt312_get_frontend(struct dvb_frontend* fe, | |||
577 | 577 | ||
578 | static int mt312_sleep(struct dvb_frontend* fe) | 578 | static int mt312_sleep(struct dvb_frontend* fe) |
579 | { | 579 | { |
580 | struct mt312_state *state = (struct mt312_state*) fe->demodulator_priv; | 580 | struct mt312_state *state = fe->demodulator_priv; |
581 | int ret; | 581 | int ret; |
582 | u8 config; | 582 | u8 config; |
583 | 583 | ||
@@ -605,7 +605,7 @@ static int mt312_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_ | |||
605 | 605 | ||
606 | static void mt312_release(struct dvb_frontend* fe) | 606 | static void mt312_release(struct dvb_frontend* fe) |
607 | { | 607 | { |
608 | struct mt312_state* state = (struct mt312_state*) fe->demodulator_priv; | 608 | struct mt312_state* state = fe->demodulator_priv; |
609 | kfree(state); | 609 | kfree(state); |
610 | } | 610 | } |
611 | 611 | ||
@@ -617,7 +617,7 @@ struct dvb_frontend* vp310_attach(const struct mt312_config* config, | |||
617 | struct mt312_state* state = NULL; | 617 | struct mt312_state* state = NULL; |
618 | 618 | ||
619 | /* allocate memory for the internal state */ | 619 | /* allocate memory for the internal state */ |
620 | state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL); | 620 | state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); |
621 | if (state == NULL) | 621 | if (state == NULL) |
622 | goto error; | 622 | goto error; |
623 | 623 | ||
@@ -651,7 +651,7 @@ struct dvb_frontend* mt312_attach(const struct mt312_config* config, | |||
651 | struct mt312_state* state = NULL; | 651 | struct mt312_state* state = NULL; |
652 | 652 | ||
653 | /* allocate memory for the internal state */ | 653 | /* allocate memory for the internal state */ |
654 | state = (struct mt312_state*) kmalloc(sizeof(struct mt312_state), GFP_KERNEL); | 654 | state = kmalloc(sizeof(struct mt312_state), GFP_KERNEL); |
655 | if (state == NULL) | 655 | if (state == NULL) |
656 | goto error; | 656 | goto error; |
657 | 657 | ||
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c index 50326c7248fa..d32dc4de9e7f 100644 --- a/drivers/media/dvb/frontends/mt352.c +++ b/drivers/media/dvb/frontends/mt352.c | |||
@@ -46,7 +46,7 @@ struct mt352_state { | |||
46 | struct dvb_frontend_ops ops; | 46 | struct dvb_frontend_ops ops; |
47 | 47 | ||
48 | /* configuration settings */ | 48 | /* configuration settings */ |
49 | const struct mt352_config* config; | 49 | struct mt352_config config; |
50 | }; | 50 | }; |
51 | 51 | ||
52 | static int debug; | 52 | static int debug; |
@@ -59,7 +59,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val) | |||
59 | { | 59 | { |
60 | struct mt352_state* state = fe->demodulator_priv; | 60 | struct mt352_state* state = fe->demodulator_priv; |
61 | u8 buf[2] = { reg, val }; | 61 | u8 buf[2] = { reg, val }; |
62 | struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, | 62 | struct i2c_msg msg = { .addr = state->config.demod_address, .flags = 0, |
63 | .buf = buf, .len = 2 }; | 63 | .buf = buf, .len = 2 }; |
64 | int err = i2c_transfer(state->i2c, &msg, 1); | 64 | int err = i2c_transfer(state->i2c, &msg, 1); |
65 | if (err != 1) { | 65 | if (err != 1) { |
@@ -84,10 +84,10 @@ static int mt352_read_register(struct mt352_state* state, u8 reg) | |||
84 | int ret; | 84 | int ret; |
85 | u8 b0 [] = { reg }; | 85 | u8 b0 [] = { reg }; |
86 | u8 b1 [] = { 0 }; | 86 | u8 b1 [] = { 0 }; |
87 | struct i2c_msg msg [] = { { .addr = state->config->demod_address, | 87 | struct i2c_msg msg [] = { { .addr = state->config.demod_address, |
88 | .flags = 0, | 88 | .flags = 0, |
89 | .buf = b0, .len = 1 }, | 89 | .buf = b0, .len = 1 }, |
90 | { .addr = state->config->demod_address, | 90 | { .addr = state->config.demod_address, |
91 | .flags = I2C_M_RD, | 91 | .flags = I2C_M_RD, |
92 | .buf = b1, .len = 1 } }; | 92 | .buf = b1, .len = 1 } }; |
93 | 93 | ||
@@ -102,11 +102,6 @@ static int mt352_read_register(struct mt352_state* state, u8 reg) | |||
102 | return b1[0]; | 102 | return b1[0]; |
103 | } | 103 | } |
104 | 104 | ||
105 | int mt352_read(struct dvb_frontend *fe, u8 reg) | ||
106 | { | ||
107 | return mt352_read_register(fe->demodulator_priv,reg); | ||
108 | } | ||
109 | |||
110 | static int mt352_sleep(struct dvb_frontend* fe) | 105 | static int mt352_sleep(struct dvb_frontend* fe) |
111 | { | 106 | { |
112 | static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; | 107 | static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; |
@@ -134,8 +129,8 @@ static void mt352_calc_nominal_rate(struct mt352_state* state, | |||
134 | bw = 8; | 129 | bw = 8; |
135 | break; | 130 | break; |
136 | } | 131 | } |
137 | if (state->config->adc_clock) | 132 | if (state->config.adc_clock) |
138 | adc_clock = state->config->adc_clock; | 133 | adc_clock = state->config.adc_clock; |
139 | 134 | ||
140 | value = 64 * bw * (1<<16) / (7 * 8); | 135 | value = 64 * bw * (1<<16) / (7 * 8); |
141 | value = value * 1000 / adc_clock; | 136 | value = value * 1000 / adc_clock; |
@@ -152,10 +147,10 @@ static void mt352_calc_input_freq(struct mt352_state* state, | |||
152 | int if2 = 36167; /* 36.166667 MHz */ | 147 | int if2 = 36167; /* 36.166667 MHz */ |
153 | int ife,value; | 148 | int ife,value; |
154 | 149 | ||
155 | if (state->config->adc_clock) | 150 | if (state->config.adc_clock) |
156 | adc_clock = state->config->adc_clock; | 151 | adc_clock = state->config.adc_clock; |
157 | if (state->config->if2) | 152 | if (state->config.if2) |
158 | if2 = state->config->if2; | 153 | if2 = state->config.if2; |
159 | 154 | ||
160 | ife = (2*adc_clock - if2); | 155 | ife = (2*adc_clock - if2); |
161 | value = -16374 * ife / adc_clock; | 156 | value = -16374 * ife / adc_clock; |
@@ -289,10 +284,10 @@ static int mt352_set_parameters(struct dvb_frontend* fe, | |||
289 | 284 | ||
290 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); | 285 | mt352_calc_nominal_rate(state, op->bandwidth, buf+4); |
291 | mt352_calc_input_freq(state, buf+6); | 286 | mt352_calc_input_freq(state, buf+6); |
292 | state->config->pll_set(fe, param, buf+8); | 287 | state->config.pll_set(fe, param, buf+8); |
293 | 288 | ||
294 | mt352_write(fe, buf, sizeof(buf)); | 289 | mt352_write(fe, buf, sizeof(buf)); |
295 | if (state->config->no_tuner) { | 290 | if (state->config.no_tuner) { |
296 | /* start decoding */ | 291 | /* start decoding */ |
297 | mt352_write(fe, fsm_go, 2); | 292 | mt352_write(fe, fsm_go, 2); |
298 | } else { | 293 | } else { |
@@ -516,7 +511,7 @@ static int mt352_init(struct dvb_frontend* fe) | |||
516 | 511 | ||
517 | /* Do a "hard" reset */ | 512 | /* Do a "hard" reset */ |
518 | mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach)); | 513 | mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach)); |
519 | return state->config->demod_init(fe); | 514 | return state->config.demod_init(fe); |
520 | } | 515 | } |
521 | 516 | ||
522 | return 0; | 517 | return 0; |
@@ -541,8 +536,8 @@ struct dvb_frontend* mt352_attach(const struct mt352_config* config, | |||
541 | memset(state,0,sizeof(*state)); | 536 | memset(state,0,sizeof(*state)); |
542 | 537 | ||
543 | /* setup the state */ | 538 | /* setup the state */ |
544 | state->config = config; | ||
545 | state->i2c = i2c; | 539 | state->i2c = i2c; |
540 | memcpy(&state->config,config,sizeof(struct mt352_config)); | ||
546 | memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); | 541 | memcpy(&state->ops, &mt352_ops, sizeof(struct dvb_frontend_ops)); |
547 | 542 | ||
548 | /* check if the demod is there */ | 543 | /* check if the demod is there */ |
@@ -601,10 +596,3 @@ MODULE_LICENSE("GPL"); | |||
601 | 596 | ||
602 | EXPORT_SYMBOL(mt352_attach); | 597 | EXPORT_SYMBOL(mt352_attach); |
603 | EXPORT_SYMBOL(mt352_write); | 598 | EXPORT_SYMBOL(mt352_write); |
604 | EXPORT_SYMBOL(mt352_read); | ||
605 | /* | ||
606 | * Local variables: | ||
607 | * c-basic-offset: 8 | ||
608 | * compile-command: "make DVB=1" | ||
609 | * End: | ||
610 | */ | ||
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h index f5d8a5aed8a9..03040cd595bb 100644 --- a/drivers/media/dvb/frontends/mt352.h +++ b/drivers/media/dvb/frontends/mt352.h | |||
@@ -61,12 +61,5 @@ extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, | |||
61 | struct i2c_adapter* i2c); | 61 | struct i2c_adapter* i2c); |
62 | 62 | ||
63 | extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen); | 63 | extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen); |
64 | extern int mt352_read(struct dvb_frontend *fe, u8 reg); | ||
65 | 64 | ||
66 | #endif // MT352_H | 65 | #endif // MT352_H |
67 | |||
68 | /* | ||
69 | * Local variables: | ||
70 | * c-basic-offset: 8 | ||
71 | * End: | ||
72 | */ | ||
diff --git a/drivers/media/dvb/frontends/nxt2002.c b/drivers/media/dvb/frontends/nxt2002.c index 4743aa17406e..35a1d60f1927 100644 --- a/drivers/media/dvb/frontends/nxt2002.c +++ b/drivers/media/dvb/frontends/nxt2002.c | |||
@@ -241,7 +241,7 @@ static void nxt2002_agc_reset(struct nxt2002_state* state) | |||
241 | static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 241 | static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) |
242 | { | 242 | { |
243 | 243 | ||
244 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 244 | struct nxt2002_state* state = fe->demodulator_priv; |
245 | u8 buf[256],written = 0,chunkpos = 0; | 245 | u8 buf[256],written = 0,chunkpos = 0; |
246 | u16 rambase,position,crc = 0; | 246 | u16 rambase,position,crc = 0; |
247 | 247 | ||
@@ -309,7 +309,7 @@ static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware | |||
309 | static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, | 309 | static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, |
310 | struct dvb_frontend_parameters *p) | 310 | struct dvb_frontend_parameters *p) |
311 | { | 311 | { |
312 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 312 | struct nxt2002_state* state = fe->demodulator_priv; |
313 | u32 freq = 0; | 313 | u32 freq = 0; |
314 | u16 tunerfreq = 0; | 314 | u16 tunerfreq = 0; |
315 | u8 buf[4]; | 315 | u8 buf[4]; |
@@ -343,8 +343,6 @@ static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, | |||
343 | /* reset the agc now that tuning has been completed */ | 343 | /* reset the agc now that tuning has been completed */ |
344 | nxt2002_agc_reset(state); | 344 | nxt2002_agc_reset(state); |
345 | 345 | ||
346 | |||
347 | |||
348 | /* set target power level */ | 346 | /* set target power level */ |
349 | switch (p->u.vsb.modulation) { | 347 | switch (p->u.vsb.modulation) { |
350 | case QAM_64: | 348 | case QAM_64: |
@@ -453,7 +451,7 @@ static int nxt2002_setup_frontend_parameters (struct dvb_frontend* fe, | |||
453 | 451 | ||
454 | static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status) | 452 | static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status) |
455 | { | 453 | { |
456 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 454 | struct nxt2002_state* state = fe->demodulator_priv; |
457 | u8 lock; | 455 | u8 lock; |
458 | i2c_readbytes(state,0x31,&lock,1); | 456 | i2c_readbytes(state,0x31,&lock,1); |
459 | 457 | ||
@@ -470,7 +468,7 @@ static int nxt2002_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
470 | 468 | ||
471 | static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber) | 469 | static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber) |
472 | { | 470 | { |
473 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 471 | struct nxt2002_state* state = fe->demodulator_priv; |
474 | u8 b[3]; | 472 | u8 b[3]; |
475 | 473 | ||
476 | nxt2002_readreg_multibyte(state,0xE6,b,3); | 474 | nxt2002_readreg_multibyte(state,0xE6,b,3); |
@@ -482,7 +480,7 @@ static int nxt2002_read_ber(struct dvb_frontend* fe, u32* ber) | |||
482 | 480 | ||
483 | static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 481 | static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
484 | { | 482 | { |
485 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 483 | struct nxt2002_state* state = fe->demodulator_priv; |
486 | u8 b[2]; | 484 | u8 b[2]; |
487 | u16 temp = 0; | 485 | u16 temp = 0; |
488 | 486 | ||
@@ -502,7 +500,7 @@ static int nxt2002_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
502 | static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr) | 500 | static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr) |
503 | { | 501 | { |
504 | 502 | ||
505 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 503 | struct nxt2002_state* state = fe->demodulator_priv; |
506 | u8 b[2]; | 504 | u8 b[2]; |
507 | u16 temp = 0, temp2; | 505 | u16 temp = 0, temp2; |
508 | u32 snrdb = 0; | 506 | u32 snrdb = 0; |
@@ -536,7 +534,7 @@ static int nxt2002_read_snr(struct dvb_frontend* fe, u16* snr) | |||
536 | 534 | ||
537 | static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 535 | static int nxt2002_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
538 | { | 536 | { |
539 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 537 | struct nxt2002_state* state = fe->demodulator_priv; |
540 | u8 b[3]; | 538 | u8 b[3]; |
541 | 539 | ||
542 | nxt2002_readreg_multibyte(state,0xE6,b,3); | 540 | nxt2002_readreg_multibyte(state,0xE6,b,3); |
@@ -552,7 +550,7 @@ static int nxt2002_sleep(struct dvb_frontend* fe) | |||
552 | 550 | ||
553 | static int nxt2002_init(struct dvb_frontend* fe) | 551 | static int nxt2002_init(struct dvb_frontend* fe) |
554 | { | 552 | { |
555 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 553 | struct nxt2002_state* state = fe->demodulator_priv; |
556 | const struct firmware *fw; | 554 | const struct firmware *fw; |
557 | int ret; | 555 | int ret; |
558 | u8 buf[2]; | 556 | u8 buf[2]; |
@@ -624,7 +622,7 @@ static int nxt2002_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten | |||
624 | 622 | ||
625 | static void nxt2002_release(struct dvb_frontend* fe) | 623 | static void nxt2002_release(struct dvb_frontend* fe) |
626 | { | 624 | { |
627 | struct nxt2002_state* state = (struct nxt2002_state*) fe->demodulator_priv; | 625 | struct nxt2002_state* state = fe->demodulator_priv; |
628 | kfree(state); | 626 | kfree(state); |
629 | } | 627 | } |
630 | 628 | ||
@@ -637,7 +635,7 @@ struct dvb_frontend* nxt2002_attach(const struct nxt2002_config* config, | |||
637 | u8 buf [] = {0,0,0,0,0}; | 635 | u8 buf [] = {0,0,0,0,0}; |
638 | 636 | ||
639 | /* allocate memory for the internal state */ | 637 | /* allocate memory for the internal state */ |
640 | state = (struct nxt2002_state*) kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL); | 638 | state = kmalloc(sizeof(struct nxt2002_state), GFP_KERNEL); |
641 | if (state == NULL) goto error; | 639 | if (state == NULL) goto error; |
642 | 640 | ||
643 | /* setup the state */ | 641 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/nxt6000.c b/drivers/media/dvb/frontends/nxt6000.c index a41f7da8b842..966de9853d18 100644 --- a/drivers/media/dvb/frontends/nxt6000.c +++ b/drivers/media/dvb/frontends/nxt6000.c | |||
@@ -176,11 +176,16 @@ static int nxt6000_set_transmission_mode(struct nxt6000_state* state, fe_transmi | |||
176 | 176 | ||
177 | static void nxt6000_setup(struct dvb_frontend* fe) | 177 | static void nxt6000_setup(struct dvb_frontend* fe) |
178 | { | 178 | { |
179 | struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv; | 179 | struct nxt6000_state* state = fe->demodulator_priv; |
180 | 180 | ||
181 | nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM); | 181 | nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM); |
182 | nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01); | 182 | nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01); |
183 | nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC); | 183 | nxt6000_writereg(state, VIT_BERTIME_2, 0x00); // BER Timer = 0x000200 * 256 = 131072 bits |
184 | nxt6000_writereg(state, VIT_BERTIME_1, 0x02); // | ||
185 | nxt6000_writereg(state, VIT_BERTIME_0, 0x00); // | ||
186 | nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts | ||
187 | nxt6000_writereg(state, VIT_COR_CTL, 0x82); // Enable BER measurement | ||
188 | nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 ); | ||
184 | nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F)); | 189 | nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F)); |
185 | nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02); | 190 | nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02); |
186 | nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW); | 191 | nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW); |
@@ -422,7 +427,7 @@ static void nxt6000_dump_status(struct nxt6000_state *state) | |||
422 | static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) | 427 | static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) |
423 | { | 428 | { |
424 | u8 core_status; | 429 | u8 core_status; |
425 | struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv; | 430 | struct nxt6000_state* state = fe->demodulator_priv; |
426 | 431 | ||
427 | *status = 0; | 432 | *status = 0; |
428 | 433 | ||
@@ -451,7 +456,7 @@ static int nxt6000_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
451 | 456 | ||
452 | static int nxt6000_init(struct dvb_frontend* fe) | 457 | static int nxt6000_init(struct dvb_frontend* fe) |
453 | { | 458 | { |
454 | struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv; | 459 | struct nxt6000_state* state = fe->demodulator_priv; |
455 | 460 | ||
456 | nxt6000_reset(state); | 461 | nxt6000_reset(state); |
457 | nxt6000_setup(fe); | 462 | nxt6000_setup(fe); |
@@ -461,7 +466,7 @@ static int nxt6000_init(struct dvb_frontend* fe) | |||
461 | 466 | ||
462 | static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) | 467 | static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *param) |
463 | { | 468 | { |
464 | struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv; | 469 | struct nxt6000_state* state = fe->demodulator_priv; |
465 | int result; | 470 | int result; |
466 | 471 | ||
467 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ | 472 | nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01); /* open i2c bus switch */ |
@@ -482,10 +487,44 @@ static int nxt6000_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
482 | 487 | ||
483 | static void nxt6000_release(struct dvb_frontend* fe) | 488 | static void nxt6000_release(struct dvb_frontend* fe) |
484 | { | 489 | { |
485 | struct nxt6000_state* state = (struct nxt6000_state*) fe->demodulator_priv; | 490 | struct nxt6000_state* state = fe->demodulator_priv; |
486 | kfree(state); | 491 | kfree(state); |
487 | } | 492 | } |
488 | 493 | ||
494 | static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr) | ||
495 | { | ||
496 | struct nxt6000_state* state = fe->demodulator_priv; | ||
497 | |||
498 | *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8; | ||
499 | |||
500 | return 0; | ||
501 | } | ||
502 | |||
503 | static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber) | ||
504 | { | ||
505 | struct nxt6000_state* state = fe->demodulator_priv; | ||
506 | |||
507 | nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 ); | ||
508 | |||
509 | *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) | | ||
510 | nxt6000_readreg( state, VIT_BER_0 ); | ||
511 | |||
512 | nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts | ||
513 | |||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) | ||
518 | { | ||
519 | struct nxt6000_state* state = fe->demodulator_priv; | ||
520 | |||
521 | *signal_strength = (short) (511 - | ||
522 | (nxt6000_readreg(state, AGC_GAIN_1) + | ||
523 | ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8))); | ||
524 | |||
525 | return 0; | ||
526 | } | ||
527 | |||
489 | static struct dvb_frontend_ops nxt6000_ops; | 528 | static struct dvb_frontend_ops nxt6000_ops; |
490 | 529 | ||
491 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | 530 | struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, |
@@ -494,7 +533,7 @@ struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, | |||
494 | struct nxt6000_state* state = NULL; | 533 | struct nxt6000_state* state = NULL; |
495 | 534 | ||
496 | /* allocate memory for the internal state */ | 535 | /* allocate memory for the internal state */ |
497 | state = (struct nxt6000_state*) kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL); | 536 | state = kmalloc(sizeof(struct nxt6000_state), GFP_KERNEL); |
498 | if (state == NULL) goto error; | 537 | if (state == NULL) goto error; |
499 | 538 | ||
500 | /* setup the state */ | 539 | /* setup the state */ |
@@ -542,6 +581,9 @@ static struct dvb_frontend_ops nxt6000_ops = { | |||
542 | .set_frontend = nxt6000_set_frontend, | 581 | .set_frontend = nxt6000_set_frontend, |
543 | 582 | ||
544 | .read_status = nxt6000_read_status, | 583 | .read_status = nxt6000_read_status, |
584 | .read_ber = nxt6000_read_ber, | ||
585 | .read_signal_strength = nxt6000_read_signal_strength, | ||
586 | .read_snr = nxt6000_read_snr, | ||
545 | }; | 587 | }; |
546 | 588 | ||
547 | module_param(debug, int, 0644); | 589 | module_param(debug, int, 0644); |
diff --git a/drivers/media/dvb/frontends/nxt6000_priv.h b/drivers/media/dvb/frontends/nxt6000_priv.h index 64b1a89b2a22..0422e580038a 100644 --- a/drivers/media/dvb/frontends/nxt6000_priv.h +++ b/drivers/media/dvb/frontends/nxt6000_priv.h | |||
@@ -65,12 +65,27 @@ | |||
65 | #define BER_DONE (0x08) | 65 | #define BER_DONE (0x08) |
66 | #define BER_OVERFLOW (0x10) | 66 | #define BER_OVERFLOW (0x10) |
67 | 67 | ||
68 | /* 0x38 VIT_BERTIME_2 */ | ||
69 | #define VIT_BERTIME_2 (0x38) | ||
70 | |||
71 | /* 0x39 VIT_BERTIME_1 */ | ||
72 | #define VIT_BERTIME_1 (0x39) | ||
73 | |||
74 | /* 0x3A VIT_BERTIME_0 */ | ||
75 | #define VIT_BERTIME_0 (0x3a) | ||
76 | |||
68 | /* 0x38 OFDM_BERTimer *//* Use the alias registers */ | 77 | /* 0x38 OFDM_BERTimer *//* Use the alias registers */ |
69 | #define A_VIT_BER_TIMER_0 (0x1D) | 78 | #define A_VIT_BER_TIMER_0 (0x1D) |
70 | 79 | ||
71 | /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */ | 80 | /* 0x3A VIT_BER_TIMER_0 *//* Use the alias registers */ |
72 | #define A_VIT_BER_0 (0x1B) | 81 | #define A_VIT_BER_0 (0x1B) |
73 | 82 | ||
83 | /* 0x3B VIT_BER_1 */ | ||
84 | #define VIT_BER_1 (0x3b) | ||
85 | |||
86 | /* 0x3C VIT_BER_0 */ | ||
87 | #define VIT_BER_0 (0x3c) | ||
88 | |||
74 | /* 0x40 OFDM_COR_CTL */ | 89 | /* 0x40 OFDM_COR_CTL */ |
75 | #define OFDM_COR_CTL (0x40) | 90 | #define OFDM_COR_CTL (0x40) |
76 | #define COREACT (0x20) | 91 | #define COREACT (0x20) |
@@ -117,6 +132,12 @@ | |||
117 | #define OFDM_ITB_CTL (0x4B) | 132 | #define OFDM_ITB_CTL (0x4B) |
118 | #define ITBINV (0x01) | 133 | #define ITBINV (0x01) |
119 | 134 | ||
135 | /* 0x49 AGC_GAIN_1 */ | ||
136 | #define AGC_GAIN_1 (0x49) | ||
137 | |||
138 | /* 0x4A AGC_GAIN_2 */ | ||
139 | #define AGC_GAIN_2 (0x4A) | ||
140 | |||
120 | /* 0x4C OFDM_ITB_FREQ_1 */ | 141 | /* 0x4C OFDM_ITB_FREQ_1 */ |
121 | #define OFDM_ITB_FREQ_1 (0x4C) | 142 | #define OFDM_ITB_FREQ_1 (0x4C) |
122 | 143 | ||
diff --git a/drivers/media/dvb/frontends/or51132.c b/drivers/media/dvb/frontends/or51132.c index df5dee7760a3..cc0a77c790f1 100644 --- a/drivers/media/dvb/frontends/or51132.c +++ b/drivers/media/dvb/frontends/or51132.c | |||
@@ -102,7 +102,7 @@ static u8 i2c_readbytes (struct or51132_state* state, u8 reg, u8* buf, int len) | |||
102 | 102 | ||
103 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) | 103 | static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw) |
104 | { | 104 | { |
105 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 105 | struct or51132_state* state = fe->demodulator_priv; |
106 | static u8 run_buf[] = {0x7F,0x01}; | 106 | static u8 run_buf[] = {0x7F,0x01}; |
107 | static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; | 107 | static u8 get_ver_buf[] = {0x04,0x00,0x30,0x00,0x00}; |
108 | u8 rec_buf[14]; | 108 | u8 rec_buf[14]; |
@@ -240,7 +240,7 @@ static int or51132_sleep(struct dvb_frontend* fe) | |||
240 | 240 | ||
241 | static int or51132_setmode(struct dvb_frontend* fe) | 241 | static int or51132_setmode(struct dvb_frontend* fe) |
242 | { | 242 | { |
243 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 243 | struct or51132_state* state = fe->demodulator_priv; |
244 | unsigned char cmd_buf[4]; | 244 | unsigned char cmd_buf[4]; |
245 | 245 | ||
246 | dprintk("setmode %d\n",(int)state->current_modulation); | 246 | dprintk("setmode %d\n",(int)state->current_modulation); |
@@ -316,7 +316,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
316 | { | 316 | { |
317 | int ret; | 317 | int ret; |
318 | u8 buf[4]; | 318 | u8 buf[4]; |
319 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 319 | struct or51132_state* state = fe->demodulator_priv; |
320 | const struct firmware *fw; | 320 | const struct firmware *fw; |
321 | 321 | ||
322 | /* Change only if we are actually changing the modulation */ | 322 | /* Change only if we are actually changing the modulation */ |
@@ -391,7 +391,7 @@ static int or51132_set_parameters(struct dvb_frontend* fe, | |||
391 | 391 | ||
392 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) | 392 | static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status) |
393 | { | 393 | { |
394 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 394 | struct or51132_state* state = fe->demodulator_priv; |
395 | unsigned char rec_buf[2]; | 395 | unsigned char rec_buf[2]; |
396 | unsigned char snd_buf[2]; | 396 | unsigned char snd_buf[2]; |
397 | *status = 0; | 397 | *status = 0; |
@@ -464,7 +464,7 @@ static unsigned int i20Log10(unsigned short val) | |||
464 | 464 | ||
465 | static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 465 | static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
466 | { | 466 | { |
467 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 467 | struct or51132_state* state = fe->demodulator_priv; |
468 | unsigned char rec_buf[2]; | 468 | unsigned char rec_buf[2]; |
469 | unsigned char snd_buf[2]; | 469 | unsigned char snd_buf[2]; |
470 | u8 rcvr_stat; | 470 | u8 rcvr_stat; |
@@ -512,7 +512,7 @@ static int or51132_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
512 | 512 | ||
513 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) | 513 | static int or51132_read_snr(struct dvb_frontend* fe, u16* snr) |
514 | { | 514 | { |
515 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 515 | struct or51132_state* state = fe->demodulator_priv; |
516 | unsigned char rec_buf[2]; | 516 | unsigned char rec_buf[2]; |
517 | unsigned char snd_buf[2]; | 517 | unsigned char snd_buf[2]; |
518 | u16 snr_equ; | 518 | u16 snr_equ; |
@@ -549,7 +549,7 @@ static int or51132_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten | |||
549 | 549 | ||
550 | static void or51132_release(struct dvb_frontend* fe) | 550 | static void or51132_release(struct dvb_frontend* fe) |
551 | { | 551 | { |
552 | struct or51132_state* state = (struct or51132_state*) fe->demodulator_priv; | 552 | struct or51132_state* state = fe->demodulator_priv; |
553 | kfree(state); | 553 | kfree(state); |
554 | } | 554 | } |
555 | 555 | ||
diff --git a/drivers/media/dvb/frontends/sp8870.c b/drivers/media/dvb/frontends/sp8870.c index 58ad34ef0a00..764a95a2e212 100644 --- a/drivers/media/dvb/frontends/sp8870.c +++ b/drivers/media/dvb/frontends/sp8870.c | |||
@@ -248,7 +248,7 @@ static int sp8870_wake_up(struct sp8870_state* state) | |||
248 | static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, | 248 | static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, |
249 | struct dvb_frontend_parameters *p) | 249 | struct dvb_frontend_parameters *p) |
250 | { | 250 | { |
251 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 251 | struct sp8870_state* state = fe->demodulator_priv; |
252 | int err; | 252 | int err; |
253 | u16 reg0xc05; | 253 | u16 reg0xc05; |
254 | 254 | ||
@@ -302,7 +302,7 @@ static int sp8870_set_frontend_parameters (struct dvb_frontend* fe, | |||
302 | 302 | ||
303 | static int sp8870_init (struct dvb_frontend* fe) | 303 | static int sp8870_init (struct dvb_frontend* fe) |
304 | { | 304 | { |
305 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 305 | struct sp8870_state* state = fe->demodulator_priv; |
306 | const struct firmware *fw = NULL; | 306 | const struct firmware *fw = NULL; |
307 | 307 | ||
308 | sp8870_wake_up(state); | 308 | sp8870_wake_up(state); |
@@ -358,7 +358,7 @@ static int sp8870_init (struct dvb_frontend* fe) | |||
358 | 358 | ||
359 | static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) | 359 | static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) |
360 | { | 360 | { |
361 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 361 | struct sp8870_state* state = fe->demodulator_priv; |
362 | int status; | 362 | int status; |
363 | int signal; | 363 | int signal; |
364 | 364 | ||
@@ -384,7 +384,7 @@ static int sp8870_read_status (struct dvb_frontend* fe, fe_status_t * fe_status) | |||
384 | 384 | ||
385 | static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) | 385 | static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) |
386 | { | 386 | { |
387 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 387 | struct sp8870_state* state = fe->demodulator_priv; |
388 | int ret; | 388 | int ret; |
389 | u32 tmp; | 389 | u32 tmp; |
390 | 390 | ||
@@ -412,7 +412,7 @@ static int sp8870_read_ber (struct dvb_frontend* fe, u32 * ber) | |||
412 | 412 | ||
413 | static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) | 413 | static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) |
414 | { | 414 | { |
415 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 415 | struct sp8870_state* state = fe->demodulator_priv; |
416 | int ret; | 416 | int ret; |
417 | u16 tmp; | 417 | u16 tmp; |
418 | 418 | ||
@@ -438,7 +438,7 @@ static int sp8870_read_signal_strength(struct dvb_frontend* fe, u16 * signal) | |||
438 | 438 | ||
439 | static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) | 439 | static int sp8870_read_uncorrected_blocks (struct dvb_frontend* fe, u32* ublocks) |
440 | { | 440 | { |
441 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 441 | struct sp8870_state* state = fe->demodulator_priv; |
442 | int ret; | 442 | int ret; |
443 | 443 | ||
444 | *ublocks = 0; | 444 | *ublocks = 0; |
@@ -467,7 +467,7 @@ static int switches = 0; | |||
467 | 467 | ||
468 | static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 468 | static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
469 | { | 469 | { |
470 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 470 | struct sp8870_state* state = fe->demodulator_priv; |
471 | 471 | ||
472 | /* | 472 | /* |
473 | The firmware of the sp8870 sometimes locks up after setting frontend parameters. | 473 | The firmware of the sp8870 sometimes locks up after setting frontend parameters. |
@@ -524,7 +524,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par | |||
524 | 524 | ||
525 | static int sp8870_sleep(struct dvb_frontend* fe) | 525 | static int sp8870_sleep(struct dvb_frontend* fe) |
526 | { | 526 | { |
527 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 527 | struct sp8870_state* state = fe->demodulator_priv; |
528 | 528 | ||
529 | // tristate TS output and disable interface pins | 529 | // tristate TS output and disable interface pins |
530 | return sp8870_writereg(state, 0xC18, 0x000); | 530 | return sp8870_writereg(state, 0xC18, 0x000); |
@@ -540,7 +540,7 @@ static int sp8870_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend | |||
540 | 540 | ||
541 | static void sp8870_release(struct dvb_frontend* fe) | 541 | static void sp8870_release(struct dvb_frontend* fe) |
542 | { | 542 | { |
543 | struct sp8870_state* state = (struct sp8870_state*) fe->demodulator_priv; | 543 | struct sp8870_state* state = fe->demodulator_priv; |
544 | kfree(state); | 544 | kfree(state); |
545 | } | 545 | } |
546 | 546 | ||
@@ -552,7 +552,7 @@ struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, | |||
552 | struct sp8870_state* state = NULL; | 552 | struct sp8870_state* state = NULL; |
553 | 553 | ||
554 | /* allocate memory for the internal state */ | 554 | /* allocate memory for the internal state */ |
555 | state = (struct sp8870_state*) kmalloc(sizeof(struct sp8870_state), GFP_KERNEL); | 555 | state = kmalloc(sizeof(struct sp8870_state), GFP_KERNEL); |
556 | if (state == NULL) goto error; | 556 | if (state == NULL) goto error; |
557 | 557 | ||
558 | /* setup the state */ | 558 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/sp887x.c b/drivers/media/dvb/frontends/sp887x.c index 7eae833ece49..d868a6927a16 100644 --- a/drivers/media/dvb/frontends/sp887x.c +++ b/drivers/media/dvb/frontends/sp887x.c | |||
@@ -135,7 +135,7 @@ static void sp887x_setup_agc (struct sp887x_state* state) | |||
135 | */ | 135 | */ |
136 | static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) | 136 | static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware *fw) |
137 | { | 137 | { |
138 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 138 | struct sp887x_state* state = fe->demodulator_priv; |
139 | u8 buf [BLOCKSIZE+2]; | 139 | u8 buf [BLOCKSIZE+2]; |
140 | int i; | 140 | int i; |
141 | int fw_size = fw->size; | 141 | int fw_size = fw->size; |
@@ -344,7 +344,7 @@ static void sp887x_correct_offsets (struct sp887x_state* state, | |||
344 | static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, | 344 | static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, |
345 | struct dvb_frontend_parameters *p) | 345 | struct dvb_frontend_parameters *p) |
346 | { | 346 | { |
347 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 347 | struct sp887x_state* state = fe->demodulator_priv; |
348 | int actual_freq, err; | 348 | int actual_freq, err; |
349 | u16 val, reg0xc05; | 349 | u16 val, reg0xc05; |
350 | 350 | ||
@@ -405,7 +405,7 @@ static int sp887x_setup_frontend_parameters (struct dvb_frontend* fe, | |||
405 | 405 | ||
406 | static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) | 406 | static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) |
407 | { | 407 | { |
408 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 408 | struct sp887x_state* state = fe->demodulator_priv; |
409 | u16 snr12 = sp887x_readreg(state, 0xf16); | 409 | u16 snr12 = sp887x_readreg(state, 0xf16); |
410 | u16 sync0x200 = sp887x_readreg(state, 0x200); | 410 | u16 sync0x200 = sp887x_readreg(state, 0x200); |
411 | u16 sync0xf17 = sp887x_readreg(state, 0xf17); | 411 | u16 sync0xf17 = sp887x_readreg(state, 0xf17); |
@@ -439,7 +439,7 @@ static int sp887x_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
439 | 439 | ||
440 | static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber) | 440 | static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber) |
441 | { | 441 | { |
442 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 442 | struct sp887x_state* state = fe->demodulator_priv; |
443 | 443 | ||
444 | *ber = (sp887x_readreg(state, 0xc08) & 0x3f) | | 444 | *ber = (sp887x_readreg(state, 0xc08) & 0x3f) | |
445 | (sp887x_readreg(state, 0xc07) << 6); | 445 | (sp887x_readreg(state, 0xc07) << 6); |
@@ -453,7 +453,7 @@ static int sp887x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
453 | 453 | ||
454 | static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 454 | static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
455 | { | 455 | { |
456 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 456 | struct sp887x_state* state = fe->demodulator_priv; |
457 | 457 | ||
458 | u16 snr12 = sp887x_readreg(state, 0xf16); | 458 | u16 snr12 = sp887x_readreg(state, 0xf16); |
459 | u32 signal = 3 * (snr12 << 4); | 459 | u32 signal = 3 * (snr12 << 4); |
@@ -464,7 +464,7 @@ static int sp887x_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
464 | 464 | ||
465 | static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr) | 465 | static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr) |
466 | { | 466 | { |
467 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 467 | struct sp887x_state* state = fe->demodulator_priv; |
468 | 468 | ||
469 | u16 snr12 = sp887x_readreg(state, 0xf16); | 469 | u16 snr12 = sp887x_readreg(state, 0xf16); |
470 | *snr = (snr12 << 4) | (snr12 >> 8); | 470 | *snr = (snr12 << 4) | (snr12 >> 8); |
@@ -474,7 +474,7 @@ static int sp887x_read_snr(struct dvb_frontend* fe, u16* snr) | |||
474 | 474 | ||
475 | static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 475 | static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
476 | { | 476 | { |
477 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 477 | struct sp887x_state* state = fe->demodulator_priv; |
478 | 478 | ||
479 | *ucblocks = sp887x_readreg(state, 0xc0c); | 479 | *ucblocks = sp887x_readreg(state, 0xc0c); |
480 | if (*ucblocks == 0xfff) | 480 | if (*ucblocks == 0xfff) |
@@ -485,7 +485,7 @@ static int sp887x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
485 | 485 | ||
486 | static int sp887x_sleep(struct dvb_frontend* fe) | 486 | static int sp887x_sleep(struct dvb_frontend* fe) |
487 | { | 487 | { |
488 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 488 | struct sp887x_state* state = fe->demodulator_priv; |
489 | 489 | ||
490 | /* tristate TS output and disable interface pins */ | 490 | /* tristate TS output and disable interface pins */ |
491 | sp887x_writereg(state, 0xc18, 0x000); | 491 | sp887x_writereg(state, 0xc18, 0x000); |
@@ -495,7 +495,7 @@ static int sp887x_sleep(struct dvb_frontend* fe) | |||
495 | 495 | ||
496 | static int sp887x_init(struct dvb_frontend* fe) | 496 | static int sp887x_init(struct dvb_frontend* fe) |
497 | { | 497 | { |
498 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 498 | struct sp887x_state* state = fe->demodulator_priv; |
499 | const struct firmware *fw = NULL; | 499 | const struct firmware *fw = NULL; |
500 | int ret; | 500 | int ret; |
501 | 501 | ||
@@ -534,7 +534,7 @@ static int sp887x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend | |||
534 | 534 | ||
535 | static void sp887x_release(struct dvb_frontend* fe) | 535 | static void sp887x_release(struct dvb_frontend* fe) |
536 | { | 536 | { |
537 | struct sp887x_state* state = (struct sp887x_state*) fe->demodulator_priv; | 537 | struct sp887x_state* state = fe->demodulator_priv; |
538 | kfree(state); | 538 | kfree(state); |
539 | } | 539 | } |
540 | 540 | ||
@@ -546,7 +546,7 @@ struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, | |||
546 | struct sp887x_state* state = NULL; | 546 | struct sp887x_state* state = NULL; |
547 | 547 | ||
548 | /* allocate memory for the internal state */ | 548 | /* allocate memory for the internal state */ |
549 | state = (struct sp887x_state*) kmalloc(sizeof(struct sp887x_state), GFP_KERNEL); | 549 | state = kmalloc(sizeof(struct sp887x_state), GFP_KERNEL); |
550 | if (state == NULL) goto error; | 550 | if (state == NULL) goto error; |
551 | 551 | ||
552 | /* setup the state */ | 552 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/stv0297.c b/drivers/media/dvb/frontends/stv0297.c index 502c6403dfc6..e681263bf079 100644 --- a/drivers/media/dvb/frontends/stv0297.c +++ b/drivers/media/dvb/frontends/stv0297.c | |||
@@ -365,7 +365,7 @@ static int stv0297_set_inversion(struct stv0297_state *state, fe_spectral_invers | |||
365 | 365 | ||
366 | int stv0297_enable_plli2c(struct dvb_frontend *fe) | 366 | int stv0297_enable_plli2c(struct dvb_frontend *fe) |
367 | { | 367 | { |
368 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 368 | struct stv0297_state *state = fe->demodulator_priv; |
369 | 369 | ||
370 | stv0297_writereg(state, 0x87, 0x78); | 370 | stv0297_writereg(state, 0x87, 0x78); |
371 | stv0297_writereg(state, 0x86, 0xc8); | 371 | stv0297_writereg(state, 0x86, 0xc8); |
@@ -375,7 +375,7 @@ int stv0297_enable_plli2c(struct dvb_frontend *fe) | |||
375 | 375 | ||
376 | static int stv0297_init(struct dvb_frontend *fe) | 376 | static int stv0297_init(struct dvb_frontend *fe) |
377 | { | 377 | { |
378 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 378 | struct stv0297_state *state = fe->demodulator_priv; |
379 | int i; | 379 | int i; |
380 | 380 | ||
381 | /* soft reset */ | 381 | /* soft reset */ |
@@ -416,7 +416,7 @@ static int stv0297_init(struct dvb_frontend *fe) | |||
416 | 416 | ||
417 | static int stv0297_sleep(struct dvb_frontend *fe) | 417 | static int stv0297_sleep(struct dvb_frontend *fe) |
418 | { | 418 | { |
419 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 419 | struct stv0297_state *state = fe->demodulator_priv; |
420 | 420 | ||
421 | stv0297_writereg_mask(state, 0x80, 1, 1); | 421 | stv0297_writereg_mask(state, 0x80, 1, 1); |
422 | 422 | ||
@@ -425,7 +425,7 @@ static int stv0297_sleep(struct dvb_frontend *fe) | |||
425 | 425 | ||
426 | static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) | 426 | static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) |
427 | { | 427 | { |
428 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 428 | struct stv0297_state *state = fe->demodulator_priv; |
429 | 429 | ||
430 | u8 sync = stv0297_readreg(state, 0xDF); | 430 | u8 sync = stv0297_readreg(state, 0xDF); |
431 | 431 | ||
@@ -438,7 +438,7 @@ static int stv0297_read_status(struct dvb_frontend *fe, fe_status_t * status) | |||
438 | 438 | ||
439 | static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) | 439 | static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) |
440 | { | 440 | { |
441 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 441 | struct stv0297_state *state = fe->demodulator_priv; |
442 | u8 BER[3]; | 442 | u8 BER[3]; |
443 | 443 | ||
444 | stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes | 444 | stv0297_writereg(state, 0xA0, 0x80); // Start Counting bit errors for 4096 Bytes |
@@ -453,7 +453,7 @@ static int stv0297_read_ber(struct dvb_frontend *fe, u32 * ber) | |||
453 | 453 | ||
454 | static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | 454 | static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) |
455 | { | 455 | { |
456 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 456 | struct stv0297_state *state = fe->demodulator_priv; |
457 | u8 STRENGTH[2]; | 457 | u8 STRENGTH[2]; |
458 | 458 | ||
459 | stv0297_readregs(state, 0x41, STRENGTH, 2); | 459 | stv0297_readregs(state, 0x41, STRENGTH, 2); |
@@ -464,7 +464,7 @@ static int stv0297_read_signal_strength(struct dvb_frontend *fe, u16 * strength) | |||
464 | 464 | ||
465 | static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) | 465 | static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) |
466 | { | 466 | { |
467 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 467 | struct stv0297_state *state = fe->demodulator_priv; |
468 | u8 SNR[2]; | 468 | u8 SNR[2]; |
469 | 469 | ||
470 | stv0297_readregs(state, 0x07, SNR, 2); | 470 | stv0297_readregs(state, 0x07, SNR, 2); |
@@ -475,7 +475,7 @@ static int stv0297_read_snr(struct dvb_frontend *fe, u16 * snr) | |||
475 | 475 | ||
476 | static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) | 476 | static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) |
477 | { | 477 | { |
478 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 478 | struct stv0297_state *state = fe->demodulator_priv; |
479 | 479 | ||
480 | *ucblocks = (stv0297_readreg(state, 0xD5) << 8) | 480 | *ucblocks = (stv0297_readreg(state, 0xD5) << 8) |
481 | | stv0297_readreg(state, 0xD4); | 481 | | stv0297_readreg(state, 0xD4); |
@@ -485,7 +485,7 @@ static int stv0297_read_ucblocks(struct dvb_frontend *fe, u32 * ucblocks) | |||
485 | 485 | ||
486 | static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 486 | static int stv0297_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
487 | { | 487 | { |
488 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 488 | struct stv0297_state *state = fe->demodulator_priv; |
489 | int u_threshold; | 489 | int u_threshold; |
490 | int initial_u; | 490 | int initial_u; |
491 | int blind_u; | 491 | int blind_u; |
@@ -689,7 +689,7 @@ timeout: | |||
689 | 689 | ||
690 | static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) | 690 | static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) |
691 | { | 691 | { |
692 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 692 | struct stv0297_state *state = fe->demodulator_priv; |
693 | int reg_00, reg_83; | 693 | int reg_00, reg_83; |
694 | 694 | ||
695 | reg_00 = stv0297_readreg(state, 0x00); | 695 | reg_00 = stv0297_readreg(state, 0x00); |
@@ -725,7 +725,7 @@ static int stv0297_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par | |||
725 | 725 | ||
726 | static void stv0297_release(struct dvb_frontend *fe) | 726 | static void stv0297_release(struct dvb_frontend *fe) |
727 | { | 727 | { |
728 | struct stv0297_state *state = (struct stv0297_state *) fe->demodulator_priv; | 728 | struct stv0297_state *state = fe->demodulator_priv; |
729 | kfree(state); | 729 | kfree(state); |
730 | } | 730 | } |
731 | 731 | ||
@@ -737,7 +737,7 @@ struct dvb_frontend *stv0297_attach(const struct stv0297_config *config, | |||
737 | struct stv0297_state *state = NULL; | 737 | struct stv0297_state *state = NULL; |
738 | 738 | ||
739 | /* allocate memory for the internal state */ | 739 | /* allocate memory for the internal state */ |
740 | state = (struct stv0297_state *) kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); | 740 | state = kmalloc(sizeof(struct stv0297_state), GFP_KERNEL); |
741 | if (state == NULL) | 741 | if (state == NULL) |
742 | goto error; | 742 | goto error; |
743 | 743 | ||
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c index 15b40541b62d..cfa3928bb487 100644 --- a/drivers/media/dvb/frontends/stv0299.c +++ b/drivers/media/dvb/frontends/stv0299.c | |||
@@ -70,6 +70,7 @@ struct stv0299_state { | |||
70 | #define STATUS_UCBLOCKS 1 | 70 | #define STATUS_UCBLOCKS 1 |
71 | 71 | ||
72 | static int debug; | 72 | static int debug; |
73 | static int debug_legacy_dish_switch; | ||
73 | #define dprintk(args...) \ | 74 | #define dprintk(args...) \ |
74 | do { \ | 75 | do { \ |
75 | if (debug) printk(KERN_DEBUG "stv0299: " args); \ | 76 | if (debug) printk(KERN_DEBUG "stv0299: " args); \ |
@@ -93,7 +94,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data) | |||
93 | 94 | ||
94 | int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data) | 95 | int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data) |
95 | { | 96 | { |
96 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 97 | struct stv0299_state* state = fe->demodulator_priv; |
97 | 98 | ||
98 | return stv0299_writeregI(state, reg, data); | 99 | return stv0299_writeregI(state, reg, data); |
99 | } | 100 | } |
@@ -218,7 +219,7 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout) | |||
218 | 219 | ||
219 | static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate) | 220 | static int stv0299_set_symbolrate (struct dvb_frontend* fe, u32 srate) |
220 | { | 221 | { |
221 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 222 | struct stv0299_state* state = fe->demodulator_priv; |
222 | u64 big = srate; | 223 | u64 big = srate; |
223 | u32 ratio; | 224 | u32 ratio; |
224 | 225 | ||
@@ -269,7 +270,7 @@ static int stv0299_get_symbolrate (struct stv0299_state* state) | |||
269 | static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, | 270 | static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, |
270 | struct dvb_diseqc_master_cmd *m) | 271 | struct dvb_diseqc_master_cmd *m) |
271 | { | 272 | { |
272 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 273 | struct stv0299_state* state = fe->demodulator_priv; |
273 | u8 val; | 274 | u8 val; |
274 | int i; | 275 | int i; |
275 | 276 | ||
@@ -299,7 +300,7 @@ static int stv0299_send_diseqc_msg (struct dvb_frontend* fe, | |||
299 | 300 | ||
300 | static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 301 | static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
301 | { | 302 | { |
302 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 303 | struct stv0299_state* state = fe->demodulator_priv; |
303 | u8 val; | 304 | u8 val; |
304 | 305 | ||
305 | dprintk ("%s\n", __FUNCTION__); | 306 | dprintk ("%s\n", __FUNCTION__); |
@@ -326,7 +327,7 @@ static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
326 | 327 | ||
327 | static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 328 | static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
328 | { | 329 | { |
329 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 330 | struct stv0299_state* state = fe->demodulator_priv; |
330 | u8 val; | 331 | u8 val; |
331 | 332 | ||
332 | if (stv0299_wait_diseqc_idle (state, 100) < 0) | 333 | if (stv0299_wait_diseqc_idle (state, 100) < 0) |
@@ -348,7 +349,7 @@ static int stv0299_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
348 | 349 | ||
349 | static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 350 | static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
350 | { | 351 | { |
351 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 352 | struct stv0299_state* state = fe->demodulator_priv; |
352 | u8 reg0x08; | 353 | u8 reg0x08; |
353 | u8 reg0x0c; | 354 | u8 reg0x0c; |
354 | 355 | ||
@@ -385,34 +386,84 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
385 | }; | 386 | }; |
386 | } | 387 | } |
387 | 388 | ||
388 | static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd) | 389 | static inline s32 stv0299_calc_usec_delay (struct timeval lasttime, struct timeval curtime) |
389 | { | 390 | { |
391 | return ((curtime.tv_usec < lasttime.tv_usec) ? | ||
392 | 1000000 - lasttime.tv_usec + curtime.tv_usec : | ||
393 | curtime.tv_usec - lasttime.tv_usec); | ||
394 | } | ||
395 | |||
396 | static void stv0299_sleep_until (struct timeval *waketime, u32 add_usec) | ||
397 | { | ||
398 | struct timeval lasttime; | ||
399 | s32 delta, newdelta; | ||
400 | |||
401 | waketime->tv_usec += add_usec; | ||
402 | if (waketime->tv_usec >= 1000000) { | ||
403 | waketime->tv_usec -= 1000000; | ||
404 | waketime->tv_sec++; | ||
405 | } | ||
406 | |||
407 | do_gettimeofday (&lasttime); | ||
408 | delta = stv0299_calc_usec_delay (lasttime, *waketime); | ||
409 | if (delta > 2500) { | ||
410 | msleep ((delta - 1500) / 1000); | ||
411 | do_gettimeofday (&lasttime); | ||
412 | newdelta = stv0299_calc_usec_delay (lasttime, *waketime); | ||
413 | delta = (newdelta > delta) ? 0 : newdelta; | ||
414 | } | ||
415 | if (delta > 0) | ||
416 | udelay (delta); | ||
417 | } | ||
418 | |||
419 | static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, u32 cmd) | ||
420 | { | ||
421 | struct stv0299_state* state = fe->demodulator_priv; | ||
422 | u8 reg0x08; | ||
423 | u8 reg0x0c; | ||
424 | u8 lv_mask = 0x40; | ||
390 | u8 last = 1; | 425 | u8 last = 1; |
391 | int i; | 426 | int i; |
427 | struct timeval nexttime; | ||
428 | struct timeval tv[10]; | ||
392 | 429 | ||
393 | /* reset voltage at the end | 430 | reg0x08 = stv0299_readreg (state, 0x08); |
394 | if((0x50 & stv0299_readreg (i2c, 0x0c)) == 0x50) | 431 | reg0x0c = stv0299_readreg (state, 0x0c); |
395 | cmd |= 0x80; | 432 | reg0x0c &= 0x0f; |
396 | else | 433 | stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6)); |
397 | cmd &= 0x7F; | 434 | if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) |
398 | */ | 435 | lv_mask = 0x10; |
399 | 436 | ||
400 | cmd = cmd << 1; | 437 | cmd = cmd << 1; |
401 | dprintk("%s switch command: 0x%04x\n",__FUNCTION__, cmd); | 438 | if (debug_legacy_dish_switch) |
439 | printk ("%s switch command: 0x%04x\n",__FUNCTION__, cmd); | ||
440 | |||
441 | do_gettimeofday (&nexttime); | ||
442 | if (debug_legacy_dish_switch) | ||
443 | memcpy (&tv[0], &nexttime, sizeof (struct timeval)); | ||
444 | stv0299_writeregI (state, 0x0c, reg0x0c | 0x50); /* set LNB to 18V */ | ||
402 | 445 | ||
403 | stv0299_set_voltage(fe,SEC_VOLTAGE_18); | 446 | stv0299_sleep_until (&nexttime, 32000); |
404 | msleep(32); | ||
405 | 447 | ||
406 | for (i=0; i<9; i++) { | 448 | for (i=0; i<9; i++) { |
449 | if (debug_legacy_dish_switch) | ||
450 | do_gettimeofday (&tv[i+1]); | ||
407 | if((cmd & 0x01) != last) { | 451 | if((cmd & 0x01) != last) { |
408 | stv0299_set_voltage(fe, last ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18); | 452 | /* set voltage to (last ? 13V : 18V) */ |
453 | stv0299_writeregI (state, 0x0c, reg0x0c | (last ? lv_mask : 0x50)); | ||
409 | last = (last) ? 0 : 1; | 454 | last = (last) ? 0 : 1; |
410 | } | 455 | } |
411 | 456 | ||
412 | cmd = cmd >> 1; | 457 | cmd = cmd >> 1; |
413 | 458 | ||
414 | if (i != 8) | 459 | if (i != 8) |
415 | msleep(8); | 460 | stv0299_sleep_until (&nexttime, 8000); |
461 | } | ||
462 | if (debug_legacy_dish_switch) { | ||
463 | printk ("%s(%d): switch delay (should be 32k followed by all 8k\n", | ||
464 | __FUNCTION__, fe->dvb->num); | ||
465 | for (i=1; i < 10; i++) | ||
466 | printk ("%d: %d\n", i, stv0299_calc_usec_delay (tv[i-1] , tv[i])); | ||
416 | } | 467 | } |
417 | 468 | ||
418 | return 0; | 469 | return 0; |
@@ -420,7 +471,7 @@ static int stv0299_send_legacy_dish_cmd(struct dvb_frontend* fe, u32 cmd) | |||
420 | 471 | ||
421 | static int stv0299_init (struct dvb_frontend* fe) | 472 | static int stv0299_init (struct dvb_frontend* fe) |
422 | { | 473 | { |
423 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 474 | struct stv0299_state* state = fe->demodulator_priv; |
424 | int i; | 475 | int i; |
425 | 476 | ||
426 | dprintk("stv0299: init chip\n"); | 477 | dprintk("stv0299: init chip\n"); |
@@ -439,7 +490,7 @@ static int stv0299_init (struct dvb_frontend* fe) | |||
439 | 490 | ||
440 | static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) | 491 | static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) |
441 | { | 492 | { |
442 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 493 | struct stv0299_state* state = fe->demodulator_priv; |
443 | 494 | ||
444 | u8 signal = 0xff - stv0299_readreg (state, 0x18); | 495 | u8 signal = 0xff - stv0299_readreg (state, 0x18); |
445 | u8 sync = stv0299_readreg (state, 0x1b); | 496 | u8 sync = stv0299_readreg (state, 0x1b); |
@@ -467,7 +518,7 @@ static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
467 | 518 | ||
468 | static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) | 519 | static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) |
469 | { | 520 | { |
470 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 521 | struct stv0299_state* state = fe->demodulator_priv; |
471 | 522 | ||
472 | if (state->errmode != STATUS_BER) return 0; | 523 | if (state->errmode != STATUS_BER) return 0; |
473 | *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); | 524 | *ber = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); |
@@ -477,7 +528,7 @@ static int stv0299_read_ber(struct dvb_frontend* fe, u32* ber) | |||
477 | 528 | ||
478 | static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 529 | static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
479 | { | 530 | { |
480 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 531 | struct stv0299_state* state = fe->demodulator_priv; |
481 | 532 | ||
482 | s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8) | 533 | s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8) |
483 | | stv0299_readreg (state, 0x19)); | 534 | | stv0299_readreg (state, 0x19)); |
@@ -494,7 +545,7 @@ static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
494 | 545 | ||
495 | static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr) | 546 | static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr) |
496 | { | 547 | { |
497 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 548 | struct stv0299_state* state = fe->demodulator_priv; |
498 | 549 | ||
499 | s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8) | 550 | s32 xsnr = 0xffff - ((stv0299_readreg (state, 0x24) << 8) |
500 | | stv0299_readreg (state, 0x25)); | 551 | | stv0299_readreg (state, 0x25)); |
@@ -506,7 +557,7 @@ static int stv0299_read_snr(struct dvb_frontend* fe, u16* snr) | |||
506 | 557 | ||
507 | static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 558 | static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
508 | { | 559 | { |
509 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 560 | struct stv0299_state* state = fe->demodulator_priv; |
510 | 561 | ||
511 | if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; | 562 | if (state->errmode != STATUS_UCBLOCKS) *ucblocks = 0; |
512 | else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); | 563 | else *ucblocks = (stv0299_readreg (state, 0x1d) << 8) | stv0299_readreg (state, 0x1e); |
@@ -516,7 +567,7 @@ static int stv0299_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
516 | 567 | ||
517 | static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) | 568 | static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) |
518 | { | 569 | { |
519 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 570 | struct stv0299_state* state = fe->demodulator_priv; |
520 | int invval = 0; | 571 | int invval = 0; |
521 | 572 | ||
522 | dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__); | 573 | dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__); |
@@ -584,7 +635,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
584 | 635 | ||
585 | static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) | 636 | static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters * p) |
586 | { | 637 | { |
587 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 638 | struct stv0299_state* state = fe->demodulator_priv; |
588 | s32 derot_freq; | 639 | s32 derot_freq; |
589 | int invval; | 640 | int invval; |
590 | 641 | ||
@@ -609,7 +660,7 @@ static int stv0299_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
609 | 660 | ||
610 | static int stv0299_sleep(struct dvb_frontend* fe) | 661 | static int stv0299_sleep(struct dvb_frontend* fe) |
611 | { | 662 | { |
612 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 663 | struct stv0299_state* state = fe->demodulator_priv; |
613 | 664 | ||
614 | stv0299_writeregI(state, 0x02, 0x80); | 665 | stv0299_writeregI(state, 0x02, 0x80); |
615 | state->initialised = 0; | 666 | state->initialised = 0; |
@@ -619,7 +670,7 @@ static int stv0299_sleep(struct dvb_frontend* fe) | |||
619 | 670 | ||
620 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) | 671 | static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings) |
621 | { | 672 | { |
622 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 673 | struct stv0299_state* state = fe->demodulator_priv; |
623 | 674 | ||
624 | fesettings->min_delay_ms = state->config->min_delay_ms; | 675 | fesettings->min_delay_ms = state->config->min_delay_ms; |
625 | if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { | 676 | if (fesettings->parameters.u.qpsk.symbol_rate < 10000000) { |
@@ -634,7 +685,7 @@ static int stv0299_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten | |||
634 | 685 | ||
635 | static void stv0299_release(struct dvb_frontend* fe) | 686 | static void stv0299_release(struct dvb_frontend* fe) |
636 | { | 687 | { |
637 | struct stv0299_state* state = (struct stv0299_state*) fe->demodulator_priv; | 688 | struct stv0299_state* state = fe->demodulator_priv; |
638 | kfree(state); | 689 | kfree(state); |
639 | } | 690 | } |
640 | 691 | ||
@@ -647,7 +698,7 @@ struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, | |||
647 | int id; | 698 | int id; |
648 | 699 | ||
649 | /* allocate memory for the internal state */ | 700 | /* allocate memory for the internal state */ |
650 | state = (struct stv0299_state*) kmalloc(sizeof(struct stv0299_state), GFP_KERNEL); | 701 | state = kmalloc(sizeof(struct stv0299_state), GFP_KERNEL); |
651 | if (state == NULL) goto error; | 702 | if (state == NULL) goto error; |
652 | 703 | ||
653 | /* setup the state */ | 704 | /* setup the state */ |
@@ -719,6 +770,9 @@ static struct dvb_frontend_ops stv0299_ops = { | |||
719 | .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, | 770 | .dishnetwork_send_legacy_command = stv0299_send_legacy_dish_cmd, |
720 | }; | 771 | }; |
721 | 772 | ||
773 | module_param(debug_legacy_dish_switch, int, 0444); | ||
774 | MODULE_PARM_DESC(debug_legacy_dish_switch, "Enable timing analysis for Dish Network legacy switches"); | ||
775 | |||
722 | module_param(debug, int, 0644); | 776 | module_param(debug, int, 0644); |
723 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 777 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
724 | 778 | ||
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c index 4e40d95ee95d..87d5f4d8790f 100644 --- a/drivers/media/dvb/frontends/tda10021.c +++ b/drivers/media/dvb/frontends/tda10021.c | |||
@@ -205,7 +205,7 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate | |||
205 | 205 | ||
206 | static int tda10021_init (struct dvb_frontend *fe) | 206 | static int tda10021_init (struct dvb_frontend *fe) |
207 | { | 207 | { |
208 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 208 | struct tda10021_state* state = fe->demodulator_priv; |
209 | int i; | 209 | int i; |
210 | 210 | ||
211 | dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num); | 211 | dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num); |
@@ -238,7 +238,7 @@ static int tda10021_init (struct dvb_frontend *fe) | |||
238 | static int tda10021_set_parameters (struct dvb_frontend *fe, | 238 | static int tda10021_set_parameters (struct dvb_frontend *fe, |
239 | struct dvb_frontend_parameters *p) | 239 | struct dvb_frontend_parameters *p) |
240 | { | 240 | { |
241 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 241 | struct tda10021_state* state = fe->demodulator_priv; |
242 | 242 | ||
243 | //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 | 243 | //table for QAM4-QAM256 ready QAM4 QAM16 QAM32 QAM64 QAM128 QAM256 |
244 | //CONF | 244 | //CONF |
@@ -278,7 +278,7 @@ static int tda10021_set_parameters (struct dvb_frontend *fe, | |||
278 | 278 | ||
279 | static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) | 279 | static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) |
280 | { | 280 | { |
281 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 281 | struct tda10021_state* state = fe->demodulator_priv; |
282 | int sync; | 282 | int sync; |
283 | 283 | ||
284 | *status = 0; | 284 | *status = 0; |
@@ -303,7 +303,7 @@ static int tda10021_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
303 | 303 | ||
304 | static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber) | 304 | static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber) |
305 | { | 305 | { |
306 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 306 | struct tda10021_state* state = fe->demodulator_priv; |
307 | 307 | ||
308 | u32 _ber = tda10021_readreg(state, 0x14) | | 308 | u32 _ber = tda10021_readreg(state, 0x14) | |
309 | (tda10021_readreg(state, 0x15) << 8) | | 309 | (tda10021_readreg(state, 0x15) << 8) | |
@@ -315,7 +315,7 @@ static int tda10021_read_ber(struct dvb_frontend* fe, u32* ber) | |||
315 | 315 | ||
316 | static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 316 | static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
317 | { | 317 | { |
318 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 318 | struct tda10021_state* state = fe->demodulator_priv; |
319 | 319 | ||
320 | u8 gain = tda10021_readreg(state, 0x17); | 320 | u8 gain = tda10021_readreg(state, 0x17); |
321 | *strength = (gain << 8) | gain; | 321 | *strength = (gain << 8) | gain; |
@@ -325,7 +325,7 @@ static int tda10021_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
325 | 325 | ||
326 | static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr) | 326 | static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr) |
327 | { | 327 | { |
328 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 328 | struct tda10021_state* state = fe->demodulator_priv; |
329 | 329 | ||
330 | u8 quality = ~tda10021_readreg(state, 0x18); | 330 | u8 quality = ~tda10021_readreg(state, 0x18); |
331 | *snr = (quality << 8) | quality; | 331 | *snr = (quality << 8) | quality; |
@@ -335,7 +335,7 @@ static int tda10021_read_snr(struct dvb_frontend* fe, u16* snr) | |||
335 | 335 | ||
336 | static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 336 | static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
337 | { | 337 | { |
338 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 338 | struct tda10021_state* state = fe->demodulator_priv; |
339 | 339 | ||
340 | *ucblocks = tda10021_readreg (state, 0x13) & 0x7f; | 340 | *ucblocks = tda10021_readreg (state, 0x13) & 0x7f; |
341 | if (*ucblocks == 0x7f) | 341 | if (*ucblocks == 0x7f) |
@@ -350,7 +350,7 @@ static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
350 | 350 | ||
351 | static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 351 | static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
352 | { | 352 | { |
353 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 353 | struct tda10021_state* state = fe->demodulator_priv; |
354 | int sync; | 354 | int sync; |
355 | s8 afc = 0; | 355 | s8 afc = 0; |
356 | 356 | ||
@@ -378,7 +378,7 @@ static int tda10021_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa | |||
378 | 378 | ||
379 | static int tda10021_sleep(struct dvb_frontend* fe) | 379 | static int tda10021_sleep(struct dvb_frontend* fe) |
380 | { | 380 | { |
381 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 381 | struct tda10021_state* state = fe->demodulator_priv; |
382 | 382 | ||
383 | tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */ | 383 | tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */ |
384 | tda10021_writereg (state, 0x00, 0x80); /* standby */ | 384 | tda10021_writereg (state, 0x00, 0x80); /* standby */ |
@@ -388,7 +388,7 @@ static int tda10021_sleep(struct dvb_frontend* fe) | |||
388 | 388 | ||
389 | static void tda10021_release(struct dvb_frontend* fe) | 389 | static void tda10021_release(struct dvb_frontend* fe) |
390 | { | 390 | { |
391 | struct tda10021_state* state = (struct tda10021_state*) fe->demodulator_priv; | 391 | struct tda10021_state* state = fe->demodulator_priv; |
392 | kfree(state); | 392 | kfree(state); |
393 | } | 393 | } |
394 | 394 | ||
@@ -401,7 +401,7 @@ struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, | |||
401 | struct tda10021_state* state = NULL; | 401 | struct tda10021_state* state = NULL; |
402 | 402 | ||
403 | /* allocate memory for the internal state */ | 403 | /* allocate memory for the internal state */ |
404 | state = (struct tda10021_state*) kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); | 404 | state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL); |
405 | if (state == NULL) goto error; | 405 | if (state == NULL) goto error; |
406 | 406 | ||
407 | /* setup the state */ | 407 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c index 687ad9cf3384..0beb370792ae 100644 --- a/drivers/media/dvb/frontends/tda1004x.c +++ b/drivers/media/dvb/frontends/tda1004x.c | |||
@@ -35,9 +35,10 @@ | |||
35 | #include "dvb_frontend.h" | 35 | #include "dvb_frontend.h" |
36 | #include "tda1004x.h" | 36 | #include "tda1004x.h" |
37 | 37 | ||
38 | #define TDA1004X_DEMOD_TDA10045 0 | 38 | enum tda1004x_demod { |
39 | #define TDA1004X_DEMOD_TDA10046 1 | 39 | TDA1004X_DEMOD_TDA10045, |
40 | 40 | TDA1004X_DEMOD_TDA10046, | |
41 | }; | ||
41 | 42 | ||
42 | struct tda1004x_state { | 43 | struct tda1004x_state { |
43 | struct i2c_adapter* i2c; | 44 | struct i2c_adapter* i2c; |
@@ -46,8 +47,9 @@ struct tda1004x_state { | |||
46 | struct dvb_frontend frontend; | 47 | struct dvb_frontend frontend; |
47 | 48 | ||
48 | /* private demod data */ | 49 | /* private demod data */ |
49 | u8 initialised:1; | 50 | u8 initialised; |
50 | u8 demod_type; | 51 | enum tda1004x_demod demod_type; |
52 | u8 fw_version; | ||
51 | }; | 53 | }; |
52 | 54 | ||
53 | 55 | ||
@@ -139,7 +141,7 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data) | |||
139 | { | 141 | { |
140 | int ret; | 142 | int ret; |
141 | u8 buf[] = { reg, data }; | 143 | u8 buf[] = { reg, data }; |
142 | struct i2c_msg msg = { .addr=0, .flags=0, .buf=buf, .len=2 }; | 144 | struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 }; |
143 | 145 | ||
144 | dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); | 146 | dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data); |
145 | 147 | ||
@@ -160,8 +162,8 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg) | |||
160 | int ret; | 162 | int ret; |
161 | u8 b0[] = { reg }; | 163 | u8 b0[] = { reg }; |
162 | u8 b1[] = { 0 }; | 164 | u8 b1[] = { 0 }; |
163 | struct i2c_msg msg[] = {{ .addr=0, .flags=0, .buf=b0, .len=1}, | 165 | struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 }, |
164 | { .addr=0, .flags=I2C_M_RD, .buf=b1, .len = 1}}; | 166 | { .flags = I2C_M_RD, .buf = b1, .len = 1 }}; |
165 | 167 | ||
166 | dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); | 168 | dprintk("%s: reg=0x%x\n", __FUNCTION__, reg); |
167 | 169 | ||
@@ -294,7 +296,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
294 | u8 dspCodeCounterReg, u8 dspCodeInReg) | 296 | u8 dspCodeCounterReg, u8 dspCodeInReg) |
295 | { | 297 | { |
296 | u8 buf[65]; | 298 | u8 buf[65]; |
297 | struct i2c_msg fw_msg = {.addr = 0,.flags = 0,.buf = buf,.len = 0 }; | 299 | struct i2c_msg fw_msg = { .flags = 0, .buf = buf, .len = 0 }; |
298 | int tx_size; | 300 | int tx_size; |
299 | int pos = 0; | 301 | int pos = 0; |
300 | 302 | ||
@@ -304,12 +306,10 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
304 | 306 | ||
305 | buf[0] = dspCodeInReg; | 307 | buf[0] = dspCodeInReg; |
306 | while (pos != len) { | 308 | while (pos != len) { |
307 | |||
308 | // work out how much to send this time | 309 | // work out how much to send this time |
309 | tx_size = len - pos; | 310 | tx_size = len - pos; |
310 | if (tx_size > 0x10) { | 311 | if (tx_size > 0x10) |
311 | tx_size = 0x10; | 312 | tx_size = 0x10; |
312 | } | ||
313 | 313 | ||
314 | // send the chunk | 314 | // send the chunk |
315 | memcpy(buf + 1, mem + pos, tx_size); | 315 | memcpy(buf + 1, mem + pos, tx_size); |
@@ -322,6 +322,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state, | |||
322 | 322 | ||
323 | dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); | 323 | dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos); |
324 | } | 324 | } |
325 | |||
325 | return 0; | 326 | return 0; |
326 | } | 327 | } |
327 | 328 | ||
@@ -335,9 +336,8 @@ static int tda1004x_check_upload_ok(struct tda1004x_state *state, u8 dspVersion) | |||
335 | 336 | ||
336 | data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); | 337 | data1 = tda1004x_read_byte(state, TDA1004X_DSP_DATA1); |
337 | data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); | 338 | data2 = tda1004x_read_byte(state, TDA1004X_DSP_DATA2); |
338 | if (data1 != 0x67 || data2 != dspVersion) { | 339 | if ((data1 != 0x67) || (data2 != dspVersion)) |
339 | return -EIO; | 340 | return -EIO; |
340 | } | ||
341 | 341 | ||
342 | return 0; | 342 | return 0; |
343 | } | 343 | } |
@@ -348,9 +348,9 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
348 | int ret; | 348 | int ret; |
349 | const struct firmware *fw; | 349 | const struct firmware *fw; |
350 | 350 | ||
351 | |||
352 | /* don't re-upload unless necessary */ | 351 | /* don't re-upload unless necessary */ |
353 | if (tda1004x_check_upload_ok(state, 0x2c) == 0) return 0; | 352 | if (tda1004x_check_upload_ok(state, 0x2c) == 0) |
353 | return 0; | ||
354 | 354 | ||
355 | /* request the firmware, this will block until someone uploads it */ | 355 | /* request the firmware, this will block until someone uploads it */ |
356 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); | 356 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); |
@@ -381,6 +381,25 @@ static int tda10045_fwupload(struct dvb_frontend* fe) | |||
381 | return tda1004x_check_upload_ok(state, 0x2c); | 381 | return tda1004x_check_upload_ok(state, 0x2c); |
382 | } | 382 | } |
383 | 383 | ||
384 | static int tda10046_get_fw_version(struct tda1004x_state *state, | ||
385 | const struct firmware *fw) | ||
386 | { | ||
387 | const unsigned char pattern[] = { 0x67, 0x00, 0x50, 0x62, 0x5e, 0x18, 0x67 }; | ||
388 | unsigned int i; | ||
389 | |||
390 | /* area guessed from firmware v20, v21 and v25 */ | ||
391 | for (i = 0x660; i < 0x700; i++) { | ||
392 | if (!memcmp(&fw->data[i], pattern, sizeof(pattern))) { | ||
393 | state->fw_version = fw->data[i + sizeof(pattern)]; | ||
394 | printk(KERN_INFO "tda1004x: using firmware v%02x\n", | ||
395 | state->fw_version); | ||
396 | return 0; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | return -EINVAL; | ||
401 | } | ||
402 | |||
384 | static int tda10046_fwupload(struct dvb_frontend* fe) | 403 | static int tda10046_fwupload(struct dvb_frontend* fe) |
385 | { | 404 | { |
386 | struct tda1004x_state* state = fe->demodulator_priv; | 405 | struct tda1004x_state* state = fe->demodulator_priv; |
@@ -394,7 +413,8 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
394 | msleep(100); | 413 | msleep(100); |
395 | 414 | ||
396 | /* don't re-upload unless necessary */ | 415 | /* don't re-upload unless necessary */ |
397 | if (tda1004x_check_upload_ok(state, 0x20) == 0) return 0; | 416 | if (tda1004x_check_upload_ok(state, state->fw_version) == 0) |
417 | return 0; | ||
398 | 418 | ||
399 | /* request the firmware, this will block until someone uploads it */ | 419 | /* request the firmware, this will block until someone uploads it */ |
400 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); | 420 | printk("tda1004x: waiting for firmware upload (%s)...\n", TDA10046_DEFAULT_FIRMWARE); |
@@ -404,9 +424,20 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
404 | return ret; | 424 | return ret; |
405 | } | 425 | } |
406 | 426 | ||
427 | if (fw->size < 24478) { /* size of firmware v20, which is the smallest of v20, v21 and v25 */ | ||
428 | printk("tda1004x: firmware file seems to be too small (%d bytes)\n", fw->size); | ||
429 | return -EINVAL; | ||
430 | } | ||
431 | |||
432 | ret = tda10046_get_fw_version(state, fw); | ||
433 | if (ret < 0) { | ||
434 | printk("tda1004x: unable to find firmware version\n"); | ||
435 | return ret; | ||
436 | } | ||
437 | |||
407 | /* set parameters */ | 438 | /* set parameters */ |
408 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); | 439 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); |
409 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); | 440 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); |
410 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); | 441 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); |
411 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); | 442 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); |
412 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); | 443 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); |
@@ -419,7 +450,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
419 | 450 | ||
420 | /* wait for DSP to initialise */ | 451 | /* wait for DSP to initialise */ |
421 | timeout = jiffies + HZ; | 452 | timeout = jiffies + HZ; |
422 | while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { | 453 | while (!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) { |
423 | if (time_after(jiffies, timeout)) { | 454 | if (time_after(jiffies, timeout)) { |
424 | printk("tda1004x: DSP failed to initialised.\n"); | 455 | printk("tda1004x: DSP failed to initialised.\n"); |
425 | return -EIO; | 456 | return -EIO; |
@@ -427,7 +458,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe) | |||
427 | msleep(1); | 458 | msleep(1); |
428 | } | 459 | } |
429 | 460 | ||
430 | return tda1004x_check_upload_ok(state, 0x20); | 461 | return tda1004x_check_upload_ok(state, state->fw_version); |
431 | } | 462 | } |
432 | 463 | ||
433 | static int tda1004x_encode_fec(int fec) | 464 | static int tda1004x_encode_fec(int fec) |
@@ -483,7 +514,8 @@ static int tda10045_init(struct dvb_frontend* fe) | |||
483 | 514 | ||
484 | dprintk("%s\n", __FUNCTION__); | 515 | dprintk("%s\n", __FUNCTION__); |
485 | 516 | ||
486 | if (state->initialised) return 0; | 517 | if (state->initialised) |
518 | return 0; | ||
487 | 519 | ||
488 | if (tda10045_fwupload(fe)) { | 520 | if (tda10045_fwupload(fe)) { |
489 | printk("tda1004x: firmware upload failed\n"); | 521 | printk("tda1004x: firmware upload failed\n"); |
@@ -523,7 +555,8 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
523 | struct tda1004x_state* state = fe->demodulator_priv; | 555 | struct tda1004x_state* state = fe->demodulator_priv; |
524 | dprintk("%s\n", __FUNCTION__); | 556 | dprintk("%s\n", __FUNCTION__); |
525 | 557 | ||
526 | if (state->initialised) return 0; | 558 | if (state->initialised) |
559 | return 0; | ||
527 | 560 | ||
528 | if (tda10046_fwupload(fe)) { | 561 | if (tda10046_fwupload(fe)) { |
529 | printk("tda1004x: firmware upload failed\n"); | 562 | printk("tda1004x: firmware upload failed\n"); |
@@ -545,7 +578,7 @@ static int tda10046_init(struct dvb_frontend* fe) | |||
545 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream | 578 | tda1004x_write_mask(state, TDA1004X_AUTO, 8, 0); // select HP stream |
546 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer | 579 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x80, 0); // disable pulse killer |
547 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 | 580 | tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 10); // PLL M = 10 |
548 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0 | 581 | tda1004x_write_byteI(state, TDA10046H_CONFPLL3, state->config->n_i2c); // PLL P = N = 0 |
549 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 | 582 | tda1004x_write_byteI(state, TDA10046H_FREQ_OFFSET, 99); // FREQOFFS = 99 |
550 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 | 583 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0xd4); // } PHY2 = -11221 |
551 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } | 584 | tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0x2c); // } |
@@ -621,12 +654,14 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
621 | 654 | ||
622 | // set HP FEC | 655 | // set HP FEC |
623 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); | 656 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_HP); |
624 | if (tmp < 0) return tmp; | 657 | if (tmp < 0) |
658 | return tmp; | ||
625 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); | 659 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 7, tmp); |
626 | 660 | ||
627 | // set LP FEC | 661 | // set LP FEC |
628 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); | 662 | tmp = tda1004x_encode_fec(fe_params->u.ofdm.code_rate_LP); |
629 | if (tmp < 0) return tmp; | 663 | if (tmp < 0) |
664 | return tmp; | ||
630 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); | 665 | tda1004x_write_mask(state, TDA1004X_IN_CONF2, 0x38, tmp << 3); |
631 | 666 | ||
632 | // set constellation | 667 | // set constellation |
@@ -671,7 +706,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
671 | } | 706 | } |
672 | 707 | ||
673 | // set bandwidth | 708 | // set bandwidth |
674 | switch(state->demod_type) { | 709 | switch (state->demod_type) { |
675 | case TDA1004X_DEMOD_TDA10045: | 710 | case TDA1004X_DEMOD_TDA10045: |
676 | tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); | 711 | tda10045h_set_bandwidth(state, fe_params->u.ofdm.bandwidth); |
677 | break; | 712 | break; |
@@ -683,7 +718,8 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
683 | 718 | ||
684 | // set inversion | 719 | // set inversion |
685 | inversion = fe_params->inversion; | 720 | inversion = fe_params->inversion; |
686 | if (state->config->invert) inversion = inversion ? INVERSION_OFF : INVERSION_ON; | 721 | if (state->config->invert) |
722 | inversion = inversion ? INVERSION_OFF : INVERSION_ON; | ||
687 | switch (inversion) { | 723 | switch (inversion) { |
688 | case INVERSION_OFF: | 724 | case INVERSION_OFF: |
689 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); | 725 | tda1004x_write_mask(state, TDA1004X_CONFC1, 0x20, 0); |
@@ -750,19 +786,19 @@ static int tda1004x_set_fe(struct dvb_frontend* fe, | |||
750 | } | 786 | } |
751 | 787 | ||
752 | // start the lock | 788 | // start the lock |
753 | switch(state->demod_type) { | 789 | switch (state->demod_type) { |
754 | case TDA1004X_DEMOD_TDA10045: | 790 | case TDA1004X_DEMOD_TDA10045: |
755 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); | 791 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 8); |
756 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); | 792 | tda1004x_write_mask(state, TDA1004X_CONFC4, 8, 0); |
757 | msleep(10); | ||
758 | break; | 793 | break; |
759 | 794 | ||
760 | case TDA1004X_DEMOD_TDA10046: | 795 | case TDA1004X_DEMOD_TDA10046: |
761 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); | 796 | tda1004x_write_mask(state, TDA1004X_AUTO, 0x40, 0x40); |
762 | msleep(10); | ||
763 | break; | 797 | break; |
764 | } | 798 | } |
765 | 799 | ||
800 | msleep(10); | ||
801 | |||
766 | return 0; | 802 | return 0; |
767 | } | 803 | } |
768 | 804 | ||
@@ -773,13 +809,13 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
773 | 809 | ||
774 | // inversion status | 810 | // inversion status |
775 | fe_params->inversion = INVERSION_OFF; | 811 | fe_params->inversion = INVERSION_OFF; |
776 | if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) { | 812 | if (tda1004x_read_byte(state, TDA1004X_CONFC1) & 0x20) |
777 | fe_params->inversion = INVERSION_ON; | 813 | fe_params->inversion = INVERSION_ON; |
778 | } | 814 | if (state->config->invert) |
779 | if (state->config->invert) fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; | 815 | fe_params->inversion = fe_params->inversion ? INVERSION_OFF : INVERSION_ON; |
780 | 816 | ||
781 | // bandwidth | 817 | // bandwidth |
782 | switch(state->demod_type) { | 818 | switch (state->demod_type) { |
783 | case TDA1004X_DEMOD_TDA10045: | 819 | case TDA1004X_DEMOD_TDA10045: |
784 | switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { | 820 | switch (tda1004x_read_byte(state, TDA10045H_WREF_LSB)) { |
785 | case 0x14: | 821 | case 0x14: |
@@ -830,9 +866,8 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete | |||
830 | 866 | ||
831 | // transmission mode | 867 | // transmission mode |
832 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; | 868 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; |
833 | if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) { | 869 | if (tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x10) |
834 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; | 870 | fe_params->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; |
835 | } | ||
836 | 871 | ||
837 | // guard interval | 872 | // guard interval |
838 | switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { | 873 | switch ((tda1004x_read_byte(state, TDA1004X_OUT_CONF1) & 0x0c) >> 2) { |
@@ -880,30 +915,33 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
880 | 915 | ||
881 | // read status | 916 | // read status |
882 | status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); | 917 | status = tda1004x_read_byte(state, TDA1004X_STATUS_CD); |
883 | if (status == -1) { | 918 | if (status == -1) |
884 | return -EIO; | 919 | return -EIO; |
885 | } | ||
886 | 920 | ||
887 | // decode | 921 | // decode |
888 | *fe_status = 0; | 922 | *fe_status = 0; |
889 | if (status & 4) *fe_status |= FE_HAS_SIGNAL; | 923 | if (status & 4) |
890 | if (status & 2) *fe_status |= FE_HAS_CARRIER; | 924 | *fe_status |= FE_HAS_SIGNAL; |
891 | if (status & 8) *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | 925 | if (status & 2) |
926 | *fe_status |= FE_HAS_CARRIER; | ||
927 | if (status & 8) | ||
928 | *fe_status |= FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK; | ||
892 | 929 | ||
893 | // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi | 930 | // if we don't already have VITERBI (i.e. not LOCKED), see if the viterbi |
894 | // is getting anything valid | 931 | // is getting anything valid |
895 | if (!(*fe_status & FE_HAS_VITERBI)) { | 932 | if (!(*fe_status & FE_HAS_VITERBI)) { |
896 | // read the CBER | 933 | // read the CBER |
897 | cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); | 934 | cber = tda1004x_read_byte(state, TDA1004X_CBER_LSB); |
898 | if (cber == -1) return -EIO; | 935 | if (cber == -1) |
936 | return -EIO; | ||
899 | status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); | 937 | status = tda1004x_read_byte(state, TDA1004X_CBER_MSB); |
900 | if (status == -1) return -EIO; | 938 | if (status == -1) |
939 | return -EIO; | ||
901 | cber |= (status << 8); | 940 | cber |= (status << 8); |
902 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 941 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
903 | 942 | ||
904 | if (cber != 65535) { | 943 | if (cber != 65535) |
905 | *fe_status |= FE_HAS_VITERBI; | 944 | *fe_status |= FE_HAS_VITERBI; |
906 | } | ||
907 | } | 945 | } |
908 | 946 | ||
909 | // if we DO have some valid VITERBI output, but don't already have SYNC | 947 | // if we DO have some valid VITERBI output, but don't already have SYNC |
@@ -911,20 +949,22 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status | |||
911 | if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { | 949 | if ((*fe_status & FE_HAS_VITERBI) && (!(*fe_status & FE_HAS_SYNC))) { |
912 | // read the VBER | 950 | // read the VBER |
913 | vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); | 951 | vber = tda1004x_read_byte(state, TDA1004X_VBER_LSB); |
914 | if (vber == -1) return -EIO; | 952 | if (vber == -1) |
953 | return -EIO; | ||
915 | status = tda1004x_read_byte(state, TDA1004X_VBER_MID); | 954 | status = tda1004x_read_byte(state, TDA1004X_VBER_MID); |
916 | if (status == -1) return -EIO; | 955 | if (status == -1) |
956 | return -EIO; | ||
917 | vber |= (status << 8); | 957 | vber |= (status << 8); |
918 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); | 958 | status = tda1004x_read_byte(state, TDA1004X_VBER_MSB); |
919 | if (status == -1) return -EIO; | 959 | if (status == -1) |
960 | return -EIO; | ||
920 | vber |= ((status << 16) & 0x0f); | 961 | vber |= ((status << 16) & 0x0f); |
921 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); | 962 | tda1004x_read_byte(state, TDA1004X_CVBER_LUT); |
922 | 963 | ||
923 | // if RS has passed some valid TS packets, then we must be | 964 | // if RS has passed some valid TS packets, then we must be |
924 | // getting some SYNC bytes | 965 | // getting some SYNC bytes |
925 | if (vber < 16632) { | 966 | if (vber < 16632) |
926 | *fe_status |= FE_HAS_SYNC; | 967 | *fe_status |= FE_HAS_SYNC; |
927 | } | ||
928 | } | 968 | } |
929 | 969 | ||
930 | // success | 970 | // success |
@@ -941,7 +981,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal) | |||
941 | dprintk("%s\n", __FUNCTION__); | 981 | dprintk("%s\n", __FUNCTION__); |
942 | 982 | ||
943 | // determine the register to use | 983 | // determine the register to use |
944 | switch(state->demod_type) { | 984 | switch (state->demod_type) { |
945 | case TDA1004X_DEMOD_TDA10045: | 985 | case TDA1004X_DEMOD_TDA10045: |
946 | reg = TDA10045H_S_AGC; | 986 | reg = TDA10045H_S_AGC; |
947 | break; | 987 | break; |
@@ -972,9 +1012,8 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr) | |||
972 | tmp = tda1004x_read_byte(state, TDA1004X_SNR); | 1012 | tmp = tda1004x_read_byte(state, TDA1004X_SNR); |
973 | if (tmp < 0) | 1013 | if (tmp < 0) |
974 | return -EIO; | 1014 | return -EIO; |
975 | if (tmp) { | 1015 | if (tmp) |
976 | tmp = 255 - tmp; | 1016 | tmp = 255 - tmp; |
977 | } | ||
978 | 1017 | ||
979 | *snr = ((tmp << 8) | tmp); | 1018 | *snr = ((tmp << 8) | tmp); |
980 | dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); | 1019 | dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr); |
@@ -1009,11 +1048,11 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
1009 | break; | 1048 | break; |
1010 | } | 1049 | } |
1011 | 1050 | ||
1012 | if (tmp != 0x7f) { | 1051 | if (tmp != 0x7f) |
1013 | *ucblocks = tmp; | 1052 | *ucblocks = tmp; |
1014 | } else { | 1053 | else |
1015 | *ucblocks = 0xffffffff; | 1054 | *ucblocks = 0xffffffff; |
1016 | } | 1055 | |
1017 | dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); | 1056 | dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks); |
1018 | return 0; | 1057 | return 0; |
1019 | } | 1058 | } |
@@ -1027,10 +1066,12 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber) | |||
1027 | 1066 | ||
1028 | // read it in | 1067 | // read it in |
1029 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); | 1068 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB); |
1030 | if (tmp < 0) return -EIO; | 1069 | if (tmp < 0) |
1070 | return -EIO; | ||
1031 | *ber = tmp << 1; | 1071 | *ber = tmp << 1; |
1032 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); | 1072 | tmp = tda1004x_read_byte(state, TDA1004X_CBER_MSB); |
1033 | if (tmp < 0) return -EIO; | 1073 | if (tmp < 0) |
1074 | return -EIO; | ||
1034 | *ber |= (tmp << 9); | 1075 | *ber |= (tmp << 9); |
1035 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); | 1076 | tda1004x_read_byte(state, TDA1004X_CBER_RESET); |
1036 | 1077 | ||
@@ -1042,7 +1083,7 @@ static int tda1004x_sleep(struct dvb_frontend* fe) | |||
1042 | { | 1083 | { |
1043 | struct tda1004x_state* state = fe->demodulator_priv; | 1084 | struct tda1004x_state* state = fe->demodulator_priv; |
1044 | 1085 | ||
1045 | switch(state->demod_type) { | 1086 | switch (state->demod_type) { |
1046 | case TDA1004X_DEMOD_TDA10045: | 1087 | case TDA1004X_DEMOD_TDA10045: |
1047 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); | 1088 | tda1004x_write_mask(state, TDA1004X_CONFADC1, 0x10, 0x10); |
1048 | break; | 1089 | break; |
@@ -1066,74 +1107,11 @@ static int tda1004x_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronte | |||
1066 | 1107 | ||
1067 | static void tda1004x_release(struct dvb_frontend* fe) | 1108 | static void tda1004x_release(struct dvb_frontend* fe) |
1068 | { | 1109 | { |
1069 | struct tda1004x_state* state = (struct tda1004x_state*) fe->demodulator_priv; | 1110 | struct tda1004x_state *state = fe->demodulator_priv; |
1070 | kfree(state); | ||
1071 | } | ||
1072 | |||
1073 | static struct dvb_frontend_ops tda10045_ops; | ||
1074 | |||
1075 | struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, | ||
1076 | struct i2c_adapter* i2c) | ||
1077 | { | ||
1078 | struct tda1004x_state* state = NULL; | ||
1079 | |||
1080 | /* allocate memory for the internal state */ | ||
1081 | state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1082 | if (state == NULL) goto error; | ||
1083 | |||
1084 | /* setup the state */ | ||
1085 | state->config = config; | ||
1086 | state->i2c = i2c; | ||
1087 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1088 | state->initialised = 0; | ||
1089 | state->demod_type = TDA1004X_DEMOD_TDA10045; | ||
1090 | |||
1091 | /* check if the demod is there */ | ||
1092 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) goto error; | ||
1093 | |||
1094 | /* create dvb_frontend */ | ||
1095 | state->frontend.ops = &state->ops; | ||
1096 | state->frontend.demodulator_priv = state; | ||
1097 | return &state->frontend; | ||
1098 | |||
1099 | error: | ||
1100 | kfree(state); | 1111 | kfree(state); |
1101 | return NULL; | ||
1102 | } | ||
1103 | |||
1104 | static struct dvb_frontend_ops tda10046_ops; | ||
1105 | |||
1106 | struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | ||
1107 | struct i2c_adapter* i2c) | ||
1108 | { | ||
1109 | struct tda1004x_state* state = NULL; | ||
1110 | |||
1111 | /* allocate memory for the internal state */ | ||
1112 | state = (struct tda1004x_state*) kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1113 | if (state == NULL) goto error; | ||
1114 | |||
1115 | /* setup the state */ | ||
1116 | state->config = config; | ||
1117 | state->i2c = i2c; | ||
1118 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1119 | state->initialised = 0; | ||
1120 | state->demod_type = TDA1004X_DEMOD_TDA10046; | ||
1121 | |||
1122 | /* check if the demod is there */ | ||
1123 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) goto error; | ||
1124 | |||
1125 | /* create dvb_frontend */ | ||
1126 | state->frontend.ops = &state->ops; | ||
1127 | state->frontend.demodulator_priv = state; | ||
1128 | return &state->frontend; | ||
1129 | |||
1130 | error: | ||
1131 | if (state) kfree(state); | ||
1132 | return NULL; | ||
1133 | } | 1112 | } |
1134 | 1113 | ||
1135 | static struct dvb_frontend_ops tda10045_ops = { | 1114 | static struct dvb_frontend_ops tda10045_ops = { |
1136 | |||
1137 | .info = { | 1115 | .info = { |
1138 | .name = "Philips TDA10045H DVB-T", | 1116 | .name = "Philips TDA10045H DVB-T", |
1139 | .type = FE_OFDM, | 1117 | .type = FE_OFDM, |
@@ -1163,8 +1141,36 @@ static struct dvb_frontend_ops tda10045_ops = { | |||
1163 | .read_ucblocks = tda1004x_read_ucblocks, | 1141 | .read_ucblocks = tda1004x_read_ucblocks, |
1164 | }; | 1142 | }; |
1165 | 1143 | ||
1166 | static struct dvb_frontend_ops tda10046_ops = { | 1144 | struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, |
1145 | struct i2c_adapter* i2c) | ||
1146 | { | ||
1147 | struct tda1004x_state *state; | ||
1148 | |||
1149 | /* allocate memory for the internal state */ | ||
1150 | state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1151 | if (!state) | ||
1152 | return NULL; | ||
1153 | |||
1154 | /* setup the state */ | ||
1155 | state->config = config; | ||
1156 | state->i2c = i2c; | ||
1157 | memcpy(&state->ops, &tda10045_ops, sizeof(struct dvb_frontend_ops)); | ||
1158 | state->initialised = 0; | ||
1159 | state->demod_type = TDA1004X_DEMOD_TDA10045; | ||
1160 | |||
1161 | /* check if the demod is there */ | ||
1162 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x25) { | ||
1163 | kfree(state); | ||
1164 | return NULL; | ||
1165 | } | ||
1167 | 1166 | ||
1167 | /* create dvb_frontend */ | ||
1168 | state->frontend.ops = &state->ops; | ||
1169 | state->frontend.demodulator_priv = state; | ||
1170 | return &state->frontend; | ||
1171 | } | ||
1172 | |||
1173 | static struct dvb_frontend_ops tda10046_ops = { | ||
1168 | .info = { | 1174 | .info = { |
1169 | .name = "Philips TDA10046H DVB-T", | 1175 | .name = "Philips TDA10046H DVB-T", |
1170 | .type = FE_OFDM, | 1176 | .type = FE_OFDM, |
@@ -1194,6 +1200,36 @@ static struct dvb_frontend_ops tda10046_ops = { | |||
1194 | .read_ucblocks = tda1004x_read_ucblocks, | 1200 | .read_ucblocks = tda1004x_read_ucblocks, |
1195 | }; | 1201 | }; |
1196 | 1202 | ||
1203 | struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, | ||
1204 | struct i2c_adapter* i2c) | ||
1205 | { | ||
1206 | struct tda1004x_state *state; | ||
1207 | |||
1208 | /* allocate memory for the internal state */ | ||
1209 | state = kmalloc(sizeof(struct tda1004x_state), GFP_KERNEL); | ||
1210 | if (!state) | ||
1211 | return NULL; | ||
1212 | |||
1213 | /* setup the state */ | ||
1214 | state->config = config; | ||
1215 | state->i2c = i2c; | ||
1216 | memcpy(&state->ops, &tda10046_ops, sizeof(struct dvb_frontend_ops)); | ||
1217 | state->initialised = 0; | ||
1218 | state->demod_type = TDA1004X_DEMOD_TDA10046; | ||
1219 | state->fw_version = 0x20; /* dummy default value */ | ||
1220 | |||
1221 | /* check if the demod is there */ | ||
1222 | if (tda1004x_read_byte(state, TDA1004X_CHIPID) != 0x46) { | ||
1223 | kfree(state); | ||
1224 | return NULL; | ||
1225 | } | ||
1226 | |||
1227 | /* create dvb_frontend */ | ||
1228 | state->frontend.ops = &state->ops; | ||
1229 | state->frontend.demodulator_priv = state; | ||
1230 | return &state->frontend; | ||
1231 | } | ||
1232 | |||
1197 | module_param(debug, int, 0644); | 1233 | module_param(debug, int, 0644); |
1198 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); | 1234 | MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off)."); |
1199 | 1235 | ||
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h index e452fc0bad11..c8e1d54ff262 100644 --- a/drivers/media/dvb/frontends/tda1004x.h +++ b/drivers/media/dvb/frontends/tda1004x.h | |||
@@ -32,10 +32,13 @@ struct tda1004x_config | |||
32 | u8 demod_address; | 32 | u8 demod_address; |
33 | 33 | ||
34 | /* does the "inversion" need inverted? */ | 34 | /* does the "inversion" need inverted? */ |
35 | u8 invert:1; | 35 | u8 invert; |
36 | 36 | ||
37 | /* Does the OCLK signal need inverted? */ | 37 | /* Does the OCLK signal need inverted? */ |
38 | u8 invert_oclk:1; | 38 | u8 invert_oclk; |
39 | |||
40 | /* value of N_I2C of the CONF_PLL3 register */ | ||
41 | u8 n_i2c; | ||
39 | 42 | ||
40 | /* PLL maintenance */ | 43 | /* PLL maintenance */ |
41 | int (*pll_init)(struct dvb_frontend* fe); | 44 | int (*pll_init)(struct dvb_frontend* fe); |
diff --git a/drivers/media/dvb/frontends/tda8083.c b/drivers/media/dvb/frontends/tda8083.c index da82e90d6d13..168e013d23bd 100644 --- a/drivers/media/dvb/frontends/tda8083.c +++ b/drivers/media/dvb/frontends/tda8083.c | |||
@@ -226,7 +226,7 @@ static int tda8083_send_diseqc_burst (struct tda8083_state* state, fe_sec_mini_c | |||
226 | static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, | 226 | static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, |
227 | struct dvb_diseqc_master_cmd *m) | 227 | struct dvb_diseqc_master_cmd *m) |
228 | { | 228 | { |
229 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 229 | struct tda8083_state* state = fe->demodulator_priv; |
230 | int i; | 230 | int i; |
231 | 231 | ||
232 | tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */ | 232 | tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2)); /* enable */ |
@@ -243,7 +243,7 @@ static int tda8083_send_diseqc_msg (struct dvb_frontend* fe, | |||
243 | 243 | ||
244 | static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) | 244 | static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) |
245 | { | 245 | { |
246 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 246 | struct tda8083_state* state = fe->demodulator_priv; |
247 | 247 | ||
248 | u8 signal = ~tda8083_readreg (state, 0x01); | 248 | u8 signal = ~tda8083_readreg (state, 0x01); |
249 | u8 sync = tda8083_readreg (state, 0x02); | 249 | u8 sync = tda8083_readreg (state, 0x02); |
@@ -270,7 +270,7 @@ static int tda8083_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
270 | 270 | ||
271 | static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 271 | static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
272 | { | 272 | { |
273 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 273 | struct tda8083_state* state = fe->demodulator_priv; |
274 | 274 | ||
275 | u8 signal = ~tda8083_readreg (state, 0x01); | 275 | u8 signal = ~tda8083_readreg (state, 0x01); |
276 | *strength = (signal << 8) | signal; | 276 | *strength = (signal << 8) | signal; |
@@ -280,7 +280,7 @@ static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
280 | 280 | ||
281 | static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) | 281 | static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) |
282 | { | 282 | { |
283 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 283 | struct tda8083_state* state = fe->demodulator_priv; |
284 | 284 | ||
285 | u8 _snr = tda8083_readreg (state, 0x08); | 285 | u8 _snr = tda8083_readreg (state, 0x08); |
286 | *snr = (_snr << 8) | _snr; | 286 | *snr = (_snr << 8) | _snr; |
@@ -290,7 +290,7 @@ static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr) | |||
290 | 290 | ||
291 | static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 291 | static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
292 | { | 292 | { |
293 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 293 | struct tda8083_state* state = fe->demodulator_priv; |
294 | 294 | ||
295 | state->config->pll_set(fe, p); | 295 | state->config->pll_set(fe, p); |
296 | tda8083_set_inversion (state, p->inversion); | 296 | tda8083_set_inversion (state, p->inversion); |
@@ -305,7 +305,7 @@ static int tda8083_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
305 | 305 | ||
306 | static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 306 | static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
307 | { | 307 | { |
308 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 308 | struct tda8083_state* state = fe->demodulator_priv; |
309 | 309 | ||
310 | /* FIXME: get symbolrate & frequency offset...*/ | 310 | /* FIXME: get symbolrate & frequency offset...*/ |
311 | /*p->frequency = ???;*/ | 311 | /*p->frequency = ???;*/ |
@@ -319,7 +319,7 @@ static int tda8083_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
319 | 319 | ||
320 | static int tda8083_sleep(struct dvb_frontend* fe) | 320 | static int tda8083_sleep(struct dvb_frontend* fe) |
321 | { | 321 | { |
322 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 322 | struct tda8083_state* state = fe->demodulator_priv; |
323 | 323 | ||
324 | tda8083_writereg (state, 0x00, 0x02); | 324 | tda8083_writereg (state, 0x00, 0x02); |
325 | return 0; | 325 | return 0; |
@@ -327,7 +327,7 @@ static int tda8083_sleep(struct dvb_frontend* fe) | |||
327 | 327 | ||
328 | static int tda8083_init(struct dvb_frontend* fe) | 328 | static int tda8083_init(struct dvb_frontend* fe) |
329 | { | 329 | { |
330 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 330 | struct tda8083_state* state = fe->demodulator_priv; |
331 | int i; | 331 | int i; |
332 | 332 | ||
333 | for (i=0; i<44; i++) | 333 | for (i=0; i<44; i++) |
@@ -343,7 +343,7 @@ static int tda8083_init(struct dvb_frontend* fe) | |||
343 | 343 | ||
344 | static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) | 344 | static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) |
345 | { | 345 | { |
346 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 346 | struct tda8083_state* state = fe->demodulator_priv; |
347 | 347 | ||
348 | tda8083_send_diseqc_burst (state, burst); | 348 | tda8083_send_diseqc_burst (state, burst); |
349 | tda8083_writereg (state, 0x00, 0x3c); | 349 | tda8083_writereg (state, 0x00, 0x3c); |
@@ -354,7 +354,7 @@ static int tda8083_diseqc_send_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
354 | 354 | ||
355 | static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 355 | static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
356 | { | 356 | { |
357 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 357 | struct tda8083_state* state = fe->demodulator_priv; |
358 | 358 | ||
359 | tda8083_set_tone (state, tone); | 359 | tda8083_set_tone (state, tone); |
360 | tda8083_writereg (state, 0x00, 0x3c); | 360 | tda8083_writereg (state, 0x00, 0x3c); |
@@ -365,7 +365,7 @@ static int tda8083_diseqc_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t t | |||
365 | 365 | ||
366 | static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 366 | static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
367 | { | 367 | { |
368 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 368 | struct tda8083_state* state = fe->demodulator_priv; |
369 | 369 | ||
370 | tda8083_set_voltage (state, voltage); | 370 | tda8083_set_voltage (state, voltage); |
371 | tda8083_writereg (state, 0x00, 0x3c); | 371 | tda8083_writereg (state, 0x00, 0x3c); |
@@ -376,7 +376,7 @@ static int tda8083_diseqc_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t | |||
376 | 376 | ||
377 | static void tda8083_release(struct dvb_frontend* fe) | 377 | static void tda8083_release(struct dvb_frontend* fe) |
378 | { | 378 | { |
379 | struct tda8083_state* state = (struct tda8083_state*) fe->demodulator_priv; | 379 | struct tda8083_state* state = fe->demodulator_priv; |
380 | kfree(state); | 380 | kfree(state); |
381 | } | 381 | } |
382 | 382 | ||
@@ -388,7 +388,7 @@ struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, | |||
388 | struct tda8083_state* state = NULL; | 388 | struct tda8083_state* state = NULL; |
389 | 389 | ||
390 | /* allocate memory for the internal state */ | 390 | /* allocate memory for the internal state */ |
391 | state = (struct tda8083_state*) kmalloc(sizeof(struct tda8083_state), GFP_KERNEL); | 391 | state = kmalloc(sizeof(struct tda8083_state), GFP_KERNEL); |
392 | if (state == NULL) goto error; | 392 | if (state == NULL) goto error; |
393 | 393 | ||
394 | /* setup the state */ | 394 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/tda80xx.c b/drivers/media/dvb/frontends/tda80xx.c index c99632114283..032d348dafb7 100644 --- a/drivers/media/dvb/frontends/tda80xx.c +++ b/drivers/media/dvb/frontends/tda80xx.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/threads.h> | 28 | #include <linux/threads.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <asm/irq.h> | 30 | #include <linux/irq.h> |
31 | #include <linux/kernel.h> | 31 | #include <linux/kernel.h> |
32 | #include <linux/module.h> | 32 | #include <linux/module.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
@@ -400,7 +400,7 @@ static void tda80xx_wait_diseqc_fifo(struct tda80xx_state* state) | |||
400 | 400 | ||
401 | static int tda8044_init(struct dvb_frontend* fe) | 401 | static int tda8044_init(struct dvb_frontend* fe) |
402 | { | 402 | { |
403 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 403 | struct tda80xx_state* state = fe->demodulator_priv; |
404 | int ret; | 404 | int ret; |
405 | 405 | ||
406 | /* | 406 | /* |
@@ -432,7 +432,7 @@ static int tda8044_init(struct dvb_frontend* fe) | |||
432 | 432 | ||
433 | static int tda8083_init(struct dvb_frontend* fe) | 433 | static int tda8083_init(struct dvb_frontend* fe) |
434 | { | 434 | { |
435 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 435 | struct tda80xx_state* state = fe->demodulator_priv; |
436 | 436 | ||
437 | tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab)); | 437 | tda80xx_write(state, 0x00, tda8083_inittab, sizeof(tda8083_inittab)); |
438 | 438 | ||
@@ -447,7 +447,7 @@ static int tda8083_init(struct dvb_frontend* fe) | |||
447 | 447 | ||
448 | static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 448 | static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
449 | { | 449 | { |
450 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 450 | struct tda80xx_state* state = fe->demodulator_priv; |
451 | 451 | ||
452 | switch (voltage) { | 452 | switch (voltage) { |
453 | case SEC_VOLTAGE_13: | 453 | case SEC_VOLTAGE_13: |
@@ -463,7 +463,7 @@ static int tda80xx_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage | |||
463 | 463 | ||
464 | static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | 464 | static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) |
465 | { | 465 | { |
466 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 466 | struct tda80xx_state* state = fe->demodulator_priv; |
467 | 467 | ||
468 | switch (tone) { | 468 | switch (tone) { |
469 | case SEC_TONE_OFF: | 469 | case SEC_TONE_OFF: |
@@ -477,7 +477,7 @@ static int tda80xx_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) | |||
477 | 477 | ||
478 | static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) | 478 | static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) |
479 | { | 479 | { |
480 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 480 | struct tda80xx_state* state = fe->demodulator_priv; |
481 | 481 | ||
482 | if (cmd->msg_len > 6) | 482 | if (cmd->msg_len > 6) |
483 | return -EINVAL; | 483 | return -EINVAL; |
@@ -492,7 +492,7 @@ static int tda80xx_send_diseqc_msg(struct dvb_frontend* fe, struct dvb_diseqc_ma | |||
492 | 492 | ||
493 | static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd) | 493 | static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t cmd) |
494 | { | 494 | { |
495 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 495 | struct tda80xx_state* state = fe->demodulator_priv; |
496 | 496 | ||
497 | switch (cmd) { | 497 | switch (cmd) { |
498 | case SEC_MINI_A: | 498 | case SEC_MINI_A: |
@@ -512,7 +512,7 @@ static int tda80xx_send_diseqc_burst(struct dvb_frontend* fe, fe_sec_mini_cmd_t | |||
512 | 512 | ||
513 | static int tda80xx_sleep(struct dvb_frontend* fe) | 513 | static int tda80xx_sleep(struct dvb_frontend* fe) |
514 | { | 514 | { |
515 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 515 | struct tda80xx_state* state = fe->demodulator_priv; |
516 | 516 | ||
517 | tda80xx_writereg(state, 0x00, 0x02); /* enter standby */ | 517 | tda80xx_writereg(state, 0x00, 0x02); /* enter standby */ |
518 | 518 | ||
@@ -521,7 +521,7 @@ static int tda80xx_sleep(struct dvb_frontend* fe) | |||
521 | 521 | ||
522 | static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 522 | static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
523 | { | 523 | { |
524 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 524 | struct tda80xx_state* state = fe->demodulator_priv; |
525 | 525 | ||
526 | tda80xx_writereg(state, 0x1c, 0x80); | 526 | tda80xx_writereg(state, 0x1c, 0x80); |
527 | state->config->pll_set(fe, p); | 527 | state->config->pll_set(fe, p); |
@@ -537,7 +537,7 @@ static int tda80xx_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
537 | 537 | ||
538 | static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 538 | static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
539 | { | 539 | { |
540 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 540 | struct tda80xx_state* state = fe->demodulator_priv; |
541 | 541 | ||
542 | if (!state->config->irq) | 542 | if (!state->config->irq) |
543 | tda80xx_read_status_int(state); | 543 | tda80xx_read_status_int(state); |
@@ -550,7 +550,7 @@ static int tda80xx_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
550 | 550 | ||
551 | static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) | 551 | static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) |
552 | { | 552 | { |
553 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 553 | struct tda80xx_state* state = fe->demodulator_priv; |
554 | 554 | ||
555 | if (!state->config->irq) | 555 | if (!state->config->irq) |
556 | tda80xx_read_status_int(state); | 556 | tda80xx_read_status_int(state); |
@@ -561,7 +561,7 @@ static int tda80xx_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
561 | 561 | ||
562 | static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) | 562 | static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) |
563 | { | 563 | { |
564 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 564 | struct tda80xx_state* state = fe->demodulator_priv; |
565 | int ret; | 565 | int ret; |
566 | u8 buf[3]; | 566 | u8 buf[3]; |
567 | 567 | ||
@@ -575,7 +575,7 @@ static int tda80xx_read_ber(struct dvb_frontend* fe, u32* ber) | |||
575 | 575 | ||
576 | static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 576 | static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
577 | { | 577 | { |
578 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 578 | struct tda80xx_state* state = fe->demodulator_priv; |
579 | 579 | ||
580 | u8 gain = ~tda80xx_readreg(state, 0x01); | 580 | u8 gain = ~tda80xx_readreg(state, 0x01); |
581 | *strength = (gain << 8) | gain; | 581 | *strength = (gain << 8) | gain; |
@@ -585,7 +585,7 @@ static int tda80xx_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
585 | 585 | ||
586 | static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) | 586 | static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) |
587 | { | 587 | { |
588 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 588 | struct tda80xx_state* state = fe->demodulator_priv; |
589 | 589 | ||
590 | u8 quality = tda80xx_readreg(state, 0x08); | 590 | u8 quality = tda80xx_readreg(state, 0x08); |
591 | *snr = (quality << 8) | quality; | 591 | *snr = (quality << 8) | quality; |
@@ -595,7 +595,7 @@ static int tda80xx_read_snr(struct dvb_frontend* fe, u16* snr) | |||
595 | 595 | ||
596 | static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 596 | static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
597 | { | 597 | { |
598 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 598 | struct tda80xx_state* state = fe->demodulator_priv; |
599 | 599 | ||
600 | *ucblocks = tda80xx_readreg(state, 0x0f); | 600 | *ucblocks = tda80xx_readreg(state, 0x0f); |
601 | if (*ucblocks == 0xff) | 601 | if (*ucblocks == 0xff) |
@@ -606,7 +606,7 @@ static int tda80xx_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
606 | 606 | ||
607 | static int tda80xx_init(struct dvb_frontend* fe) | 607 | static int tda80xx_init(struct dvb_frontend* fe) |
608 | { | 608 | { |
609 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 609 | struct tda80xx_state* state = fe->demodulator_priv; |
610 | 610 | ||
611 | switch(state->id) { | 611 | switch(state->id) { |
612 | case ID_TDA8044: | 612 | case ID_TDA8044: |
@@ -620,7 +620,7 @@ static int tda80xx_init(struct dvb_frontend* fe) | |||
620 | 620 | ||
621 | static void tda80xx_release(struct dvb_frontend* fe) | 621 | static void tda80xx_release(struct dvb_frontend* fe) |
622 | { | 622 | { |
623 | struct tda80xx_state* state = (struct tda80xx_state*) fe->demodulator_priv; | 623 | struct tda80xx_state* state = fe->demodulator_priv; |
624 | 624 | ||
625 | if (state->config->irq) | 625 | if (state->config->irq) |
626 | free_irq(state->config->irq, &state->worklet); | 626 | free_irq(state->config->irq, &state->worklet); |
@@ -637,7 +637,7 @@ struct dvb_frontend* tda80xx_attach(const struct tda80xx_config* config, | |||
637 | int ret; | 637 | int ret; |
638 | 638 | ||
639 | /* allocate memory for the internal state */ | 639 | /* allocate memory for the internal state */ |
640 | state = (struct tda80xx_state*) kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL); | 640 | state = kmalloc(sizeof(struct tda80xx_state), GFP_KERNEL); |
641 | if (state == NULL) goto error; | 641 | if (state == NULL) goto error; |
642 | 642 | ||
643 | /* setup the state */ | 643 | /* setup the state */ |
diff --git a/drivers/media/dvb/frontends/ves1820.c b/drivers/media/dvb/frontends/ves1820.c index 9c0d23e1d9e5..70fb44b391a7 100644 --- a/drivers/media/dvb/frontends/ves1820.c +++ b/drivers/media/dvb/frontends/ves1820.c | |||
@@ -70,7 +70,6 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data) | |||
70 | printk("ves1820: %s(): writereg error (reg == 0x%02x," | 70 | printk("ves1820: %s(): writereg error (reg == 0x%02x," |
71 | "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret); | 71 | "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret); |
72 | 72 | ||
73 | msleep(10); | ||
74 | return (ret != 1) ? -EREMOTEIO : 0; | 73 | return (ret != 1) ? -EREMOTEIO : 0; |
75 | } | 74 | } |
76 | 75 | ||
@@ -193,7 +192,7 @@ static int ves1820_set_symbolrate(struct ves1820_state *state, u32 symbolrate) | |||
193 | 192 | ||
194 | static int ves1820_init(struct dvb_frontend* fe) | 193 | static int ves1820_init(struct dvb_frontend* fe) |
195 | { | 194 | { |
196 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 195 | struct ves1820_state* state = fe->demodulator_priv; |
197 | int i; | 196 | int i; |
198 | int val; | 197 | int val; |
199 | 198 | ||
@@ -214,7 +213,7 @@ static int ves1820_init(struct dvb_frontend* fe) | |||
214 | 213 | ||
215 | static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 214 | static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
216 | { | 215 | { |
217 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 216 | struct ves1820_state* state = fe->demodulator_priv; |
218 | static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; | 217 | static const u8 reg0x00[] = { 0x00, 0x04, 0x08, 0x0c, 0x10 }; |
219 | static const u8 reg0x01[] = { 140, 140, 106, 100, 92 }; | 218 | static const u8 reg0x01[] = { 140, 140, 106, 100, 92 }; |
220 | static const u8 reg0x05[] = { 135, 100, 70, 54, 38 }; | 219 | static const u8 reg0x05[] = { 135, 100, 70, 54, 38 }; |
@@ -241,7 +240,7 @@ static int ves1820_set_parameters(struct dvb_frontend* fe, struct dvb_frontend_p | |||
241 | 240 | ||
242 | static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) | 241 | static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) |
243 | { | 242 | { |
244 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 243 | struct ves1820_state* state = fe->demodulator_priv; |
245 | int sync; | 244 | int sync; |
246 | 245 | ||
247 | *status = 0; | 246 | *status = 0; |
@@ -267,7 +266,7 @@ static int ves1820_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
267 | 266 | ||
268 | static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber) | 267 | static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber) |
269 | { | 268 | { |
270 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 269 | struct ves1820_state* state = fe->demodulator_priv; |
271 | 270 | ||
272 | u32 _ber = ves1820_readreg(state, 0x14) | | 271 | u32 _ber = ves1820_readreg(state, 0x14) | |
273 | (ves1820_readreg(state, 0x15) << 8) | | 272 | (ves1820_readreg(state, 0x15) << 8) | |
@@ -279,7 +278,7 @@ static int ves1820_read_ber(struct dvb_frontend* fe, u32* ber) | |||
279 | 278 | ||
280 | static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 279 | static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
281 | { | 280 | { |
282 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 281 | struct ves1820_state* state = fe->demodulator_priv; |
283 | 282 | ||
284 | u8 gain = ves1820_readreg(state, 0x17); | 283 | u8 gain = ves1820_readreg(state, 0x17); |
285 | *strength = (gain << 8) | gain; | 284 | *strength = (gain << 8) | gain; |
@@ -289,7 +288,7 @@ static int ves1820_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
289 | 288 | ||
290 | static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr) | 289 | static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr) |
291 | { | 290 | { |
292 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 291 | struct ves1820_state* state = fe->demodulator_priv; |
293 | 292 | ||
294 | u8 quality = ~ves1820_readreg(state, 0x18); | 293 | u8 quality = ~ves1820_readreg(state, 0x18); |
295 | *snr = (quality << 8) | quality; | 294 | *snr = (quality << 8) | quality; |
@@ -299,7 +298,7 @@ static int ves1820_read_snr(struct dvb_frontend* fe, u16* snr) | |||
299 | 298 | ||
300 | static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 299 | static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
301 | { | 300 | { |
302 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 301 | struct ves1820_state* state = fe->demodulator_priv; |
303 | 302 | ||
304 | *ucblocks = ves1820_readreg(state, 0x13) & 0x7f; | 303 | *ucblocks = ves1820_readreg(state, 0x13) & 0x7f; |
305 | if (*ucblocks == 0x7f) | 304 | if (*ucblocks == 0x7f) |
@@ -314,7 +313,7 @@ static int ves1820_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
314 | 313 | ||
315 | static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 314 | static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
316 | { | 315 | { |
317 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 316 | struct ves1820_state* state = fe->demodulator_priv; |
318 | int sync; | 317 | int sync; |
319 | s8 afc = 0; | 318 | s8 afc = 0; |
320 | 319 | ||
@@ -345,7 +344,7 @@ static int ves1820_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
345 | 344 | ||
346 | static int ves1820_sleep(struct dvb_frontend* fe) | 345 | static int ves1820_sleep(struct dvb_frontend* fe) |
347 | { | 346 | { |
348 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 347 | struct ves1820_state* state = fe->demodulator_priv; |
349 | 348 | ||
350 | ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */ | 349 | ves1820_writereg(state, 0x1b, 0x02); /* pdown ADC */ |
351 | ves1820_writereg(state, 0x00, 0x80); /* standby */ | 350 | ves1820_writereg(state, 0x00, 0x80); /* standby */ |
@@ -364,7 +363,7 @@ static int ves1820_get_tune_settings(struct dvb_frontend* fe, struct dvb_fronten | |||
364 | 363 | ||
365 | static void ves1820_release(struct dvb_frontend* fe) | 364 | static void ves1820_release(struct dvb_frontend* fe) |
366 | { | 365 | { |
367 | struct ves1820_state* state = (struct ves1820_state*) fe->demodulator_priv; | 366 | struct ves1820_state* state = fe->demodulator_priv; |
368 | kfree(state); | 367 | kfree(state); |
369 | } | 368 | } |
370 | 369 | ||
@@ -377,7 +376,7 @@ struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, | |||
377 | struct ves1820_state* state = NULL; | 376 | struct ves1820_state* state = NULL; |
378 | 377 | ||
379 | /* allocate memory for the internal state */ | 378 | /* allocate memory for the internal state */ |
380 | state = (struct ves1820_state*) kmalloc(sizeof(struct ves1820_state), GFP_KERNEL); | 379 | state = kmalloc(sizeof(struct ves1820_state), GFP_KERNEL); |
381 | if (state == NULL) | 380 | if (state == NULL) |
382 | goto error; | 381 | goto error; |
383 | 382 | ||
diff --git a/drivers/media/dvb/frontends/ves1x93.c b/drivers/media/dvb/frontends/ves1x93.c index edcad283aa86..821df8e839d0 100644 --- a/drivers/media/dvb/frontends/ves1x93.c +++ b/drivers/media/dvb/frontends/ves1x93.c | |||
@@ -263,7 +263,7 @@ static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate) | |||
263 | 263 | ||
264 | static int ves1x93_init (struct dvb_frontend* fe) | 264 | static int ves1x93_init (struct dvb_frontend* fe) |
265 | { | 265 | { |
266 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 266 | struct ves1x93_state* state = fe->demodulator_priv; |
267 | int i; | 267 | int i; |
268 | int val; | 268 | int val; |
269 | 269 | ||
@@ -289,7 +289,7 @@ static int ves1x93_init (struct dvb_frontend* fe) | |||
289 | 289 | ||
290 | static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) | 290 | static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage) |
291 | { | 291 | { |
292 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 292 | struct ves1x93_state* state = fe->demodulator_priv; |
293 | 293 | ||
294 | switch (voltage) { | 294 | switch (voltage) { |
295 | case SEC_VOLTAGE_13: | 295 | case SEC_VOLTAGE_13: |
@@ -305,7 +305,7 @@ static int ves1x93_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag | |||
305 | 305 | ||
306 | static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) | 306 | static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) |
307 | { | 307 | { |
308 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 308 | struct ves1x93_state* state = fe->demodulator_priv; |
309 | 309 | ||
310 | u8 sync = ves1x93_readreg (state, 0x0e); | 310 | u8 sync = ves1x93_readreg (state, 0x0e); |
311 | 311 | ||
@@ -346,7 +346,7 @@ static int ves1x93_read_status(struct dvb_frontend* fe, fe_status_t* status) | |||
346 | 346 | ||
347 | static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) | 347 | static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) |
348 | { | 348 | { |
349 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 349 | struct ves1x93_state* state = fe->demodulator_priv; |
350 | 350 | ||
351 | *ber = ves1x93_readreg (state, 0x15); | 351 | *ber = ves1x93_readreg (state, 0x15); |
352 | *ber |= (ves1x93_readreg (state, 0x16) << 8); | 352 | *ber |= (ves1x93_readreg (state, 0x16) << 8); |
@@ -358,7 +358,7 @@ static int ves1x93_read_ber(struct dvb_frontend* fe, u32* ber) | |||
358 | 358 | ||
359 | static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) | 359 | static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) |
360 | { | 360 | { |
361 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 361 | struct ves1x93_state* state = fe->demodulator_priv; |
362 | 362 | ||
363 | u8 signal = ~ves1x93_readreg (state, 0x0b); | 363 | u8 signal = ~ves1x93_readreg (state, 0x0b); |
364 | *strength = (signal << 8) | signal; | 364 | *strength = (signal << 8) | signal; |
@@ -368,7 +368,7 @@ static int ves1x93_read_signal_strength(struct dvb_frontend* fe, u16* strength) | |||
368 | 368 | ||
369 | static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) | 369 | static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) |
370 | { | 370 | { |
371 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 371 | struct ves1x93_state* state = fe->demodulator_priv; |
372 | 372 | ||
373 | u8 _snr = ~ves1x93_readreg (state, 0x1c); | 373 | u8 _snr = ~ves1x93_readreg (state, 0x1c); |
374 | *snr = (_snr << 8) | _snr; | 374 | *snr = (_snr << 8) | _snr; |
@@ -378,7 +378,7 @@ static int ves1x93_read_snr(struct dvb_frontend* fe, u16* snr) | |||
378 | 378 | ||
379 | static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | 379 | static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) |
380 | { | 380 | { |
381 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 381 | struct ves1x93_state* state = fe->demodulator_priv; |
382 | 382 | ||
383 | *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; | 383 | *ucblocks = ves1x93_readreg (state, 0x18) & 0x7f; |
384 | 384 | ||
@@ -393,7 +393,7 @@ static int ves1x93_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) | |||
393 | 393 | ||
394 | static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 394 | static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
395 | { | 395 | { |
396 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 396 | struct ves1x93_state* state = fe->demodulator_priv; |
397 | 397 | ||
398 | ves1x93_writereg(state, 0x00, 0x11); | 398 | ves1x93_writereg(state, 0x00, 0x11); |
399 | state->config->pll_set(fe, p); | 399 | state->config->pll_set(fe, p); |
@@ -408,7 +408,7 @@ static int ves1x93_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
408 | 408 | ||
409 | static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) | 409 | static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p) |
410 | { | 410 | { |
411 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 411 | struct ves1x93_state* state = fe->demodulator_priv; |
412 | int afc; | 412 | int afc; |
413 | 413 | ||
414 | afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; | 414 | afc = ((int)((char)(ves1x93_readreg (state, 0x0a) << 1)))/2; |
@@ -431,14 +431,14 @@ static int ves1x93_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_par | |||
431 | 431 | ||
432 | static int ves1x93_sleep(struct dvb_frontend* fe) | 432 | static int ves1x93_sleep(struct dvb_frontend* fe) |
433 | { | 433 | { |
434 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 434 | struct ves1x93_state* state = fe->demodulator_priv; |
435 | 435 | ||
436 | return ves1x93_writereg (state, 0x00, 0x08); | 436 | return ves1x93_writereg (state, 0x00, 0x08); |
437 | } | 437 | } |
438 | 438 | ||
439 | static void ves1x93_release(struct dvb_frontend* fe) | 439 | static void ves1x93_release(struct dvb_frontend* fe) |
440 | { | 440 | { |
441 | struct ves1x93_state* state = (struct ves1x93_state*) fe->demodulator_priv; | 441 | struct ves1x93_state* state = fe->demodulator_priv; |
442 | kfree(state); | 442 | kfree(state); |
443 | } | 443 | } |
444 | 444 | ||
@@ -451,7 +451,7 @@ struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, | |||
451 | u8 identity; | 451 | u8 identity; |
452 | 452 | ||
453 | /* allocate memory for the internal state */ | 453 | /* allocate memory for the internal state */ |
454 | state = (struct ves1x93_state*) kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL); | 454 | state = kmalloc(sizeof(struct ves1x93_state), GFP_KERNEL); |
455 | if (state == NULL) goto error; | 455 | if (state == NULL) goto error; |
456 | 456 | ||
457 | /* setup the state */ | 457 | /* setup the state */ |
diff --git a/drivers/media/dvb/ttpci/av7110.c b/drivers/media/dvb/ttpci/av7110.c index 922c205a2652..8e33a850e13e 100644 --- a/drivers/media/dvb/ttpci/av7110.c +++ b/drivers/media/dvb/ttpci/av7110.c | |||
@@ -130,7 +130,7 @@ static void init_av7110_av(struct av7110 *av7110) | |||
130 | av7110->current_input = 0; | 130 | av7110->current_input = 0; |
131 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { | 131 | if (i2c_writereg(av7110, 0x20, 0x00, 0x00) == 1) { |
132 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", | 132 | printk ("dvb-ttpci: Crystal audio DAC @ card %d detected\n", |
133 | av7110->dvb_adapter->num); | 133 | av7110->dvb_adapter.num); |
134 | av7110->adac_type = DVB_ADAC_CRYSTAL; | 134 | av7110->adac_type = DVB_ADAC_CRYSTAL; |
135 | i2c_writereg(av7110, 0x20, 0x01, 0xd2); | 135 | i2c_writereg(av7110, 0x20, 0x01, 0xd2); |
136 | i2c_writereg(av7110, 0x20, 0x02, 0x49); | 136 | i2c_writereg(av7110, 0x20, 0x02, 0x49); |
@@ -145,13 +145,13 @@ static void init_av7110_av(struct av7110 *av7110) | |||
145 | } | 145 | } |
146 | else if (dev->pci->subsystem_vendor == 0x110a) { | 146 | else if (dev->pci->subsystem_vendor == 0x110a) { |
147 | printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n", | 147 | printk("dvb-ttpci: DVB-C w/o analog module @ card %d detected\n", |
148 | av7110->dvb_adapter->num); | 148 | av7110->dvb_adapter.num); |
149 | av7110->adac_type = DVB_ADAC_NONE; | 149 | av7110->adac_type = DVB_ADAC_NONE; |
150 | } | 150 | } |
151 | else { | 151 | else { |
152 | av7110->adac_type = adac; | 152 | av7110->adac_type = adac; |
153 | printk("dvb-ttpci: adac type set to %d @ card %d\n", | 153 | printk("dvb-ttpci: adac type set to %d @ card %d\n", |
154 | av7110->dvb_adapter->num, av7110->adac_type); | 154 | av7110->dvb_adapter.num, av7110->adac_type); |
155 | } | 155 | } |
156 | 156 | ||
157 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { | 157 | if (av7110->adac_type == DVB_ADAC_NONE || av7110->adac_type == DVB_ADAC_MSP) { |
@@ -231,7 +231,7 @@ static int arm_thread(void *data) | |||
231 | 231 | ||
232 | if (newloops == av7110->arm_loops) { | 232 | if (newloops == av7110->arm_loops) { |
233 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", | 233 | printk(KERN_ERR "dvb-ttpci: ARM crashed @ card %d\n", |
234 | av7110->dvb_adapter->num); | 234 | av7110->dvb_adapter.num); |
235 | 235 | ||
236 | arm_error(av7110); | 236 | arm_error(av7110); |
237 | av7710_set_video_mode(av7110, vidmode); | 237 | av7710_set_video_mode(av7110, vidmode); |
@@ -1282,7 +1282,7 @@ static int av7110_register(struct av7110 *av7110) | |||
1282 | av7110->dmxdev.demux = &dvbdemux->dmx; | 1282 | av7110->dmxdev.demux = &dvbdemux->dmx; |
1283 | av7110->dmxdev.capabilities = 0; | 1283 | av7110->dmxdev.capabilities = 0; |
1284 | 1284 | ||
1285 | dvb_dmxdev_init(&av7110->dmxdev, av7110->dvb_adapter); | 1285 | dvb_dmxdev_init(&av7110->dmxdev, &av7110->dvb_adapter); |
1286 | 1286 | ||
1287 | av7110->hw_frontend.source = DMX_FRONTEND_0; | 1287 | av7110->hw_frontend.source = DMX_FRONTEND_0; |
1288 | 1288 | ||
@@ -1307,11 +1307,11 @@ static int av7110_register(struct av7110 *av7110) | |||
1307 | av7110_ca_register(av7110); | 1307 | av7110_ca_register(av7110); |
1308 | 1308 | ||
1309 | #ifdef CONFIG_DVB_AV7110_OSD | 1309 | #ifdef CONFIG_DVB_AV7110_OSD |
1310 | dvb_register_device(av7110->dvb_adapter, &av7110->osd_dev, | 1310 | dvb_register_device(&av7110->dvb_adapter, &av7110->osd_dev, |
1311 | &dvbdev_osd, av7110, DVB_DEVICE_OSD); | 1311 | &dvbdev_osd, av7110, DVB_DEVICE_OSD); |
1312 | #endif | 1312 | #endif |
1313 | 1313 | ||
1314 | dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); | 1314 | dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net, &dvbdemux->dmx); |
1315 | 1315 | ||
1316 | if (budgetpatch) { | 1316 | if (budgetpatch) { |
1317 | /* initialize software demux1 without its own frontend | 1317 | /* initialize software demux1 without its own frontend |
@@ -1334,9 +1334,9 @@ static int av7110_register(struct av7110 *av7110) | |||
1334 | av7110->dmxdev1.demux = &dvbdemux1->dmx; | 1334 | av7110->dmxdev1.demux = &dvbdemux1->dmx; |
1335 | av7110->dmxdev1.capabilities = 0; | 1335 | av7110->dmxdev1.capabilities = 0; |
1336 | 1336 | ||
1337 | dvb_dmxdev_init(&av7110->dmxdev1, av7110->dvb_adapter); | 1337 | dvb_dmxdev_init(&av7110->dmxdev1, &av7110->dvb_adapter); |
1338 | 1338 | ||
1339 | dvb_net_init(av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); | 1339 | dvb_net_init(&av7110->dvb_adapter, &av7110->dvb_net1, &dvbdemux1->dmx); |
1340 | printk("dvb-ttpci: additional demux1 for budget-patch registered\n"); | 1340 | printk("dvb-ttpci: additional demux1 for budget-patch registered\n"); |
1341 | } | 1341 | } |
1342 | return 0; | 1342 | return 0; |
@@ -1673,6 +1673,106 @@ static struct stv0299_config alps_bsru6_config = { | |||
1673 | }; | 1673 | }; |
1674 | 1674 | ||
1675 | 1675 | ||
1676 | static u8 alps_bsbe1_inittab[] = { | ||
1677 | 0x01, 0x15, | ||
1678 | 0x02, 0x30, | ||
1679 | 0x03, 0x00, | ||
1680 | 0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */ | ||
1681 | 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */ | ||
1682 | 0x06, 0x40, /* DAC not used, set to high impendance mode */ | ||
1683 | 0x07, 0x00, /* DAC LSB */ | ||
1684 | 0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */ | ||
1685 | 0x09, 0x00, /* FIFO */ | ||
1686 | 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */ | ||
1687 | 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */ | ||
1688 | 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */ | ||
1689 | 0x10, 0x3f, // AGC2 0x3d | ||
1690 | 0x11, 0x84, | ||
1691 | 0x12, 0xb5, // Lock detect: -64 Carrier freq detect:on | ||
1692 | 0x15, 0xc9, // lock detector threshold | ||
1693 | 0x16, 0x00, | ||
1694 | 0x17, 0x00, | ||
1695 | 0x18, 0x00, | ||
1696 | 0x19, 0x00, | ||
1697 | 0x1a, 0x00, | ||
1698 | 0x1f, 0x50, | ||
1699 | 0x20, 0x00, | ||
1700 | 0x21, 0x00, | ||
1701 | 0x22, 0x00, | ||
1702 | 0x23, 0x00, | ||
1703 | 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0 | ||
1704 | 0x29, 0x1e, // 1/2 threshold | ||
1705 | 0x2a, 0x14, // 2/3 threshold | ||
1706 | 0x2b, 0x0f, // 3/4 threshold | ||
1707 | 0x2c, 0x09, // 5/6 threshold | ||
1708 | 0x2d, 0x05, // 7/8 threshold | ||
1709 | 0x2e, 0x01, | ||
1710 | 0x31, 0x1f, // test all FECs | ||
1711 | 0x32, 0x19, // viterbi and synchro search | ||
1712 | 0x33, 0xfc, // rs control | ||
1713 | 0x34, 0x93, // error control | ||
1714 | 0x0f, 0x92, | ||
1715 | 0xff, 0xff | ||
1716 | }; | ||
1717 | |||
1718 | static int alps_bsbe1_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | ||
1719 | { | ||
1720 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | ||
1721 | int ret; | ||
1722 | u8 data[4]; | ||
1723 | u32 div; | ||
1724 | struct i2c_msg msg = { .addr = 0x61, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1725 | |||
1726 | if ((params->frequency < 950000) || (params->frequency > 2150000)) | ||
1727 | return -EINVAL; | ||
1728 | |||
1729 | div = (params->frequency + (125 - 1)) / 125; // round correctly | ||
1730 | data[0] = (div >> 8) & 0x7f; | ||
1731 | data[1] = div & 0xff; | ||
1732 | data[2] = 0x80 | ((div & 0x18000) >> 10) | 4; | ||
1733 | data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4; | ||
1734 | |||
1735 | ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); | ||
1736 | return (ret != 1) ? -EIO : 0; | ||
1737 | } | ||
1738 | |||
1739 | static struct stv0299_config alps_bsbe1_config = { | ||
1740 | .demod_address = 0x68, | ||
1741 | .inittab = alps_bsbe1_inittab, | ||
1742 | .mclk = 88000000UL, | ||
1743 | .invert = 1, | ||
1744 | .enhanced_tuning = 0, | ||
1745 | .skip_reinit = 0, | ||
1746 | .min_delay_ms = 100, | ||
1747 | .set_symbol_rate = alps_bsru6_set_symbol_rate, | ||
1748 | .pll_set = alps_bsbe1_pll_set, | ||
1749 | }; | ||
1750 | |||
1751 | static int lnbp21_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) | ||
1752 | { | ||
1753 | struct av7110* av7110 = (struct av7110*) fe->dvb->priv; | ||
1754 | int ret; | ||
1755 | u8 data[1]; | ||
1756 | struct i2c_msg msg = { .addr = 0x08, .flags = 0, .buf = data, .len = sizeof(data) }; | ||
1757 | |||
1758 | switch(voltage) { | ||
1759 | case SEC_VOLTAGE_OFF: | ||
1760 | data[0] = 0x00; | ||
1761 | break; | ||
1762 | case SEC_VOLTAGE_13: | ||
1763 | data[0] = 0x44; | ||
1764 | break; | ||
1765 | case SEC_VOLTAGE_18: | ||
1766 | data[0] = 0x4c; | ||
1767 | break; | ||
1768 | default: | ||
1769 | return -EINVAL; | ||
1770 | }; | ||
1771 | |||
1772 | ret = i2c_transfer(&av7110->i2c_adap, &msg, 1); | ||
1773 | return (ret != 1) ? -EIO : 0; | ||
1774 | } | ||
1775 | |||
1676 | 1776 | ||
1677 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) | 1777 | static int alps_tdbe2_pll_set(struct dvb_frontend* fe, struct dvb_frontend_parameters* params) |
1678 | { | 1778 | { |
@@ -2116,6 +2216,14 @@ static int frontend_init(struct av7110 *av7110) | |||
2116 | av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; | 2216 | av7110->dev->i2c_bitrate = SAA7146_I2C_BUS_BIT_RATE_240; |
2117 | break; | 2217 | break; |
2118 | } | 2218 | } |
2219 | break; | ||
2220 | |||
2221 | case 0x000E: /* Hauppauge/TT Nexus-S rev 2.3 */ | ||
2222 | /* ALPS BSBE1 */ | ||
2223 | av7110->fe = stv0299_attach(&alps_bsbe1_config, &av7110->i2c_adap); | ||
2224 | if (av7110->fe) | ||
2225 | av7110->fe->ops->set_voltage = lnbp21_set_voltage; | ||
2226 | break; | ||
2119 | } | 2227 | } |
2120 | } | 2228 | } |
2121 | 2229 | ||
@@ -2138,7 +2246,7 @@ static int frontend_init(struct av7110 *av7110) | |||
2138 | FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); | 2246 | FE_FUNC_OVERRIDE(av7110->fe->ops->dishnetwork_send_legacy_command, av7110->fe_dishnetwork_send_legacy_command, av7110_fe_dishnetwork_send_legacy_command); |
2139 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); | 2247 | FE_FUNC_OVERRIDE(av7110->fe->ops->set_frontend, av7110->fe_set_frontend, av7110_fe_set_frontend); |
2140 | 2248 | ||
2141 | ret = dvb_register_frontend(av7110->dvb_adapter, av7110->fe); | 2249 | ret = dvb_register_frontend(&av7110->dvb_adapter, av7110->fe); |
2142 | if (ret < 0) { | 2250 | if (ret < 0) { |
2143 | printk("av7110: Frontend registration failed!\n"); | 2251 | printk("av7110: Frontend registration failed!\n"); |
2144 | if (av7110->fe->ops->release) | 2252 | if (av7110->fe->ops->release) |
@@ -2352,7 +2460,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d | |||
2352 | goto err_dvb_unregister_adapter_2; | 2460 | goto err_dvb_unregister_adapter_2; |
2353 | 2461 | ||
2354 | ttpci_eeprom_parse_mac(&av7110->i2c_adap, | 2462 | ttpci_eeprom_parse_mac(&av7110->i2c_adap, |
2355 | av7110->dvb_adapter->proposed_mac); | 2463 | av7110->dvb_adapter.proposed_mac); |
2356 | ret = -ENOMEM; | 2464 | ret = -ENOMEM; |
2357 | 2465 | ||
2358 | if (budgetpatch) { | 2466 | if (budgetpatch) { |
@@ -2523,7 +2631,7 @@ static int av7110_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_d | |||
2523 | if (ret < 0) | 2631 | if (ret < 0) |
2524 | goto err_av7110_unregister_11; | 2632 | goto err_av7110_unregister_11; |
2525 | 2633 | ||
2526 | av7110->dvb_adapter->priv = av7110; | 2634 | av7110->dvb_adapter.priv = av7110; |
2527 | ret = frontend_init(av7110); | 2635 | ret = frontend_init(av7110); |
2528 | if (ret < 0) | 2636 | if (ret < 0) |
2529 | goto err_av7110_exit_v4l_12; | 2637 | goto err_av7110_exit_v4l_12; |
@@ -2558,7 +2666,7 @@ err_saa71466_vfree_4: | |||
2558 | err_i2c_del_3: | 2666 | err_i2c_del_3: |
2559 | i2c_del_adapter(&av7110->i2c_adap); | 2667 | i2c_del_adapter(&av7110->i2c_adap); |
2560 | err_dvb_unregister_adapter_2: | 2668 | err_dvb_unregister_adapter_2: |
2561 | dvb_unregister_adapter(av7110->dvb_adapter); | 2669 | dvb_unregister_adapter(&av7110->dvb_adapter); |
2562 | err_put_firmware_1: | 2670 | err_put_firmware_1: |
2563 | put_firmware(av7110); | 2671 | put_firmware(av7110); |
2564 | err_kfree_0: | 2672 | err_kfree_0: |
@@ -2604,7 +2712,7 @@ static int av7110_detach(struct saa7146_dev* saa) | |||
2604 | 2712 | ||
2605 | i2c_del_adapter(&av7110->i2c_adap); | 2713 | i2c_del_adapter(&av7110->i2c_adap); |
2606 | 2714 | ||
2607 | dvb_unregister_adapter (av7110->dvb_adapter); | 2715 | dvb_unregister_adapter (&av7110->dvb_adapter); |
2608 | 2716 | ||
2609 | av7110_num--; | 2717 | av7110_num--; |
2610 | 2718 | ||
@@ -2672,21 +2780,23 @@ MAKE_AV7110_INFO(ttt_1_X, "Technotrend/Hauppauge WinTV DVB-T rev1.X"); | |||
2672 | MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); | 2780 | MAKE_AV7110_INFO(ttc_1_X, "Technotrend/Hauppauge WinTV Nexus-CA rev1.X"); |
2673 | MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); | 2781 | MAKE_AV7110_INFO(ttc_2_X, "Technotrend/Hauppauge WinTV DVB-C rev2.X"); |
2674 | MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X"); | 2782 | MAKE_AV7110_INFO(tts_2_X, "Technotrend/Hauppauge WinTV Nexus-S rev2.X"); |
2783 | MAKE_AV7110_INFO(tts_2_3, "Technotrend/Hauppauge WinTV Nexus-S rev2.3"); | ||
2675 | MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); | 2784 | MAKE_AV7110_INFO(tts_1_3se, "Technotrend/Hauppauge WinTV DVB-S rev1.3 SE"); |
2676 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); | 2785 | MAKE_AV7110_INFO(ttt, "Technotrend/Hauppauge DVB-T"); |
2677 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); | 2786 | MAKE_AV7110_INFO(fsc, "Fujitsu Siemens DVB-C"); |
2678 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); | 2787 | MAKE_AV7110_INFO(fss, "Fujitsu Siemens DVB-S rev1.6"); |
2679 | 2788 | ||
2680 | static struct pci_device_id pci_tbl[] = { | 2789 | static struct pci_device_id pci_tbl[] = { |
2790 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), | ||
2681 | MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000), | 2791 | MAKE_EXTENSION_PCI(tts_1_X, 0x13c2, 0x0000), |
2682 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), | 2792 | MAKE_EXTENSION_PCI(ttt_1_X, 0x13c2, 0x0001), |
2683 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), | 2793 | MAKE_EXTENSION_PCI(ttc_2_X, 0x13c2, 0x0002), |
2684 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), | 2794 | MAKE_EXTENSION_PCI(tts_2_X, 0x13c2, 0x0003), |
2685 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), | ||
2686 | MAKE_EXTENSION_PCI(fsc, 0x110a, 0x0000), | ||
2687 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), | ||
2688 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), | 2795 | MAKE_EXTENSION_PCI(fss, 0x13c2, 0x0006), |
2689 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), | 2796 | MAKE_EXTENSION_PCI(ttt, 0x13c2, 0x0008), |
2797 | MAKE_EXTENSION_PCI(ttc_1_X, 0x13c2, 0x000a), | ||
2798 | MAKE_EXTENSION_PCI(tts_2_3, 0x13c2, 0x000e), | ||
2799 | MAKE_EXTENSION_PCI(tts_1_3se, 0x13c2, 0x1002), | ||
2690 | 2800 | ||
2691 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte | 2801 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0004), UNDEFINED CARD */ // Galaxis DVB PC-Sat-Carte |
2692 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 | 2802 | /* MAKE_EXTENSION_PCI(???, 0x13c2, 0x0005), UNDEFINED CARD */ // Technisat SkyStar1 |
diff --git a/drivers/media/dvb/ttpci/av7110.h b/drivers/media/dvb/ttpci/av7110.h index 5070e0523da7..4f69b4d01479 100644 --- a/drivers/media/dvb/ttpci/av7110.h +++ b/drivers/media/dvb/ttpci/av7110.h | |||
@@ -220,7 +220,7 @@ struct av7110 { | |||
220 | 220 | ||
221 | struct audio_mixer mixer; | 221 | struct audio_mixer mixer; |
222 | 222 | ||
223 | struct dvb_adapter *dvb_adapter; | 223 | struct dvb_adapter dvb_adapter; |
224 | struct dvb_device *video_dev; | 224 | struct dvb_device *video_dev; |
225 | struct dvb_device *audio_dev; | 225 | struct dvb_device *audio_dev; |
226 | struct dvb_device *ca_dev; | 226 | struct dvb_device *ca_dev; |
@@ -274,7 +274,6 @@ extern void av7110_ir_exit (void); | |||
274 | extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); | 274 | extern int i2c_writereg(struct av7110 *av7110, u8 id, u8 reg, u8 val); |
275 | extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); | 275 | extern u8 i2c_readreg(struct av7110 *av7110, u8 id, u8 reg); |
276 | extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val); | 276 | extern int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val); |
277 | extern int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val); | ||
278 | 277 | ||
279 | 278 | ||
280 | extern int av7110_init_analog_module(struct av7110 *av7110); | 279 | extern int av7110_init_analog_module(struct av7110 *av7110); |
diff --git a/drivers/media/dvb/ttpci/av7110_av.c b/drivers/media/dvb/ttpci/av7110_av.c index d77e8a00688f..ccf946125d02 100644 --- a/drivers/media/dvb/ttpci/av7110_av.c +++ b/drivers/media/dvb/ttpci/av7110_av.c | |||
@@ -1075,7 +1075,7 @@ static int dvb_video_ioctl(struct inode *inode, struct file *file, | |||
1075 | } | 1075 | } |
1076 | if (ret < 0) | 1076 | if (ret < 0) |
1077 | break; | 1077 | break; |
1078 | av7110->videostate.video_format = format; | 1078 | av7110->videostate.display_format = format; |
1079 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, | 1079 | ret = av7110_fw_cmd(av7110, COMTYPE_ENCODER, SetPanScanType, |
1080 | 1, (u16) val); | 1080 | 1, (u16) val); |
1081 | break; | 1081 | break; |
@@ -1230,14 +1230,20 @@ static int dvb_audio_ioctl(struct inode *inode, struct file *file, | |||
1230 | switch(av7110->audiostate.channel_select) { | 1230 | switch(av7110->audiostate.channel_select) { |
1231 | case AUDIO_STEREO: | 1231 | case AUDIO_STEREO: |
1232 | audcom(av7110, AUDIO_CMD_STEREO); | 1232 | audcom(av7110, AUDIO_CMD_STEREO); |
1233 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1234 | i2c_writereg(av7110, 0x20, 0x02, 0x49); | ||
1233 | break; | 1235 | break; |
1234 | 1236 | ||
1235 | case AUDIO_MONO_LEFT: | 1237 | case AUDIO_MONO_LEFT: |
1236 | audcom(av7110, AUDIO_CMD_MONO_L); | 1238 | audcom(av7110, AUDIO_CMD_MONO_L); |
1239 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1240 | i2c_writereg(av7110, 0x20, 0x02, 0x4a); | ||
1237 | break; | 1241 | break; |
1238 | 1242 | ||
1239 | case AUDIO_MONO_RIGHT: | 1243 | case AUDIO_MONO_RIGHT: |
1240 | audcom(av7110, AUDIO_CMD_MONO_R); | 1244 | audcom(av7110, AUDIO_CMD_MONO_R); |
1245 | if (av7110->adac_type == DVB_ADAC_CRYSTAL) | ||
1246 | i2c_writereg(av7110, 0x20, 0x02, 0x45); | ||
1241 | break; | 1247 | break; |
1242 | 1248 | ||
1243 | default: | 1249 | default: |
@@ -1409,10 +1415,10 @@ int av7110_av_register(struct av7110 *av7110) | |||
1409 | av7110->video_events.overflow = 0; | 1415 | av7110->video_events.overflow = 0; |
1410 | memset(&av7110->video_size, 0, sizeof (video_size_t)); | 1416 | memset(&av7110->video_size, 0, sizeof (video_size_t)); |
1411 | 1417 | ||
1412 | dvb_register_device(av7110->dvb_adapter, &av7110->video_dev, | 1418 | dvb_register_device(&av7110->dvb_adapter, &av7110->video_dev, |
1413 | &dvbdev_video, av7110, DVB_DEVICE_VIDEO); | 1419 | &dvbdev_video, av7110, DVB_DEVICE_VIDEO); |
1414 | 1420 | ||
1415 | dvb_register_device(av7110->dvb_adapter, &av7110->audio_dev, | 1421 | dvb_register_device(&av7110->dvb_adapter, &av7110->audio_dev, |
1416 | &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); | 1422 | &dvbdev_audio, av7110, DVB_DEVICE_AUDIO); |
1417 | 1423 | ||
1418 | return 0; | 1424 | return 0; |
diff --git a/drivers/media/dvb/ttpci/av7110_ca.c b/drivers/media/dvb/ttpci/av7110_ca.c index 21f7aacf7726..c3801e328fe9 100644 --- a/drivers/media/dvb/ttpci/av7110_ca.c +++ b/drivers/media/dvb/ttpci/av7110_ca.c | |||
@@ -123,7 +123,7 @@ static void ci_ll_release(struct dvb_ringbuffer *cirbuf, struct dvb_ringbuffer * | |||
123 | } | 123 | } |
124 | 124 | ||
125 | static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, | 125 | static int ci_ll_reset(struct dvb_ringbuffer *cibuf, struct file *file, |
126 | int slots, ca_slot_info_t *slot) | 126 | int slots, ca_slot_info_t *slot) |
127 | { | 127 | { |
128 | int i; | 128 | int i; |
129 | int len = 0; | 129 | int len = 0; |
@@ -370,7 +370,7 @@ static struct dvb_device dvbdev_ca = { | |||
370 | 370 | ||
371 | int av7110_ca_register(struct av7110 *av7110) | 371 | int av7110_ca_register(struct av7110 *av7110) |
372 | { | 372 | { |
373 | return dvb_register_device(av7110->dvb_adapter, &av7110->ca_dev, | 373 | return dvb_register_device(&av7110->dvb_adapter, &av7110->ca_dev, |
374 | &dvbdev_ca, av7110, DVB_DEVICE_CA); | 374 | &dvbdev_ca, av7110, DVB_DEVICE_CA); |
375 | } | 375 | } |
376 | 376 | ||
diff --git a/drivers/media/dvb/ttpci/av7110_hw.c b/drivers/media/dvb/ttpci/av7110_hw.c index bd6e5ea4aefe..7fa4a0ebe133 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.c +++ b/drivers/media/dvb/ttpci/av7110_hw.c | |||
@@ -104,7 +104,7 @@ u32 av7110_debiread(struct av7110 *av7110, u32 config, int addr, int count) | |||
104 | 104 | ||
105 | 105 | ||
106 | /* av7110 ARM core boot stuff */ | 106 | /* av7110 ARM core boot stuff */ |
107 | 107 | #if 0 | |
108 | void av7110_reset_arm(struct av7110 *av7110) | 108 | void av7110_reset_arm(struct av7110 *av7110) |
109 | { | 109 | { |
110 | saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); | 110 | saa7146_setgpio(av7110->dev, RESET_LINE, SAA7146_GPIO_OUTLO); |
@@ -124,7 +124,7 @@ void av7110_reset_arm(struct av7110 *av7110) | |||
124 | av7110->arm_ready = 1; | 124 | av7110->arm_ready = 1; |
125 | dprintk(1, "reset ARM\n"); | 125 | dprintk(1, "reset ARM\n"); |
126 | } | 126 | } |
127 | 127 | #endif /* 0 */ | |
128 | 128 | ||
129 | static int waitdebi(struct av7110 *av7110, int adr, int state) | 129 | static int waitdebi(struct av7110 *av7110, int adr, int state) |
130 | { | 130 | { |
@@ -335,7 +335,7 @@ int av7110_wait_msgstate(struct av7110 *av7110, u16 flags) | |||
335 | return 0; | 335 | return 0; |
336 | } | 336 | } |
337 | 337 | ||
338 | int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | 338 | static int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) |
339 | { | 339 | { |
340 | int i; | 340 | int i; |
341 | unsigned long start; | 341 | unsigned long start; |
@@ -455,7 +455,7 @@ int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | |||
455 | return 0; | 455 | return 0; |
456 | } | 456 | } |
457 | 457 | ||
458 | int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) | 458 | static int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length) |
459 | { | 459 | { |
460 | int ret; | 460 | int ret; |
461 | 461 | ||
@@ -500,6 +500,7 @@ int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...) | |||
500 | return ret; | 500 | return ret; |
501 | } | 501 | } |
502 | 502 | ||
503 | #if 0 | ||
503 | int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) | 504 | int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) |
504 | { | 505 | { |
505 | int i, ret; | 506 | int i, ret; |
@@ -521,6 +522,7 @@ int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len) | |||
521 | printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); | 522 | printk(KERN_ERR "dvb-ttpci: av7110_send_ci_cmd error %d\n", ret); |
522 | return ret; | 523 | return ret; |
523 | } | 524 | } |
525 | #endif /* 0 */ | ||
524 | 526 | ||
525 | int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | 527 | int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, |
526 | int request_buf_len, u16 *reply_buf, int reply_buf_len) | 528 | int request_buf_len, u16 *reply_buf, int reply_buf_len) |
@@ -593,7 +595,7 @@ int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | |||
593 | return 0; | 595 | return 0; |
594 | } | 596 | } |
595 | 597 | ||
596 | int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length) | 598 | static int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* buf, s16 length) |
597 | { | 599 | { |
598 | int ret; | 600 | int ret; |
599 | ret = av7110_fw_request(av7110, &tag, 0, buf, length); | 601 | ret = av7110_fw_request(av7110, &tag, 0, buf, length); |
@@ -617,7 +619,7 @@ int av7110_firmversion(struct av7110 *av7110) | |||
617 | 619 | ||
618 | if (av7110_fw_query(av7110, tag, buf, 16)) { | 620 | if (av7110_fw_query(av7110, tag, buf, 16)) { |
619 | printk("dvb-ttpci: failed to boot firmware @ card %d\n", | 621 | printk("dvb-ttpci: failed to boot firmware @ card %d\n", |
620 | av7110->dvb_adapter->num); | 622 | av7110->dvb_adapter.num); |
621 | return -EIO; | 623 | return -EIO; |
622 | } | 624 | } |
623 | 625 | ||
@@ -628,16 +630,16 @@ int av7110_firmversion(struct av7110 *av7110) | |||
628 | av7110->avtype = (buf[8] << 16) + buf[9]; | 630 | av7110->avtype = (buf[8] << 16) + buf[9]; |
629 | 631 | ||
630 | printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", | 632 | printk("dvb-ttpci: info @ card %d: firm %08x, rtsl %08x, vid %08x, app %08x\n", |
631 | av7110->dvb_adapter->num, av7110->arm_fw, | 633 | av7110->dvb_adapter.num, av7110->arm_fw, |
632 | av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); | 634 | av7110->arm_rtsl, av7110->arm_vid, av7110->arm_app); |
633 | 635 | ||
634 | /* print firmware capabilities */ | 636 | /* print firmware capabilities */ |
635 | if (FW_CI_LL_SUPPORT(av7110->arm_app)) | 637 | if (FW_CI_LL_SUPPORT(av7110->arm_app)) |
636 | printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n", | 638 | printk("dvb-ttpci: firmware @ card %d supports CI link layer interface\n", |
637 | av7110->dvb_adapter->num); | 639 | av7110->dvb_adapter.num); |
638 | else | 640 | else |
639 | printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n", | 641 | printk("dvb-ttpci: no firmware support for CI link layer interface @ card %d\n", |
640 | av7110->dvb_adapter->num); | 642 | av7110->dvb_adapter.num); |
641 | 643 | ||
642 | return 0; | 644 | return 0; |
643 | } | 645 | } |
diff --git a/drivers/media/dvb/ttpci/av7110_hw.h b/drivers/media/dvb/ttpci/av7110_hw.h index bf901c624682..52061e17c6dd 100644 --- a/drivers/media/dvb/ttpci/av7110_hw.h +++ b/drivers/media/dvb/ttpci/av7110_hw.h | |||
@@ -364,7 +364,6 @@ enum av7110_command_type { | |||
364 | 364 | ||
365 | 365 | ||
366 | 366 | ||
367 | extern void av7110_reset_arm(struct av7110 *av7110); | ||
368 | extern int av7110_bootarm(struct av7110 *av7110); | 367 | extern int av7110_bootarm(struct av7110 *av7110); |
369 | extern int av7110_firmversion(struct av7110 *av7110); | 368 | extern int av7110_firmversion(struct av7110 *av7110); |
370 | #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) | 369 | #define FW_CI_LL_SUPPORT(arm_app) ((arm_app) & 0x80000000) |
@@ -373,12 +372,8 @@ extern int av7110_firmversion(struct av7110 *av7110); | |||
373 | 372 | ||
374 | extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags); | 373 | extern int av7110_wait_msgstate(struct av7110 *av7110, u16 flags); |
375 | extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); | 374 | extern int av7110_fw_cmd(struct av7110 *av7110, int type, int com, int num, ...); |
376 | extern int __av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length); | ||
377 | extern int av7110_send_fw_cmd(struct av7110 *av7110, u16* buf, int length); | ||
378 | extern int av7110_send_ci_cmd(struct av7110 *av7110, u8 subcom, u8 *buf, u8 len); | ||
379 | extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, | 375 | extern int av7110_fw_request(struct av7110 *av7110, u16 *request_buf, |
380 | int request_buf_len, u16 *reply_buf, int reply_buf_len); | 376 | int request_buf_len, u16 *reply_buf, int reply_buf_len); |
381 | extern int av7110_fw_query(struct av7110 *av7110, u16 tag, u16* Buff, s16 length); | ||
382 | 377 | ||
383 | 378 | ||
384 | /* DEBI (saa7146 data extension bus interface) access */ | 379 | /* DEBI (saa7146 data extension bus interface) access */ |
diff --git a/drivers/media/dvb/ttpci/av7110_ir.c b/drivers/media/dvb/ttpci/av7110_ir.c index 6d2256f1e354..665cdb8a3f71 100644 --- a/drivers/media/dvb/ttpci/av7110_ir.c +++ b/drivers/media/dvb/ttpci/av7110_ir.c | |||
@@ -10,7 +10,7 @@ | |||
10 | 10 | ||
11 | #define UP_TIMEOUT (HZ/4) | 11 | #define UP_TIMEOUT (HZ/4) |
12 | 12 | ||
13 | /* enable ir debugging by or'ing av7110_debug with 16 */ | 13 | /* enable ir debugging by or'ing debug with 16 */ |
14 | 14 | ||
15 | static int ir_initialized; | 15 | static int ir_initialized; |
16 | static struct input_dev input_dev; | 16 | static struct input_dev input_dev; |
diff --git a/drivers/media/dvb/ttpci/av7110_v4l.c b/drivers/media/dvb/ttpci/av7110_v4l.c index eb84fb08d95c..e65fc36e2ce8 100644 --- a/drivers/media/dvb/ttpci/av7110_v4l.c +++ b/drivers/media/dvb/ttpci/av7110_v4l.c | |||
@@ -46,13 +46,13 @@ int msp_writereg(struct av7110 *av7110, u8 dev, u16 reg, u16 val) | |||
46 | 46 | ||
47 | if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { | 47 | if (i2c_transfer(&av7110->i2c_adap, &msgs, 1) != 1) { |
48 | dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", | 48 | dprintk(1, "dvb-ttpci: failed @ card %d, %u = %u\n", |
49 | av7110->dvb_adapter->num, reg, val); | 49 | av7110->dvb_adapter.num, reg, val); |
50 | return -EIO; | 50 | return -EIO; |
51 | } | 51 | } |
52 | return 0; | 52 | return 0; |
53 | } | 53 | } |
54 | 54 | ||
55 | int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) | 55 | static int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) |
56 | { | 56 | { |
57 | u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; | 57 | u8 msg1[3] = { dev, reg >> 8, reg & 0xff }; |
58 | u8 msg2[2]; | 58 | u8 msg2[2]; |
@@ -63,7 +63,7 @@ int msp_readreg(struct av7110 *av7110, u8 dev, u16 reg, u16 *val) | |||
63 | 63 | ||
64 | if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { | 64 | if (i2c_transfer(&av7110->i2c_adap, &msgs[0], 2) != 2) { |
65 | dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", | 65 | dprintk(1, "dvb-ttpci: failed @ card %d, %u\n", |
66 | av7110->dvb_adapter->num, reg); | 66 | av7110->dvb_adapter.num, reg); |
67 | return -EIO; | 67 | return -EIO; |
68 | } | 68 | } |
69 | *val = (msg2[0] << 8) | msg2[1]; | 69 | *val = (msg2[0] << 8) | msg2[1]; |
@@ -552,13 +552,13 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
552 | return -ENODEV; | 552 | return -ENODEV; |
553 | 553 | ||
554 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", | 554 | printk("dvb-ttpci: DVB-C analog module @ card %d detected, initializing MSP3400\n", |
555 | av7110->dvb_adapter->num); | 555 | av7110->dvb_adapter.num); |
556 | av7110->adac_type = DVB_ADAC_MSP; | 556 | av7110->adac_type = DVB_ADAC_MSP; |
557 | msleep(100); // the probing above resets the msp... | 557 | msleep(100); // the probing above resets the msp... |
558 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); | 558 | msp_readreg(av7110, MSP_RD_DSP, 0x001e, &version1); |
559 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); | 559 | msp_readreg(av7110, MSP_RD_DSP, 0x001f, &version2); |
560 | dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n", | 560 | dprintk(1, "dvb-ttpci: @ card %d MSP3400 version 0x%04x 0x%04x\n", |
561 | av7110->dvb_adapter->num, version1, version2); | 561 | av7110->dvb_adapter.num, version1, version2); |
562 | msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); | 562 | msp_writereg(av7110, MSP_WR_DSP, 0x0013, 0x0c00); |
563 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone | 563 | msp_writereg(av7110, MSP_WR_DSP, 0x0000, 0x7f00); // loudspeaker + headphone |
564 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source | 564 | msp_writereg(av7110, MSP_WR_DSP, 0x0008, 0x0220); // loudspeaker source |
@@ -596,7 +596,7 @@ int av7110_init_analog_module(struct av7110 *av7110) | |||
596 | /* init the saa7113 */ | 596 | /* init the saa7113 */ |
597 | while (*i != 0xff) { | 597 | while (*i != 0xff) { |
598 | if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { | 598 | if (i2c_writereg(av7110, 0x48, i[0], i[1]) != 1) { |
599 | dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter->num); | 599 | dprintk(1, "saa7113 initialization failed @ card %d", av7110->dvb_adapter.num); |
600 | break; | 600 | break; |
601 | } | 601 | } |
602 | i += 2; | 602 | i += 2; |
@@ -726,11 +726,11 @@ static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) | |||
726 | { | 726 | { |
727 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; | 727 | struct av7110 *av7110 = (struct av7110*) dev->ext_priv; |
728 | 728 | ||
729 | if (std->id == V4L2_STD_PAL) { | 729 | if (std->id & V4L2_STD_PAL) { |
730 | av7110->vidmode = VIDEO_MODE_PAL; | 730 | av7110->vidmode = VIDEO_MODE_PAL; |
731 | av7110_set_vidmode(av7110, av7110->vidmode); | 731 | av7110_set_vidmode(av7110, av7110->vidmode); |
732 | } | 732 | } |
733 | else if (std->id == V4L2_STD_NTSC) { | 733 | else if (std->id & V4L2_STD_NTSC) { |
734 | av7110->vidmode = VIDEO_MODE_NTSC; | 734 | av7110->vidmode = VIDEO_MODE_NTSC; |
735 | av7110_set_vidmode(av7110, av7110->vidmode); | 735 | av7110_set_vidmode(av7110, av7110->vidmode); |
736 | } | 736 | } |
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c index 14e963206b89..6e0f5d307c52 100644 --- a/drivers/media/dvb/ttpci/budget-av.c +++ b/drivers/media/dvb/ttpci/budget-av.c | |||
@@ -59,8 +59,12 @@ struct budget_av { | |||
59 | struct dvb_ca_en50221 ca; | 59 | struct dvb_ca_en50221 ca; |
60 | }; | 60 | }; |
61 | 61 | ||
62 | static int enable_ci = 0; | 62 | /* GPIO CI Connections: |
63 | 63 | * 0 - Vcc/Reset (Reset is controlled by capacitor) | |
64 | * 1 - Attribute Memory | ||
65 | * 2 - Card Enable (Active Low) | ||
66 | * 3 - Card Detect | ||
67 | */ | ||
64 | 68 | ||
65 | /**************************************************************************** | 69 | /**************************************************************************** |
66 | * INITIALIZATION | 70 | * INITIALIZATION |
@@ -188,22 +192,35 @@ static int ciintf_slot_reset(struct dvb_ca_en50221 *ca, int slot) | |||
188 | { | 192 | { |
189 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 193 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
190 | struct saa7146_dev *saa = budget_av->budget.dev; | 194 | struct saa7146_dev *saa = budget_av->budget.dev; |
191 | int max = 20; | 195 | int timeout = 50; // 5 seconds (4.4.6 Ready) |
192 | 196 | ||
193 | if (slot != 0) | 197 | if (slot != 0) |
194 | return -EINVAL; | 198 | return -EINVAL; |
195 | 199 | ||
196 | dprintk(1, "ciintf_slot_reset\n"); | 200 | dprintk(1, "ciintf_slot_reset\n"); |
197 | 201 | ||
198 | /* reset the card */ | 202 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ |
199 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); | ||
200 | msleep(100); | ||
201 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
202 | 203 | ||
203 | while (--max > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) | 204 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ |
205 | msleep(2); | ||
206 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); /* Vcc on */ | ||
207 | msleep(20); /* 20 ms Vcc settling time */ | ||
208 | |||
209 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); /* enable card */ | ||
210 | |||
211 | /* This should have been based on pin 16 READY of the pcmcia port, | ||
212 | * but AFAICS it is not routed to the saa7146 */ | ||
213 | while (--timeout > 0 && ciintf_read_attribute_mem(ca, slot, 0) != 0x1d) | ||
204 | msleep(100); | 214 | msleep(100); |
205 | 215 | ||
206 | ttpci_budget_set_video_port(saa, BUDGET_VIDEO_PORTB); | 216 | if (timeout <= 0) |
217 | { | ||
218 | printk(KERN_ERR "budget-av: cam reset failed (timeout).\n"); | ||
219 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | ||
220 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ | ||
221 | return -ETIMEDOUT; | ||
222 | } | ||
223 | |||
207 | return 0; | 224 | return 0; |
208 | } | 225 | } |
209 | 226 | ||
@@ -240,7 +257,6 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
240 | { | 257 | { |
241 | struct budget_av *budget_av = (struct budget_av *) ca->data; | 258 | struct budget_av *budget_av = (struct budget_av *) ca->data; |
242 | struct saa7146_dev *saa = budget_av->budget.dev; | 259 | struct saa7146_dev *saa = budget_av->budget.dev; |
243 | int cam = 0; | ||
244 | 260 | ||
245 | if (slot != 0) | 261 | if (slot != 0) |
246 | return -EINVAL; | 262 | return -EINVAL; |
@@ -248,15 +264,21 @@ static int ciintf_poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open | |||
248 | if (!budget_av->slot_status) { | 264 | if (!budget_av->slot_status) { |
249 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); | 265 | saa7146_setgpio(saa, 3, SAA7146_GPIO_INPUT); |
250 | udelay(1); | 266 | udelay(1); |
251 | cam = saa7146_read(saa, PSR) & MASK_06; | 267 | if (saa7146_read(saa, PSR) & MASK_06) |
252 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 268 | { |
253 | 269 | printk(KERN_INFO "budget-av: cam inserted\n"); | |
254 | if (cam) | ||
255 | budget_av->slot_status = 1; | 270 | budget_av->slot_status = 1; |
271 | } | ||
272 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | ||
256 | } else if (!open) { | 273 | } else if (!open) { |
257 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); | 274 | saa7146_setgpio(budget_av->budget.dev, 1, SAA7146_GPIO_OUTLO); |
258 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) | 275 | if (ttpci_budget_debiread(&budget_av->budget, DEBICICAM, 0, 1, 0, 1) == -ETIMEDOUT) |
276 | { | ||
277 | printk(KERN_INFO "budget-av: cam ejected\n"); | ||
278 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTHI); /* disable card */ | ||
279 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); /* Vcc off */ | ||
259 | budget_av->slot_status = 0; | 280 | budget_av->slot_status = 0; |
281 | } | ||
260 | } | 282 | } |
261 | 283 | ||
262 | if (budget_av->slot_status == 1) | 284 | if (budget_av->slot_status == 1) |
@@ -272,17 +294,11 @@ static int ciintf_init(struct budget_av *budget_av) | |||
272 | 294 | ||
273 | memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); | 295 | memset(&budget_av->ca, 0, sizeof(struct dvb_ca_en50221)); |
274 | 296 | ||
275 | /* setup GPIOs */ | 297 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); |
276 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTHI); | 298 | saa7146_setgpio(saa, 1, SAA7146_GPIO_OUTLO); |
277 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); | 299 | saa7146_setgpio(saa, 2, SAA7146_GPIO_OUTLO); |
278 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); | 300 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTLO); |
279 | 301 | ||
280 | /* Reset the card */ | ||
281 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); | ||
282 | msleep(50); | ||
283 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTLO); | ||
284 | msleep(100); | ||
285 | |||
286 | /* Enable DEBI pins */ | 302 | /* Enable DEBI pins */ |
287 | saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); | 303 | saa7146_write(saa, MC1, saa7146_read(saa, MC1) | (0x800 << 16) | 0x800); |
288 | 304 | ||
@@ -297,13 +313,14 @@ static int ciintf_init(struct budget_av *budget_av) | |||
297 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; | 313 | budget_av->ca.slot_ts_enable = ciintf_slot_ts_enable; |
298 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; | 314 | budget_av->ca.poll_slot_status = ciintf_poll_slot_status; |
299 | budget_av->ca.data = budget_av; | 315 | budget_av->ca.data = budget_av; |
300 | if ((result = dvb_ca_en50221_init(budget_av->budget.dvb_adapter, | 316 | |
317 | if ((result = dvb_ca_en50221_init(&budget_av->budget.dvb_adapter, | ||
301 | &budget_av->ca, 0, 1)) != 0) { | 318 | &budget_av->ca, 0, 1)) != 0) { |
302 | printk("budget_av: CI interface detected, but initialisation failed.\n"); | 319 | printk(KERN_ERR "budget-av: ci initialisation failed.\n"); |
303 | goto error; | 320 | goto error; |
304 | } | 321 | } |
305 | // success! | 322 | |
306 | printk("ciintf_init: CI interface initialised\n"); | 323 | printk(KERN_INFO "budget-av: ci interface initialised.\n"); |
307 | budget_av->budget.ci_present = 1; | 324 | budget_av->budget.ci_present = 1; |
308 | return 0; | 325 | return 0; |
309 | 326 | ||
@@ -361,8 +378,12 @@ static const u8 saa7113_tab[] = { | |||
361 | static int saa7113_init(struct budget_av *budget_av) | 378 | static int saa7113_init(struct budget_av *budget_av) |
362 | { | 379 | { |
363 | struct budget *budget = &budget_av->budget; | 380 | struct budget *budget = &budget_av->budget; |
381 | struct saa7146_dev *saa = budget->dev; | ||
364 | const u8 *data = saa7113_tab; | 382 | const u8 *data = saa7113_tab; |
365 | 383 | ||
384 | saa7146_setgpio(saa, 0, SAA7146_GPIO_OUTHI); | ||
385 | msleep(200); | ||
386 | |||
366 | if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { | 387 | if (i2c_writereg(&budget->i2c_adap, 0x4a, 0x01, 0x08) != 1) { |
367 | dprintk(1, "saa7113 not found on KNC card\n"); | 388 | dprintk(1, "saa7113 not found on KNC card\n"); |
368 | return -ENODEV; | 389 | return -ENODEV; |
@@ -697,75 +718,90 @@ static u8 read_pwm(struct budget_av *budget_av) | |||
697 | return pwm; | 718 | return pwm; |
698 | } | 719 | } |
699 | 720 | ||
721 | #define SUBID_DVBS_KNC1 0x0010 | ||
722 | #define SUBID_DVBS_KNC1_PLUS 0x0011 | ||
723 | #define SUBID_DVBS_TYPHOON 0x4f56 | ||
724 | #define SUBID_DVBS_CINERGY1200 0x1154 | ||
725 | |||
726 | #define SUBID_DVBC_KNC1 0x0020 | ||
727 | #define SUBID_DVBC_KNC1_PLUS 0x0021 | ||
728 | #define SUBID_DVBC_CINERGY1200 0x1156 | ||
729 | |||
730 | #define SUBID_DVBT_KNC1_PLUS 0x0031 | ||
731 | #define SUBID_DVBT_KNC1 0x0030 | ||
732 | #define SUBID_DVBT_CINERGY1200 0x1157 | ||
700 | 733 | ||
701 | static void frontend_init(struct budget_av *budget_av) | 734 | static void frontend_init(struct budget_av *budget_av) |
702 | { | 735 | { |
703 | switch (budget_av->budget.dev->pci->subsystem_device) { | 736 | struct saa7146_dev * saa = budget_av->budget.dev; |
704 | case 0x4f56: // Typhoon/KNC1 DVB-S budget (stv0299/Philips SU1278(tsa5059)) | 737 | struct dvb_frontend * fe = NULL; |
705 | budget_av->budget.dvb_frontend = | 738 | |
706 | stv0299_attach(&typhoon_config, &budget_av->budget.i2c_adap); | 739 | switch (saa->pci->subsystem_device) { |
707 | if (budget_av->budget.dvb_frontend != NULL) { | 740 | case SUBID_DVBS_KNC1_PLUS: |
741 | case SUBID_DVBC_KNC1_PLUS: | ||
742 | case SUBID_DVBT_KNC1_PLUS: | ||
743 | // Enable / PowerON Frontend | ||
744 | saa7146_setgpio(saa, 3, SAA7146_GPIO_OUTHI); | ||
708 | break; | 745 | break; |
709 | } | 746 | } |
747 | |||
748 | switch (saa->pci->subsystem_device) { | ||
749 | |||
750 | case SUBID_DVBS_KNC1: | ||
751 | case SUBID_DVBS_KNC1_PLUS: | ||
752 | case SUBID_DVBS_TYPHOON: | ||
753 | fe = stv0299_attach(&typhoon_config, | ||
754 | &budget_av->budget.i2c_adap); | ||
710 | break; | 755 | break; |
711 | 756 | ||
712 | case 0x0020: // KNC1 DVB-C budget (tda10021/Philips CU1216(tua6034)) | 757 | case SUBID_DVBS_CINERGY1200: |
713 | budget_av->budget.dvb_frontend = | 758 | fe = stv0299_attach(&cinergy_1200s_config, |
714 | tda10021_attach(&philips_cu1216_config, | 759 | &budget_av->budget.i2c_adap); |
715 | &budget_av->budget.i2c_adap, read_pwm(budget_av)); | ||
716 | if (budget_av->budget.dvb_frontend != NULL) { | ||
717 | break; | ||
718 | } | ||
719 | break; | 760 | break; |
720 | 761 | ||
721 | case 0x0030: // KNC1 DVB-T budget (tda10046/Philips TU1216(tda6651tt)) | 762 | case SUBID_DVBC_KNC1: |
722 | budget_av->budget.dvb_frontend = | 763 | case SUBID_DVBC_KNC1_PLUS: |
723 | tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap); | 764 | fe = tda10021_attach(&philips_cu1216_config, |
724 | if (budget_av->budget.dvb_frontend != NULL) { | 765 | &budget_av->budget.i2c_adap, |
725 | break; | 766 | read_pwm(budget_av)); |
726 | } | ||
727 | break; | 767 | break; |
728 | 768 | ||
729 | case 0x1154: // TerraTec Cinergy 1200 DVB-S (stv0299/Philips SU1278(tsa5059)) | 769 | case SUBID_DVBT_KNC1: |
730 | budget_av->budget.dvb_frontend = | 770 | case SUBID_DVBT_KNC1_PLUS: |
731 | stv0299_attach(&cinergy_1200s_config, &budget_av->budget.i2c_adap); | 771 | fe = tda10046_attach(&philips_tu1216_config, |
732 | if (budget_av->budget.dvb_frontend != NULL) { | 772 | &budget_av->budget.i2c_adap); |
733 | break; | ||
734 | } | ||
735 | break; | 773 | break; |
736 | 774 | ||
737 | case 0x1156: // Terratec Cinergy 1200 DVB-C (tda10021/Philips CU1216(tua6034)) | 775 | case SUBID_DVBC_CINERGY1200: |
738 | budget_av->budget.dvb_frontend = | 776 | fe = tda10021_attach(&philips_cu1216_config, |
739 | tda10021_attach(&philips_cu1216_config, | 777 | &budget_av->budget.i2c_adap, |
740 | &budget_av->budget.i2c_adap, read_pwm(budget_av)); | 778 | read_pwm(budget_av)); |
741 | if (budget_av->budget.dvb_frontend) { | ||
742 | break; | ||
743 | } | ||
744 | break; | 779 | break; |
745 | 780 | ||
746 | case 0x1157: // Terratec Cinergy 1200 DVB-T (tda10046/Philips TU1216(tda6651tt)) | 781 | case SUBID_DVBT_CINERGY1200: |
747 | budget_av->budget.dvb_frontend = | 782 | fe = tda10046_attach(&philips_tu1216_config, |
748 | tda10046_attach(&philips_tu1216_config, &budget_av->budget.i2c_adap); | 783 | &budget_av->budget.i2c_adap); |
749 | if (budget_av->budget.dvb_frontend) { | ||
750 | break; | ||
751 | } | ||
752 | break; | 784 | break; |
753 | } | 785 | } |
754 | 786 | ||
755 | if (budget_av->budget.dvb_frontend == NULL) { | 787 | if (fe == NULL) { |
756 | printk("budget_av: A frontend driver was not found for device %04x/%04x subsystem %04x/%04x\n", | 788 | printk(KERN_ERR "budget-av: A frontend driver was not found " |
757 | budget_av->budget.dev->pci->vendor, | 789 | "for device %04x/%04x subsystem %04x/%04x\n", |
758 | budget_av->budget.dev->pci->device, | 790 | saa->pci->vendor, |
759 | budget_av->budget.dev->pci->subsystem_vendor, | 791 | saa->pci->device, |
760 | budget_av->budget.dev->pci->subsystem_device); | 792 | saa->pci->subsystem_vendor, |
761 | } else { | 793 | saa->pci->subsystem_device); |
762 | if (dvb_register_frontend | 794 | return; |
763 | (budget_av->budget.dvb_adapter, budget_av->budget.dvb_frontend)) { | 795 | } |
764 | printk("budget-av: Frontend registration failed!\n"); | 796 | |
765 | if (budget_av->budget.dvb_frontend->ops->release) | 797 | budget_av->budget.dvb_frontend = fe; |
766 | budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); | 798 | |
767 | budget_av->budget.dvb_frontend = NULL; | 799 | if (dvb_register_frontend(&budget_av->budget.dvb_adapter, |
768 | } | 800 | budget_av->budget.dvb_frontend)) { |
801 | printk(KERN_ERR "budget-av: Frontend registration failed!\n"); | ||
802 | if (budget_av->budget.dvb_frontend->ops->release) | ||
803 | budget_av->budget.dvb_frontend->ops->release(budget_av->budget.dvb_frontend); | ||
804 | budget_av->budget.dvb_frontend = NULL; | ||
769 | } | 805 | } |
770 | } | 806 | } |
771 | 807 | ||
@@ -822,6 +858,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
822 | 858 | ||
823 | memset(budget_av, 0, sizeof(struct budget_av)); | 859 | memset(budget_av, 0, sizeof(struct budget_av)); |
824 | 860 | ||
861 | budget_av->has_saa7113 = 0; | ||
825 | budget_av->budget.ci_present = 0; | 862 | budget_av->budget.ci_present = 0; |
826 | 863 | ||
827 | dev->ext_priv = budget_av; | 864 | dev->ext_priv = budget_av; |
@@ -836,10 +873,7 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
836 | saa7146_write(dev, DD1_INIT, 0x07000600); | 873 | saa7146_write(dev, DD1_INIT, 0x07000600); |
837 | saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); | 874 | saa7146_write(dev, MC2, MASK_09 | MASK_25 | MASK_10 | MASK_26); |
838 | 875 | ||
839 | saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI); | 876 | if (saa7113_init(budget_av) == 0) { |
840 | msleep(500); | ||
841 | |||
842 | if (0 == saa7113_init(budget_av)) { | ||
843 | budget_av->has_saa7113 = 1; | 877 | budget_av->has_saa7113 = 1; |
844 | 878 | ||
845 | if (0 != saa7146_vv_init(dev, &vv_data)) { | 879 | if (0 != saa7146_vv_init(dev, &vv_data)) { |
@@ -860,31 +894,26 @@ static int budget_av_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
860 | 894 | ||
861 | saa7113_setinput(budget_av, 0); | 895 | saa7113_setinput(budget_av, 0); |
862 | } else { | 896 | } else { |
863 | budget_av->has_saa7113 = 0; | 897 | ciintf_init(budget_av); |
864 | |||
865 | saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTLO); | ||
866 | } | 898 | } |
867 | 899 | ||
868 | /* fixme: find some sane values here... */ | 900 | /* fixme: find some sane values here... */ |
869 | saa7146_write(dev, PCI_BT_V1, 0x1c00101f); | 901 | saa7146_write(dev, PCI_BT_V1, 0x1c00101f); |
870 | 902 | ||
871 | mac = budget_av->budget.dvb_adapter->proposed_mac; | 903 | mac = budget_av->budget.dvb_adapter.proposed_mac; |
872 | if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { | 904 | if (i2c_readregs(&budget_av->budget.i2c_adap, 0xa0, 0x30, mac, 6)) { |
873 | printk("KNC1-%d: Could not read MAC from KNC1 card\n", | 905 | printk(KERN_ERR "KNC1-%d: Could not read MAC from KNC1 card\n", |
874 | budget_av->budget.dvb_adapter->num); | 906 | budget_av->budget.dvb_adapter.num); |
875 | memset(mac, 0, 6); | 907 | memset(mac, 0, 6); |
876 | } else { | 908 | } else { |
877 | printk("KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", | 909 | printk(KERN_INFO "KNC1-%d: MAC addr = %.2x:%.2x:%.2x:%.2x:%.2x:%.2x\n", |
878 | budget_av->budget.dvb_adapter->num, | 910 | budget_av->budget.dvb_adapter.num, |
879 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); | 911 | mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); |
880 | } | 912 | } |
881 | 913 | ||
882 | budget_av->budget.dvb_adapter->priv = budget_av; | 914 | budget_av->budget.dvb_adapter.priv = budget_av; |
883 | frontend_init(budget_av); | 915 | frontend_init(budget_av); |
884 | 916 | ||
885 | if (enable_ci) | ||
886 | ciintf_init(budget_av); | ||
887 | |||
888 | return 0; | 917 | return 0; |
889 | } | 918 | } |
890 | 919 | ||
@@ -963,14 +992,21 @@ static struct saa7146_extension budget_extension; | |||
963 | MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); | 992 | MAKE_BUDGET_INFO(knc1s, "KNC1 DVB-S", BUDGET_KNC1S); |
964 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); | 993 | MAKE_BUDGET_INFO(knc1c, "KNC1 DVB-C", BUDGET_KNC1C); |
965 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); | 994 | MAKE_BUDGET_INFO(knc1t, "KNC1 DVB-T", BUDGET_KNC1T); |
995 | MAKE_BUDGET_INFO(knc1sp, "KNC1 DVB-S Plus", BUDGET_KNC1SP); | ||
996 | MAKE_BUDGET_INFO(knc1cp, "KNC1 DVB-C Plus", BUDGET_KNC1CP); | ||
997 | MAKE_BUDGET_INFO(knc1tp, "KNC1 DVB-T Plus", BUDGET_KNC1TP); | ||
966 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); | 998 | MAKE_BUDGET_INFO(cin1200s, "TerraTec Cinergy 1200 DVB-S", BUDGET_CIN1200S); |
967 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); | 999 | MAKE_BUDGET_INFO(cin1200c, "Terratec Cinergy 1200 DVB-C", BUDGET_CIN1200C); |
968 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); | 1000 | MAKE_BUDGET_INFO(cin1200t, "Terratec Cinergy 1200 DVB-T", BUDGET_CIN1200T); |
969 | 1001 | ||
970 | static struct pci_device_id pci_tbl[] = { | 1002 | static struct pci_device_id pci_tbl[] = { |
971 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), | 1003 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x4f56), |
1004 | MAKE_EXTENSION_PCI(knc1s, 0x1131, 0x0010), | ||
1005 | MAKE_EXTENSION_PCI(knc1sp, 0x1131, 0x0011), | ||
972 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), | 1006 | MAKE_EXTENSION_PCI(knc1c, 0x1894, 0x0020), |
1007 | MAKE_EXTENSION_PCI(knc1cp, 0x1894, 0x0021), | ||
973 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), | 1008 | MAKE_EXTENSION_PCI(knc1t, 0x1894, 0x0030), |
1009 | MAKE_EXTENSION_PCI(knc1tp, 0x1894, 0x0031), | ||
974 | MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), | 1010 | MAKE_EXTENSION_PCI(cin1200s, 0x153b, 0x1154), |
975 | MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), | 1011 | MAKE_EXTENSION_PCI(cin1200c, 0x153b, 0x1156), |
976 | MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), | 1012 | MAKE_EXTENSION_PCI(cin1200t, 0x153b, 0x1157), |
@@ -1010,5 +1046,3 @@ MODULE_LICENSE("GPL"); | |||
1010 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); | 1046 | MODULE_AUTHOR("Ralph Metzler, Marcus Metzler, Michael Hunold, others"); |
1011 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " | 1047 | MODULE_DESCRIPTION("driver for the SAA7146 based so-called " |
1012 | "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); | 1048 | "budget PCI DVB w/ analog input and CI-module (e.g. the KNC cards)"); |
1013 | module_param_named(enable_ci, enable_ci, int, 0644); | ||
1014 | MODULE_PARM_DESC(enable_ci, "Turn on/off CI module (default:off)."); | ||
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c index 521111be3558..dce116111376 100644 --- a/drivers/media/dvb/ttpci/budget-ci.c +++ b/drivers/media/dvb/ttpci/budget-ci.c | |||
@@ -395,7 +395,7 @@ static int ciintf_init(struct budget_ci *budget_ci) | |||
395 | budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; | 395 | budget_ci->ca.slot_shutdown = ciintf_slot_shutdown; |
396 | budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; | 396 | budget_ci->ca.slot_ts_enable = ciintf_slot_ts_enable; |
397 | budget_ci->ca.data = budget_ci; | 397 | budget_ci->ca.data = budget_ci; |
398 | if ((result = dvb_ca_en50221_init(budget_ci->budget.dvb_adapter, | 398 | if ((result = dvb_ca_en50221_init(&budget_ci->budget.dvb_adapter, |
399 | &budget_ci->ca, | 399 | &budget_ci->ca, |
400 | DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | | 400 | DVB_CA_EN50221_FLAG_IRQ_CAMCHANGE | |
401 | DVB_CA_EN50221_FLAG_IRQ_FR | | 401 | DVB_CA_EN50221_FLAG_IRQ_FR | |
@@ -881,7 +881,7 @@ static void frontend_init(struct budget_ci *budget_ci) | |||
881 | budget_ci->budget.dev->pci->subsystem_device); | 881 | budget_ci->budget.dev->pci->subsystem_device); |
882 | } else { | 882 | } else { |
883 | if (dvb_register_frontend | 883 | if (dvb_register_frontend |
884 | (budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { | 884 | (&budget_ci->budget.dvb_adapter, budget_ci->budget.dvb_frontend)) { |
885 | printk("budget-ci: Frontend registration failed!\n"); | 885 | printk("budget-ci: Frontend registration failed!\n"); |
886 | if (budget_ci->budget.dvb_frontend->ops->release) | 886 | if (budget_ci->budget.dvb_frontend->ops->release) |
887 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); | 887 | budget_ci->budget.dvb_frontend->ops->release(budget_ci->budget.dvb_frontend); |
@@ -916,7 +916,7 @@ static int budget_ci_attach(struct saa7146_dev *dev, struct saa7146_pci_extensio | |||
916 | 916 | ||
917 | ciintf_init(budget_ci); | 917 | ciintf_init(budget_ci); |
918 | 918 | ||
919 | budget_ci->budget.dvb_adapter->priv = budget_ci; | 919 | budget_ci->budget.dvb_adapter.priv = budget_ci; |
920 | frontend_init(budget_ci); | 920 | frontend_init(budget_ci); |
921 | 921 | ||
922 | return 0; | 922 | return 0; |
diff --git a/drivers/media/dvb/ttpci/budget-core.c b/drivers/media/dvb/ttpci/budget-core.c index 93a9b40917e4..0498a055a4cd 100644 --- a/drivers/media/dvb/ttpci/budget-core.c +++ b/drivers/media/dvb/ttpci/budget-core.c | |||
@@ -298,7 +298,7 @@ static int budget_register(struct budget *budget) | |||
298 | budget->dmxdev.demux = &dvbdemux->dmx; | 298 | budget->dmxdev.demux = &dvbdemux->dmx; |
299 | budget->dmxdev.capabilities = 0; | 299 | budget->dmxdev.capabilities = 0; |
300 | 300 | ||
301 | dvb_dmxdev_init(&budget->dmxdev, budget->dvb_adapter); | 301 | dvb_dmxdev_init(&budget->dmxdev, &budget->dvb_adapter); |
302 | 302 | ||
303 | budget->hw_frontend.source = DMX_FRONTEND_0; | 303 | budget->hw_frontend.source = DMX_FRONTEND_0; |
304 | 304 | ||
@@ -316,7 +316,7 @@ static int budget_register(struct budget *budget) | |||
316 | if (ret < 0) | 316 | if (ret < 0) |
317 | return ret; | 317 | return ret; |
318 | 318 | ||
319 | dvb_net_init(budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); | 319 | dvb_net_init(&budget->dvb_adapter, &budget->dvb_net, &dvbdemux->dmx); |
320 | 320 | ||
321 | return 0; | 321 | return 0; |
322 | } | 322 | } |
@@ -385,11 +385,11 @@ int ttpci_budget_init(struct budget *budget, struct saa7146_dev *dev, | |||
385 | strcpy(budget->i2c_adap.name, budget->card->name); | 385 | strcpy(budget->i2c_adap.name, budget->card->name); |
386 | 386 | ||
387 | if (i2c_add_adapter(&budget->i2c_adap) < 0) { | 387 | if (i2c_add_adapter(&budget->i2c_adap) < 0) { |
388 | dvb_unregister_adapter(budget->dvb_adapter); | 388 | dvb_unregister_adapter(&budget->dvb_adapter); |
389 | return -ENOMEM; | 389 | return -ENOMEM; |
390 | } | 390 | } |
391 | 391 | ||
392 | ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter->proposed_mac); | 392 | ttpci_eeprom_parse_mac(&budget->i2c_adap, budget->dvb_adapter.proposed_mac); |
393 | 393 | ||
394 | if (NULL == | 394 | if (NULL == |
395 | (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) { | 395 | (budget->grabbing = saa7146_vmalloc_build_pgtable(dev->pci, length, &budget->pt))) { |
@@ -417,7 +417,7 @@ err: | |||
417 | 417 | ||
418 | vfree(budget->grabbing); | 418 | vfree(budget->grabbing); |
419 | 419 | ||
420 | dvb_unregister_adapter(budget->dvb_adapter); | 420 | dvb_unregister_adapter(&budget->dvb_adapter); |
421 | 421 | ||
422 | return ret; | 422 | return ret; |
423 | } | 423 | } |
@@ -432,7 +432,7 @@ int ttpci_budget_deinit(struct budget *budget) | |||
432 | 432 | ||
433 | i2c_del_adapter(&budget->i2c_adap); | 433 | i2c_del_adapter(&budget->i2c_adap); |
434 | 434 | ||
435 | dvb_unregister_adapter(budget->dvb_adapter); | 435 | dvb_unregister_adapter(&budget->dvb_adapter); |
436 | 436 | ||
437 | tasklet_kill(&budget->vpe_tasklet); | 437 | tasklet_kill(&budget->vpe_tasklet); |
438 | 438 | ||
diff --git a/drivers/media/dvb/ttpci/budget-patch.c b/drivers/media/dvb/ttpci/budget-patch.c index 5d524a4f213f..8142e26b47f5 100644 --- a/drivers/media/dvb/ttpci/budget-patch.c +++ b/drivers/media/dvb/ttpci/budget-patch.c | |||
@@ -453,7 +453,7 @@ static void frontend_init(struct budget_patch* budget) | |||
453 | budget->dev->pci->subsystem_vendor, | 453 | budget->dev->pci->subsystem_vendor, |
454 | budget->dev->pci->subsystem_device); | 454 | budget->dev->pci->subsystem_device); |
455 | } else { | 455 | } else { |
456 | if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) { | 456 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { |
457 | printk("budget-av: Frontend registration failed!\n"); | 457 | printk("budget-av: Frontend registration failed!\n"); |
458 | if (budget->dvb_frontend->ops->release) | 458 | if (budget->dvb_frontend->ops->release) |
459 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 459 | budget->dvb_frontend->ops->release(budget->dvb_frontend); |
@@ -702,7 +702,7 @@ static int budget_patch_attach (struct saa7146_dev* dev, struct saa7146_pci_exte | |||
702 | 702 | ||
703 | dev->ext_priv = budget; | 703 | dev->ext_priv = budget; |
704 | 704 | ||
705 | budget->dvb_adapter->priv = budget; | 705 | budget->dvb_adapter.priv = budget; |
706 | frontend_init(budget); | 706 | frontend_init(budget); |
707 | 707 | ||
708 | return 0; | 708 | return 0; |
diff --git a/drivers/media/dvb/ttpci/budget.c b/drivers/media/dvb/ttpci/budget.c index 5e6a10f4ad95..083fd44e5f90 100644 --- a/drivers/media/dvb/ttpci/budget.c +++ b/drivers/media/dvb/ttpci/budget.c | |||
@@ -468,7 +468,7 @@ static void frontend_init(struct budget *budget) | |||
468 | budget->dev->pci->subsystem_vendor, | 468 | budget->dev->pci->subsystem_vendor, |
469 | budget->dev->pci->subsystem_device); | 469 | budget->dev->pci->subsystem_device); |
470 | } else { | 470 | } else { |
471 | if (dvb_register_frontend(budget->dvb_adapter, budget->dvb_frontend)) { | 471 | if (dvb_register_frontend(&budget->dvb_adapter, budget->dvb_frontend)) { |
472 | printk("budget: Frontend registration failed!\n"); | 472 | printk("budget: Frontend registration failed!\n"); |
473 | if (budget->dvb_frontend->ops->release) | 473 | if (budget->dvb_frontend->ops->release) |
474 | budget->dvb_frontend->ops->release(budget->dvb_frontend); | 474 | budget->dvb_frontend->ops->release(budget->dvb_frontend); |
@@ -497,7 +497,7 @@ static int budget_attach (struct saa7146_dev* dev, struct saa7146_pci_extension_ | |||
497 | return err; | 497 | return err; |
498 | } | 498 | } |
499 | 499 | ||
500 | budget->dvb_adapter->priv = budget; | 500 | budget->dvb_adapter.priv = budget; |
501 | frontend_init(budget); | 501 | frontend_init(budget); |
502 | 502 | ||
503 | return 0; | 503 | return 0; |
diff --git a/drivers/media/dvb/ttpci/budget.h b/drivers/media/dvb/ttpci/budget.h index 10bd41f0363b..c6ef496ba70a 100644 --- a/drivers/media/dvb/ttpci/budget.h +++ b/drivers/media/dvb/ttpci/budget.h | |||
@@ -64,7 +64,7 @@ struct budget { | |||
64 | 64 | ||
65 | spinlock_t debilock; | 65 | spinlock_t debilock; |
66 | 66 | ||
67 | struct dvb_adapter *dvb_adapter; | 67 | struct dvb_adapter dvb_adapter; |
68 | struct dvb_frontend *dvb_frontend; | 68 | struct dvb_frontend *dvb_frontend; |
69 | void *priv; | 69 | void *priv; |
70 | }; | 70 | }; |
@@ -92,6 +92,9 @@ static struct saa7146_pci_extension_data x_var = { \ | |||
92 | #define BUDGET_KNC1S 8 | 92 | #define BUDGET_KNC1S 8 |
93 | #define BUDGET_KNC1C 9 | 93 | #define BUDGET_KNC1C 9 |
94 | #define BUDGET_KNC1T 10 | 94 | #define BUDGET_KNC1T 10 |
95 | #define BUDGET_KNC1SP 11 | ||
96 | #define BUDGET_KNC1CP 12 | ||
97 | #define BUDGET_KNC1TP 13 | ||
95 | 98 | ||
96 | #define BUDGET_VIDEO_PORTA 0 | 99 | #define BUDGET_VIDEO_PORTA 0 |
97 | #define BUDGET_VIDEO_PORTB 1 | 100 | #define BUDGET_VIDEO_PORTB 1 |
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c index 4c046ece883a..afa0e7a0e506 100644 --- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c +++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c | |||
@@ -84,7 +84,7 @@ struct ttusb { | |||
84 | struct semaphore semi2c; | 84 | struct semaphore semi2c; |
85 | struct semaphore semusb; | 85 | struct semaphore semusb; |
86 | 86 | ||
87 | struct dvb_adapter *adapter; | 87 | struct dvb_adapter adapter; |
88 | struct usb_device *dev; | 88 | struct usb_device *dev; |
89 | 89 | ||
90 | struct i2c_adapter i2c_adap; | 90 | struct i2c_adapter i2c_adap; |
@@ -1065,7 +1065,7 @@ static int alps_tdmb7_pll_set(struct dvb_frontend* fe, struct dvb_frontend_param | |||
1065 | return 0; | 1065 | return 0; |
1066 | } | 1066 | } |
1067 | 1067 | ||
1068 | struct cx22700_config alps_tdmb7_config = { | 1068 | static struct cx22700_config alps_tdmb7_config = { |
1069 | .demod_address = 0x43, | 1069 | .demod_address = 0x43, |
1070 | .pll_set = alps_tdmb7_pll_set, | 1070 | .pll_set = alps_tdmb7_pll_set, |
1071 | }; | 1071 | }; |
@@ -1412,7 +1412,7 @@ static void frontend_init(struct ttusb* ttusb) | |||
1412 | le16_to_cpu(ttusb->dev->descriptor.idVendor), | 1412 | le16_to_cpu(ttusb->dev->descriptor.idVendor), |
1413 | le16_to_cpu(ttusb->dev->descriptor.idProduct)); | 1413 | le16_to_cpu(ttusb->dev->descriptor.idProduct)); |
1414 | } else { | 1414 | } else { |
1415 | if (dvb_register_frontend(ttusb->adapter, ttusb->fe)) { | 1415 | if (dvb_register_frontend(&ttusb->adapter, ttusb->fe)) { |
1416 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); | 1416 | printk("dvb-ttusb-budget: Frontend registration failed!\n"); |
1417 | if (ttusb->fe->ops->release) | 1417 | if (ttusb->fe->ops->release) |
1418 | ttusb->fe->ops->release(ttusb->fe); | 1418 | ttusb->fe->ops->release(ttusb->fe); |
@@ -1462,7 +1462,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1462 | up(&ttusb->semi2c); | 1462 | up(&ttusb->semi2c); |
1463 | 1463 | ||
1464 | dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); | 1464 | dvb_register_adapter(&ttusb->adapter, "Technotrend/Hauppauge Nova-USB", THIS_MODULE); |
1465 | ttusb->adapter->priv = ttusb; | 1465 | ttusb->adapter.priv = ttusb; |
1466 | 1466 | ||
1467 | /* i2c */ | 1467 | /* i2c */ |
1468 | memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter)); | 1468 | memset(&ttusb->i2c_adap, 0, sizeof(struct i2c_adapter)); |
@@ -1481,7 +1481,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1481 | 1481 | ||
1482 | result = i2c_add_adapter(&ttusb->i2c_adap); | 1482 | result = i2c_add_adapter(&ttusb->i2c_adap); |
1483 | if (result) { | 1483 | if (result) { |
1484 | dvb_unregister_adapter (ttusb->adapter); | 1484 | dvb_unregister_adapter (&ttusb->adapter); |
1485 | return result; | 1485 | return result; |
1486 | } | 1486 | } |
1487 | 1487 | ||
@@ -1503,7 +1503,7 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1503 | if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) { | 1503 | if ((result = dvb_dmx_init(&ttusb->dvb_demux)) < 0) { |
1504 | printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result); | 1504 | printk("ttusb_dvb: dvb_dmx_init failed (errno = %d)\n", result); |
1505 | i2c_del_adapter(&ttusb->i2c_adap); | 1505 | i2c_del_adapter(&ttusb->i2c_adap); |
1506 | dvb_unregister_adapter (ttusb->adapter); | 1506 | dvb_unregister_adapter (&ttusb->adapter); |
1507 | return -ENODEV; | 1507 | return -ENODEV; |
1508 | } | 1508 | } |
1509 | //FIXME dmxdev (nur WAS?) | 1509 | //FIXME dmxdev (nur WAS?) |
@@ -1511,21 +1511,21 @@ static int ttusb_probe(struct usb_interface *intf, const struct usb_device_id *i | |||
1511 | ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx; | 1511 | ttusb->dmxdev.demux = &ttusb->dvb_demux.dmx; |
1512 | ttusb->dmxdev.capabilities = 0; | 1512 | ttusb->dmxdev.capabilities = 0; |
1513 | 1513 | ||
1514 | if ((result = dvb_dmxdev_init(&ttusb->dmxdev, ttusb->adapter)) < 0) { | 1514 | if ((result = dvb_dmxdev_init(&ttusb->dmxdev, &ttusb->adapter)) < 0) { |
1515 | printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n", | 1515 | printk("ttusb_dvb: dvb_dmxdev_init failed (errno = %d)\n", |
1516 | result); | 1516 | result); |
1517 | dvb_dmx_release(&ttusb->dvb_demux); | 1517 | dvb_dmx_release(&ttusb->dvb_demux); |
1518 | i2c_del_adapter(&ttusb->i2c_adap); | 1518 | i2c_del_adapter(&ttusb->i2c_adap); |
1519 | dvb_unregister_adapter (ttusb->adapter); | 1519 | dvb_unregister_adapter (&ttusb->adapter); |
1520 | return -ENODEV; | 1520 | return -ENODEV; |
1521 | } | 1521 | } |
1522 | 1522 | ||
1523 | if (dvb_net_init(ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) { | 1523 | if (dvb_net_init(&ttusb->adapter, &ttusb->dvbnet, &ttusb->dvb_demux.dmx)) { |
1524 | printk("ttusb_dvb: dvb_net_init failed!\n"); | 1524 | printk("ttusb_dvb: dvb_net_init failed!\n"); |
1525 | dvb_dmxdev_release(&ttusb->dmxdev); | 1525 | dvb_dmxdev_release(&ttusb->dmxdev); |
1526 | dvb_dmx_release(&ttusb->dvb_demux); | 1526 | dvb_dmx_release(&ttusb->dvb_demux); |
1527 | i2c_del_adapter(&ttusb->i2c_adap); | 1527 | i2c_del_adapter(&ttusb->i2c_adap); |
1528 | dvb_unregister_adapter (ttusb->adapter); | 1528 | dvb_unregister_adapter (&ttusb->adapter); |
1529 | return -ENODEV; | 1529 | return -ENODEV; |
1530 | } | 1530 | } |
1531 | 1531 | ||
@@ -1559,7 +1559,7 @@ static void ttusb_disconnect(struct usb_interface *intf) | |||
1559 | dvb_dmx_release(&ttusb->dvb_demux); | 1559 | dvb_dmx_release(&ttusb->dvb_demux); |
1560 | if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe); | 1560 | if (ttusb->fe != NULL) dvb_unregister_frontend(ttusb->fe); |
1561 | i2c_del_adapter(&ttusb->i2c_adap); | 1561 | i2c_del_adapter(&ttusb->i2c_adap); |
1562 | dvb_unregister_adapter(ttusb->adapter); | 1562 | dvb_unregister_adapter(&ttusb->adapter); |
1563 | 1563 | ||
1564 | ttusb_free_iso_urbs(ttusb); | 1564 | ttusb_free_iso_urbs(ttusb); |
1565 | 1565 | ||
diff --git a/drivers/media/dvb/ttusb-dec/ttusb_dec.c b/drivers/media/dvb/ttusb-dec/ttusb_dec.c index 64e771bd8907..505bdaff5a7e 100644 --- a/drivers/media/dvb/ttusb-dec/ttusb_dec.c +++ b/drivers/media/dvb/ttusb-dec/ttusb_dec.c | |||
@@ -98,7 +98,7 @@ struct ttusb_dec { | |||
98 | int can_playback; | 98 | int can_playback; |
99 | 99 | ||
100 | /* DVB bits */ | 100 | /* DVB bits */ |
101 | struct dvb_adapter *adapter; | 101 | struct dvb_adapter adapter; |
102 | struct dmxdev dmxdev; | 102 | struct dmxdev dmxdev; |
103 | struct dvb_demux demux; | 103 | struct dvb_demux demux; |
104 | struct dmx_frontend frontend; | 104 | struct dmx_frontend frontend; |
@@ -1435,7 +1435,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1435 | printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__, | 1435 | printk("%s: dvb_dmx_init failed: error %d\n", __FUNCTION__, |
1436 | result); | 1436 | result); |
1437 | 1437 | ||
1438 | dvb_unregister_adapter(dec->adapter); | 1438 | dvb_unregister_adapter(&dec->adapter); |
1439 | 1439 | ||
1440 | return result; | 1440 | return result; |
1441 | } | 1441 | } |
@@ -1444,12 +1444,12 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1444 | dec->dmxdev.demux = &dec->demux.dmx; | 1444 | dec->dmxdev.demux = &dec->demux.dmx; |
1445 | dec->dmxdev.capabilities = 0; | 1445 | dec->dmxdev.capabilities = 0; |
1446 | 1446 | ||
1447 | if ((result = dvb_dmxdev_init(&dec->dmxdev, dec->adapter)) < 0) { | 1447 | if ((result = dvb_dmxdev_init(&dec->dmxdev, &dec->adapter)) < 0) { |
1448 | printk("%s: dvb_dmxdev_init failed: error %d\n", | 1448 | printk("%s: dvb_dmxdev_init failed: error %d\n", |
1449 | __FUNCTION__, result); | 1449 | __FUNCTION__, result); |
1450 | 1450 | ||
1451 | dvb_dmx_release(&dec->demux); | 1451 | dvb_dmx_release(&dec->demux); |
1452 | dvb_unregister_adapter(dec->adapter); | 1452 | dvb_unregister_adapter(&dec->adapter); |
1453 | 1453 | ||
1454 | return result; | 1454 | return result; |
1455 | } | 1455 | } |
@@ -1463,7 +1463,7 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1463 | 1463 | ||
1464 | dvb_dmxdev_release(&dec->dmxdev); | 1464 | dvb_dmxdev_release(&dec->dmxdev); |
1465 | dvb_dmx_release(&dec->demux); | 1465 | dvb_dmx_release(&dec->demux); |
1466 | dvb_unregister_adapter(dec->adapter); | 1466 | dvb_unregister_adapter(&dec->adapter); |
1467 | 1467 | ||
1468 | return result; | 1468 | return result; |
1469 | } | 1469 | } |
@@ -1476,12 +1476,12 @@ static int ttusb_dec_init_dvb(struct ttusb_dec *dec) | |||
1476 | dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); | 1476 | dec->demux.dmx.remove_frontend(&dec->demux.dmx, &dec->frontend); |
1477 | dvb_dmxdev_release(&dec->dmxdev); | 1477 | dvb_dmxdev_release(&dec->dmxdev); |
1478 | dvb_dmx_release(&dec->demux); | 1478 | dvb_dmx_release(&dec->demux); |
1479 | dvb_unregister_adapter(dec->adapter); | 1479 | dvb_unregister_adapter(&dec->adapter); |
1480 | 1480 | ||
1481 | return result; | 1481 | return result; |
1482 | } | 1482 | } |
1483 | 1483 | ||
1484 | dvb_net_init(dec->adapter, &dec->dvb_net, &dec->demux.dmx); | 1484 | dvb_net_init(&dec->adapter, &dec->dvb_net, &dec->demux.dmx); |
1485 | 1485 | ||
1486 | return 0; | 1486 | return 0; |
1487 | } | 1487 | } |
@@ -1496,7 +1496,7 @@ static void ttusb_dec_exit_dvb(struct ttusb_dec *dec) | |||
1496 | dvb_dmxdev_release(&dec->dmxdev); | 1496 | dvb_dmxdev_release(&dec->dmxdev); |
1497 | dvb_dmx_release(&dec->demux); | 1497 | dvb_dmx_release(&dec->demux); |
1498 | if (dec->fe) dvb_unregister_frontend(dec->fe); | 1498 | if (dec->fe) dvb_unregister_frontend(dec->fe); |
1499 | dvb_unregister_adapter(dec->adapter); | 1499 | dvb_unregister_adapter(&dec->adapter); |
1500 | } | 1500 | } |
1501 | 1501 | ||
1502 | static void ttusb_dec_exit_rc(struct ttusb_dec *dec) | 1502 | static void ttusb_dec_exit_rc(struct ttusb_dec *dec) |
@@ -1565,15 +1565,15 @@ static void ttusb_dec_exit_filters(struct ttusb_dec *dec) | |||
1565 | } | 1565 | } |
1566 | } | 1566 | } |
1567 | 1567 | ||
1568 | int fe_send_command(struct dvb_frontend* fe, const u8 command, | 1568 | static int fe_send_command(struct dvb_frontend* fe, const u8 command, |
1569 | int param_length, const u8 params[], | 1569 | int param_length, const u8 params[], |
1570 | int *result_length, u8 cmd_result[]) | 1570 | int *result_length, u8 cmd_result[]) |
1571 | { | 1571 | { |
1572 | struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; | 1572 | struct ttusb_dec* dec = (struct ttusb_dec*) fe->dvb->priv; |
1573 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); | 1573 | return ttusb_dec_send_command(dec, command, param_length, params, result_length, cmd_result); |
1574 | } | 1574 | } |
1575 | 1575 | ||
1576 | struct ttusbdecfe_config fe_config = { | 1576 | static struct ttusbdecfe_config fe_config = { |
1577 | .send_command = fe_send_command | 1577 | .send_command = fe_send_command |
1578 | }; | 1578 | }; |
1579 | 1579 | ||
@@ -1620,7 +1620,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1620 | } | 1620 | } |
1621 | ttusb_dec_init_dvb(dec); | 1621 | ttusb_dec_init_dvb(dec); |
1622 | 1622 | ||
1623 | dec->adapter->priv = dec; | 1623 | dec->adapter.priv = dec; |
1624 | switch (le16_to_cpu(id->idProduct)) { | 1624 | switch (le16_to_cpu(id->idProduct)) { |
1625 | case 0x1006: | 1625 | case 0x1006: |
1626 | dec->fe = ttusbdecfe_dvbs_attach(&fe_config); | 1626 | dec->fe = ttusbdecfe_dvbs_attach(&fe_config); |
@@ -1637,7 +1637,7 @@ static int ttusb_dec_probe(struct usb_interface *intf, | |||
1637 | le16_to_cpu(dec->udev->descriptor.idVendor), | 1637 | le16_to_cpu(dec->udev->descriptor.idVendor), |
1638 | le16_to_cpu(dec->udev->descriptor.idProduct)); | 1638 | le16_to_cpu(dec->udev->descriptor.idProduct)); |
1639 | } else { | 1639 | } else { |
1640 | if (dvb_register_frontend(dec->adapter, dec->fe)) { | 1640 | if (dvb_register_frontend(&dec->adapter, dec->fe)) { |
1641 | printk("budget-ci: Frontend registration failed!\n"); | 1641 | printk("budget-ci: Frontend registration failed!\n"); |
1642 | if (dec->fe->ops->release) | 1642 | if (dec->fe->ops->release) |
1643 | dec->fe->ops->release(dec->fe); | 1643 | dec->fe->ops->release(dec->fe); |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index d3dd4228b72d..6c05fddb69ab 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -240,6 +240,7 @@ config VIDEO_SAA7134 | |||
240 | select VIDEO_BUF | 240 | select VIDEO_BUF |
241 | select VIDEO_IR | 241 | select VIDEO_IR |
242 | select VIDEO_TUNER | 242 | select VIDEO_TUNER |
243 | select CRC32 | ||
243 | ---help--- | 244 | ---help--- |
244 | This is a video4linux driver for Philips SAA7130/7134 based | 245 | This is a video4linux driver for Philips SAA7130/7134 based |
245 | TV cards. | 246 | TV cards. |
diff --git a/drivers/media/video/bttv-cards.c b/drivers/media/video/bttv-cards.c index 85224b90e394..6334122704ae 100644 --- a/drivers/media/video/bttv-cards.c +++ b/drivers/media/video/bttv-cards.c | |||
@@ -1946,7 +1946,6 @@ struct tvcard bttv_tvcards[] = { | |||
1946 | .no_tda9875 = 1, | 1946 | .no_tda9875 = 1, |
1947 | .no_tda7432 = 1, | 1947 | .no_tda7432 = 1, |
1948 | .tuner_type = TUNER_ABSENT, | 1948 | .tuner_type = TUNER_ABSENT, |
1949 | .no_video = 1, | ||
1950 | .pll = PLL_28, | 1949 | .pll = PLL_28, |
1951 | },{ | 1950 | },{ |
1952 | .name = "Teppro TEV-560/InterVision IV-560", | 1951 | .name = "Teppro TEV-560/InterVision IV-560", |
diff --git a/drivers/media/video/bttv-i2c.c b/drivers/media/video/bttv-i2c.c index e42f1ec13f3e..e3f477dff827 100644 --- a/drivers/media/video/bttv-i2c.c +++ b/drivers/media/video/bttv-i2c.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/moduleparam.h> | 29 | #include <linux/moduleparam.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/delay.h> | 31 | #include <linux/delay.h> |
32 | #include <linux/jiffies.h> | ||
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
33 | 34 | ||
34 | #include "bttvp.h" | 35 | #include "bttvp.h" |
@@ -130,17 +131,14 @@ static u32 functionality(struct i2c_adapter *adap) | |||
130 | static int | 131 | static int |
131 | bttv_i2c_wait_done(struct bttv *btv) | 132 | bttv_i2c_wait_done(struct bttv *btv) |
132 | { | 133 | { |
133 | DECLARE_WAITQUEUE(wait, current); | ||
134 | int rc = 0; | 134 | int rc = 0; |
135 | 135 | ||
136 | add_wait_queue(&btv->i2c_queue, &wait); | 136 | /* timeout */ |
137 | if (0 == btv->i2c_done) | 137 | if (wait_event_interruptible_timeout(btv->i2c_queue, |
138 | msleep_interruptible(20); | 138 | btv->i2c_done, msecs_to_jiffies(85)) == -ERESTARTSYS) |
139 | remove_wait_queue(&btv->i2c_queue, &wait); | 139 | |
140 | rc = -EIO; | ||
140 | 141 | ||
141 | if (0 == btv->i2c_done) | ||
142 | /* timeout */ | ||
143 | rc = -EIO; | ||
144 | if (btv->i2c_done & BT848_INT_RACK) | 142 | if (btv->i2c_done & BT848_INT_RACK) |
145 | rc = 1; | 143 | rc = 1; |
146 | btv->i2c_done = 0; | 144 | btv->i2c_done = 0; |
diff --git a/drivers/media/video/saa7134/saa6752hs.c b/drivers/media/video/saa7134/saa6752hs.c index cee13584c9cf..fe6abe34168c 100644 --- a/drivers/media/video/saa7134/saa6752hs.c +++ b/drivers/media/video/saa7134/saa6752hs.c | |||
@@ -32,9 +32,32 @@ MODULE_LICENSE("GPL"); | |||
32 | static struct i2c_driver driver; | 32 | static struct i2c_driver driver; |
33 | static struct i2c_client client_template; | 33 | static struct i2c_client client_template; |
34 | 34 | ||
35 | enum saa6752hs_videoformat { | ||
36 | SAA6752HS_VF_D1 = 0, /* standard D1 video format: 720x576 */ | ||
37 | SAA6752HS_VF_2_3_D1 = 1,/* 2/3D1 video format: 480x576 */ | ||
38 | SAA6752HS_VF_1_2_D1 = 2,/* 1/2D1 video format: 352x576 */ | ||
39 | SAA6752HS_VF_SIF = 3, /* SIF video format: 352x288 */ | ||
40 | SAA6752HS_VF_UNKNOWN, | ||
41 | }; | ||
42 | |||
43 | static const struct v4l2_format v4l2_format_table[] = | ||
44 | { | ||
45 | [SAA6752HS_VF_D1] = { | ||
46 | .fmt.pix.width = 720, .fmt.pix.height = 576 }, | ||
47 | [SAA6752HS_VF_2_3_D1] = { | ||
48 | .fmt.pix.width = 480, .fmt.pix.height = 576 }, | ||
49 | [SAA6752HS_VF_1_2_D1] = { | ||
50 | .fmt.pix.width = 352, .fmt.pix.height = 576 }, | ||
51 | [SAA6752HS_VF_SIF] = { | ||
52 | .fmt.pix.width = 352, .fmt.pix.height = 288 }, | ||
53 | [SAA6752HS_VF_UNKNOWN] = { | ||
54 | .fmt.pix.width = 0, .fmt.pix.height = 0}, | ||
55 | }; | ||
56 | |||
35 | struct saa6752hs_state { | 57 | struct saa6752hs_state { |
36 | struct i2c_client client; | 58 | struct i2c_client client; |
37 | struct v4l2_mpeg_compression params; | 59 | struct v4l2_mpeg_compression params; |
60 | enum saa6752hs_videoformat video_format; | ||
38 | }; | 61 | }; |
39 | 62 | ||
40 | enum saa6752hs_command { | 63 | enum saa6752hs_command { |
@@ -256,6 +279,51 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, | |||
256 | return 0; | 279 | return 0; |
257 | } | 280 | } |
258 | 281 | ||
282 | static void saa6752hs_set_subsampling(struct i2c_client* client, | ||
283 | struct v4l2_format* f) | ||
284 | { | ||
285 | struct saa6752hs_state *h = i2c_get_clientdata(client); | ||
286 | int dist_352, dist_480, dist_720; | ||
287 | |||
288 | /* | ||
289 | FIXME: translate and round width/height into EMPRESS | ||
290 | subsample type: | ||
291 | |||
292 | type | PAL | NTSC | ||
293 | --------------------------- | ||
294 | SIF | 352x288 | 352x240 | ||
295 | 1/2 D1 | 352x576 | 352x480 | ||
296 | 2/3 D1 | 480x576 | 480x480 | ||
297 | D1 | 720x576 | 720x480 | ||
298 | */ | ||
299 | |||
300 | dist_352 = abs(f->fmt.pix.width - 352); | ||
301 | dist_480 = abs(f->fmt.pix.width - 480); | ||
302 | dist_720 = abs(f->fmt.pix.width - 720); | ||
303 | if (dist_720 < dist_480) { | ||
304 | f->fmt.pix.width = 720; | ||
305 | f->fmt.pix.height = 576; | ||
306 | h->video_format = SAA6752HS_VF_D1; | ||
307 | } | ||
308 | else if (dist_480 < dist_352) { | ||
309 | f->fmt.pix.width = 480; | ||
310 | f->fmt.pix.height = 576; | ||
311 | h->video_format = SAA6752HS_VF_2_3_D1; | ||
312 | } | ||
313 | else { | ||
314 | f->fmt.pix.width = 352; | ||
315 | if (abs(f->fmt.pix.height - 576) < | ||
316 | abs(f->fmt.pix.height - 288)) { | ||
317 | f->fmt.pix.height = 576; | ||
318 | h->video_format = SAA6752HS_VF_1_2_D1; | ||
319 | } | ||
320 | else { | ||
321 | f->fmt.pix.height = 288; | ||
322 | h->video_format = SAA6752HS_VF_SIF; | ||
323 | } | ||
324 | } | ||
325 | } | ||
326 | |||
259 | 327 | ||
260 | static void saa6752hs_set_params(struct i2c_client* client, | 328 | static void saa6752hs_set_params(struct i2c_client* client, |
261 | struct v4l2_mpeg_compression* params) | 329 | struct v4l2_mpeg_compression* params) |
@@ -315,7 +383,7 @@ static int saa6752hs_init(struct i2c_client* client) | |||
315 | 383 | ||
316 | // Set video format - must be done first as it resets other settings | 384 | // Set video format - must be done first as it resets other settings |
317 | buf[0] = 0x41; | 385 | buf[0] = 0x41; |
318 | buf[1] = 0 /* MPEG_VIDEO_FORMAT_D1 */; | 386 | buf[1] = h->video_format; |
319 | i2c_master_send(client, buf, 2); | 387 | i2c_master_send(client, buf, 2); |
320 | 388 | ||
321 | // set bitrate | 389 | // set bitrate |
@@ -494,6 +562,25 @@ saa6752hs_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
494 | case VIDIOC_G_MPEGCOMP: | 562 | case VIDIOC_G_MPEGCOMP: |
495 | *params = h->params; | 563 | *params = h->params; |
496 | break; | 564 | break; |
565 | case VIDIOC_G_FMT: | ||
566 | { | ||
567 | struct v4l2_format *f = arg; | ||
568 | |||
569 | if (h->video_format == SAA6752HS_VF_UNKNOWN) | ||
570 | h->video_format = SAA6752HS_VF_D1; | ||
571 | f->fmt.pix.width = | ||
572 | v4l2_format_table[h->video_format].fmt.pix.width; | ||
573 | f->fmt.pix.height = | ||
574 | v4l2_format_table[h->video_format].fmt.pix.height; | ||
575 | break ; | ||
576 | } | ||
577 | case VIDIOC_S_FMT: | ||
578 | { | ||
579 | struct v4l2_format *f = arg; | ||
580 | |||
581 | saa6752hs_set_subsampling(client, f); | ||
582 | break; | ||
583 | } | ||
497 | default: | 584 | default: |
498 | /* nothing */ | 585 | /* nothing */ |
499 | break; | 586 | break; |
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c index 2021e099e35a..fa1357336907 100644 --- a/drivers/media/video/saa7134/saa7134-empress.c +++ b/drivers/media/video/saa7134/saa7134-empress.c | |||
@@ -233,10 +233,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
233 | memset(f,0,sizeof(*f)); | 233 | memset(f,0,sizeof(*f)); |
234 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; | 234 | f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; |
235 | 235 | ||
236 | /* FIXME: translate subsampling type EMPRESS into | 236 | saa7134_i2c_call_clients(dev, cmd, arg); |
237 | * width/height: */ | ||
238 | f->fmt.pix.width = 720; /* D1 */ | ||
239 | f->fmt.pix.height = 576; | ||
240 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 237 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
241 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; | 238 | f->fmt.pix.sizeimage = TS_PACKET_SIZE * dev->ts.nr_packets; |
242 | return 0; | 239 | return 0; |
@@ -249,20 +246,7 @@ static int ts_do_ioctl(struct inode *inode, struct file *file, | |||
249 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) | 246 | if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) |
250 | return -EINVAL; | 247 | return -EINVAL; |
251 | 248 | ||
252 | /* | 249 | saa7134_i2c_call_clients(dev, cmd, arg); |
253 | FIXME: translate and round width/height into EMPRESS | ||
254 | subsample type: | ||
255 | |||
256 | type | PAL | NTSC | ||
257 | --------------------------- | ||
258 | SIF | 352x288 | 352x240 | ||
259 | 1/2 D1 | 352x576 | 352x480 | ||
260 | 2/3 D1 | 480x576 | 480x480 | ||
261 | D1 | 720x576 | 720x480 | ||
262 | */ | ||
263 | |||
264 | f->fmt.pix.width = 720; /* D1 */ | ||
265 | f->fmt.pix.height = 576; | ||
266 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; | 250 | f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG; |
267 | f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets; | 251 | f->fmt.pix.sizeimage = TS_PACKET_SIZE* dev->ts.nr_packets; |
268 | return 0; | 252 | return 0; |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index 881a0539fc17..6212388edb75 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -357,8 +357,16 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
357 | V4L2_TUNER_RADIO != t->mode) | 357 | V4L2_TUNER_RADIO != t->mode) |
358 | set_tv_freq(client,400*16); | 358 | set_tv_freq(client,400*16); |
359 | t->mode = f->type; | 359 | t->mode = f->type; |
360 | t->freq = f->frequency; | 360 | set_freq(client,f->frequency); |
361 | set_freq(client,t->freq); | 361 | break; |
362 | } | ||
363 | case VIDIOC_G_FREQUENCY: | ||
364 | { | ||
365 | struct v4l2_frequency *f = arg; | ||
366 | |||
367 | SWITCH_V4L2; | ||
368 | f->type = t->mode; | ||
369 | f->frequency = t->freq; | ||
362 | break; | 370 | break; |
363 | } | 371 | } |
364 | case VIDIOC_G_TUNER: | 372 | case VIDIOC_G_TUNER: |
@@ -368,6 +376,8 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
368 | SWITCH_V4L2; | 376 | SWITCH_V4L2; |
369 | if (V4L2_TUNER_RADIO == t->mode && t->has_signal) | 377 | if (V4L2_TUNER_RADIO == t->mode && t->has_signal) |
370 | tuner->signal = t->has_signal(client); | 378 | tuner->signal = t->has_signal(client); |
379 | tuner->rangelow = tv_range[0] * 16; | ||
380 | tuner->rangehigh = tv_range[1] * 16; | ||
371 | break; | 381 | break; |
372 | } | 382 | } |
373 | default: | 383 | default: |
diff --git a/drivers/media/video/video-buf-dvb.c b/drivers/media/video/video-buf-dvb.c index 31cc4ed9b747..5f870075b55e 100644 --- a/drivers/media/video/video-buf-dvb.c +++ b/drivers/media/video/video-buf-dvb.c | |||
@@ -149,10 +149,10 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
149 | dvb->name, result); | 149 | dvb->name, result); |
150 | goto fail_adapter; | 150 | goto fail_adapter; |
151 | } | 151 | } |
152 | dvb->adapter->priv = adapter_priv; | 152 | dvb->adapter.priv = adapter_priv; |
153 | 153 | ||
154 | /* register frontend */ | 154 | /* register frontend */ |
155 | result = dvb_register_frontend(dvb->adapter, dvb->frontend); | 155 | result = dvb_register_frontend(&dvb->adapter, dvb->frontend); |
156 | if (result < 0) { | 156 | if (result < 0) { |
157 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", | 157 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", |
158 | dvb->name, result); | 158 | dvb->name, result); |
@@ -178,7 +178,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
178 | dvb->dmxdev.filternum = 256; | 178 | dvb->dmxdev.filternum = 256; |
179 | dvb->dmxdev.demux = &dvb->demux.dmx; | 179 | dvb->dmxdev.demux = &dvb->demux.dmx; |
180 | dvb->dmxdev.capabilities = 0; | 180 | dvb->dmxdev.capabilities = 0; |
181 | result = dvb_dmxdev_init(&dvb->dmxdev, dvb->adapter); | 181 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); |
182 | if (result < 0) { | 182 | if (result < 0) { |
183 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", | 183 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", |
184 | dvb->name, result); | 184 | dvb->name, result); |
@@ -209,7 +209,7 @@ int videobuf_dvb_register(struct videobuf_dvb *dvb, | |||
209 | } | 209 | } |
210 | 210 | ||
211 | /* register network adapter */ | 211 | /* register network adapter */ |
212 | dvb_net_init(dvb->adapter, &dvb->net, &dvb->demux.dmx); | 212 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); |
213 | return 0; | 213 | return 0; |
214 | 214 | ||
215 | fail_fe_conn: | 215 | fail_fe_conn: |
@@ -223,7 +223,7 @@ fail_dmxdev: | |||
223 | fail_dmx: | 223 | fail_dmx: |
224 | dvb_unregister_frontend(dvb->frontend); | 224 | dvb_unregister_frontend(dvb->frontend); |
225 | fail_frontend: | 225 | fail_frontend: |
226 | dvb_unregister_adapter(dvb->adapter); | 226 | dvb_unregister_adapter(&dvb->adapter); |
227 | fail_adapter: | 227 | fail_adapter: |
228 | return result; | 228 | return result; |
229 | } | 229 | } |
@@ -236,7 +236,7 @@ void videobuf_dvb_unregister(struct videobuf_dvb *dvb) | |||
236 | dvb_dmxdev_release(&dvb->dmxdev); | 236 | dvb_dmxdev_release(&dvb->dmxdev); |
237 | dvb_dmx_release(&dvb->demux); | 237 | dvb_dmx_release(&dvb->demux); |
238 | dvb_unregister_frontend(dvb->frontend); | 238 | dvb_unregister_frontend(dvb->frontend); |
239 | dvb_unregister_adapter(dvb->adapter); | 239 | dvb_unregister_adapter(&dvb->adapter); |
240 | } | 240 | } |
241 | 241 | ||
242 | EXPORT_SYMBOL(videobuf_dvb_register); | 242 | EXPORT_SYMBOL(videobuf_dvb_register); |
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 2e70d74fbdee..4991bbd054f3 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig | |||
@@ -51,7 +51,7 @@ config MMC_PXA | |||
51 | 51 | ||
52 | config MMC_WBSD | 52 | config MMC_WBSD |
53 | tristate "Winbond W83L51xD SD/MMC Card Interface support" | 53 | tristate "Winbond W83L51xD SD/MMC Card Interface support" |
54 | depends on MMC && ISA && ISA_DMA_API | 54 | depends on MMC && ISA_DMA_API |
55 | help | 55 | help |
56 | This selects the Winbond(R) W83L51xD Secure digital and | 56 | This selects the Winbond(R) W83L51xD Secure digital and |
57 | Multimedia card Interface. | 57 | Multimedia card Interface. |
diff --git a/drivers/mmc/wbsd.c b/drivers/mmc/wbsd.c index 39747526c719..b7fbd30b49a0 100644 --- a/drivers/mmc/wbsd.c +++ b/drivers/mmc/wbsd.c | |||
@@ -28,7 +28,9 @@ | |||
28 | #include <linux/ioport.h> | 28 | #include <linux/ioport.h> |
29 | #include <linux/device.h> | 29 | #include <linux/device.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/dma-mapping.h> | ||
31 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
33 | #include <linux/pnp.h> | ||
32 | #include <linux/highmem.h> | 34 | #include <linux/highmem.h> |
33 | #include <linux/mmc/host.h> | 35 | #include <linux/mmc/host.h> |
34 | #include <linux/mmc/protocol.h> | 36 | #include <linux/mmc/protocol.h> |
@@ -40,7 +42,7 @@ | |||
40 | #include "wbsd.h" | 42 | #include "wbsd.h" |
41 | 43 | ||
42 | #define DRIVER_NAME "wbsd" | 44 | #define DRIVER_NAME "wbsd" |
43 | #define DRIVER_VERSION "1.1" | 45 | #define DRIVER_VERSION "1.2" |
44 | 46 | ||
45 | #ifdef CONFIG_MMC_DEBUG | 47 | #ifdef CONFIG_MMC_DEBUG |
46 | #define DBG(x...) \ | 48 | #define DBG(x...) \ |
@@ -52,10 +54,6 @@ | |||
52 | #define DBGF(x...) do { } while (0) | 54 | #define DBGF(x...) do { } while (0) |
53 | #endif | 55 | #endif |
54 | 56 | ||
55 | static unsigned int io = 0x248; | ||
56 | static unsigned int irq = 6; | ||
57 | static int dma = 2; | ||
58 | |||
59 | #ifdef CONFIG_MMC_DEBUG | 57 | #ifdef CONFIG_MMC_DEBUG |
60 | void DBG_REG(int reg, u8 value) | 58 | void DBG_REG(int reg, u8 value) |
61 | { | 59 | { |
@@ -79,28 +77,61 @@ void DBG_REG(int reg, u8 value) | |||
79 | #endif | 77 | #endif |
80 | 78 | ||
81 | /* | 79 | /* |
80 | * Device resources | ||
81 | */ | ||
82 | |||
83 | #ifdef CONFIG_PNP | ||
84 | |||
85 | static const struct pnp_device_id pnp_dev_table[] = { | ||
86 | { "WEC0517", 0 }, | ||
87 | { "WEC0518", 0 }, | ||
88 | { "", 0 }, | ||
89 | }; | ||
90 | |||
91 | MODULE_DEVICE_TABLE(pnp, pnp_dev_table); | ||
92 | |||
93 | #endif /* CONFIG_PNP */ | ||
94 | |||
95 | #ifdef CONFIG_PNP | ||
96 | static unsigned int nopnp = 0; | ||
97 | #else | ||
98 | static const unsigned int nopnp = 1; | ||
99 | #endif | ||
100 | static unsigned int io = 0x248; | ||
101 | static unsigned int irq = 6; | ||
102 | static int dma = 2; | ||
103 | |||
104 | /* | ||
82 | * Basic functions | 105 | * Basic functions |
83 | */ | 106 | */ |
84 | 107 | ||
85 | static inline void wbsd_unlock_config(struct wbsd_host* host) | 108 | static inline void wbsd_unlock_config(struct wbsd_host* host) |
86 | { | 109 | { |
110 | BUG_ON(host->config == 0); | ||
111 | |||
87 | outb(host->unlock_code, host->config); | 112 | outb(host->unlock_code, host->config); |
88 | outb(host->unlock_code, host->config); | 113 | outb(host->unlock_code, host->config); |
89 | } | 114 | } |
90 | 115 | ||
91 | static inline void wbsd_lock_config(struct wbsd_host* host) | 116 | static inline void wbsd_lock_config(struct wbsd_host* host) |
92 | { | 117 | { |
118 | BUG_ON(host->config == 0); | ||
119 | |||
93 | outb(LOCK_CODE, host->config); | 120 | outb(LOCK_CODE, host->config); |
94 | } | 121 | } |
95 | 122 | ||
96 | static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) | 123 | static inline void wbsd_write_config(struct wbsd_host* host, u8 reg, u8 value) |
97 | { | 124 | { |
125 | BUG_ON(host->config == 0); | ||
126 | |||
98 | outb(reg, host->config); | 127 | outb(reg, host->config); |
99 | outb(value, host->config + 1); | 128 | outb(value, host->config + 1); |
100 | } | 129 | } |
101 | 130 | ||
102 | static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) | 131 | static inline u8 wbsd_read_config(struct wbsd_host* host, u8 reg) |
103 | { | 132 | { |
133 | BUG_ON(host->config == 0); | ||
134 | |||
104 | outb(reg, host->config); | 135 | outb(reg, host->config); |
105 | return inb(host->config + 1); | 136 | return inb(host->config + 1); |
106 | } | 137 | } |
@@ -133,6 +164,13 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
133 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | 164 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); |
134 | 165 | ||
135 | /* | 166 | /* |
167 | * Set DAT3 to input | ||
168 | */ | ||
169 | setup &= ~WBSD_DAT3_H; | ||
170 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | ||
171 | host->flags &= ~WBSD_FIGNORE_DETECT; | ||
172 | |||
173 | /* | ||
136 | * Read back default clock. | 174 | * Read back default clock. |
137 | */ | 175 | */ |
138 | host->clk = wbsd_read_index(host, WBSD_IDX_CLK); | 176 | host->clk = wbsd_read_index(host, WBSD_IDX_CLK); |
@@ -148,6 +186,14 @@ static void wbsd_init_device(struct wbsd_host* host) | |||
148 | wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); | 186 | wbsd_write_index(host, WBSD_IDX_TAAC, 0x7F); |
149 | 187 | ||
150 | /* | 188 | /* |
189 | * Test for card presence | ||
190 | */ | ||
191 | if (inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT) | ||
192 | host->flags |= WBSD_FCARD_PRESENT; | ||
193 | else | ||
194 | host->flags &= ~WBSD_FCARD_PRESENT; | ||
195 | |||
196 | /* | ||
151 | * Enable interesting interrupts. | 197 | * Enable interesting interrupts. |
152 | */ | 198 | */ |
153 | ier = 0; | 199 | ier = 0; |
@@ -407,8 +453,6 @@ static inline void wbsd_get_long_reply(struct wbsd_host* host, | |||
407 | } | 453 | } |
408 | } | 454 | } |
409 | 455 | ||
410 | static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs); | ||
411 | |||
412 | static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) | 456 | static void wbsd_send_command(struct wbsd_host* host, struct mmc_command* cmd) |
413 | { | 457 | { |
414 | int i; | 458 | int i; |
@@ -646,6 +690,13 @@ static void wbsd_fill_fifo(struct wbsd_host* host) | |||
646 | } | 690 | } |
647 | 691 | ||
648 | wbsd_kunmap_sg(host); | 692 | wbsd_kunmap_sg(host); |
693 | |||
694 | /* | ||
695 | * The controller stops sending interrupts for | ||
696 | * 'FIFO empty' under certain conditions. So we | ||
697 | * need to be a bit more pro-active. | ||
698 | */ | ||
699 | tasklet_schedule(&host->fifo_tasklet); | ||
649 | } | 700 | } |
650 | 701 | ||
651 | static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) | 702 | static void wbsd_prepare_data(struct wbsd_host* host, struct mmc_data* data) |
@@ -850,9 +901,11 @@ static void wbsd_finish_data(struct wbsd_host* host, struct mmc_data* data) | |||
850 | wbsd_request_end(host, host->mrq); | 901 | wbsd_request_end(host, host->mrq); |
851 | } | 902 | } |
852 | 903 | ||
853 | /* | 904 | /*****************************************************************************\ |
854 | * MMC Callbacks | 905 | * * |
855 | */ | 906 | * MMC layer callbacks * |
907 | * * | ||
908 | \*****************************************************************************/ | ||
856 | 909 | ||
857 | static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | 910 | static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) |
858 | { | 911 | { |
@@ -874,7 +927,7 @@ static void wbsd_request(struct mmc_host* mmc, struct mmc_request* mrq) | |||
874 | * If there is no card in the slot then | 927 | * If there is no card in the slot then |
875 | * timeout immediatly. | 928 | * timeout immediatly. |
876 | */ | 929 | */ |
877 | if (!(inb(host->base + WBSD_CSR) & WBSD_CARDPRESENT)) | 930 | if (!(host->flags & WBSD_FCARD_PRESENT)) |
878 | { | 931 | { |
879 | cmd->error = MMC_ERR_TIMEOUT; | 932 | cmd->error = MMC_ERR_TIMEOUT; |
880 | goto done; | 933 | goto done; |
@@ -953,33 +1006,50 @@ static void wbsd_set_ios(struct mmc_host* mmc, struct mmc_ios* ios) | |||
953 | host->clk = clk; | 1006 | host->clk = clk; |
954 | } | 1007 | } |
955 | 1008 | ||
1009 | /* | ||
1010 | * Power up card. | ||
1011 | */ | ||
956 | if (ios->power_mode != MMC_POWER_OFF) | 1012 | if (ios->power_mode != MMC_POWER_OFF) |
957 | { | 1013 | { |
958 | /* | ||
959 | * Power up card. | ||
960 | */ | ||
961 | pwr = inb(host->base + WBSD_CSR); | 1014 | pwr = inb(host->base + WBSD_CSR); |
962 | pwr &= ~WBSD_POWER_N; | 1015 | pwr &= ~WBSD_POWER_N; |
963 | outb(pwr, host->base + WBSD_CSR); | 1016 | outb(pwr, host->base + WBSD_CSR); |
964 | |||
965 | /* | ||
966 | * This behaviour is stolen from the | ||
967 | * Windows driver. Don't know why, but | ||
968 | * it is needed. | ||
969 | */ | ||
970 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | ||
971 | if (ios->bus_mode == MMC_BUSMODE_OPENDRAIN) | ||
972 | setup |= WBSD_DAT3_H; | ||
973 | else | ||
974 | setup &= ~WBSD_DAT3_H; | ||
975 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | ||
976 | |||
977 | mdelay(1); | ||
978 | } | 1017 | } |
979 | 1018 | ||
1019 | /* | ||
1020 | * MMC cards need to have pin 1 high during init. | ||
1021 | * Init time corresponds rather nicely with the bus mode. | ||
1022 | * It wreaks havoc with the card detection though so | ||
1023 | * that needs to be disabed. | ||
1024 | */ | ||
1025 | setup = wbsd_read_index(host, WBSD_IDX_SETUP); | ||
1026 | if ((ios->power_mode == MMC_POWER_ON) && | ||
1027 | (ios->bus_mode == MMC_BUSMODE_OPENDRAIN)) | ||
1028 | { | ||
1029 | setup |= WBSD_DAT3_H; | ||
1030 | host->flags |= WBSD_FIGNORE_DETECT; | ||
1031 | } | ||
1032 | else | ||
1033 | { | ||
1034 | setup &= ~WBSD_DAT3_H; | ||
1035 | host->flags &= ~WBSD_FIGNORE_DETECT; | ||
1036 | } | ||
1037 | wbsd_write_index(host, WBSD_IDX_SETUP, setup); | ||
1038 | |||
980 | spin_unlock_bh(&host->lock); | 1039 | spin_unlock_bh(&host->lock); |
981 | } | 1040 | } |
982 | 1041 | ||
1042 | static struct mmc_host_ops wbsd_ops = { | ||
1043 | .request = wbsd_request, | ||
1044 | .set_ios = wbsd_set_ios, | ||
1045 | }; | ||
1046 | |||
1047 | /*****************************************************************************\ | ||
1048 | * * | ||
1049 | * Interrupt handling * | ||
1050 | * * | ||
1051 | \*****************************************************************************/ | ||
1052 | |||
983 | /* | 1053 | /* |
984 | * Tasklets | 1054 | * Tasklets |
985 | */ | 1055 | */ |
@@ -1005,17 +1075,33 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1005 | { | 1075 | { |
1006 | struct wbsd_host* host = (struct wbsd_host*)param; | 1076 | struct wbsd_host* host = (struct wbsd_host*)param; |
1007 | u8 csr; | 1077 | u8 csr; |
1078 | int change = 0; | ||
1008 | 1079 | ||
1009 | spin_lock(&host->lock); | 1080 | spin_lock(&host->lock); |
1010 | 1081 | ||
1082 | if (host->flags & WBSD_FIGNORE_DETECT) | ||
1083 | { | ||
1084 | spin_unlock(&host->lock); | ||
1085 | return; | ||
1086 | } | ||
1087 | |||
1011 | csr = inb(host->base + WBSD_CSR); | 1088 | csr = inb(host->base + WBSD_CSR); |
1012 | WARN_ON(csr == 0xff); | 1089 | WARN_ON(csr == 0xff); |
1013 | 1090 | ||
1014 | if (csr & WBSD_CARDPRESENT) | 1091 | if (csr & WBSD_CARDPRESENT) |
1015 | DBG("Card inserted\n"); | 1092 | { |
1016 | else | 1093 | if (!(host->flags & WBSD_FCARD_PRESENT)) |
1094 | { | ||
1095 | DBG("Card inserted\n"); | ||
1096 | host->flags |= WBSD_FCARD_PRESENT; | ||
1097 | change = 1; | ||
1098 | } | ||
1099 | } | ||
1100 | else if (host->flags & WBSD_FCARD_PRESENT) | ||
1017 | { | 1101 | { |
1018 | DBG("Card removed\n"); | 1102 | DBG("Card removed\n"); |
1103 | host->flags &= ~WBSD_FCARD_PRESENT; | ||
1104 | change = 1; | ||
1019 | 1105 | ||
1020 | if (host->mrq) | 1106 | if (host->mrq) |
1021 | { | 1107 | { |
@@ -1033,7 +1119,8 @@ static void wbsd_tasklet_card(unsigned long param) | |||
1033 | */ | 1119 | */ |
1034 | spin_unlock(&host->lock); | 1120 | spin_unlock(&host->lock); |
1035 | 1121 | ||
1036 | mmc_detect_change(host->mmc); | 1122 | if (change) |
1123 | mmc_detect_change(host->mmc); | ||
1037 | } | 1124 | } |
1038 | 1125 | ||
1039 | static void wbsd_tasklet_fifo(unsigned long param) | 1126 | static void wbsd_tasklet_fifo(unsigned long param) |
@@ -1200,11 +1287,85 @@ static irqreturn_t wbsd_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
1200 | return IRQ_HANDLED; | 1287 | return IRQ_HANDLED; |
1201 | } | 1288 | } |
1202 | 1289 | ||
1290 | /*****************************************************************************\ | ||
1291 | * * | ||
1292 | * Device initialisation and shutdown * | ||
1293 | * * | ||
1294 | \*****************************************************************************/ | ||
1295 | |||
1203 | /* | 1296 | /* |
1204 | * Support functions for probe | 1297 | * Allocate/free MMC structure. |
1205 | */ | 1298 | */ |
1206 | 1299 | ||
1207 | static int wbsd_scan(struct wbsd_host* host) | 1300 | static int __devinit wbsd_alloc_mmc(struct device* dev) |
1301 | { | ||
1302 | struct mmc_host* mmc; | ||
1303 | struct wbsd_host* host; | ||
1304 | |||
1305 | /* | ||
1306 | * Allocate MMC structure. | ||
1307 | */ | ||
1308 | mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); | ||
1309 | if (!mmc) | ||
1310 | return -ENOMEM; | ||
1311 | |||
1312 | host = mmc_priv(mmc); | ||
1313 | host->mmc = mmc; | ||
1314 | |||
1315 | host->dma = -1; | ||
1316 | |||
1317 | /* | ||
1318 | * Set host parameters. | ||
1319 | */ | ||
1320 | mmc->ops = &wbsd_ops; | ||
1321 | mmc->f_min = 375000; | ||
1322 | mmc->f_max = 24000000; | ||
1323 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | ||
1324 | |||
1325 | spin_lock_init(&host->lock); | ||
1326 | |||
1327 | /* | ||
1328 | * Maximum number of segments. Worst case is one sector per segment | ||
1329 | * so this will be 64kB/512. | ||
1330 | */ | ||
1331 | mmc->max_hw_segs = 128; | ||
1332 | mmc->max_phys_segs = 128; | ||
1333 | |||
1334 | /* | ||
1335 | * Maximum number of sectors in one transfer. Also limited by 64kB | ||
1336 | * buffer. | ||
1337 | */ | ||
1338 | mmc->max_sectors = 128; | ||
1339 | |||
1340 | /* | ||
1341 | * Maximum segment size. Could be one segment with the maximum number | ||
1342 | * of segments. | ||
1343 | */ | ||
1344 | mmc->max_seg_size = mmc->max_sectors * 512; | ||
1345 | |||
1346 | dev_set_drvdata(dev, mmc); | ||
1347 | |||
1348 | return 0; | ||
1349 | } | ||
1350 | |||
1351 | static void __devexit wbsd_free_mmc(struct device* dev) | ||
1352 | { | ||
1353 | struct mmc_host* mmc; | ||
1354 | |||
1355 | mmc = dev_get_drvdata(dev); | ||
1356 | if (!mmc) | ||
1357 | return; | ||
1358 | |||
1359 | mmc_free_host(mmc); | ||
1360 | |||
1361 | dev_set_drvdata(dev, NULL); | ||
1362 | } | ||
1363 | |||
1364 | /* | ||
1365 | * Scan for known chip id:s | ||
1366 | */ | ||
1367 | |||
1368 | static int __devinit wbsd_scan(struct wbsd_host* host) | ||
1208 | { | 1369 | { |
1209 | int i, j, k; | 1370 | int i, j, k; |
1210 | int id; | 1371 | int id; |
@@ -1258,12 +1419,16 @@ static int wbsd_scan(struct wbsd_host* host) | |||
1258 | return -ENODEV; | 1419 | return -ENODEV; |
1259 | } | 1420 | } |
1260 | 1421 | ||
1261 | static int wbsd_request_regions(struct wbsd_host* host) | 1422 | /* |
1423 | * Allocate/free io port ranges | ||
1424 | */ | ||
1425 | |||
1426 | static int __devinit wbsd_request_region(struct wbsd_host* host, int base) | ||
1262 | { | 1427 | { |
1263 | if (io & 0x7) | 1428 | if (io & 0x7) |
1264 | return -EINVAL; | 1429 | return -EINVAL; |
1265 | 1430 | ||
1266 | if (!request_region(io, 8, DRIVER_NAME)) | 1431 | if (!request_region(base, 8, DRIVER_NAME)) |
1267 | return -EIO; | 1432 | return -EIO; |
1268 | 1433 | ||
1269 | host->base = io; | 1434 | host->base = io; |
@@ -1271,19 +1436,25 @@ static int wbsd_request_regions(struct wbsd_host* host) | |||
1271 | return 0; | 1436 | return 0; |
1272 | } | 1437 | } |
1273 | 1438 | ||
1274 | static void wbsd_release_regions(struct wbsd_host* host) | 1439 | static void __devexit wbsd_release_regions(struct wbsd_host* host) |
1275 | { | 1440 | { |
1276 | if (host->base) | 1441 | if (host->base) |
1277 | release_region(host->base, 8); | 1442 | release_region(host->base, 8); |
1443 | |||
1444 | host->base = 0; | ||
1278 | 1445 | ||
1279 | if (host->config) | 1446 | if (host->config) |
1280 | release_region(host->config, 2); | 1447 | release_region(host->config, 2); |
1448 | |||
1449 | host->config = 0; | ||
1281 | } | 1450 | } |
1282 | 1451 | ||
1283 | static void wbsd_init_dma(struct wbsd_host* host) | 1452 | /* |
1453 | * Allocate/free DMA port and buffer | ||
1454 | */ | ||
1455 | |||
1456 | static void __devinit wbsd_request_dma(struct wbsd_host* host, int dma) | ||
1284 | { | 1457 | { |
1285 | host->dma = -1; | ||
1286 | |||
1287 | if (dma < 0) | 1458 | if (dma < 0) |
1288 | return; | 1459 | return; |
1289 | 1460 | ||
@@ -1294,7 +1465,7 @@ static void wbsd_init_dma(struct wbsd_host* host) | |||
1294 | * We need to allocate a special buffer in | 1465 | * We need to allocate a special buffer in |
1295 | * order for ISA to be able to DMA to it. | 1466 | * order for ISA to be able to DMA to it. |
1296 | */ | 1467 | */ |
1297 | host->dma_buffer = kmalloc(65536, | 1468 | host->dma_buffer = kmalloc(WBSD_DMA_SIZE, |
1298 | GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN); | 1469 | GFP_NOIO | GFP_DMA | __GFP_REPEAT | __GFP_NOWARN); |
1299 | if (!host->dma_buffer) | 1470 | if (!host->dma_buffer) |
1300 | goto free; | 1471 | goto free; |
@@ -1302,7 +1473,8 @@ static void wbsd_init_dma(struct wbsd_host* host) | |||
1302 | /* | 1473 | /* |
1303 | * Translate the address to a physical address. | 1474 | * Translate the address to a physical address. |
1304 | */ | 1475 | */ |
1305 | host->dma_addr = isa_virt_to_bus(host->dma_buffer); | 1476 | host->dma_addr = dma_map_single(host->mmc->dev, host->dma_buffer, |
1477 | WBSD_DMA_SIZE, DMA_BIDIRECTIONAL); | ||
1306 | 1478 | ||
1307 | /* | 1479 | /* |
1308 | * ISA DMA must be aligned on a 64k basis. | 1480 | * ISA DMA must be aligned on a 64k basis. |
@@ -1325,6 +1497,10 @@ kfree: | |||
1325 | */ | 1497 | */ |
1326 | BUG_ON(1); | 1498 | BUG_ON(1); |
1327 | 1499 | ||
1500 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, | ||
1501 | DMA_BIDIRECTIONAL); | ||
1502 | host->dma_addr = (dma_addr_t)NULL; | ||
1503 | |||
1328 | kfree(host->dma_buffer); | 1504 | kfree(host->dma_buffer); |
1329 | host->dma_buffer = NULL; | 1505 | host->dma_buffer = NULL; |
1330 | 1506 | ||
@@ -1336,60 +1512,122 @@ err: | |||
1336 | "Falling back on FIFO.\n", dma); | 1512 | "Falling back on FIFO.\n", dma); |
1337 | } | 1513 | } |
1338 | 1514 | ||
1339 | static struct mmc_host_ops wbsd_ops = { | 1515 | static void __devexit wbsd_release_dma(struct wbsd_host* host) |
1340 | .request = wbsd_request, | 1516 | { |
1341 | .set_ios = wbsd_set_ios, | 1517 | if (host->dma_addr) |
1342 | }; | 1518 | dma_unmap_single(host->mmc->dev, host->dma_addr, WBSD_DMA_SIZE, |
1519 | DMA_BIDIRECTIONAL); | ||
1520 | if (host->dma_buffer) | ||
1521 | kfree(host->dma_buffer); | ||
1522 | if (host->dma >= 0) | ||
1523 | free_dma(host->dma); | ||
1524 | |||
1525 | host->dma = -1; | ||
1526 | host->dma_buffer = NULL; | ||
1527 | host->dma_addr = (dma_addr_t)NULL; | ||
1528 | } | ||
1343 | 1529 | ||
1344 | /* | 1530 | /* |
1345 | * Device probe | 1531 | * Allocate/free IRQ. |
1346 | */ | 1532 | */ |
1347 | 1533 | ||
1348 | static int wbsd_probe(struct device* dev) | 1534 | static int __devinit wbsd_request_irq(struct wbsd_host* host, int irq) |
1349 | { | 1535 | { |
1350 | struct wbsd_host* host = NULL; | ||
1351 | struct mmc_host* mmc = NULL; | ||
1352 | int ret; | 1536 | int ret; |
1353 | 1537 | ||
1354 | /* | 1538 | /* |
1355 | * Allocate MMC structure. | 1539 | * Allocate interrupt. |
1356 | */ | 1540 | */ |
1357 | mmc = mmc_alloc_host(sizeof(struct wbsd_host), dev); | 1541 | |
1358 | if (!mmc) | 1542 | ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); |
1359 | return -ENOMEM; | 1543 | if (ret) |
1360 | 1544 | return ret; | |
1361 | host = mmc_priv(mmc); | ||
1362 | host->mmc = mmc; | ||
1363 | 1545 | ||
1546 | host->irq = irq; | ||
1547 | |||
1364 | /* | 1548 | /* |
1365 | * Scan for hardware. | 1549 | * Set up tasklets. |
1366 | */ | 1550 | */ |
1367 | ret = wbsd_scan(host); | 1551 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); |
1368 | if (ret) | 1552 | tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); |
1369 | goto freemmc; | 1553 | tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); |
1554 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); | ||
1555 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); | ||
1556 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); | ||
1557 | |||
1558 | return 0; | ||
1559 | } | ||
1370 | 1560 | ||
1371 | /* | 1561 | static void __devexit wbsd_release_irq(struct wbsd_host* host) |
1372 | * Reset the chip. | 1562 | { |
1373 | */ | 1563 | if (!host->irq) |
1374 | wbsd_write_config(host, WBSD_CONF_SWRST, 1); | 1564 | return; |
1375 | wbsd_write_config(host, WBSD_CONF_SWRST, 0); | ||
1376 | 1565 | ||
1566 | free_irq(host->irq, host); | ||
1567 | |||
1568 | host->irq = 0; | ||
1569 | |||
1570 | tasklet_kill(&host->card_tasklet); | ||
1571 | tasklet_kill(&host->fifo_tasklet); | ||
1572 | tasklet_kill(&host->crc_tasklet); | ||
1573 | tasklet_kill(&host->timeout_tasklet); | ||
1574 | tasklet_kill(&host->finish_tasklet); | ||
1575 | tasklet_kill(&host->block_tasklet); | ||
1576 | } | ||
1577 | |||
1578 | /* | ||
1579 | * Allocate all resources for the host. | ||
1580 | */ | ||
1581 | |||
1582 | static int __devinit wbsd_request_resources(struct wbsd_host* host, | ||
1583 | int base, int irq, int dma) | ||
1584 | { | ||
1585 | int ret; | ||
1586 | |||
1377 | /* | 1587 | /* |
1378 | * Allocate I/O ports. | 1588 | * Allocate I/O ports. |
1379 | */ | 1589 | */ |
1380 | ret = wbsd_request_regions(host); | 1590 | ret = wbsd_request_region(host, base); |
1381 | if (ret) | 1591 | if (ret) |
1382 | goto release; | 1592 | return ret; |
1383 | 1593 | ||
1384 | /* | 1594 | /* |
1385 | * Set host parameters. | 1595 | * Allocate interrupt. |
1386 | */ | 1596 | */ |
1387 | mmc->ops = &wbsd_ops; | 1597 | ret = wbsd_request_irq(host, irq); |
1388 | mmc->f_min = 375000; | 1598 | if (ret) |
1389 | mmc->f_max = 24000000; | 1599 | return ret; |
1390 | mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; | 1600 | |
1601 | /* | ||
1602 | * Allocate DMA. | ||
1603 | */ | ||
1604 | wbsd_request_dma(host, dma); | ||
1391 | 1605 | ||
1392 | spin_lock_init(&host->lock); | 1606 | return 0; |
1607 | } | ||
1608 | |||
1609 | /* | ||
1610 | * Release all resources for the host. | ||
1611 | */ | ||
1612 | |||
1613 | static void __devexit wbsd_release_resources(struct wbsd_host* host) | ||
1614 | { | ||
1615 | wbsd_release_dma(host); | ||
1616 | wbsd_release_irq(host); | ||
1617 | wbsd_release_regions(host); | ||
1618 | } | ||
1619 | |||
1620 | /* | ||
1621 | * Configure the resources the chip should use. | ||
1622 | */ | ||
1623 | |||
1624 | static void __devinit wbsd_chip_config(struct wbsd_host* host) | ||
1625 | { | ||
1626 | /* | ||
1627 | * Reset the chip. | ||
1628 | */ | ||
1629 | wbsd_write_config(host, WBSD_CONF_SWRST, 1); | ||
1630 | wbsd_write_config(host, WBSD_CONF_SWRST, 0); | ||
1393 | 1631 | ||
1394 | /* | 1632 | /* |
1395 | * Select SD/MMC function. | 1633 | * Select SD/MMC function. |
@@ -1399,165 +1637,241 @@ static int wbsd_probe(struct device* dev) | |||
1399 | /* | 1637 | /* |
1400 | * Set up card detection. | 1638 | * Set up card detection. |
1401 | */ | 1639 | */ |
1402 | wbsd_write_config(host, WBSD_CONF_PINS, 0x02); | 1640 | wbsd_write_config(host, WBSD_CONF_PINS, WBSD_PINS_DETECT_GP11); |
1403 | 1641 | ||
1404 | /* | 1642 | /* |
1405 | * Configure I/O port. | 1643 | * Configure chip |
1406 | */ | 1644 | */ |
1407 | wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); | 1645 | wbsd_write_config(host, WBSD_CONF_PORT_HI, host->base >> 8); |
1408 | wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); | 1646 | wbsd_write_config(host, WBSD_CONF_PORT_LO, host->base & 0xff); |
1409 | |||
1410 | /* | ||
1411 | * Allocate interrupt. | ||
1412 | */ | ||
1413 | ret = request_irq(irq, wbsd_irq, SA_SHIRQ, DRIVER_NAME, host); | ||
1414 | if (ret) | ||
1415 | goto release; | ||
1416 | 1647 | ||
1417 | host->irq = irq; | 1648 | wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); |
1418 | 1649 | ||
1419 | /* | 1650 | if (host->dma >= 0) |
1420 | * Set up tasklets. | 1651 | wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); |
1421 | */ | ||
1422 | tasklet_init(&host->card_tasklet, wbsd_tasklet_card, (unsigned long)host); | ||
1423 | tasklet_init(&host->fifo_tasklet, wbsd_tasklet_fifo, (unsigned long)host); | ||
1424 | tasklet_init(&host->crc_tasklet, wbsd_tasklet_crc, (unsigned long)host); | ||
1425 | tasklet_init(&host->timeout_tasklet, wbsd_tasklet_timeout, (unsigned long)host); | ||
1426 | tasklet_init(&host->finish_tasklet, wbsd_tasklet_finish, (unsigned long)host); | ||
1427 | tasklet_init(&host->block_tasklet, wbsd_tasklet_block, (unsigned long)host); | ||
1428 | 1652 | ||
1429 | /* | 1653 | /* |
1430 | * Configure interrupt. | 1654 | * Enable and power up chip. |
1431 | */ | 1655 | */ |
1432 | wbsd_write_config(host, WBSD_CONF_IRQ, host->irq); | 1656 | wbsd_write_config(host, WBSD_CONF_ENABLE, 1); |
1657 | wbsd_write_config(host, WBSD_CONF_POWER, 0x20); | ||
1658 | } | ||
1659 | |||
1660 | /* | ||
1661 | * Check that configured resources are correct. | ||
1662 | */ | ||
1663 | |||
1664 | static int __devinit wbsd_chip_validate(struct wbsd_host* host) | ||
1665 | { | ||
1666 | int base, irq, dma; | ||
1433 | 1667 | ||
1434 | /* | 1668 | /* |
1435 | * Allocate DMA. | 1669 | * Select SD/MMC function. |
1436 | */ | 1670 | */ |
1437 | wbsd_init_dma(host); | 1671 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); |
1438 | 1672 | ||
1439 | /* | 1673 | /* |
1440 | * If all went well, then configure DMA. | 1674 | * Read configuration. |
1441 | */ | 1675 | */ |
1442 | if (host->dma >= 0) | 1676 | base = wbsd_read_config(host, WBSD_CONF_PORT_HI) << 8; |
1443 | wbsd_write_config(host, WBSD_CONF_DRQ, host->dma); | 1677 | base |= wbsd_read_config(host, WBSD_CONF_PORT_LO); |
1444 | 1678 | ||
1445 | /* | 1679 | irq = wbsd_read_config(host, WBSD_CONF_IRQ); |
1446 | * Maximum number of segments. Worst case is one sector per segment | 1680 | |
1447 | * so this will be 64kB/512. | 1681 | dma = wbsd_read_config(host, WBSD_CONF_DRQ); |
1448 | */ | ||
1449 | mmc->max_hw_segs = 128; | ||
1450 | mmc->max_phys_segs = 128; | ||
1451 | 1682 | ||
1452 | /* | 1683 | /* |
1453 | * Maximum number of sectors in one transfer. Also limited by 64kB | 1684 | * Validate against given configuration. |
1454 | * buffer. | ||
1455 | */ | 1685 | */ |
1456 | mmc->max_sectors = 128; | 1686 | if (base != host->base) |
1687 | return 0; | ||
1688 | if (irq != host->irq) | ||
1689 | return 0; | ||
1690 | if ((dma != host->dma) && (host->dma != -1)) | ||
1691 | return 0; | ||
1692 | |||
1693 | return 1; | ||
1694 | } | ||
1695 | |||
1696 | /*****************************************************************************\ | ||
1697 | * * | ||
1698 | * Devices setup and shutdown * | ||
1699 | * * | ||
1700 | \*****************************************************************************/ | ||
1701 | |||
1702 | static int __devinit wbsd_init(struct device* dev, int base, int irq, int dma, | ||
1703 | int pnp) | ||
1704 | { | ||
1705 | struct wbsd_host* host = NULL; | ||
1706 | struct mmc_host* mmc = NULL; | ||
1707 | int ret; | ||
1708 | |||
1709 | ret = wbsd_alloc_mmc(dev); | ||
1710 | if (ret) | ||
1711 | return ret; | ||
1712 | |||
1713 | mmc = dev_get_drvdata(dev); | ||
1714 | host = mmc_priv(mmc); | ||
1457 | 1715 | ||
1458 | /* | 1716 | /* |
1459 | * Maximum segment size. Could be one segment with the maximum number | 1717 | * Scan for hardware. |
1460 | * of segments. | ||
1461 | */ | 1718 | */ |
1462 | mmc->max_seg_size = mmc->max_sectors * 512; | 1719 | ret = wbsd_scan(host); |
1720 | if (ret) | ||
1721 | { | ||
1722 | if (pnp && (ret == -ENODEV)) | ||
1723 | { | ||
1724 | printk(KERN_WARNING DRIVER_NAME | ||
1725 | ": Unable to confirm device presence. You may " | ||
1726 | "experience lock-ups.\n"); | ||
1727 | } | ||
1728 | else | ||
1729 | { | ||
1730 | wbsd_free_mmc(dev); | ||
1731 | return ret; | ||
1732 | } | ||
1733 | } | ||
1463 | 1734 | ||
1464 | /* | 1735 | /* |
1465 | * Enable chip. | 1736 | * Request resources. |
1466 | */ | 1737 | */ |
1467 | wbsd_write_config(host, WBSD_CONF_ENABLE, 1); | 1738 | ret = wbsd_request_resources(host, io, irq, dma); |
1739 | if (ret) | ||
1740 | { | ||
1741 | wbsd_release_resources(host); | ||
1742 | wbsd_free_mmc(dev); | ||
1743 | return ret; | ||
1744 | } | ||
1468 | 1745 | ||
1469 | /* | 1746 | /* |
1470 | * Power up chip. | 1747 | * See if chip needs to be configured. |
1471 | */ | 1748 | */ |
1472 | wbsd_write_config(host, WBSD_CONF_POWER, 0x20); | 1749 | if (pnp && (host->config != 0)) |
1750 | { | ||
1751 | if (!wbsd_chip_validate(host)) | ||
1752 | { | ||
1753 | printk(KERN_WARNING DRIVER_NAME | ||
1754 | ": PnP active but chip not configured! " | ||
1755 | "You probably have a buggy BIOS. " | ||
1756 | "Configuring chip manually.\n"); | ||
1757 | wbsd_chip_config(host); | ||
1758 | } | ||
1759 | } | ||
1760 | else | ||
1761 | wbsd_chip_config(host); | ||
1473 | 1762 | ||
1474 | /* | 1763 | /* |
1475 | * Power Management stuff. No idea how this works. | 1764 | * Power Management stuff. No idea how this works. |
1476 | * Not tested. | 1765 | * Not tested. |
1477 | */ | 1766 | */ |
1478 | #ifdef CONFIG_PM | 1767 | #ifdef CONFIG_PM |
1479 | wbsd_write_config(host, WBSD_CONF_PME, 0xA0); | 1768 | if (host->config) |
1769 | wbsd_write_config(host, WBSD_CONF_PME, 0xA0); | ||
1480 | #endif | 1770 | #endif |
1771 | /* | ||
1772 | * Allow device to initialise itself properly. | ||
1773 | */ | ||
1774 | mdelay(5); | ||
1481 | 1775 | ||
1482 | /* | 1776 | /* |
1483 | * Reset the chip into a known state. | 1777 | * Reset the chip into a known state. |
1484 | */ | 1778 | */ |
1485 | wbsd_init_device(host); | 1779 | wbsd_init_device(host); |
1486 | 1780 | ||
1487 | dev_set_drvdata(dev, mmc); | ||
1488 | |||
1489 | /* | ||
1490 | * Add host to MMC layer. | ||
1491 | */ | ||
1492 | mmc_add_host(mmc); | 1781 | mmc_add_host(mmc); |
1493 | 1782 | ||
1494 | printk(KERN_INFO "%s: W83L51xD id %x at 0x%x irq %d dma %d\n", | 1783 | printk(KERN_INFO "%s: W83L51xD", mmc->host_name); |
1495 | mmc->host_name, (int)host->chip_id, (int)host->base, | 1784 | if (host->chip_id != 0) |
1496 | (int)host->irq, (int)host->dma); | 1785 | printk(" id %x", (int)host->chip_id); |
1786 | printk(" at 0x%x irq %d", (int)host->base, (int)host->irq); | ||
1787 | if (host->dma >= 0) | ||
1788 | printk(" dma %d", (int)host->dma); | ||
1789 | else | ||
1790 | printk(" FIFO"); | ||
1791 | if (pnp) | ||
1792 | printk(" PnP"); | ||
1793 | printk("\n"); | ||
1497 | 1794 | ||
1498 | return 0; | 1795 | return 0; |
1499 | |||
1500 | release: | ||
1501 | wbsd_release_regions(host); | ||
1502 | |||
1503 | freemmc: | ||
1504 | mmc_free_host(mmc); | ||
1505 | |||
1506 | return ret; | ||
1507 | } | 1796 | } |
1508 | 1797 | ||
1509 | /* | 1798 | static void __devexit wbsd_shutdown(struct device* dev, int pnp) |
1510 | * Device remove | ||
1511 | */ | ||
1512 | |||
1513 | static int wbsd_remove(struct device* dev) | ||
1514 | { | 1799 | { |
1515 | struct mmc_host* mmc = dev_get_drvdata(dev); | 1800 | struct mmc_host* mmc = dev_get_drvdata(dev); |
1516 | struct wbsd_host* host; | 1801 | struct wbsd_host* host; |
1517 | 1802 | ||
1518 | if (!mmc) | 1803 | if (!mmc) |
1519 | return 0; | 1804 | return; |
1520 | 1805 | ||
1521 | host = mmc_priv(mmc); | 1806 | host = mmc_priv(mmc); |
1522 | 1807 | ||
1523 | /* | ||
1524 | * Unregister host with MMC layer. | ||
1525 | */ | ||
1526 | mmc_remove_host(mmc); | 1808 | mmc_remove_host(mmc); |
1527 | 1809 | ||
1528 | /* | 1810 | if (!pnp) |
1529 | * Power down the SD/MMC function. | 1811 | { |
1530 | */ | 1812 | /* |
1531 | wbsd_unlock_config(host); | 1813 | * Power down the SD/MMC function. |
1532 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); | 1814 | */ |
1533 | wbsd_write_config(host, WBSD_CONF_ENABLE, 0); | 1815 | wbsd_unlock_config(host); |
1534 | wbsd_lock_config(host); | 1816 | wbsd_write_config(host, WBSD_CONF_DEVICE, DEVICE_SD); |
1817 | wbsd_write_config(host, WBSD_CONF_ENABLE, 0); | ||
1818 | wbsd_lock_config(host); | ||
1819 | } | ||
1535 | 1820 | ||
1536 | /* | 1821 | wbsd_release_resources(host); |
1537 | * Free resources. | ||
1538 | */ | ||
1539 | if (host->dma_buffer) | ||
1540 | kfree(host->dma_buffer); | ||
1541 | 1822 | ||
1542 | if (host->dma >= 0) | 1823 | wbsd_free_mmc(dev); |
1543 | free_dma(host->dma); | 1824 | } |
1544 | 1825 | ||
1545 | free_irq(host->irq, host); | 1826 | /* |
1827 | * Non-PnP | ||
1828 | */ | ||
1829 | |||
1830 | static int __devinit wbsd_probe(struct device* dev) | ||
1831 | { | ||
1832 | return wbsd_init(dev, io, irq, dma, 0); | ||
1833 | } | ||
1834 | |||
1835 | static int __devexit wbsd_remove(struct device* dev) | ||
1836 | { | ||
1837 | wbsd_shutdown(dev, 0); | ||
1838 | |||
1839 | return 0; | ||
1840 | } | ||
1841 | |||
1842 | /* | ||
1843 | * PnP | ||
1844 | */ | ||
1845 | |||
1846 | #ifdef CONFIG_PNP | ||
1847 | |||
1848 | static int __devinit | ||
1849 | wbsd_pnp_probe(struct pnp_dev * pnpdev, const struct pnp_device_id *dev_id) | ||
1850 | { | ||
1851 | int io, irq, dma; | ||
1546 | 1852 | ||
1547 | tasklet_kill(&host->card_tasklet); | 1853 | /* |
1548 | tasklet_kill(&host->fifo_tasklet); | 1854 | * Get resources from PnP layer. |
1549 | tasklet_kill(&host->crc_tasklet); | 1855 | */ |
1550 | tasklet_kill(&host->timeout_tasklet); | 1856 | io = pnp_port_start(pnpdev, 0); |
1551 | tasklet_kill(&host->finish_tasklet); | 1857 | irq = pnp_irq(pnpdev, 0); |
1552 | tasklet_kill(&host->block_tasklet); | 1858 | if (pnp_dma_valid(pnpdev, 0)) |
1859 | dma = pnp_dma(pnpdev, 0); | ||
1860 | else | ||
1861 | dma = -1; | ||
1553 | 1862 | ||
1554 | wbsd_release_regions(host); | 1863 | DBGF("PnP resources: port %3x irq %d dma %d\n", io, irq, dma); |
1555 | 1864 | ||
1556 | mmc_free_host(mmc); | 1865 | return wbsd_init(&pnpdev->dev, io, irq, dma, 1); |
1866 | } | ||
1557 | 1867 | ||
1558 | return 0; | 1868 | static void __devexit wbsd_pnp_remove(struct pnp_dev * dev) |
1869 | { | ||
1870 | wbsd_shutdown(&dev->dev, 1); | ||
1559 | } | 1871 | } |
1560 | 1872 | ||
1873 | #endif /* CONFIG_PNP */ | ||
1874 | |||
1561 | /* | 1875 | /* |
1562 | * Power management | 1876 | * Power management |
1563 | */ | 1877 | */ |
@@ -1581,17 +1895,7 @@ static int wbsd_resume(struct device *dev, u32 level) | |||
1581 | #define wbsd_resume NULL | 1895 | #define wbsd_resume NULL |
1582 | #endif | 1896 | #endif |
1583 | 1897 | ||
1584 | static void wbsd_release(struct device *dev) | 1898 | static struct platform_device *wbsd_device; |
1585 | { | ||
1586 | } | ||
1587 | |||
1588 | static struct platform_device wbsd_device = { | ||
1589 | .name = DRIVER_NAME, | ||
1590 | .id = -1, | ||
1591 | .dev = { | ||
1592 | .release = wbsd_release, | ||
1593 | }, | ||
1594 | }; | ||
1595 | 1899 | ||
1596 | static struct device_driver wbsd_driver = { | 1900 | static struct device_driver wbsd_driver = { |
1597 | .name = DRIVER_NAME, | 1901 | .name = DRIVER_NAME, |
@@ -1603,6 +1907,17 @@ static struct device_driver wbsd_driver = { | |||
1603 | .resume = wbsd_resume, | 1907 | .resume = wbsd_resume, |
1604 | }; | 1908 | }; |
1605 | 1909 | ||
1910 | #ifdef CONFIG_PNP | ||
1911 | |||
1912 | static struct pnp_driver wbsd_pnp_driver = { | ||
1913 | .name = DRIVER_NAME, | ||
1914 | .id_table = pnp_dev_table, | ||
1915 | .probe = wbsd_pnp_probe, | ||
1916 | .remove = wbsd_pnp_remove, | ||
1917 | }; | ||
1918 | |||
1919 | #endif /* CONFIG_PNP */ | ||
1920 | |||
1606 | /* | 1921 | /* |
1607 | * Module loading/unloading | 1922 | * Module loading/unloading |
1608 | */ | 1923 | */ |
@@ -1615,29 +1930,57 @@ static int __init wbsd_drv_init(void) | |||
1615 | ": Winbond W83L51xD SD/MMC card interface driver, " | 1930 | ": Winbond W83L51xD SD/MMC card interface driver, " |
1616 | DRIVER_VERSION "\n"); | 1931 | DRIVER_VERSION "\n"); |
1617 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); | 1932 | printk(KERN_INFO DRIVER_NAME ": Copyright(c) Pierre Ossman\n"); |
1618 | |||
1619 | result = driver_register(&wbsd_driver); | ||
1620 | if (result < 0) | ||
1621 | return result; | ||
1622 | 1933 | ||
1623 | result = platform_device_register(&wbsd_device); | 1934 | #ifdef CONFIG_PNP |
1624 | if (result < 0) | 1935 | |
1625 | return result; | 1936 | if (!nopnp) |
1937 | { | ||
1938 | result = pnp_register_driver(&wbsd_pnp_driver); | ||
1939 | if (result < 0) | ||
1940 | return result; | ||
1941 | } | ||
1942 | |||
1943 | #endif /* CONFIG_PNP */ | ||
1944 | |||
1945 | if (nopnp) | ||
1946 | { | ||
1947 | result = driver_register(&wbsd_driver); | ||
1948 | if (result < 0) | ||
1949 | return result; | ||
1950 | |||
1951 | wbsd_device = platform_device_register_simple(DRIVER_NAME, -1, | ||
1952 | NULL, 0); | ||
1953 | if (IS_ERR(wbsd_device)) | ||
1954 | return PTR_ERR(wbsd_device); | ||
1955 | } | ||
1626 | 1956 | ||
1627 | return 0; | 1957 | return 0; |
1628 | } | 1958 | } |
1629 | 1959 | ||
1630 | static void __exit wbsd_drv_exit(void) | 1960 | static void __exit wbsd_drv_exit(void) |
1631 | { | 1961 | { |
1632 | platform_device_unregister(&wbsd_device); | 1962 | #ifdef CONFIG_PNP |
1963 | |||
1964 | if (!nopnp) | ||
1965 | pnp_unregister_driver(&wbsd_pnp_driver); | ||
1633 | 1966 | ||
1634 | driver_unregister(&wbsd_driver); | 1967 | #endif /* CONFIG_PNP */ |
1968 | |||
1969 | if (nopnp) | ||
1970 | { | ||
1971 | platform_device_unregister(wbsd_device); | ||
1972 | |||
1973 | driver_unregister(&wbsd_driver); | ||
1974 | } | ||
1635 | 1975 | ||
1636 | DBG("unloaded\n"); | 1976 | DBG("unloaded\n"); |
1637 | } | 1977 | } |
1638 | 1978 | ||
1639 | module_init(wbsd_drv_init); | 1979 | module_init(wbsd_drv_init); |
1640 | module_exit(wbsd_drv_exit); | 1980 | module_exit(wbsd_drv_exit); |
1981 | #ifdef CONFIG_PNP | ||
1982 | module_param(nopnp, uint, 0444); | ||
1983 | #endif | ||
1641 | module_param(io, uint, 0444); | 1984 | module_param(io, uint, 0444); |
1642 | module_param(irq, uint, 0444); | 1985 | module_param(irq, uint, 0444); |
1643 | module_param(dma, int, 0444); | 1986 | module_param(dma, int, 0444); |
@@ -1646,6 +1989,9 @@ MODULE_LICENSE("GPL"); | |||
1646 | MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); | 1989 | MODULE_DESCRIPTION("Winbond W83L51xD SD/MMC card interface driver"); |
1647 | MODULE_VERSION(DRIVER_VERSION); | 1990 | MODULE_VERSION(DRIVER_VERSION); |
1648 | 1991 | ||
1992 | #ifdef CONFIG_PNP | ||
1993 | MODULE_PARM_DESC(nopnp, "Scan for device instead of relying on PNP. (default 0)"); | ||
1994 | #endif | ||
1649 | MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)"); | 1995 | MODULE_PARM_DESC(io, "I/O base to allocate. Must be 8 byte aligned. (default 0x248)"); |
1650 | MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)"); | 1996 | MODULE_PARM_DESC(irq, "IRQ to allocate. (default 6)"); |
1651 | MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)"); | 1997 | MODULE_PARM_DESC(dma, "DMA channel to allocate. -1 for no DMA. (default 2)"); |
diff --git a/drivers/mmc/wbsd.h b/drivers/mmc/wbsd.h index fdc03b56a81f..864f30828d01 100644 --- a/drivers/mmc/wbsd.h +++ b/drivers/mmc/wbsd.h | |||
@@ -35,6 +35,12 @@ const int valid_ids[] = { | |||
35 | 35 | ||
36 | #define DEVICE_SD 0x03 | 36 | #define DEVICE_SD 0x03 |
37 | 37 | ||
38 | #define WBSD_PINS_DAT3_HI 0x20 | ||
39 | #define WBSD_PINS_DAT3_OUT 0x10 | ||
40 | #define WBSD_PINS_GP11_HI 0x04 | ||
41 | #define WBSD_PINS_DETECT_GP11 0x02 | ||
42 | #define WBSD_PINS_DETECT_DAT3 0x01 | ||
43 | |||
38 | #define WBSD_CMDR 0x00 | 44 | #define WBSD_CMDR 0x00 |
39 | #define WBSD_DFR 0x01 | 45 | #define WBSD_DFR 0x01 |
40 | #define WBSD_EIR 0x02 | 46 | #define WBSD_EIR 0x02 |
@@ -133,6 +139,7 @@ const int valid_ids[] = { | |||
133 | #define WBSD_CRC_OK 0x05 /* S010E (00101) */ | 139 | #define WBSD_CRC_OK 0x05 /* S010E (00101) */ |
134 | #define WBSD_CRC_FAIL 0x0B /* S101E (01011) */ | 140 | #define WBSD_CRC_FAIL 0x0B /* S101E (01011) */ |
135 | 141 | ||
142 | #define WBSD_DMA_SIZE 65536 | ||
136 | 143 | ||
137 | struct wbsd_host | 144 | struct wbsd_host |
138 | { | 145 | { |
@@ -140,6 +147,11 @@ struct wbsd_host | |||
140 | 147 | ||
141 | spinlock_t lock; /* Mutex */ | 148 | spinlock_t lock; /* Mutex */ |
142 | 149 | ||
150 | int flags; /* Driver states */ | ||
151 | |||
152 | #define WBSD_FCARD_PRESENT (1<<0) /* Card is present */ | ||
153 | #define WBSD_FIGNORE_DETECT (1<<1) /* Ignore card detection */ | ||
154 | |||
143 | struct mmc_request* mrq; /* Current request */ | 155 | struct mmc_request* mrq; /* Current request */ |
144 | 156 | ||
145 | u8 isr; /* Accumulated ISR */ | 157 | u8 isr; /* Accumulated ISR */ |
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index 43e2ac532f82..b5e076043431 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c | |||
@@ -1581,7 +1581,8 @@ vortex_up(struct net_device *dev) | |||
1581 | 1581 | ||
1582 | if (VORTEX_PCI(vp)) { | 1582 | if (VORTEX_PCI(vp)) { |
1583 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ | 1583 | pci_set_power_state(VORTEX_PCI(vp), PCI_D0); /* Go active */ |
1584 | pci_restore_state(VORTEX_PCI(vp)); | 1584 | if (vp->pm_state_valid) |
1585 | pci_restore_state(VORTEX_PCI(vp)); | ||
1585 | pci_enable_device(VORTEX_PCI(vp)); | 1586 | pci_enable_device(VORTEX_PCI(vp)); |
1586 | } | 1587 | } |
1587 | 1588 | ||
@@ -2741,6 +2742,7 @@ vortex_down(struct net_device *dev, int final_down) | |||
2741 | outl(0, ioaddr + DownListPtr); | 2742 | outl(0, ioaddr + DownListPtr); |
2742 | 2743 | ||
2743 | if (final_down && VORTEX_PCI(vp)) { | 2744 | if (final_down && VORTEX_PCI(vp)) { |
2745 | vp->pm_state_valid = 1; | ||
2744 | pci_save_state(VORTEX_PCI(vp)); | 2746 | pci_save_state(VORTEX_PCI(vp)); |
2745 | acpi_set_WOL(dev); | 2747 | acpi_set_WOL(dev); |
2746 | } | 2748 | } |
@@ -3243,9 +3245,10 @@ static void acpi_set_WOL(struct net_device *dev) | |||
3243 | outw(RxEnable, ioaddr + EL3_CMD); | 3245 | outw(RxEnable, ioaddr + EL3_CMD); |
3244 | 3246 | ||
3245 | pci_enable_wake(VORTEX_PCI(vp), 0, 1); | 3247 | pci_enable_wake(VORTEX_PCI(vp), 0, 1); |
3248 | |||
3249 | /* Change the power state to D3; RxEnable doesn't take effect. */ | ||
3250 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | ||
3246 | } | 3251 | } |
3247 | /* Change the power state to D3; RxEnable doesn't take effect. */ | ||
3248 | pci_set_power_state(VORTEX_PCI(vp), PCI_D3hot); | ||
3249 | } | 3252 | } |
3250 | 3253 | ||
3251 | 3254 | ||
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6202b10dbb4d..e038d55e4f6f 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -187,7 +187,7 @@ obj-$(CONFIG_TR) += tokenring/ | |||
187 | obj-$(CONFIG_WAN) += wan/ | 187 | obj-$(CONFIG_WAN) += wan/ |
188 | obj-$(CONFIG_ARCNET) += arcnet/ | 188 | obj-$(CONFIG_ARCNET) += arcnet/ |
189 | obj-$(CONFIG_NET_PCMCIA) += pcmcia/ | 189 | obj-$(CONFIG_NET_PCMCIA) += pcmcia/ |
190 | obj-$(CONFIG_NET_WIRELESS) += wireless/ | 190 | obj-$(CONFIG_NET_RADIO) += wireless/ |
191 | obj-$(CONFIG_NET_TULIP) += tulip/ | 191 | obj-$(CONFIG_NET_TULIP) += tulip/ |
192 | obj-$(CONFIG_HAMRADIO) += hamradio/ | 192 | obj-$(CONFIG_HAMRADIO) += hamradio/ |
193 | obj-$(CONFIG_IRDA) += irda/ | 193 | obj-$(CONFIG_IRDA) += irda/ |
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index fc519377b5aa..fb433325aa27 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)Space.c 1.0.7 08/12/93 | 8 | * Version: @(#)Space.c 1.0.7 08/12/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Donald J. Becker, <becker@scyld.com> | 12 | * Donald J. Becker, <becker@scyld.com> |
13 | * | 13 | * |
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 2161c2d585f0..9edaa183227a 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c | |||
@@ -65,7 +65,7 @@ static const char *version = | |||
65 | #include <linux/etherdevice.h> | 65 | #include <linux/etherdevice.h> |
66 | #include <linux/skbuff.h> | 66 | #include <linux/skbuff.h> |
67 | #include <linux/if_arp.h> | 67 | #include <linux/if_arp.h> |
68 | #include <linux/if_ltalk.h> /* For ltalk_setup() */ | 68 | #include <linux/if_ltalk.h> |
69 | #include <linux/delay.h> /* For udelay() */ | 69 | #include <linux/delay.h> /* For udelay() */ |
70 | #include <linux/atalk.h> | 70 | #include <linux/atalk.h> |
71 | #include <linux/spinlock.h> | 71 | #include <linux/spinlock.h> |
@@ -223,7 +223,7 @@ struct net_device * __init cops_probe(int unit) | |||
223 | int base_addr; | 223 | int base_addr; |
224 | int err = 0; | 224 | int err = 0; |
225 | 225 | ||
226 | dev = alloc_netdev(sizeof(struct cops_local), "lt%d", ltalk_setup); | 226 | dev = alloc_ltalkdev(sizeof(struct cops_local)); |
227 | if (!dev) | 227 | if (!dev) |
228 | return ERR_PTR(-ENOMEM); | 228 | return ERR_PTR(-ENOMEM); |
229 | 229 | ||
diff --git a/drivers/net/appletalk/cops_ffdrv.h b/drivers/net/appletalk/cops_ffdrv.h index 4131b4a7a65b..31cf8c9c947f 100644 --- a/drivers/net/appletalk/cops_ffdrv.h +++ b/drivers/net/appletalk/cops_ffdrv.h | |||
@@ -28,7 +28,7 @@ | |||
28 | 28 | ||
29 | #ifdef CONFIG_COPS_DAYNA | 29 | #ifdef CONFIG_COPS_DAYNA |
30 | 30 | ||
31 | unsigned char ffdrv_code[] = { | 31 | static const unsigned char ffdrv_code[] = { |
32 | 58,3,0,50,228,149,33,255,255,34,226,149, | 32 | 58,3,0,50,228,149,33,255,255,34,226,149, |
33 | 249,17,40,152,33,202,154,183,237,82,77,68, | 33 | 249,17,40,152,33,202,154,183,237,82,77,68, |
34 | 11,107,98,19,54,0,237,176,175,50,80,0, | 34 | 11,107,98,19,54,0,237,176,175,50,80,0, |
diff --git a/drivers/net/appletalk/cops_ltdrv.h b/drivers/net/appletalk/cops_ltdrv.h index 05de66dd9206..4afb8e18ba65 100644 --- a/drivers/net/appletalk/cops_ltdrv.h +++ b/drivers/net/appletalk/cops_ltdrv.h | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | #ifdef CONFIG_COPS_TANGENT | 28 | #ifdef CONFIG_COPS_TANGENT |
29 | 29 | ||
30 | unsigned char ltdrv_code[] = { | 30 | static const unsigned char ltdrv_code[] = { |
31 | 58,3,0,50,148,10,33,143,15,62,85,119, | 31 | 58,3,0,50,148,10,33,143,15,62,85,119, |
32 | 190,32,9,62,170,119,190,32,3,35,24,241, | 32 | 190,32,9,62,170,119,190,32,3,35,24,241, |
33 | 34,146,10,249,17,150,10,33,143,15,183,237, | 33 | 34,146,10,249,17,150,10,33,143,15,183,237, |
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index ad8e943231a1..db4f369637b6 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c | |||
@@ -1039,7 +1039,7 @@ struct net_device * __init ltpc_probe(void) | |||
1039 | unsigned long f; | 1039 | unsigned long f; |
1040 | unsigned long timeout; | 1040 | unsigned long timeout; |
1041 | 1041 | ||
1042 | dev = alloc_netdev(sizeof(struct ltpc_private), "lt%d", ltalk_setup); | 1042 | dev = alloc_ltalkdev(sizeof(struct ltpc_private)); |
1043 | if (!dev) | 1043 | if (!dev) |
1044 | goto out; | 1044 | goto out; |
1045 | 1045 | ||
diff --git a/drivers/net/arcnet/capmode.c b/drivers/net/arcnet/capmode.c index 16e155b04129..66485585ab39 100644 --- a/drivers/net/arcnet/capmode.c +++ b/drivers/net/arcnet/capmode.c | |||
@@ -48,7 +48,7 @@ static int prepare_tx(struct net_device *dev, struct archdr *pkt, int length, | |||
48 | static int ack_tx(struct net_device *dev, int acked); | 48 | static int ack_tx(struct net_device *dev, int acked); |
49 | 49 | ||
50 | 50 | ||
51 | struct ArcProto capmode_proto = | 51 | static struct ArcProto capmode_proto = |
52 | { | 52 | { |
53 | 'r', | 53 | 'r', |
54 | XMTU, | 54 | XMTU, |
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index ab44358ddbfc..6482d994d489 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c | |||
@@ -1595,7 +1595,7 @@ static struct ethtool_ops emac_ethtool_ops = { | |||
1595 | static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 1595 | static int emac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
1596 | { | 1596 | { |
1597 | struct ocp_enet_private *fep = dev->priv; | 1597 | struct ocp_enet_private *fep = dev->priv; |
1598 | uint *data = (uint *) & rq->ifr_ifru; | 1598 | uint16_t *data = (uint16_t *) & rq->ifr_ifru; |
1599 | 1599 | ||
1600 | switch (cmd) { | 1600 | switch (cmd) { |
1601 | case SIOCGMIIPHY: | 1601 | case SIOCGMIIPHY: |
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index 2ffc31708d5f..b33111e21313 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)loopback.c 1.0.4b 08/16/93 | 8 | * Version: @(#)loopback.c 1.0.4b 08/16/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Donald Becker, <becker@scyld.com> | 12 | * Donald Becker, <becker@scyld.com> |
13 | * | 13 | * |
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 058c70c6f1ac..4d2bdbdd34e8 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -61,8 +61,8 @@ | |||
61 | 61 | ||
62 | #define DRV_MODULE_NAME "tg3" | 62 | #define DRV_MODULE_NAME "tg3" |
63 | #define PFX DRV_MODULE_NAME ": " | 63 | #define PFX DRV_MODULE_NAME ": " |
64 | #define DRV_MODULE_VERSION "3.26" | 64 | #define DRV_MODULE_VERSION "3.27" |
65 | #define DRV_MODULE_RELDATE "April 24, 2005" | 65 | #define DRV_MODULE_RELDATE "May 5, 2005" |
66 | 66 | ||
67 | #define TG3_DEF_MAC_MODE 0 | 67 | #define TG3_DEF_MAC_MODE 0 |
68 | #define TG3_DEF_RX_MODE 0 | 68 | #define TG3_DEF_RX_MODE 0 |
@@ -420,7 +420,8 @@ static void tg3_enable_ints(struct tg3 *tp) | |||
420 | { | 420 | { |
421 | tw32(TG3PCI_MISC_HOST_CTRL, | 421 | tw32(TG3PCI_MISC_HOST_CTRL, |
422 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 422 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
423 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); | 423 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
424 | (tp->last_tag << 24)); | ||
424 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 425 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); |
425 | 426 | ||
426 | tg3_cond_int(tp); | 427 | tg3_cond_int(tp); |
@@ -455,10 +456,16 @@ static void tg3_restart_ints(struct tg3 *tp) | |||
455 | { | 456 | { |
456 | tw32(TG3PCI_MISC_HOST_CTRL, | 457 | tw32(TG3PCI_MISC_HOST_CTRL, |
457 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); | 458 | (tp->misc_host_ctrl & ~MISC_HOST_CTRL_MASK_PCI_INT)); |
458 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000000); | 459 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
460 | tp->last_tag << 24); | ||
459 | mmiowb(); | 461 | mmiowb(); |
460 | 462 | ||
461 | if (tg3_has_work(tp)) | 463 | /* When doing tagged status, this work check is unnecessary. |
464 | * The last_tag we write above tells the chip which piece of | ||
465 | * work we've completed. | ||
466 | */ | ||
467 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && | ||
468 | tg3_has_work(tp)) | ||
462 | tw32(HOSTCC_MODE, tp->coalesce_mode | | 469 | tw32(HOSTCC_MODE, tp->coalesce_mode | |
463 | (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); | 470 | (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); |
464 | } | 471 | } |
@@ -2500,7 +2507,7 @@ static int tg3_setup_phy(struct tg3 *tp, int force_reset) | |||
2500 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 2507 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
2501 | if (netif_carrier_ok(tp->dev)) { | 2508 | if (netif_carrier_ok(tp->dev)) { |
2502 | tw32(HOSTCC_STAT_COAL_TICKS, | 2509 | tw32(HOSTCC_STAT_COAL_TICKS, |
2503 | DEFAULT_STAT_COAL_TICKS); | 2510 | tp->coal.stats_block_coalesce_usecs); |
2504 | } else { | 2511 | } else { |
2505 | tw32(HOSTCC_STAT_COAL_TICKS, 0); | 2512 | tw32(HOSTCC_STAT_COAL_TICKS, 0); |
2506 | } | 2513 | } |
@@ -2886,7 +2893,6 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2886 | * All RX "locking" is done by ensuring outside | 2893 | * All RX "locking" is done by ensuring outside |
2887 | * code synchronizes with dev->poll() | 2894 | * code synchronizes with dev->poll() |
2888 | */ | 2895 | */ |
2889 | done = 1; | ||
2890 | if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { | 2896 | if (sblk->idx[0].rx_producer != tp->rx_rcb_ptr) { |
2891 | int orig_budget = *budget; | 2897 | int orig_budget = *budget; |
2892 | int work_done; | 2898 | int work_done; |
@@ -2898,12 +2904,14 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
2898 | 2904 | ||
2899 | *budget -= work_done; | 2905 | *budget -= work_done; |
2900 | netdev->quota -= work_done; | 2906 | netdev->quota -= work_done; |
2901 | |||
2902 | if (work_done >= orig_budget) | ||
2903 | done = 0; | ||
2904 | } | 2907 | } |
2905 | 2908 | ||
2909 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | ||
2910 | tp->last_tag = sblk->status_tag; | ||
2911 | rmb(); | ||
2912 | |||
2906 | /* if no more work, tell net stack and NIC we're done */ | 2913 | /* if no more work, tell net stack and NIC we're done */ |
2914 | done = !tg3_has_work(tp); | ||
2907 | if (done) { | 2915 | if (done) { |
2908 | spin_lock_irqsave(&tp->lock, flags); | 2916 | spin_lock_irqsave(&tp->lock, flags); |
2909 | __netif_rx_complete(netdev); | 2917 | __netif_rx_complete(netdev); |
@@ -2928,22 +2936,21 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
2928 | spin_lock_irqsave(&tp->lock, flags); | 2936 | spin_lock_irqsave(&tp->lock, flags); |
2929 | 2937 | ||
2930 | /* | 2938 | /* |
2931 | * writing any value to intr-mbox-0 clears PCI INTA# and | 2939 | * Writing any value to intr-mbox-0 clears PCI INTA# and |
2932 | * chip-internal interrupt pending events. | 2940 | * chip-internal interrupt pending events. |
2933 | * writing non-zero to intr-mbox-0 additional tells the | 2941 | * Writing non-zero to intr-mbox-0 additional tells the |
2934 | * NIC to stop sending us irqs, engaging "in-intr-handler" | 2942 | * NIC to stop sending us irqs, engaging "in-intr-handler" |
2935 | * event coalescing. | 2943 | * event coalescing. |
2936 | */ | 2944 | */ |
2937 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 2945 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
2946 | tp->last_tag = sblk->status_tag; | ||
2938 | sblk->status &= ~SD_STATUS_UPDATED; | 2947 | sblk->status &= ~SD_STATUS_UPDATED; |
2939 | |||
2940 | if (likely(tg3_has_work(tp))) | 2948 | if (likely(tg3_has_work(tp))) |
2941 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 2949 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
2942 | else { | 2950 | else { |
2943 | /* no work, re-enable interrupts | 2951 | /* No work, re-enable interrupts. */ |
2944 | */ | ||
2945 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 2952 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
2946 | 0x00000000); | 2953 | tp->last_tag << 24); |
2947 | } | 2954 | } |
2948 | 2955 | ||
2949 | spin_unlock_irqrestore(&tp->lock, flags); | 2956 | spin_unlock_irqrestore(&tp->lock, flags); |
@@ -2969,21 +2976,62 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2969 | if ((sblk->status & SD_STATUS_UPDATED) || | 2976 | if ((sblk->status & SD_STATUS_UPDATED) || |
2970 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | 2977 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { |
2971 | /* | 2978 | /* |
2972 | * writing any value to intr-mbox-0 clears PCI INTA# and | 2979 | * Writing any value to intr-mbox-0 clears PCI INTA# and |
2973 | * chip-internal interrupt pending events. | 2980 | * chip-internal interrupt pending events. |
2974 | * writing non-zero to intr-mbox-0 additional tells the | 2981 | * Writing non-zero to intr-mbox-0 additional tells the |
2975 | * NIC to stop sending us irqs, engaging "in-intr-handler" | 2982 | * NIC to stop sending us irqs, engaging "in-intr-handler" |
2976 | * event coalescing. | 2983 | * event coalescing. |
2977 | */ | 2984 | */ |
2978 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 2985 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
2979 | 0x00000001); | 2986 | 0x00000001); |
2987 | sblk->status &= ~SD_STATUS_UPDATED; | ||
2988 | if (likely(tg3_has_work(tp))) | ||
2989 | netif_rx_schedule(dev); /* schedule NAPI poll */ | ||
2990 | else { | ||
2991 | /* No work, shared interrupt perhaps? re-enable | ||
2992 | * interrupts, and flush that PCI write | ||
2993 | */ | ||
2994 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
2995 | 0x00000000); | ||
2996 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | ||
2997 | } | ||
2998 | } else { /* shared interrupt */ | ||
2999 | handled = 0; | ||
3000 | } | ||
3001 | |||
3002 | spin_unlock_irqrestore(&tp->lock, flags); | ||
3003 | |||
3004 | return IRQ_RETVAL(handled); | ||
3005 | } | ||
3006 | |||
3007 | static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *regs) | ||
3008 | { | ||
3009 | struct net_device *dev = dev_id; | ||
3010 | struct tg3 *tp = netdev_priv(dev); | ||
3011 | struct tg3_hw_status *sblk = tp->hw_status; | ||
3012 | unsigned long flags; | ||
3013 | unsigned int handled = 1; | ||
3014 | |||
3015 | spin_lock_irqsave(&tp->lock, flags); | ||
3016 | |||
3017 | /* In INTx mode, it is possible for the interrupt to arrive at | ||
3018 | * the CPU before the status block posted prior to the interrupt. | ||
3019 | * Reading the PCI State register will confirm whether the | ||
3020 | * interrupt is ours and will flush the status block. | ||
3021 | */ | ||
3022 | if ((sblk->status & SD_STATUS_UPDATED) || | ||
3023 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | ||
2980 | /* | 3024 | /* |
2981 | * Flush PCI write. This also guarantees that our | 3025 | * writing any value to intr-mbox-0 clears PCI INTA# and |
2982 | * status block has been flushed to host memory. | 3026 | * chip-internal interrupt pending events. |
3027 | * writing non-zero to intr-mbox-0 additional tells the | ||
3028 | * NIC to stop sending us irqs, engaging "in-intr-handler" | ||
3029 | * event coalescing. | ||
2983 | */ | 3030 | */ |
2984 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 3031 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3032 | 0x00000001); | ||
3033 | tp->last_tag = sblk->status_tag; | ||
2985 | sblk->status &= ~SD_STATUS_UPDATED; | 3034 | sblk->status &= ~SD_STATUS_UPDATED; |
2986 | |||
2987 | if (likely(tg3_has_work(tp))) | 3035 | if (likely(tg3_has_work(tp))) |
2988 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3036 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
2989 | else { | 3037 | else { |
@@ -2991,7 +3039,7 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
2991 | * interrupts, and flush that PCI write | 3039 | * interrupts, and flush that PCI write |
2992 | */ | 3040 | */ |
2993 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3041 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
2994 | 0x00000000); | 3042 | tp->last_tag << 24); |
2995 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); | 3043 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); |
2996 | } | 3044 | } |
2997 | } else { /* shared interrupt */ | 3045 | } else { /* shared interrupt */ |
@@ -3020,7 +3068,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3020 | } | 3068 | } |
3021 | 3069 | ||
3022 | static int tg3_init_hw(struct tg3 *); | 3070 | static int tg3_init_hw(struct tg3 *); |
3023 | static int tg3_halt(struct tg3 *); | 3071 | static int tg3_halt(struct tg3 *, int); |
3024 | 3072 | ||
3025 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3073 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3026 | static void tg3_poll_controller(struct net_device *dev) | 3074 | static void tg3_poll_controller(struct net_device *dev) |
@@ -3044,7 +3092,7 @@ static void tg3_reset_task(void *_data) | |||
3044 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3092 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
3045 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3093 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
3046 | 3094 | ||
3047 | tg3_halt(tp); | 3095 | tg3_halt(tp, 0); |
3048 | tg3_init_hw(tp); | 3096 | tg3_init_hw(tp); |
3049 | 3097 | ||
3050 | tg3_netif_start(tp); | 3098 | tg3_netif_start(tp); |
@@ -3390,7 +3438,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3390 | spin_lock_irq(&tp->lock); | 3438 | spin_lock_irq(&tp->lock); |
3391 | spin_lock(&tp->tx_lock); | 3439 | spin_lock(&tp->tx_lock); |
3392 | 3440 | ||
3393 | tg3_halt(tp); | 3441 | tg3_halt(tp, 1); |
3394 | 3442 | ||
3395 | tg3_set_mtu(dev, tp, new_mtu); | 3443 | tg3_set_mtu(dev, tp, new_mtu); |
3396 | 3444 | ||
@@ -3657,7 +3705,7 @@ err_out: | |||
3657 | /* To stop a block, clear the enable bit and poll till it | 3705 | /* To stop a block, clear the enable bit and poll till it |
3658 | * clears. tp->lock is held. | 3706 | * clears. tp->lock is held. |
3659 | */ | 3707 | */ |
3660 | static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit) | 3708 | static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit, int silent) |
3661 | { | 3709 | { |
3662 | unsigned int i; | 3710 | unsigned int i; |
3663 | u32 val; | 3711 | u32 val; |
@@ -3690,7 +3738,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit) | |||
3690 | break; | 3738 | break; |
3691 | } | 3739 | } |
3692 | 3740 | ||
3693 | if (i == MAX_WAIT_CNT) { | 3741 | if (i == MAX_WAIT_CNT && !silent) { |
3694 | printk(KERN_ERR PFX "tg3_stop_block timed out, " | 3742 | printk(KERN_ERR PFX "tg3_stop_block timed out, " |
3695 | "ofs=%lx enable_bit=%x\n", | 3743 | "ofs=%lx enable_bit=%x\n", |
3696 | ofs, enable_bit); | 3744 | ofs, enable_bit); |
@@ -3701,7 +3749,7 @@ static int tg3_stop_block(struct tg3 *tp, unsigned long ofs, u32 enable_bit) | |||
3701 | } | 3749 | } |
3702 | 3750 | ||
3703 | /* tp->lock is held. */ | 3751 | /* tp->lock is held. */ |
3704 | static int tg3_abort_hw(struct tg3 *tp) | 3752 | static int tg3_abort_hw(struct tg3 *tp, int silent) |
3705 | { | 3753 | { |
3706 | int i, err; | 3754 | int i, err; |
3707 | 3755 | ||
@@ -3711,22 +3759,20 @@ static int tg3_abort_hw(struct tg3 *tp) | |||
3711 | tw32_f(MAC_RX_MODE, tp->rx_mode); | 3759 | tw32_f(MAC_RX_MODE, tp->rx_mode); |
3712 | udelay(10); | 3760 | udelay(10); |
3713 | 3761 | ||
3714 | err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE); | 3762 | err = tg3_stop_block(tp, RCVBDI_MODE, RCVBDI_MODE_ENABLE, silent); |
3715 | err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE); | 3763 | err |= tg3_stop_block(tp, RCVLPC_MODE, RCVLPC_MODE_ENABLE, silent); |
3716 | err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE); | 3764 | err |= tg3_stop_block(tp, RCVLSC_MODE, RCVLSC_MODE_ENABLE, silent); |
3717 | err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE); | 3765 | err |= tg3_stop_block(tp, RCVDBDI_MODE, RCVDBDI_MODE_ENABLE, silent); |
3718 | err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE); | 3766 | err |= tg3_stop_block(tp, RCVDCC_MODE, RCVDCC_MODE_ENABLE, silent); |
3719 | err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE); | 3767 | err |= tg3_stop_block(tp, RCVCC_MODE, RCVCC_MODE_ENABLE, silent); |
3720 | 3768 | ||
3721 | err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE); | 3769 | err |= tg3_stop_block(tp, SNDBDS_MODE, SNDBDS_MODE_ENABLE, silent); |
3722 | err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE); | 3770 | err |= tg3_stop_block(tp, SNDBDI_MODE, SNDBDI_MODE_ENABLE, silent); |
3723 | err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE); | 3771 | err |= tg3_stop_block(tp, SNDDATAI_MODE, SNDDATAI_MODE_ENABLE, silent); |
3724 | err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE); | 3772 | err |= tg3_stop_block(tp, RDMAC_MODE, RDMAC_MODE_ENABLE, silent); |
3725 | err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE); | 3773 | err |= tg3_stop_block(tp, SNDDATAC_MODE, SNDDATAC_MODE_ENABLE, silent); |
3726 | err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE); | 3774 | err |= tg3_stop_block(tp, DMAC_MODE, DMAC_MODE_ENABLE, silent); |
3727 | err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE); | 3775 | err |= tg3_stop_block(tp, SNDBDC_MODE, SNDBDC_MODE_ENABLE, silent); |
3728 | if (err) | ||
3729 | goto out; | ||
3730 | 3776 | ||
3731 | tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; | 3777 | tp->mac_mode &= ~MAC_MODE_TDE_ENABLE; |
3732 | tw32_f(MAC_MODE, tp->mac_mode); | 3778 | tw32_f(MAC_MODE, tp->mac_mode); |
@@ -3744,27 +3790,24 @@ static int tg3_abort_hw(struct tg3 *tp) | |||
3744 | printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, " | 3790 | printk(KERN_ERR PFX "tg3_abort_hw timed out for %s, " |
3745 | "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n", | 3791 | "TX_MODE_ENABLE will not clear MAC_TX_MODE=%08x\n", |
3746 | tp->dev->name, tr32(MAC_TX_MODE)); | 3792 | tp->dev->name, tr32(MAC_TX_MODE)); |
3747 | return -ENODEV; | 3793 | err |= -ENODEV; |
3748 | } | 3794 | } |
3749 | 3795 | ||
3750 | err = tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE); | 3796 | err |= tg3_stop_block(tp, HOSTCC_MODE, HOSTCC_MODE_ENABLE, silent); |
3751 | err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE); | 3797 | err |= tg3_stop_block(tp, WDMAC_MODE, WDMAC_MODE_ENABLE, silent); |
3752 | err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE); | 3798 | err |= tg3_stop_block(tp, MBFREE_MODE, MBFREE_MODE_ENABLE, silent); |
3753 | 3799 | ||
3754 | tw32(FTQ_RESET, 0xffffffff); | 3800 | tw32(FTQ_RESET, 0xffffffff); |
3755 | tw32(FTQ_RESET, 0x00000000); | 3801 | tw32(FTQ_RESET, 0x00000000); |
3756 | 3802 | ||
3757 | err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE); | 3803 | err |= tg3_stop_block(tp, BUFMGR_MODE, BUFMGR_MODE_ENABLE, silent); |
3758 | err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE); | 3804 | err |= tg3_stop_block(tp, MEMARB_MODE, MEMARB_MODE_ENABLE, silent); |
3759 | if (err) | ||
3760 | goto out; | ||
3761 | 3805 | ||
3762 | if (tp->hw_status) | 3806 | if (tp->hw_status) |
3763 | memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); | 3807 | memset(tp->hw_status, 0, TG3_HW_STATUS_SIZE); |
3764 | if (tp->hw_stats) | 3808 | if (tp->hw_stats) |
3765 | memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); | 3809 | memset(tp->hw_stats, 0, sizeof(struct tg3_hw_stats)); |
3766 | 3810 | ||
3767 | out: | ||
3768 | return err; | 3811 | return err; |
3769 | } | 3812 | } |
3770 | 3813 | ||
@@ -4086,7 +4129,7 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
4086 | } | 4129 | } |
4087 | 4130 | ||
4088 | /* tp->lock is held. */ | 4131 | /* tp->lock is held. */ |
4089 | static int tg3_halt(struct tg3 *tp) | 4132 | static int tg3_halt(struct tg3 *tp, int silent) |
4090 | { | 4133 | { |
4091 | int err; | 4134 | int err; |
4092 | 4135 | ||
@@ -4094,7 +4137,7 @@ static int tg3_halt(struct tg3 *tp) | |||
4094 | 4137 | ||
4095 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); | 4138 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); |
4096 | 4139 | ||
4097 | tg3_abort_hw(tp); | 4140 | tg3_abort_hw(tp, silent); |
4098 | err = tg3_chip_reset(tp); | 4141 | err = tg3_chip_reset(tp); |
4099 | 4142 | ||
4100 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); | 4143 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); |
@@ -5049,6 +5092,27 @@ static void tg3_set_bdinfo(struct tg3 *tp, u32 bdinfo_addr, | |||
5049 | } | 5092 | } |
5050 | 5093 | ||
5051 | static void __tg3_set_rx_mode(struct net_device *); | 5094 | static void __tg3_set_rx_mode(struct net_device *); |
5095 | static void tg3_set_coalesce(struct tg3 *tp, struct ethtool_coalesce *ec) | ||
5096 | { | ||
5097 | tw32(HOSTCC_RXCOL_TICKS, ec->rx_coalesce_usecs); | ||
5098 | tw32(HOSTCC_TXCOL_TICKS, ec->tx_coalesce_usecs); | ||
5099 | tw32(HOSTCC_RXMAX_FRAMES, ec->rx_max_coalesced_frames); | ||
5100 | tw32(HOSTCC_TXMAX_FRAMES, ec->tx_max_coalesced_frames); | ||
5101 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | ||
5102 | tw32(HOSTCC_RXCOAL_TICK_INT, ec->rx_coalesce_usecs_irq); | ||
5103 | tw32(HOSTCC_TXCOAL_TICK_INT, ec->tx_coalesce_usecs_irq); | ||
5104 | } | ||
5105 | tw32(HOSTCC_RXCOAL_MAXF_INT, ec->rx_max_coalesced_frames_irq); | ||
5106 | tw32(HOSTCC_TXCOAL_MAXF_INT, ec->tx_max_coalesced_frames_irq); | ||
5107 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | ||
5108 | u32 val = ec->stats_block_coalesce_usecs; | ||
5109 | |||
5110 | if (!netif_carrier_ok(tp->dev)) | ||
5111 | val = 0; | ||
5112 | |||
5113 | tw32(HOSTCC_STAT_COAL_TICKS, val); | ||
5114 | } | ||
5115 | } | ||
5052 | 5116 | ||
5053 | /* tp->lock is held. */ | 5117 | /* tp->lock is held. */ |
5054 | static int tg3_reset_hw(struct tg3 *tp) | 5118 | static int tg3_reset_hw(struct tg3 *tp) |
@@ -5063,9 +5127,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5063 | tg3_write_sig_pre_reset(tp, RESET_KIND_INIT); | 5127 | tg3_write_sig_pre_reset(tp, RESET_KIND_INIT); |
5064 | 5128 | ||
5065 | if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { | 5129 | if (tp->tg3_flags & TG3_FLAG_INIT_COMPLETE) { |
5066 | err = tg3_abort_hw(tp); | 5130 | tg3_abort_hw(tp, 1); |
5067 | if (err) | ||
5068 | return err; | ||
5069 | } | 5131 | } |
5070 | 5132 | ||
5071 | err = tg3_chip_reset(tp); | 5133 | err = tg3_chip_reset(tp); |
@@ -5373,16 +5435,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5373 | udelay(10); | 5435 | udelay(10); |
5374 | } | 5436 | } |
5375 | 5437 | ||
5376 | tw32(HOSTCC_RXCOL_TICKS, 0); | 5438 | tg3_set_coalesce(tp, &tp->coal); |
5377 | tw32(HOSTCC_TXCOL_TICKS, LOW_TXCOL_TICKS); | ||
5378 | tw32(HOSTCC_RXMAX_FRAMES, 1); | ||
5379 | tw32(HOSTCC_TXMAX_FRAMES, LOW_RXMAX_FRAMES); | ||
5380 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | ||
5381 | tw32(HOSTCC_RXCOAL_TICK_INT, 0); | ||
5382 | tw32(HOSTCC_TXCOAL_TICK_INT, 0); | ||
5383 | } | ||
5384 | tw32(HOSTCC_RXCOAL_MAXF_INT, 1); | ||
5385 | tw32(HOSTCC_TXCOAL_MAXF_INT, 0); | ||
5386 | 5439 | ||
5387 | /* set status block DMA address */ | 5440 | /* set status block DMA address */ |
5388 | tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, | 5441 | tw32(HOSTCC_STATUS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, |
@@ -5395,8 +5448,6 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5395 | * the tg3_periodic_fetch_stats call there, and | 5448 | * the tg3_periodic_fetch_stats call there, and |
5396 | * tg3_get_stats to see how this works for 5705/5750 chips. | 5449 | * tg3_get_stats to see how this works for 5705/5750 chips. |
5397 | */ | 5450 | */ |
5398 | tw32(HOSTCC_STAT_COAL_TICKS, | ||
5399 | DEFAULT_STAT_COAL_TICKS); | ||
5400 | tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, | 5451 | tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_HIGH, |
5401 | ((u64) tp->stats_mapping >> 32)); | 5452 | ((u64) tp->stats_mapping >> 32)); |
5402 | tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, | 5453 | tw32(HOSTCC_STATS_BLK_HOST_ADDR + TG3_64BIT_REG_LOW, |
@@ -5452,7 +5503,8 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5452 | udelay(100); | 5503 | udelay(100); |
5453 | 5504 | ||
5454 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); | 5505 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0); |
5455 | tr32(MAILBOX_INTERRUPT_0); | 5506 | tr32(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW); |
5507 | tp->last_tag = 0; | ||
5456 | 5508 | ||
5457 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { | 5509 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) { |
5458 | tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); | 5510 | tw32_f(DMAC_MODE, DMAC_MODE_ENABLE); |
@@ -5730,31 +5782,33 @@ static void tg3_timer(unsigned long __opaque) | |||
5730 | spin_lock_irqsave(&tp->lock, flags); | 5782 | spin_lock_irqsave(&tp->lock, flags); |
5731 | spin_lock(&tp->tx_lock); | 5783 | spin_lock(&tp->tx_lock); |
5732 | 5784 | ||
5733 | /* All of this garbage is because when using non-tagged | 5785 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { |
5734 | * IRQ status the mailbox/status_block protocol the chip | 5786 | /* All of this garbage is because when using non-tagged |
5735 | * uses with the cpu is race prone. | 5787 | * IRQ status the mailbox/status_block protocol the chip |
5736 | */ | 5788 | * uses with the cpu is race prone. |
5737 | if (tp->hw_status->status & SD_STATUS_UPDATED) { | 5789 | */ |
5738 | tw32(GRC_LOCAL_CTRL, | 5790 | if (tp->hw_status->status & SD_STATUS_UPDATED) { |
5739 | tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); | 5791 | tw32(GRC_LOCAL_CTRL, |
5740 | } else { | 5792 | tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); |
5741 | tw32(HOSTCC_MODE, tp->coalesce_mode | | 5793 | } else { |
5742 | (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); | 5794 | tw32(HOSTCC_MODE, tp->coalesce_mode | |
5743 | } | 5795 | (HOSTCC_MODE_ENABLE | HOSTCC_MODE_NOW)); |
5796 | } | ||
5744 | 5797 | ||
5745 | if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 5798 | if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
5746 | tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; | 5799 | tp->tg3_flags2 |= TG3_FLG2_RESTART_TIMER; |
5747 | spin_unlock(&tp->tx_lock); | 5800 | spin_unlock(&tp->tx_lock); |
5748 | spin_unlock_irqrestore(&tp->lock, flags); | 5801 | spin_unlock_irqrestore(&tp->lock, flags); |
5749 | schedule_work(&tp->reset_task); | 5802 | schedule_work(&tp->reset_task); |
5750 | return; | 5803 | return; |
5804 | } | ||
5751 | } | 5805 | } |
5752 | 5806 | ||
5753 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
5754 | tg3_periodic_fetch_stats(tp); | ||
5755 | |||
5756 | /* This part only runs once per second. */ | 5807 | /* This part only runs once per second. */ |
5757 | if (!--tp->timer_counter) { | 5808 | if (!--tp->timer_counter) { |
5809 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
5810 | tg3_periodic_fetch_stats(tp); | ||
5811 | |||
5758 | if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { | 5812 | if (tp->tg3_flags & TG3_FLAG_USE_LINKCHG_REG) { |
5759 | u32 mac_stat; | 5813 | u32 mac_stat; |
5760 | int phy_event; | 5814 | int phy_event; |
@@ -5853,9 +5907,13 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5853 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) | 5907 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) |
5854 | err = request_irq(tp->pdev->irq, tg3_msi, | 5908 | err = request_irq(tp->pdev->irq, tg3_msi, |
5855 | SA_SAMPLE_RANDOM, dev->name, dev); | 5909 | SA_SAMPLE_RANDOM, dev->name, dev); |
5856 | else | 5910 | else { |
5857 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 5911 | irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; |
5912 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | ||
5913 | fn = tg3_interrupt_tagged; | ||
5914 | err = request_irq(tp->pdev->irq, fn, | ||
5858 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | 5915 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
5916 | } | ||
5859 | 5917 | ||
5860 | if (err) | 5918 | if (err) |
5861 | return err; | 5919 | return err; |
@@ -5907,9 +5965,14 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5907 | 5965 | ||
5908 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 5966 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
5909 | 5967 | ||
5910 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 5968 | { |
5911 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | 5969 | irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; |
5970 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | ||
5971 | fn = tg3_interrupt_tagged; | ||
5912 | 5972 | ||
5973 | err = request_irq(tp->pdev->irq, fn, | ||
5974 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | ||
5975 | } | ||
5913 | if (err) | 5976 | if (err) |
5914 | return err; | 5977 | return err; |
5915 | 5978 | ||
@@ -5919,7 +5982,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5919 | spin_lock_irq(&tp->lock); | 5982 | spin_lock_irq(&tp->lock); |
5920 | spin_lock(&tp->tx_lock); | 5983 | spin_lock(&tp->tx_lock); |
5921 | 5984 | ||
5922 | tg3_halt(tp); | 5985 | tg3_halt(tp, 1); |
5923 | err = tg3_init_hw(tp); | 5986 | err = tg3_init_hw(tp); |
5924 | 5987 | ||
5925 | spin_unlock(&tp->tx_lock); | 5988 | spin_unlock(&tp->tx_lock); |
@@ -5955,7 +6018,13 @@ static int tg3_open(struct net_device *dev) | |||
5955 | if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && | 6018 | if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && |
5956 | (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && | 6019 | (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_AX) && |
5957 | (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) { | 6020 | (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5750_BX)) { |
5958 | if (pci_enable_msi(tp->pdev) == 0) { | 6021 | /* All MSI supporting chips should support tagged |
6022 | * status. Assert that this is the case. | ||
6023 | */ | ||
6024 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS)) { | ||
6025 | printk(KERN_WARNING PFX "%s: MSI without TAGGED? " | ||
6026 | "Not using MSI.\n", tp->dev->name); | ||
6027 | } else if (pci_enable_msi(tp->pdev) == 0) { | ||
5959 | u32 msi_mode; | 6028 | u32 msi_mode; |
5960 | 6029 | ||
5961 | msi_mode = tr32(MSGINT_MODE); | 6030 | msi_mode = tr32(MSGINT_MODE); |
@@ -5966,9 +6035,14 @@ static int tg3_open(struct net_device *dev) | |||
5966 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) | 6035 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) |
5967 | err = request_irq(tp->pdev->irq, tg3_msi, | 6036 | err = request_irq(tp->pdev->irq, tg3_msi, |
5968 | SA_SAMPLE_RANDOM, dev->name, dev); | 6037 | SA_SAMPLE_RANDOM, dev->name, dev); |
5969 | else | 6038 | else { |
5970 | err = request_irq(tp->pdev->irq, tg3_interrupt, | 6039 | irqreturn_t (*fn)(int, void *, struct pt_regs *)=tg3_interrupt; |
6040 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | ||
6041 | fn = tg3_interrupt_tagged; | ||
6042 | |||
6043 | err = request_irq(tp->pdev->irq, fn, | ||
5971 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); | 6044 | SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); |
6045 | } | ||
5972 | 6046 | ||
5973 | if (err) { | 6047 | if (err) { |
5974 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { | 6048 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { |
@@ -5984,12 +6058,19 @@ static int tg3_open(struct net_device *dev) | |||
5984 | 6058 | ||
5985 | err = tg3_init_hw(tp); | 6059 | err = tg3_init_hw(tp); |
5986 | if (err) { | 6060 | if (err) { |
5987 | tg3_halt(tp); | 6061 | tg3_halt(tp, 1); |
5988 | tg3_free_rings(tp); | 6062 | tg3_free_rings(tp); |
5989 | } else { | 6063 | } else { |
5990 | tp->timer_offset = HZ / 10; | 6064 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
5991 | tp->timer_counter = tp->timer_multiplier = 10; | 6065 | tp->timer_offset = HZ; |
5992 | tp->asf_counter = tp->asf_multiplier = (10 * 120); | 6066 | else |
6067 | tp->timer_offset = HZ / 10; | ||
6068 | |||
6069 | BUG_ON(tp->timer_offset > HZ); | ||
6070 | tp->timer_counter = tp->timer_multiplier = | ||
6071 | (HZ / tp->timer_offset); | ||
6072 | tp->asf_counter = tp->asf_multiplier = | ||
6073 | ((HZ / tp->timer_offset) * 120); | ||
5993 | 6074 | ||
5994 | init_timer(&tp->timer); | 6075 | init_timer(&tp->timer); |
5995 | tp->timer.expires = jiffies + tp->timer_offset; | 6076 | tp->timer.expires = jiffies + tp->timer_offset; |
@@ -6012,6 +6093,7 @@ static int tg3_open(struct net_device *dev) | |||
6012 | 6093 | ||
6013 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { | 6094 | if (tp->tg3_flags2 & TG3_FLG2_USING_MSI) { |
6014 | err = tg3_test_msi(tp); | 6095 | err = tg3_test_msi(tp); |
6096 | |||
6015 | if (err) { | 6097 | if (err) { |
6016 | spin_lock_irq(&tp->lock); | 6098 | spin_lock_irq(&tp->lock); |
6017 | spin_lock(&tp->tx_lock); | 6099 | spin_lock(&tp->tx_lock); |
@@ -6020,7 +6102,7 @@ static int tg3_open(struct net_device *dev) | |||
6020 | pci_disable_msi(tp->pdev); | 6102 | pci_disable_msi(tp->pdev); |
6021 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 6103 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
6022 | } | 6104 | } |
6023 | tg3_halt(tp); | 6105 | tg3_halt(tp, 1); |
6024 | tg3_free_rings(tp); | 6106 | tg3_free_rings(tp); |
6025 | tg3_free_consistent(tp); | 6107 | tg3_free_consistent(tp); |
6026 | 6108 | ||
@@ -6293,7 +6375,7 @@ static int tg3_close(struct net_device *dev) | |||
6293 | 6375 | ||
6294 | tg3_disable_ints(tp); | 6376 | tg3_disable_ints(tp); |
6295 | 6377 | ||
6296 | tg3_halt(tp); | 6378 | tg3_halt(tp, 1); |
6297 | tg3_free_rings(tp); | 6379 | tg3_free_rings(tp); |
6298 | tp->tg3_flags &= | 6380 | tp->tg3_flags &= |
6299 | ~(TG3_FLAG_INIT_COMPLETE | | 6381 | ~(TG3_FLAG_INIT_COMPLETE | |
@@ -7013,7 +7095,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7013 | tp->tx_pending = ering->tx_pending; | 7095 | tp->tx_pending = ering->tx_pending; |
7014 | 7096 | ||
7015 | if (netif_running(dev)) { | 7097 | if (netif_running(dev)) { |
7016 | tg3_halt(tp); | 7098 | tg3_halt(tp, 1); |
7017 | tg3_init_hw(tp); | 7099 | tg3_init_hw(tp); |
7018 | tg3_netif_start(tp); | 7100 | tg3_netif_start(tp); |
7019 | } | 7101 | } |
@@ -7056,7 +7138,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7056 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; | 7138 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; |
7057 | 7139 | ||
7058 | if (netif_running(dev)) { | 7140 | if (netif_running(dev)) { |
7059 | tg3_halt(tp); | 7141 | tg3_halt(tp, 1); |
7060 | tg3_init_hw(tp); | 7142 | tg3_init_hw(tp); |
7061 | tg3_netif_start(tp); | 7143 | tg3_netif_start(tp); |
7062 | } | 7144 | } |
@@ -7210,6 +7292,14 @@ static void tg3_vlan_rx_kill_vid(struct net_device *dev, unsigned short vid) | |||
7210 | } | 7292 | } |
7211 | #endif | 7293 | #endif |
7212 | 7294 | ||
7295 | static int tg3_get_coalesce(struct net_device *dev, struct ethtool_coalesce *ec) | ||
7296 | { | ||
7297 | struct tg3 *tp = netdev_priv(dev); | ||
7298 | |||
7299 | memcpy(ec, &tp->coal, sizeof(*ec)); | ||
7300 | return 0; | ||
7301 | } | ||
7302 | |||
7213 | static struct ethtool_ops tg3_ethtool_ops = { | 7303 | static struct ethtool_ops tg3_ethtool_ops = { |
7214 | .get_settings = tg3_get_settings, | 7304 | .get_settings = tg3_get_settings, |
7215 | .set_settings = tg3_set_settings, | 7305 | .set_settings = tg3_set_settings, |
@@ -7242,6 +7332,7 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
7242 | .get_strings = tg3_get_strings, | 7332 | .get_strings = tg3_get_strings, |
7243 | .get_stats_count = tg3_get_stats_count, | 7333 | .get_stats_count = tg3_get_stats_count, |
7244 | .get_ethtool_stats = tg3_get_ethtool_stats, | 7334 | .get_ethtool_stats = tg3_get_ethtool_stats, |
7335 | .get_coalesce = tg3_get_coalesce, | ||
7245 | }; | 7336 | }; |
7246 | 7337 | ||
7247 | static void __devinit tg3_get_eeprom_size(struct tg3 *tp) | 7338 | static void __devinit tg3_get_eeprom_size(struct tg3 *tp) |
@@ -8429,15 +8520,7 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
8429 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | 8520 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) |
8430 | tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; | 8521 | tp->tg3_flags2 |= TG3_FLG2_PHY_BER_BUG; |
8431 | 8522 | ||
8432 | /* Only 5701 and later support tagged irq status mode. | ||
8433 | * Also, 5788 chips cannot use tagged irq status. | ||
8434 | * | ||
8435 | * However, since we are using NAPI avoid tagged irq status | ||
8436 | * because the interrupt condition is more difficult to | ||
8437 | * fully clear in that mode. | ||
8438 | */ | ||
8439 | tp->coalesce_mode = 0; | 8523 | tp->coalesce_mode = 0; |
8440 | |||
8441 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && | 8524 | if (GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_AX && |
8442 | GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) | 8525 | GET_CHIP_REV(tp->pci_chip_rev_id) != CHIPREV_5700_BX) |
8443 | tp->coalesce_mode |= HOSTCC_MODE_32BYTE; | 8526 | tp->coalesce_mode |= HOSTCC_MODE_32BYTE; |
@@ -8501,6 +8584,18 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
8501 | grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) | 8584 | grc_misc_cfg == GRC_MISC_CFG_BOARD_ID_5788M)) |
8502 | tp->tg3_flags2 |= TG3_FLG2_IS_5788; | 8585 | tp->tg3_flags2 |= TG3_FLG2_IS_5788; |
8503 | 8586 | ||
8587 | if (!(tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
8588 | (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700)) | ||
8589 | tp->tg3_flags |= TG3_FLAG_TAGGED_STATUS; | ||
8590 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { | ||
8591 | tp->coalesce_mode |= (HOSTCC_MODE_CLRTICK_RXBD | | ||
8592 | HOSTCC_MODE_CLRTICK_TXBD); | ||
8593 | |||
8594 | tp->misc_host_ctrl |= MISC_HOST_CTRL_TAGGED_STATUS; | ||
8595 | pci_write_config_dword(tp->pdev, TG3PCI_MISC_HOST_CTRL, | ||
8596 | tp->misc_host_ctrl); | ||
8597 | } | ||
8598 | |||
8504 | /* these are limited to 10/100 only */ | 8599 | /* these are limited to 10/100 only */ |
8505 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && | 8600 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && |
8506 | (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || | 8601 | (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || |
@@ -8678,6 +8773,146 @@ static int __devinit tg3_get_device_address(struct tg3 *tp) | |||
8678 | return 0; | 8773 | return 0; |
8679 | } | 8774 | } |
8680 | 8775 | ||
8776 | #define BOUNDARY_SINGLE_CACHELINE 1 | ||
8777 | #define BOUNDARY_MULTI_CACHELINE 2 | ||
8778 | |||
8779 | static u32 __devinit tg3_calc_dma_bndry(struct tg3 *tp, u32 val) | ||
8780 | { | ||
8781 | int cacheline_size; | ||
8782 | u8 byte; | ||
8783 | int goal; | ||
8784 | |||
8785 | pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
8786 | if (byte == 0) | ||
8787 | cacheline_size = 1024; | ||
8788 | else | ||
8789 | cacheline_size = (int) byte * 4; | ||
8790 | |||
8791 | /* On 5703 and later chips, the boundary bits have no | ||
8792 | * effect. | ||
8793 | */ | ||
8794 | if (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5700 && | ||
8795 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701 && | ||
8796 | !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) | ||
8797 | goto out; | ||
8798 | |||
8799 | #if defined(CONFIG_PPC64) || defined(CONFIG_IA64) || defined(CONFIG_PARISC) | ||
8800 | goal = BOUNDARY_MULTI_CACHELINE; | ||
8801 | #else | ||
8802 | #if defined(CONFIG_SPARC64) || defined(CONFIG_ALPHA) | ||
8803 | goal = BOUNDARY_SINGLE_CACHELINE; | ||
8804 | #else | ||
8805 | goal = 0; | ||
8806 | #endif | ||
8807 | #endif | ||
8808 | |||
8809 | if (!goal) | ||
8810 | goto out; | ||
8811 | |||
8812 | /* PCI controllers on most RISC systems tend to disconnect | ||
8813 | * when a device tries to burst across a cache-line boundary. | ||
8814 | * Therefore, letting tg3 do so just wastes PCI bandwidth. | ||
8815 | * | ||
8816 | * Unfortunately, for PCI-E there are only limited | ||
8817 | * write-side controls for this, and thus for reads | ||
8818 | * we will still get the disconnects. We'll also waste | ||
8819 | * these PCI cycles for both read and write for chips | ||
8820 | * other than 5700 and 5701 which do not implement the | ||
8821 | * boundary bits. | ||
8822 | */ | ||
8823 | if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
8824 | !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { | ||
8825 | switch (cacheline_size) { | ||
8826 | case 16: | ||
8827 | case 32: | ||
8828 | case 64: | ||
8829 | case 128: | ||
8830 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8831 | val |= (DMA_RWCTRL_READ_BNDRY_128_PCIX | | ||
8832 | DMA_RWCTRL_WRITE_BNDRY_128_PCIX); | ||
8833 | } else { | ||
8834 | val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | | ||
8835 | DMA_RWCTRL_WRITE_BNDRY_384_PCIX); | ||
8836 | } | ||
8837 | break; | ||
8838 | |||
8839 | case 256: | ||
8840 | val |= (DMA_RWCTRL_READ_BNDRY_256_PCIX | | ||
8841 | DMA_RWCTRL_WRITE_BNDRY_256_PCIX); | ||
8842 | break; | ||
8843 | |||
8844 | default: | ||
8845 | val |= (DMA_RWCTRL_READ_BNDRY_384_PCIX | | ||
8846 | DMA_RWCTRL_WRITE_BNDRY_384_PCIX); | ||
8847 | break; | ||
8848 | }; | ||
8849 | } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { | ||
8850 | switch (cacheline_size) { | ||
8851 | case 16: | ||
8852 | case 32: | ||
8853 | case 64: | ||
8854 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8855 | val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; | ||
8856 | val |= DMA_RWCTRL_WRITE_BNDRY_64_PCIE; | ||
8857 | break; | ||
8858 | } | ||
8859 | /* fallthrough */ | ||
8860 | case 128: | ||
8861 | default: | ||
8862 | val &= ~DMA_RWCTRL_WRITE_BNDRY_DISAB_PCIE; | ||
8863 | val |= DMA_RWCTRL_WRITE_BNDRY_128_PCIE; | ||
8864 | break; | ||
8865 | }; | ||
8866 | } else { | ||
8867 | switch (cacheline_size) { | ||
8868 | case 16: | ||
8869 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8870 | val |= (DMA_RWCTRL_READ_BNDRY_16 | | ||
8871 | DMA_RWCTRL_WRITE_BNDRY_16); | ||
8872 | break; | ||
8873 | } | ||
8874 | /* fallthrough */ | ||
8875 | case 32: | ||
8876 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8877 | val |= (DMA_RWCTRL_READ_BNDRY_32 | | ||
8878 | DMA_RWCTRL_WRITE_BNDRY_32); | ||
8879 | break; | ||
8880 | } | ||
8881 | /* fallthrough */ | ||
8882 | case 64: | ||
8883 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8884 | val |= (DMA_RWCTRL_READ_BNDRY_64 | | ||
8885 | DMA_RWCTRL_WRITE_BNDRY_64); | ||
8886 | break; | ||
8887 | } | ||
8888 | /* fallthrough */ | ||
8889 | case 128: | ||
8890 | if (goal == BOUNDARY_SINGLE_CACHELINE) { | ||
8891 | val |= (DMA_RWCTRL_READ_BNDRY_128 | | ||
8892 | DMA_RWCTRL_WRITE_BNDRY_128); | ||
8893 | break; | ||
8894 | } | ||
8895 | /* fallthrough */ | ||
8896 | case 256: | ||
8897 | val |= (DMA_RWCTRL_READ_BNDRY_256 | | ||
8898 | DMA_RWCTRL_WRITE_BNDRY_256); | ||
8899 | break; | ||
8900 | case 512: | ||
8901 | val |= (DMA_RWCTRL_READ_BNDRY_512 | | ||
8902 | DMA_RWCTRL_WRITE_BNDRY_512); | ||
8903 | break; | ||
8904 | case 1024: | ||
8905 | default: | ||
8906 | val |= (DMA_RWCTRL_READ_BNDRY_1024 | | ||
8907 | DMA_RWCTRL_WRITE_BNDRY_1024); | ||
8908 | break; | ||
8909 | }; | ||
8910 | } | ||
8911 | |||
8912 | out: | ||
8913 | return val; | ||
8914 | } | ||
8915 | |||
8681 | static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, int size, int to_device) | 8916 | static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dma, int size, int to_device) |
8682 | { | 8917 | { |
8683 | struct tg3_internal_buffer_desc test_desc; | 8918 | struct tg3_internal_buffer_desc test_desc; |
@@ -8764,7 +8999,7 @@ static int __devinit tg3_do_test_dma(struct tg3 *tp, u32 *buf, dma_addr_t buf_dm | |||
8764 | static int __devinit tg3_test_dma(struct tg3 *tp) | 8999 | static int __devinit tg3_test_dma(struct tg3 *tp) |
8765 | { | 9000 | { |
8766 | dma_addr_t buf_dma; | 9001 | dma_addr_t buf_dma; |
8767 | u32 *buf; | 9002 | u32 *buf, saved_dma_rwctrl; |
8768 | int ret; | 9003 | int ret; |
8769 | 9004 | ||
8770 | buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma); | 9005 | buf = pci_alloc_consistent(tp->pdev, TEST_BUFFER_SIZE, &buf_dma); |
@@ -8776,46 +9011,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
8776 | tp->dma_rwctrl = ((0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | | 9011 | tp->dma_rwctrl = ((0x7 << DMA_RWCTRL_PCI_WRITE_CMD_SHIFT) | |
8777 | (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT)); | 9012 | (0x6 << DMA_RWCTRL_PCI_READ_CMD_SHIFT)); |
8778 | 9013 | ||
8779 | #ifndef CONFIG_X86 | 9014 | tp->dma_rwctrl = tg3_calc_dma_bndry(tp, tp->dma_rwctrl); |
8780 | { | ||
8781 | u8 byte; | ||
8782 | int cacheline_size; | ||
8783 | pci_read_config_byte(tp->pdev, PCI_CACHE_LINE_SIZE, &byte); | ||
8784 | |||
8785 | if (byte == 0) | ||
8786 | cacheline_size = 1024; | ||
8787 | else | ||
8788 | cacheline_size = (int) byte * 4; | ||
8789 | |||
8790 | switch (cacheline_size) { | ||
8791 | case 16: | ||
8792 | case 32: | ||
8793 | case 64: | ||
8794 | case 128: | ||
8795 | if ((tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
8796 | !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) { | ||
8797 | tp->dma_rwctrl |= | ||
8798 | DMA_RWCTRL_WRITE_BNDRY_384_PCIX; | ||
8799 | break; | ||
8800 | } else if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { | ||
8801 | tp->dma_rwctrl &= | ||
8802 | ~(DMA_RWCTRL_PCI_WRITE_CMD); | ||
8803 | tp->dma_rwctrl |= | ||
8804 | DMA_RWCTRL_WRITE_BNDRY_128_PCIE; | ||
8805 | break; | ||
8806 | } | ||
8807 | /* fallthrough */ | ||
8808 | case 256: | ||
8809 | if (!(tp->tg3_flags & TG3_FLAG_PCIX_MODE) && | ||
8810 | !(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) | ||
8811 | tp->dma_rwctrl |= | ||
8812 | DMA_RWCTRL_WRITE_BNDRY_256; | ||
8813 | else if (!(tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS)) | ||
8814 | tp->dma_rwctrl |= | ||
8815 | DMA_RWCTRL_WRITE_BNDRY_256_PCIX; | ||
8816 | }; | ||
8817 | } | ||
8818 | #endif | ||
8819 | 9015 | ||
8820 | if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { | 9016 | if (tp->tg3_flags2 & TG3_FLG2_PCI_EXPRESS) { |
8821 | /* DMA read watermark not used on PCIE */ | 9017 | /* DMA read watermark not used on PCIE */ |
@@ -8834,7 +9030,7 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
8834 | if (ccval == 0x6 || ccval == 0x7) | 9030 | if (ccval == 0x6 || ccval == 0x7) |
8835 | tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; | 9031 | tp->dma_rwctrl |= DMA_RWCTRL_ONE_DMA; |
8836 | 9032 | ||
8837 | /* Set bit 23 to renable PCIX hw bug fix */ | 9033 | /* Set bit 23 to enable PCIX hw bug fix */ |
8838 | tp->dma_rwctrl |= 0x009f0000; | 9034 | tp->dma_rwctrl |= 0x009f0000; |
8839 | } else { | 9035 | } else { |
8840 | tp->dma_rwctrl |= 0x001b000f; | 9036 | tp->dma_rwctrl |= 0x001b000f; |
@@ -8875,6 +9071,13 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
8875 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) | 9071 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) |
8876 | goto out; | 9072 | goto out; |
8877 | 9073 | ||
9074 | /* It is best to perform DMA test with maximum write burst size | ||
9075 | * to expose the 5700/5701 write DMA bug. | ||
9076 | */ | ||
9077 | saved_dma_rwctrl = tp->dma_rwctrl; | ||
9078 | tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; | ||
9079 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); | ||
9080 | |||
8878 | while (1) { | 9081 | while (1) { |
8879 | u32 *p = buf, i; | 9082 | u32 *p = buf, i; |
8880 | 9083 | ||
@@ -8913,8 +9116,9 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
8913 | if (p[i] == i) | 9116 | if (p[i] == i) |
8914 | continue; | 9117 | continue; |
8915 | 9118 | ||
8916 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) == | 9119 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != |
8917 | DMA_RWCTRL_WRITE_BNDRY_DISAB) { | 9120 | DMA_RWCTRL_WRITE_BNDRY_16) { |
9121 | tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; | ||
8918 | tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; | 9122 | tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; |
8919 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); | 9123 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); |
8920 | break; | 9124 | break; |
@@ -8931,6 +9135,14 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
8931 | break; | 9135 | break; |
8932 | } | 9136 | } |
8933 | } | 9137 | } |
9138 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != | ||
9139 | DMA_RWCTRL_WRITE_BNDRY_16) { | ||
9140 | /* DMA test passed without adjusting DMA boundary, | ||
9141 | * just restore the calculated DMA boundary | ||
9142 | */ | ||
9143 | tp->dma_rwctrl = saved_dma_rwctrl; | ||
9144 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); | ||
9145 | } | ||
8934 | 9146 | ||
8935 | out: | 9147 | out: |
8936 | pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma); | 9148 | pci_free_consistent(tp->pdev, TEST_BUFFER_SIZE, buf, buf_dma); |
@@ -9018,6 +9230,31 @@ static struct pci_dev * __devinit tg3_find_5704_peer(struct tg3 *tp) | |||
9018 | return peer; | 9230 | return peer; |
9019 | } | 9231 | } |
9020 | 9232 | ||
9233 | static void __devinit tg3_init_coal(struct tg3 *tp) | ||
9234 | { | ||
9235 | struct ethtool_coalesce *ec = &tp->coal; | ||
9236 | |||
9237 | memset(ec, 0, sizeof(*ec)); | ||
9238 | ec->cmd = ETHTOOL_GCOALESCE; | ||
9239 | ec->rx_coalesce_usecs = LOW_RXCOL_TICKS; | ||
9240 | ec->tx_coalesce_usecs = LOW_TXCOL_TICKS; | ||
9241 | ec->rx_max_coalesced_frames = LOW_RXMAX_FRAMES; | ||
9242 | ec->tx_max_coalesced_frames = LOW_TXMAX_FRAMES; | ||
9243 | ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT; | ||
9244 | ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT; | ||
9245 | ec->rx_max_coalesced_frames_irq = DEFAULT_RXCOAL_MAXF_INT; | ||
9246 | ec->tx_max_coalesced_frames_irq = DEFAULT_TXCOAL_MAXF_INT; | ||
9247 | ec->stats_block_coalesce_usecs = DEFAULT_STAT_COAL_TICKS; | ||
9248 | |||
9249 | if (tp->coalesce_mode & (HOSTCC_MODE_CLRTICK_RXBD | | ||
9250 | HOSTCC_MODE_CLRTICK_TXBD)) { | ||
9251 | ec->rx_coalesce_usecs = LOW_RXCOL_TICKS_CLRTCKS; | ||
9252 | ec->rx_coalesce_usecs_irq = DEFAULT_RXCOAL_TICK_INT_CLRTCKS; | ||
9253 | ec->tx_coalesce_usecs = LOW_TXCOL_TICKS_CLRTCKS; | ||
9254 | ec->tx_coalesce_usecs_irq = DEFAULT_TXCOAL_TICK_INT_CLRTCKS; | ||
9255 | } | ||
9256 | } | ||
9257 | |||
9021 | static int __devinit tg3_init_one(struct pci_dev *pdev, | 9258 | static int __devinit tg3_init_one(struct pci_dev *pdev, |
9022 | const struct pci_device_id *ent) | 9259 | const struct pci_device_id *ent) |
9023 | { | 9260 | { |
@@ -9239,7 +9476,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9239 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 9476 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
9240 | pci_save_state(tp->pdev); | 9477 | pci_save_state(tp->pdev); |
9241 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | 9478 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); |
9242 | tg3_halt(tp); | 9479 | tg3_halt(tp, 1); |
9243 | } | 9480 | } |
9244 | 9481 | ||
9245 | err = tg3_test_dma(tp); | 9482 | err = tg3_test_dma(tp); |
@@ -9263,6 +9500,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9263 | /* flow control autonegotiation is default behavior */ | 9500 | /* flow control autonegotiation is default behavior */ |
9264 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; | 9501 | tp->tg3_flags |= TG3_FLAG_PAUSE_AUTONEG; |
9265 | 9502 | ||
9503 | tg3_init_coal(tp); | ||
9504 | |||
9266 | err = register_netdev(dev); | 9505 | err = register_netdev(dev); |
9267 | if (err) { | 9506 | if (err) { |
9268 | printk(KERN_ERR PFX "Cannot register net device, " | 9507 | printk(KERN_ERR PFX "Cannot register net device, " |
@@ -9305,6 +9544,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9305 | (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, | 9544 | (tp->tg3_flags & TG3_FLAG_SPLIT_MODE) != 0, |
9306 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, | 9545 | (tp->tg3_flags2 & TG3_FLG2_NO_ETH_WIRE_SPEED) == 0, |
9307 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); | 9546 | (tp->tg3_flags2 & TG3_FLG2_TSO_CAPABLE) != 0); |
9547 | printk(KERN_INFO "%s: dma_rwctrl[%08x]\n", | ||
9548 | dev->name, tp->dma_rwctrl); | ||
9308 | 9549 | ||
9309 | return 0; | 9550 | return 0; |
9310 | 9551 | ||
@@ -9362,7 +9603,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
9362 | 9603 | ||
9363 | spin_lock_irq(&tp->lock); | 9604 | spin_lock_irq(&tp->lock); |
9364 | spin_lock(&tp->tx_lock); | 9605 | spin_lock(&tp->tx_lock); |
9365 | tg3_halt(tp); | 9606 | tg3_halt(tp, 1); |
9366 | spin_unlock(&tp->tx_lock); | 9607 | spin_unlock(&tp->tx_lock); |
9367 | spin_unlock_irq(&tp->lock); | 9608 | spin_unlock_irq(&tp->lock); |
9368 | 9609 | ||
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 8de6f21037ba..993f84c93dc4 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
@@ -876,10 +876,12 @@ | |||
876 | #define HOSTCC_STATUS_ERROR_ATTN 0x00000004 | 876 | #define HOSTCC_STATUS_ERROR_ATTN 0x00000004 |
877 | #define HOSTCC_RXCOL_TICKS 0x00003c08 | 877 | #define HOSTCC_RXCOL_TICKS 0x00003c08 |
878 | #define LOW_RXCOL_TICKS 0x00000032 | 878 | #define LOW_RXCOL_TICKS 0x00000032 |
879 | #define LOW_RXCOL_TICKS_CLRTCKS 0x00000014 | ||
879 | #define DEFAULT_RXCOL_TICKS 0x00000048 | 880 | #define DEFAULT_RXCOL_TICKS 0x00000048 |
880 | #define HIGH_RXCOL_TICKS 0x00000096 | 881 | #define HIGH_RXCOL_TICKS 0x00000096 |
881 | #define HOSTCC_TXCOL_TICKS 0x00003c0c | 882 | #define HOSTCC_TXCOL_TICKS 0x00003c0c |
882 | #define LOW_TXCOL_TICKS 0x00000096 | 883 | #define LOW_TXCOL_TICKS 0x00000096 |
884 | #define LOW_TXCOL_TICKS_CLRTCKS 0x00000048 | ||
883 | #define DEFAULT_TXCOL_TICKS 0x0000012c | 885 | #define DEFAULT_TXCOL_TICKS 0x0000012c |
884 | #define HIGH_TXCOL_TICKS 0x00000145 | 886 | #define HIGH_TXCOL_TICKS 0x00000145 |
885 | #define HOSTCC_RXMAX_FRAMES 0x00003c10 | 887 | #define HOSTCC_RXMAX_FRAMES 0x00003c10 |
@@ -892,8 +894,10 @@ | |||
892 | #define HIGH_TXMAX_FRAMES 0x00000052 | 894 | #define HIGH_TXMAX_FRAMES 0x00000052 |
893 | #define HOSTCC_RXCOAL_TICK_INT 0x00003c18 | 895 | #define HOSTCC_RXCOAL_TICK_INT 0x00003c18 |
894 | #define DEFAULT_RXCOAL_TICK_INT 0x00000019 | 896 | #define DEFAULT_RXCOAL_TICK_INT 0x00000019 |
897 | #define DEFAULT_RXCOAL_TICK_INT_CLRTCKS 0x00000014 | ||
895 | #define HOSTCC_TXCOAL_TICK_INT 0x00003c1c | 898 | #define HOSTCC_TXCOAL_TICK_INT 0x00003c1c |
896 | #define DEFAULT_TXCOAL_TICK_INT 0x00000019 | 899 | #define DEFAULT_TXCOAL_TICK_INT 0x00000019 |
900 | #define DEFAULT_TXCOAL_TICK_INT_CLRTCKS 0x00000014 | ||
897 | #define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 | 901 | #define HOSTCC_RXCOAL_MAXF_INT 0x00003c20 |
898 | #define DEFAULT_RXCOAL_MAXF_INT 0x00000005 | 902 | #define DEFAULT_RXCOAL_MAXF_INT 0x00000005 |
899 | #define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 | 903 | #define HOSTCC_TXCOAL_MAXF_INT 0x00003c24 |
@@ -2023,6 +2027,7 @@ struct tg3 { | |||
2023 | 2027 | ||
2024 | struct tg3_hw_status *hw_status; | 2028 | struct tg3_hw_status *hw_status; |
2025 | dma_addr_t status_mapping; | 2029 | dma_addr_t status_mapping; |
2030 | u32 last_tag; | ||
2026 | 2031 | ||
2027 | u32 msg_enable; | 2032 | u32 msg_enable; |
2028 | 2033 | ||
@@ -2068,6 +2073,7 @@ struct tg3 { | |||
2068 | 2073 | ||
2069 | u32 rx_offset; | 2074 | u32 rx_offset; |
2070 | u32 tg3_flags; | 2075 | u32 tg3_flags; |
2076 | #define TG3_FLAG_TAGGED_STATUS 0x00000001 | ||
2071 | #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 | 2077 | #define TG3_FLAG_TXD_MBOX_HWBUG 0x00000002 |
2072 | #define TG3_FLAG_RX_CHECKSUMS 0x00000004 | 2078 | #define TG3_FLAG_RX_CHECKSUMS 0x00000004 |
2073 | #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 | 2079 | #define TG3_FLAG_USE_LINKCHG_REG 0x00000008 |
@@ -2225,7 +2231,7 @@ struct tg3 { | |||
2225 | 2231 | ||
2226 | #define SST_25VF0X0_PAGE_SIZE 4098 | 2232 | #define SST_25VF0X0_PAGE_SIZE 4098 |
2227 | 2233 | ||
2228 | 2234 | struct ethtool_coalesce coal; | |
2229 | }; | 2235 | }; |
2230 | 2236 | ||
2231 | #endif /* !(_T3_H) */ | 2237 | #endif /* !(_T3_H) */ |
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c index d098b3ba3538..e0ae3ed6e578 100644 --- a/drivers/net/tulip/tulip_core.c +++ b/drivers/net/tulip/tulip_core.c | |||
@@ -1104,7 +1104,7 @@ static void set_rx_mode(struct net_device *dev) | |||
1104 | if (entry != 0) { | 1104 | if (entry != 0) { |
1105 | /* Avoid a chip errata by prefixing a dummy entry. Don't do | 1105 | /* Avoid a chip errata by prefixing a dummy entry. Don't do |
1106 | this on the ULI526X as it triggers a different problem */ | 1106 | this on the ULI526X as it triggers a different problem */ |
1107 | if (!(tp->chip_id == ULI526X && (tp->revision = 0x40 || tp->revision == 0x50))) { | 1107 | if (!(tp->chip_id == ULI526X && (tp->revision == 0x40 || tp->revision == 0x50))) { |
1108 | tp->tx_buffers[entry].skb = NULL; | 1108 | tp->tx_buffers[entry].skb = NULL; |
1109 | tp->tx_buffers[entry].mapping = 0; | 1109 | tp->tx_buffers[entry].mapping = 0; |
1110 | tp->tx_ring[entry].length = | 1110 | tp->tx_ring[entry].length = |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 0aaa12c0c098..1d3231cc471a 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -323,7 +323,7 @@ config PRISM54 | |||
323 | For a complete list of supported cards visit <http://prism54.org>. | 323 | For a complete list of supported cards visit <http://prism54.org>. |
324 | Here is the latest confirmed list of supported cards: | 324 | Here is the latest confirmed list of supported cards: |
325 | 325 | ||
326 | 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 | 326 | 3com OfficeConnect 11g Cardbus Card aka 3CRWE154G72 (version 1) |
327 | Allnet ALL0271 PCI Card | 327 | Allnet ALL0271 PCI Card |
328 | Compex WL54G Cardbus Card | 328 | Compex WL54G Cardbus Card |
329 | Corega CG-WLCB54GT Cardbus Card | 329 | Corega CG-WLCB54GT Cardbus Card |
diff --git a/drivers/pci/hotplug.c b/drivers/pci/hotplug.c index 021d0f76bc4c..3903f8c559b6 100644 --- a/drivers/pci/hotplug.c +++ b/drivers/pci/hotplug.c | |||
@@ -52,116 +52,17 @@ int pci_hotplug (struct device *dev, char **envp, int num_envp, | |||
52 | if ((buffer_size - length <= 0) || (i >= num_envp)) | 52 | if ((buffer_size - length <= 0) || (i >= num_envp)) |
53 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | 54 | ||
55 | envp[i++] = scratch; | ||
56 | length += scnprintf (scratch, buffer_size - length, | ||
57 | "MODALIAS=pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", | ||
58 | pdev->vendor, pdev->device, | ||
59 | pdev->subsystem_vendor, pdev->subsystem_device, | ||
60 | (u8)(pdev->class >> 16), (u8)(pdev->class >> 8), | ||
61 | (u8)(pdev->class)); | ||
62 | if ((buffer_size - length <= 0) || (i >= num_envp)) | ||
63 | return -ENOMEM; | ||
64 | |||
55 | envp[i] = NULL; | 65 | envp[i] = NULL; |
56 | 66 | ||
57 | return 0; | 67 | return 0; |
58 | } | 68 | } |
59 | |||
60 | static int pci_visit_bus (struct pci_visit * fn, struct pci_bus_wrapped *wrapped_bus, struct pci_dev_wrapped *wrapped_parent) | ||
61 | { | ||
62 | struct list_head *ln; | ||
63 | struct pci_dev *dev; | ||
64 | struct pci_dev_wrapped wrapped_dev; | ||
65 | int result = 0; | ||
66 | |||
67 | pr_debug("PCI: Scanning bus %04x:%02x\n", pci_domain_nr(wrapped_bus->bus), | ||
68 | wrapped_bus->bus->number); | ||
69 | |||
70 | if (fn->pre_visit_pci_bus) { | ||
71 | result = fn->pre_visit_pci_bus(wrapped_bus, wrapped_parent); | ||
72 | if (result) | ||
73 | return result; | ||
74 | } | ||
75 | |||
76 | ln = wrapped_bus->bus->devices.next; | ||
77 | while (ln != &wrapped_bus->bus->devices) { | ||
78 | dev = pci_dev_b(ln); | ||
79 | ln = ln->next; | ||
80 | |||
81 | memset(&wrapped_dev, 0, sizeof(struct pci_dev_wrapped)); | ||
82 | wrapped_dev.dev = dev; | ||
83 | |||
84 | result = pci_visit_dev(fn, &wrapped_dev, wrapped_bus); | ||
85 | if (result) | ||
86 | return result; | ||
87 | } | ||
88 | |||
89 | if (fn->post_visit_pci_bus) | ||
90 | result = fn->post_visit_pci_bus(wrapped_bus, wrapped_parent); | ||
91 | |||
92 | return result; | ||
93 | } | ||
94 | |||
95 | static int pci_visit_bridge (struct pci_visit * fn, | ||
96 | struct pci_dev_wrapped *wrapped_dev, | ||
97 | struct pci_bus_wrapped *wrapped_parent) | ||
98 | { | ||
99 | struct pci_bus *bus; | ||
100 | struct pci_bus_wrapped wrapped_bus; | ||
101 | int result = 0; | ||
102 | |||
103 | pr_debug("PCI: Scanning bridge %s\n", pci_name(wrapped_dev->dev)); | ||
104 | |||
105 | if (fn->visit_pci_dev) { | ||
106 | result = fn->visit_pci_dev(wrapped_dev, wrapped_parent); | ||
107 | if (result) | ||
108 | return result; | ||
109 | } | ||
110 | |||
111 | bus = wrapped_dev->dev->subordinate; | ||
112 | if (bus) { | ||
113 | memset(&wrapped_bus, 0, sizeof(struct pci_bus_wrapped)); | ||
114 | wrapped_bus.bus = bus; | ||
115 | |||
116 | result = pci_visit_bus(fn, &wrapped_bus, wrapped_dev); | ||
117 | } | ||
118 | return result; | ||
119 | } | ||
120 | |||
121 | /** | ||
122 | * pci_visit_dev - scans the pci buses. | ||
123 | * @fn: callback functions that are called while visiting | ||
124 | * @wrapped_dev: the device to scan | ||
125 | * @wrapped_parent: the bus where @wrapped_dev is connected to | ||
126 | * | ||
127 | * Every bus and every function is presented to a custom | ||
128 | * function that can act upon it. | ||
129 | */ | ||
130 | int pci_visit_dev(struct pci_visit *fn, struct pci_dev_wrapped *wrapped_dev, | ||
131 | struct pci_bus_wrapped *wrapped_parent) | ||
132 | { | ||
133 | struct pci_dev* dev = wrapped_dev ? wrapped_dev->dev : NULL; | ||
134 | int result = 0; | ||
135 | |||
136 | if (!dev) | ||
137 | return 0; | ||
138 | |||
139 | if (fn->pre_visit_pci_dev) { | ||
140 | result = fn->pre_visit_pci_dev(wrapped_dev, wrapped_parent); | ||
141 | if (result) | ||
142 | return result; | ||
143 | } | ||
144 | |||
145 | switch (dev->class >> 8) { | ||
146 | case PCI_CLASS_BRIDGE_PCI: | ||
147 | result = pci_visit_bridge(fn, wrapped_dev, | ||
148 | wrapped_parent); | ||
149 | if (result) | ||
150 | return result; | ||
151 | break; | ||
152 | default: | ||
153 | pr_debug("PCI: Scanning device %s\n", pci_name(dev)); | ||
154 | if (fn->visit_pci_dev) { | ||
155 | result = fn->visit_pci_dev (wrapped_dev, | ||
156 | wrapped_parent); | ||
157 | if (result) | ||
158 | return result; | ||
159 | } | ||
160 | } | ||
161 | |||
162 | if (fn->post_visit_pci_dev) | ||
163 | result = fn->post_visit_pci_dev(wrapped_dev, wrapped_parent); | ||
164 | |||
165 | return result; | ||
166 | } | ||
167 | EXPORT_SYMBOL(pci_visit_dev); | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug.h b/drivers/pci/hotplug/cpci_hotplug.h index 3ddd75937a40..d9769b30be9a 100644 --- a/drivers/pci/hotplug/cpci_hotplug.h +++ b/drivers/pci/hotplug/cpci_hotplug.h | |||
@@ -31,7 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/pci.h> | 32 | #include <linux/pci.h> |
33 | 33 | ||
34 | /* PICMG 2.12 R2.0 HS CSR bits: */ | 34 | /* PICMG 2.1 R2.0 HS CSR bits: */ |
35 | #define HS_CSR_INS 0x0080 | 35 | #define HS_CSR_INS 0x0080 |
36 | #define HS_CSR_EXT 0x0040 | 36 | #define HS_CSR_EXT 0x0040 |
37 | #define HS_CSR_PI 0x0030 | 37 | #define HS_CSR_PI 0x0030 |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index ed243605dc7b..9e9dab7fe86a 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -33,11 +33,11 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/interrupt.h> | 34 | #include <linux/interrupt.h> |
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <asm/atomic.h> | ||
36 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
37 | #include "pci_hotplug.h" | 38 | #include "pci_hotplug.h" |
38 | #include "cpci_hotplug.h" | 39 | #include "cpci_hotplug.h" |
39 | 40 | ||
40 | #define DRIVER_VERSION "0.2" | ||
41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
42 | #define DRIVER_DESC "CompactPCI Hot Plug Core" | 42 | #define DRIVER_DESC "CompactPCI Hot Plug Core" |
43 | 43 | ||
@@ -54,9 +54,10 @@ | |||
54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 54 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
55 | 55 | ||
56 | /* local variables */ | 56 | /* local variables */ |
57 | static spinlock_t list_lock; | 57 | static DECLARE_RWSEM(list_rwsem); |
58 | static LIST_HEAD(slot_list); | 58 | static LIST_HEAD(slot_list); |
59 | static int slots; | 59 | static int slots; |
60 | static atomic_t extracting; | ||
60 | int cpci_debug; | 61 | int cpci_debug; |
61 | static struct cpci_hp_controller *controller; | 62 | static struct cpci_hp_controller *controller; |
62 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | 63 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ |
@@ -68,6 +69,8 @@ static int disable_slot(struct hotplug_slot *slot); | |||
68 | static int set_attention_status(struct hotplug_slot *slot, u8 value); | 69 | static int set_attention_status(struct hotplug_slot *slot, u8 value); |
69 | static int get_power_status(struct hotplug_slot *slot, u8 * value); | 70 | static int get_power_status(struct hotplug_slot *slot, u8 * value); |
70 | static int get_attention_status(struct hotplug_slot *slot, u8 * value); | 71 | static int get_attention_status(struct hotplug_slot *slot, u8 * value); |
72 | static int get_adapter_status(struct hotplug_slot *slot, u8 * value); | ||
73 | static int get_latch_status(struct hotplug_slot *slot, u8 * value); | ||
71 | 74 | ||
72 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { | 75 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { |
73 | .owner = THIS_MODULE, | 76 | .owner = THIS_MODULE, |
@@ -76,6 +79,8 @@ static struct hotplug_slot_ops cpci_hotplug_slot_ops = { | |||
76 | .set_attention_status = set_attention_status, | 79 | .set_attention_status = set_attention_status, |
77 | .get_power_status = get_power_status, | 80 | .get_power_status = get_power_status, |
78 | .get_attention_status = get_attention_status, | 81 | .get_attention_status = get_attention_status, |
82 | .get_adapter_status = get_adapter_status, | ||
83 | .get_latch_status = get_latch_status, | ||
79 | }; | 84 | }; |
80 | 85 | ||
81 | static int | 86 | static int |
@@ -148,8 +153,10 @@ disable_slot(struct hotplug_slot *hotplug_slot) | |||
148 | warn("failure to update adapter file"); | 153 | warn("failure to update adapter file"); |
149 | } | 154 | } |
150 | 155 | ||
151 | slot->extracting = 0; | 156 | if(slot->extracting) { |
152 | 157 | slot->extracting = 0; | |
158 | atomic_dec(&extracting); | ||
159 | } | ||
153 | return retval; | 160 | return retval; |
154 | } | 161 | } |
155 | 162 | ||
@@ -188,6 +195,20 @@ set_attention_status(struct hotplug_slot *hotplug_slot, u8 status) | |||
188 | return cpci_set_attention_status(hotplug_slot->private, status); | 195 | return cpci_set_attention_status(hotplug_slot->private, status); |
189 | } | 196 | } |
190 | 197 | ||
198 | static int | ||
199 | get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) | ||
200 | { | ||
201 | *value = hotplug_slot->info->adapter_status; | ||
202 | return 0; | ||
203 | } | ||
204 | |||
205 | static int | ||
206 | get_latch_status(struct hotplug_slot *hotplug_slot, u8 * value) | ||
207 | { | ||
208 | *value = hotplug_slot->info->latch_status; | ||
209 | return 0; | ||
210 | } | ||
211 | |||
191 | static void release_slot(struct hotplug_slot *hotplug_slot) | 212 | static void release_slot(struct hotplug_slot *hotplug_slot) |
192 | { | 213 | { |
193 | struct slot *slot = hotplug_slot->private; | 214 | struct slot *slot = hotplug_slot->private; |
@@ -273,10 +294,10 @@ cpci_hp_register_bus(struct pci_bus *bus, u8 first, u8 last) | |||
273 | } | 294 | } |
274 | 295 | ||
275 | /* Add slot to our internal list */ | 296 | /* Add slot to our internal list */ |
276 | spin_lock(&list_lock); | 297 | down_write(&list_rwsem); |
277 | list_add(&slot->slot_list, &slot_list); | 298 | list_add(&slot->slot_list, &slot_list); |
278 | slots++; | 299 | slots++; |
279 | spin_unlock(&list_lock); | 300 | up_write(&list_rwsem); |
280 | } | 301 | } |
281 | return 0; | 302 | return 0; |
282 | error_name: | 303 | error_name: |
@@ -299,9 +320,9 @@ cpci_hp_unregister_bus(struct pci_bus *bus) | |||
299 | struct list_head *next; | 320 | struct list_head *next; |
300 | int status; | 321 | int status; |
301 | 322 | ||
302 | spin_lock(&list_lock); | 323 | down_write(&list_rwsem); |
303 | if(!slots) { | 324 | if(!slots) { |
304 | spin_unlock(&list_lock); | 325 | up_write(&list_rwsem); |
305 | return -1; | 326 | return -1; |
306 | } | 327 | } |
307 | list_for_each_safe(tmp, next, &slot_list) { | 328 | list_for_each_safe(tmp, next, &slot_list) { |
@@ -319,7 +340,7 @@ cpci_hp_unregister_bus(struct pci_bus *bus) | |||
319 | slots--; | 340 | slots--; |
320 | } | 341 | } |
321 | } | 342 | } |
322 | spin_unlock(&list_lock); | 343 | up_write(&list_rwsem); |
323 | return 0; | 344 | return 0; |
324 | } | 345 | } |
325 | 346 | ||
@@ -347,7 +368,7 @@ cpci_hp_intr(int irq, void *data, struct pt_regs *regs) | |||
347 | } | 368 | } |
348 | 369 | ||
349 | /* | 370 | /* |
350 | * According to PICMG 2.12 R2.0, section 6.3.2, upon | 371 | * According to PICMG 2.1 R2.0, section 6.3.2, upon |
351 | * initialization, the system driver shall clear the | 372 | * initialization, the system driver shall clear the |
352 | * INS bits of the cold-inserted devices. | 373 | * INS bits of the cold-inserted devices. |
353 | */ | 374 | */ |
@@ -359,9 +380,9 @@ init_slots(void) | |||
359 | struct pci_dev* dev; | 380 | struct pci_dev* dev; |
360 | 381 | ||
361 | dbg("%s - enter", __FUNCTION__); | 382 | dbg("%s - enter", __FUNCTION__); |
362 | spin_lock(&list_lock); | 383 | down_read(&list_rwsem); |
363 | if(!slots) { | 384 | if(!slots) { |
364 | spin_unlock(&list_lock); | 385 | up_read(&list_rwsem); |
365 | return -1; | 386 | return -1; |
366 | } | 387 | } |
367 | list_for_each(tmp, &slot_list) { | 388 | list_for_each(tmp, &slot_list) { |
@@ -386,7 +407,7 @@ init_slots(void) | |||
386 | } | 407 | } |
387 | } | 408 | } |
388 | } | 409 | } |
389 | spin_unlock(&list_lock); | 410 | up_read(&list_rwsem); |
390 | dbg("%s - exit", __FUNCTION__); | 411 | dbg("%s - exit", __FUNCTION__); |
391 | return 0; | 412 | return 0; |
392 | } | 413 | } |
@@ -398,10 +419,11 @@ check_slots(void) | |||
398 | struct list_head *tmp; | 419 | struct list_head *tmp; |
399 | int extracted; | 420 | int extracted; |
400 | int inserted; | 421 | int inserted; |
422 | u16 hs_csr; | ||
401 | 423 | ||
402 | spin_lock(&list_lock); | 424 | down_read(&list_rwsem); |
403 | if(!slots) { | 425 | if(!slots) { |
404 | spin_unlock(&list_lock); | 426 | up_read(&list_rwsem); |
405 | err("no slots registered, shutting down"); | 427 | err("no slots registered, shutting down"); |
406 | return -1; | 428 | return -1; |
407 | } | 429 | } |
@@ -411,8 +433,6 @@ check_slots(void) | |||
411 | dbg("%s - looking at slot %s", | 433 | dbg("%s - looking at slot %s", |
412 | __FUNCTION__, slot->hotplug_slot->name); | 434 | __FUNCTION__, slot->hotplug_slot->name); |
413 | if(cpci_check_and_clear_ins(slot)) { | 435 | if(cpci_check_and_clear_ins(slot)) { |
414 | u16 hs_csr; | ||
415 | |||
416 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ | 436 | /* Some broken hardware (e.g. PLX 9054AB) asserts ENUM# twice... */ |
417 | if(slot->dev) { | 437 | if(slot->dev) { |
418 | warn("slot %s already inserted", slot->hotplug_slot->name); | 438 | warn("slot %s already inserted", slot->hotplug_slot->name); |
@@ -462,8 +482,6 @@ check_slots(void) | |||
462 | 482 | ||
463 | inserted++; | 483 | inserted++; |
464 | } else if(cpci_check_ext(slot)) { | 484 | } else if(cpci_check_ext(slot)) { |
465 | u16 hs_csr; | ||
466 | |||
467 | /* Process extraction request */ | 485 | /* Process extraction request */ |
468 | dbg("%s - slot %s extracted", | 486 | dbg("%s - slot %s extracted", |
469 | __FUNCTION__, slot->hotplug_slot->name); | 487 | __FUNCTION__, slot->hotplug_slot->name); |
@@ -476,20 +494,40 @@ check_slots(void) | |||
476 | if(!slot->extracting) { | 494 | if(!slot->extracting) { |
477 | if(update_latch_status(slot->hotplug_slot, 0)) { | 495 | if(update_latch_status(slot->hotplug_slot, 0)) { |
478 | warn("failure to update latch file"); | 496 | warn("failure to update latch file"); |
497 | |||
479 | } | 498 | } |
499 | atomic_inc(&extracting); | ||
480 | slot->extracting = 1; | 500 | slot->extracting = 1; |
481 | } | 501 | } |
482 | extracted++; | 502 | extracted++; |
503 | } else if(slot->extracting) { | ||
504 | hs_csr = cpci_get_hs_csr(slot); | ||
505 | if(hs_csr == 0xffff) { | ||
506 | /* | ||
507 | * Hmmm, we're likely hosed at this point, should we | ||
508 | * bother trying to tell the driver or not? | ||
509 | */ | ||
510 | err("card in slot %s was improperly removed", | ||
511 | slot->hotplug_slot->name); | ||
512 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
513 | warn("failure to update adapter file"); | ||
514 | } | ||
515 | slot->extracting = 0; | ||
516 | atomic_dec(&extracting); | ||
517 | } | ||
483 | } | 518 | } |
484 | } | 519 | } |
485 | spin_unlock(&list_lock); | 520 | up_read(&list_rwsem); |
521 | dbg("inserted=%d, extracted=%d, extracting=%d", | ||
522 | inserted, extracted, atomic_read(&extracting)); | ||
486 | if(inserted || extracted) { | 523 | if(inserted || extracted) { |
487 | return extracted; | 524 | return extracted; |
488 | } | 525 | } |
489 | else { | 526 | else if(!atomic_read(&extracting)) { |
490 | err("cannot find ENUM# source, shutting down"); | 527 | err("cannot find ENUM# source, shutting down"); |
491 | return -1; | 528 | return -1; |
492 | } | 529 | } |
530 | return 0; | ||
493 | } | 531 | } |
494 | 532 | ||
495 | /* This is the interrupt mode worker thread body */ | 533 | /* This is the interrupt mode worker thread body */ |
@@ -497,8 +535,6 @@ static int | |||
497 | event_thread(void *data) | 535 | event_thread(void *data) |
498 | { | 536 | { |
499 | int rc; | 537 | int rc; |
500 | struct slot *slot; | ||
501 | struct list_head *tmp; | ||
502 | 538 | ||
503 | lock_kernel(); | 539 | lock_kernel(); |
504 | daemonize("cpci_hp_eventd"); | 540 | daemonize("cpci_hp_eventd"); |
@@ -512,39 +548,22 @@ event_thread(void *data) | |||
512 | thread_finished); | 548 | thread_finished); |
513 | if(thread_finished || signal_pending(current)) | 549 | if(thread_finished || signal_pending(current)) |
514 | break; | 550 | break; |
515 | while(controller->ops->query_enum()) { | 551 | do { |
516 | rc = check_slots(); | 552 | rc = check_slots(); |
517 | if (rc > 0) | 553 | if (rc > 0) { |
518 | /* Give userspace a chance to handle extraction */ | 554 | /* Give userspace a chance to handle extraction */ |
519 | msleep(500); | 555 | msleep(500); |
520 | else if (rc < 0) { | 556 | } else if (rc < 0) { |
521 | dbg("%s - error checking slots", __FUNCTION__); | 557 | dbg("%s - error checking slots", __FUNCTION__); |
522 | thread_finished = 1; | 558 | thread_finished = 1; |
523 | break; | 559 | break; |
524 | } | 560 | } |
525 | } | 561 | } while(atomic_read(&extracting) != 0); |
526 | /* Check for someone yanking out a board */ | ||
527 | list_for_each(tmp, &slot_list) { | ||
528 | slot = list_entry(tmp, struct slot, slot_list); | ||
529 | if(slot->extracting) { | ||
530 | /* | ||
531 | * Hmmm, we're likely hosed at this point, should we | ||
532 | * bother trying to tell the driver or not? | ||
533 | */ | ||
534 | err("card in slot %s was improperly removed", | ||
535 | slot->hotplug_slot->name); | ||
536 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
537 | warn("failure to update adapter file"); | ||
538 | } | ||
539 | slot->extracting = 0; | ||
540 | } | ||
541 | } | ||
542 | 562 | ||
543 | /* Re-enable ENUM# interrupt */ | 563 | /* Re-enable ENUM# interrupt */ |
544 | dbg("%s - re-enabling irq", __FUNCTION__); | 564 | dbg("%s - re-enabling irq", __FUNCTION__); |
545 | controller->ops->enable_irq(); | 565 | controller->ops->enable_irq(); |
546 | } | 566 | } |
547 | |||
548 | dbg("%s - event thread signals exit", __FUNCTION__); | 567 | dbg("%s - event thread signals exit", __FUNCTION__); |
549 | up(&thread_exit); | 568 | up(&thread_exit); |
550 | return 0; | 569 | return 0; |
@@ -555,8 +574,6 @@ static int | |||
555 | poll_thread(void *data) | 574 | poll_thread(void *data) |
556 | { | 575 | { |
557 | int rc; | 576 | int rc; |
558 | struct slot *slot; | ||
559 | struct list_head *tmp; | ||
560 | 577 | ||
561 | lock_kernel(); | 578 | lock_kernel(); |
562 | daemonize("cpci_hp_polld"); | 579 | daemonize("cpci_hp_polld"); |
@@ -565,35 +582,19 @@ poll_thread(void *data) | |||
565 | while(1) { | 582 | while(1) { |
566 | if(thread_finished || signal_pending(current)) | 583 | if(thread_finished || signal_pending(current)) |
567 | break; | 584 | break; |
568 | 585 | if(controller->ops->query_enum()) { | |
569 | while(controller->ops->query_enum()) { | 586 | do { |
570 | rc = check_slots(); | 587 | rc = check_slots(); |
571 | if(rc > 0) | 588 | if(rc > 0) { |
572 | /* Give userspace a chance to handle extraction */ | 589 | /* Give userspace a chance to handle extraction */ |
573 | msleep(500); | 590 | msleep(500); |
574 | else if (rc < 0) { | 591 | } else if(rc < 0) { |
575 | dbg("%s - error checking slots", __FUNCTION__); | 592 | dbg("%s - error checking slots", __FUNCTION__); |
576 | thread_finished = 1; | 593 | thread_finished = 1; |
577 | break; | 594 | break; |
578 | } | ||
579 | } | ||
580 | /* Check for someone yanking out a board */ | ||
581 | list_for_each(tmp, &slot_list) { | ||
582 | slot = list_entry(tmp, struct slot, slot_list); | ||
583 | if(slot->extracting) { | ||
584 | /* | ||
585 | * Hmmm, we're likely hosed at this point, should we | ||
586 | * bother trying to tell the driver or not? | ||
587 | */ | ||
588 | err("card in slot %s was improperly removed", | ||
589 | slot->hotplug_slot->name); | ||
590 | if(update_adapter_status(slot->hotplug_slot, 0)) { | ||
591 | warn("failure to update adapter file"); | ||
592 | } | 595 | } |
593 | slot->extracting = 0; | 596 | } while(atomic_read(&extracting) != 0); |
594 | } | ||
595 | } | 597 | } |
596 | |||
597 | msleep(100); | 598 | msleep(100); |
598 | } | 599 | } |
599 | dbg("poll thread signals exit"); | 600 | dbg("poll thread signals exit"); |
@@ -667,6 +668,9 @@ cpci_hp_unregister_controller(struct cpci_hp_controller *old_controller) | |||
667 | int status = 0; | 668 | int status = 0; |
668 | 669 | ||
669 | if(controller) { | 670 | if(controller) { |
671 | if(atomic_read(&extracting) != 0) { | ||
672 | return -EBUSY; | ||
673 | } | ||
670 | if(!thread_finished) { | 674 | if(!thread_finished) { |
671 | cpci_stop_thread(); | 675 | cpci_stop_thread(); |
672 | } | 676 | } |
@@ -691,12 +695,12 @@ cpci_hp_start(void) | |||
691 | return -ENODEV; | 695 | return -ENODEV; |
692 | } | 696 | } |
693 | 697 | ||
694 | spin_lock(&list_lock); | 698 | down_read(&list_rwsem); |
695 | if(!slots) { | 699 | if(list_empty(&slot_list)) { |
696 | spin_unlock(&list_lock); | 700 | up_read(&list_rwsem); |
697 | return -ENODEV; | 701 | return -ENODEV; |
698 | } | 702 | } |
699 | spin_unlock(&list_lock); | 703 | up_read(&list_rwsem); |
700 | 704 | ||
701 | if(first) { | 705 | if(first) { |
702 | status = init_slots(); | 706 | status = init_slots(); |
@@ -727,7 +731,9 @@ cpci_hp_stop(void) | |||
727 | if(!controller) { | 731 | if(!controller) { |
728 | return -ENODEV; | 732 | return -ENODEV; |
729 | } | 733 | } |
730 | 734 | if(atomic_read(&extracting) != 0) { | |
735 | return -EBUSY; | ||
736 | } | ||
731 | if(controller->irq) { | 737 | if(controller->irq) { |
732 | /* Stop enum interrupt processing */ | 738 | /* Stop enum interrupt processing */ |
733 | dbg("%s - disabling irq", __FUNCTION__); | 739 | dbg("%s - disabling irq", __FUNCTION__); |
@@ -747,7 +753,7 @@ cleanup_slots(void) | |||
747 | * Unregister all of our slots with the pci_hotplug subsystem, | 753 | * Unregister all of our slots with the pci_hotplug subsystem, |
748 | * and free up all memory that we had allocated. | 754 | * and free up all memory that we had allocated. |
749 | */ | 755 | */ |
750 | spin_lock(&list_lock); | 756 | down_write(&list_rwsem); |
751 | if(!slots) { | 757 | if(!slots) { |
752 | goto null_cleanup; | 758 | goto null_cleanup; |
753 | } | 759 | } |
@@ -761,17 +767,14 @@ cleanup_slots(void) | |||
761 | kfree(slot); | 767 | kfree(slot); |
762 | } | 768 | } |
763 | null_cleanup: | 769 | null_cleanup: |
764 | spin_unlock(&list_lock); | 770 | up_write(&list_rwsem); |
765 | return; | 771 | return; |
766 | } | 772 | } |
767 | 773 | ||
768 | int __init | 774 | int __init |
769 | cpci_hotplug_init(int debug) | 775 | cpci_hotplug_init(int debug) |
770 | { | 776 | { |
771 | spin_lock_init(&list_lock); | ||
772 | cpci_debug = debug; | 777 | cpci_debug = debug; |
773 | |||
774 | info(DRIVER_DESC " version: " DRIVER_VERSION); | ||
775 | return 0; | 778 | return 0; |
776 | } | 779 | } |
777 | 780 | ||
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 2e969616f298..69eb4fc54f2f 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -32,11 +32,7 @@ | |||
32 | #include "pci_hotplug.h" | 32 | #include "pci_hotplug.h" |
33 | #include "cpci_hotplug.h" | 33 | #include "cpci_hotplug.h" |
34 | 34 | ||
35 | #if !defined(MODULE) | ||
36 | #define MY_NAME "cpci_hotplug" | 35 | #define MY_NAME "cpci_hotplug" |
37 | #else | ||
38 | #define MY_NAME THIS_MODULE->name | ||
39 | #endif | ||
40 | 36 | ||
41 | extern int cpci_debug; | 37 | extern int cpci_debug; |
42 | 38 | ||
@@ -127,38 +123,6 @@ u16 cpci_get_hs_csr(struct slot* slot) | |||
127 | return hs_csr; | 123 | return hs_csr; |
128 | } | 124 | } |
129 | 125 | ||
130 | #if 0 | ||
131 | u16 cpci_set_hs_csr(struct slot* slot, u16 hs_csr) | ||
132 | { | ||
133 | int hs_cap; | ||
134 | u16 new_hs_csr; | ||
135 | |||
136 | hs_cap = pci_bus_find_capability(slot->bus, | ||
137 | slot->devfn, | ||
138 | PCI_CAP_ID_CHSWP); | ||
139 | if(!hs_cap) { | ||
140 | return 0xFFFF; | ||
141 | } | ||
142 | |||
143 | /* Write out the new value */ | ||
144 | if(pci_bus_write_config_word(slot->bus, | ||
145 | slot->devfn, | ||
146 | hs_cap + 2, | ||
147 | hs_csr)) { | ||
148 | return 0xFFFF; | ||
149 | } | ||
150 | |||
151 | /* Read back what we just wrote out */ | ||
152 | if(pci_bus_read_config_word(slot->bus, | ||
153 | slot->devfn, | ||
154 | hs_cap + 2, | ||
155 | &new_hs_csr)) { | ||
156 | return 0xFFFF; | ||
157 | } | ||
158 | return new_hs_csr; | ||
159 | } | ||
160 | #endif | ||
161 | |||
162 | int cpci_check_and_clear_ins(struct slot* slot) | 126 | int cpci_check_and_clear_ins(struct slot* slot) |
163 | { | 127 | { |
164 | int hs_cap; | 128 | int hs_cap; |
@@ -261,7 +225,6 @@ int cpci_led_on(struct slot* slot) | |||
261 | return -ENODEV; | 225 | return -ENODEV; |
262 | } | 226 | } |
263 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { | 227 | if((hs_csr & HS_CSR_LOO) != HS_CSR_LOO) { |
264 | /* Set LOO */ | ||
265 | hs_csr |= HS_CSR_LOO; | 228 | hs_csr |= HS_CSR_LOO; |
266 | if(pci_bus_write_config_word(slot->bus, | 229 | if(pci_bus_write_config_word(slot->bus, |
267 | slot->devfn, | 230 | slot->devfn, |
@@ -293,7 +256,6 @@ int cpci_led_off(struct slot* slot) | |||
293 | return -ENODEV; | 256 | return -ENODEV; |
294 | } | 257 | } |
295 | if(hs_csr & HS_CSR_LOO) { | 258 | if(hs_csr & HS_CSR_LOO) { |
296 | /* Clear LOO */ | ||
297 | hs_csr &= ~HS_CSR_LOO; | 259 | hs_csr &= ~HS_CSR_LOO; |
298 | if(pci_bus_write_config_word(slot->bus, | 260 | if(pci_bus_write_config_word(slot->bus, |
299 | slot->devfn, | 261 | slot->devfn, |
@@ -312,257 +274,23 @@ int cpci_led_off(struct slot* slot) | |||
312 | * Device configuration functions | 274 | * Device configuration functions |
313 | */ | 275 | */ |
314 | 276 | ||
315 | static int cpci_configure_dev(struct pci_bus *bus, struct pci_dev *dev) | 277 | static void cpci_enable_device(struct pci_dev *dev) |
316 | { | ||
317 | u8 irq_pin; | ||
318 | int r; | ||
319 | |||
320 | dbg("%s - enter", __FUNCTION__); | ||
321 | |||
322 | /* NOTE: device already setup from prior scan */ | ||
323 | |||
324 | /* FIXME: How would we know if we need to enable the expansion ROM? */ | ||
325 | pci_write_config_word(dev, PCI_ROM_ADDRESS, 0x00L); | ||
326 | |||
327 | /* Assign resources */ | ||
328 | dbg("assigning resources for %02x:%02x.%x", | ||
329 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
330 | for (r = 0; r < 6; r++) { | ||
331 | struct resource *res = dev->resource + r; | ||
332 | if(res->flags) | ||
333 | pci_assign_resource(dev, r); | ||
334 | } | ||
335 | dbg("finished assigning resources for %02x:%02x.%x", | ||
336 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
337 | |||
338 | /* Does this function have an interrupt at all? */ | ||
339 | dbg("checking for function interrupt"); | ||
340 | pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &irq_pin); | ||
341 | if(irq_pin) { | ||
342 | dbg("function uses interrupt pin %d", irq_pin); | ||
343 | } | ||
344 | |||
345 | /* | ||
346 | * Need to explicitly set irq field to 0 so that it'll get assigned | ||
347 | * by the pcibios platform dependent code called by pci_enable_device. | ||
348 | */ | ||
349 | dev->irq = 0; | ||
350 | |||
351 | dbg("enabling device"); | ||
352 | pci_enable_device(dev); /* XXX check return */ | ||
353 | dbg("now dev->irq = %d", dev->irq); | ||
354 | if(irq_pin && dev->irq) { | ||
355 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
356 | } | ||
357 | |||
358 | /* Can't use pci_insert_device at the moment, do it manually for now */ | ||
359 | pci_proc_attach_device(dev); | ||
360 | dbg("notifying drivers"); | ||
361 | //pci_announce_device_to_drivers(dev); | ||
362 | dbg("%s - exit", __FUNCTION__); | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | static int cpci_configure_bridge(struct pci_bus* bus, struct pci_dev* dev) | ||
367 | { | 278 | { |
368 | int rc; | 279 | struct pci_bus *bus; |
369 | struct pci_bus* child; | ||
370 | struct resource* r; | ||
371 | u8 max, n; | ||
372 | u16 command; | ||
373 | |||
374 | dbg("%s - enter", __FUNCTION__); | ||
375 | 280 | ||
376 | /* Do basic bridge initialization */ | 281 | pci_enable_device(dev); |
377 | rc = pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x40); | ||
378 | if(rc) { | ||
379 | printk(KERN_ERR "%s - write of PCI_LATENCY_TIMER failed\n", __FUNCTION__); | ||
380 | } | ||
381 | rc = pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); | ||
382 | if(rc) { | ||
383 | printk(KERN_ERR "%s - write of PCI_SEC_LATENCY_TIMER failed\n", __FUNCTION__); | ||
384 | } | ||
385 | rc = pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4); | ||
386 | if(rc) { | ||
387 | printk(KERN_ERR "%s - write of PCI_CACHE_LINE_SIZE failed\n", __FUNCTION__); | ||
388 | } | ||
389 | |||
390 | /* | ||
391 | * Set parent bridge's subordinate field so that configuration space | ||
392 | * access will work in pci_scan_bridge and friends. | ||
393 | */ | ||
394 | max = pci_max_busnr(); | ||
395 | bus->subordinate = max + 1; | ||
396 | pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, max + 1); | ||
397 | |||
398 | /* Scan behind bridge */ | ||
399 | n = pci_scan_bridge(bus, dev, max, 2); | ||
400 | child = pci_find_bus(0, max + 1); | ||
401 | if (!child) | ||
402 | return -ENODEV; | ||
403 | pci_proc_attach_bus(child); | ||
404 | |||
405 | /* | ||
406 | * Update parent bridge's subordinate field if there were more bridges | ||
407 | * behind the bridge that was scanned. | ||
408 | */ | ||
409 | if(n > max) { | ||
410 | bus->subordinate = n; | ||
411 | pci_write_config_byte(bus->self, PCI_SUBORDINATE_BUS, n); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Update the bridge resources of the bridge to accommodate devices | ||
416 | * behind it. | ||
417 | */ | ||
418 | pci_bus_size_bridges(child); | ||
419 | pci_bus_assign_resources(child); | ||
420 | |||
421 | /* Enable resource mapping via command register */ | ||
422 | command = PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY | PCI_COMMAND_SERR; | ||
423 | r = child->resource[0]; | ||
424 | if(r && r->start) { | ||
425 | command |= PCI_COMMAND_IO; | ||
426 | } | ||
427 | r = child->resource[1]; | ||
428 | if(r && r->start) { | ||
429 | command |= PCI_COMMAND_MEMORY; | ||
430 | } | ||
431 | r = child->resource[2]; | ||
432 | if(r && r->start) { | ||
433 | command |= PCI_COMMAND_MEMORY; | ||
434 | } | ||
435 | rc = pci_write_config_word(dev, PCI_COMMAND, command); | ||
436 | if(rc) { | ||
437 | err("Error setting command register"); | ||
438 | return rc; | ||
439 | } | ||
440 | |||
441 | /* Set bridge control register */ | ||
442 | command = PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_NO_ISA; | ||
443 | rc = pci_write_config_word(dev, PCI_BRIDGE_CONTROL, command); | ||
444 | if(rc) { | ||
445 | err("Error setting bridge control register"); | ||
446 | return rc; | ||
447 | } | ||
448 | dbg("%s - exit", __FUNCTION__); | ||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | static int configure_visit_pci_dev(struct pci_dev_wrapped *wrapped_dev, | ||
453 | struct pci_bus_wrapped *wrapped_bus) | ||
454 | { | ||
455 | int rc; | ||
456 | struct pci_dev *dev = wrapped_dev->dev; | ||
457 | struct pci_bus *bus = wrapped_bus->bus; | ||
458 | struct slot* slot; | ||
459 | |||
460 | dbg("%s - enter", __FUNCTION__); | ||
461 | |||
462 | /* | ||
463 | * We need to fix up the hotplug representation with the Linux | ||
464 | * representation. | ||
465 | */ | ||
466 | if(wrapped_dev->data) { | ||
467 | slot = (struct slot*) wrapped_dev->data; | ||
468 | slot->dev = dev; | ||
469 | } | ||
470 | |||
471 | /* If it's a bridge, scan behind it for devices */ | ||
472 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { | 282 | if(dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
473 | rc = cpci_configure_bridge(bus, dev); | 283 | bus = dev->subordinate; |
474 | if(rc) | 284 | list_for_each_entry(dev, &bus->devices, bus_list) { |
475 | return rc; | 285 | cpci_enable_device(dev); |
476 | } | ||
477 | |||
478 | /* Actually configure device */ | ||
479 | if(dev) { | ||
480 | rc = cpci_configure_dev(bus, dev); | ||
481 | if(rc) | ||
482 | return rc; | ||
483 | } | ||
484 | dbg("%s - exit", __FUNCTION__); | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | static int unconfigure_visit_pci_dev_phase2(struct pci_dev_wrapped *wrapped_dev, | ||
489 | struct pci_bus_wrapped *wrapped_bus) | ||
490 | { | ||
491 | struct pci_dev *dev = wrapped_dev->dev; | ||
492 | struct slot* slot; | ||
493 | |||
494 | dbg("%s - enter", __FUNCTION__); | ||
495 | if(!dev) | ||
496 | return -ENODEV; | ||
497 | |||
498 | /* Remove the Linux representation */ | ||
499 | if(pci_remove_device_safe(dev)) { | ||
500 | err("Could not remove device\n"); | ||
501 | return -1; | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Now remove the hotplug representation. | ||
506 | */ | ||
507 | if(wrapped_dev->data) { | ||
508 | slot = (struct slot*) wrapped_dev->data; | ||
509 | slot->dev = NULL; | ||
510 | } else { | ||
511 | dbg("No hotplug representation for %02x:%02x.%x", | ||
512 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | ||
513 | } | ||
514 | dbg("%s - exit", __FUNCTION__); | ||
515 | return 0; | ||
516 | } | ||
517 | |||
518 | static int unconfigure_visit_pci_bus_phase2(struct pci_bus_wrapped *wrapped_bus, | ||
519 | struct pci_dev_wrapped *wrapped_dev) | ||
520 | { | ||
521 | struct pci_bus *bus = wrapped_bus->bus; | ||
522 | struct pci_bus *parent = bus->self->bus; | ||
523 | |||
524 | dbg("%s - enter", __FUNCTION__); | ||
525 | |||
526 | /* The cleanup code for proc entries regarding buses should be in the kernel... */ | ||
527 | if(bus->procdir) | ||
528 | dbg("detach_pci_bus %s", bus->procdir->name); | ||
529 | pci_proc_detach_bus(bus); | ||
530 | |||
531 | /* The cleanup code should live in the kernel... */ | ||
532 | bus->self->subordinate = NULL; | ||
533 | |||
534 | /* unlink from parent bus */ | ||
535 | list_del(&bus->node); | ||
536 | |||
537 | /* Now, remove */ | ||
538 | if(bus) | ||
539 | kfree(bus); | ||
540 | |||
541 | /* Update parent's subordinate field */ | ||
542 | if(parent) { | ||
543 | u8 n = pci_bus_max_busnr(parent); | ||
544 | if(n < parent->subordinate) { | ||
545 | parent->subordinate = n; | ||
546 | pci_write_config_byte(parent->self, PCI_SUBORDINATE_BUS, n); | ||
547 | } | 286 | } |
548 | } | 287 | } |
549 | dbg("%s - exit", __FUNCTION__); | ||
550 | return 0; | ||
551 | } | 288 | } |
552 | 289 | ||
553 | static struct pci_visit configure_functions = { | ||
554 | .visit_pci_dev = configure_visit_pci_dev, | ||
555 | }; | ||
556 | |||
557 | static struct pci_visit unconfigure_functions_phase2 = { | ||
558 | .post_visit_pci_bus = unconfigure_visit_pci_bus_phase2, | ||
559 | .post_visit_pci_dev = unconfigure_visit_pci_dev_phase2 | ||
560 | }; | ||
561 | |||
562 | |||
563 | int cpci_configure_slot(struct slot* slot) | 290 | int cpci_configure_slot(struct slot* slot) |
564 | { | 291 | { |
565 | int rc = 0; | 292 | unsigned char busnr; |
293 | struct pci_bus *child; | ||
566 | 294 | ||
567 | dbg("%s - enter", __FUNCTION__); | 295 | dbg("%s - enter", __FUNCTION__); |
568 | 296 | ||
@@ -588,74 +316,44 @@ int cpci_configure_slot(struct slot* slot) | |||
588 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); | 316 | slot->dev = pci_find_slot(slot->bus->number, slot->devfn); |
589 | if(slot->dev == NULL) { | 317 | if(slot->dev == NULL) { |
590 | err("Could not find PCI device for slot %02x", slot->number); | 318 | err("Could not find PCI device for slot %02x", slot->number); |
591 | return 0; | 319 | return 1; |
592 | } | 320 | } |
593 | } | 321 | } |
594 | dbg("slot->dev = %p", slot->dev); | 322 | |
595 | if(slot->dev) { | 323 | if (slot->dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) { |
596 | struct pci_dev *dev; | 324 | pci_read_config_byte(slot->dev, PCI_SECONDARY_BUS, &busnr); |
597 | struct pci_dev_wrapped wrapped_dev; | 325 | child = pci_add_new_bus(slot->dev->bus, slot->dev, busnr); |
598 | struct pci_bus_wrapped wrapped_bus; | 326 | pci_do_scan_bus(child); |
599 | int i; | 327 | pci_bus_size_bridges(child); |
600 | |||
601 | memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); | ||
602 | memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); | ||
603 | |||
604 | for (i = 0; i < 8; i++) { | ||
605 | dev = pci_find_slot(slot->bus->number, | ||
606 | PCI_DEVFN(PCI_SLOT(slot->dev->devfn), i)); | ||
607 | if(!dev) | ||
608 | continue; | ||
609 | wrapped_dev.dev = dev; | ||
610 | wrapped_bus.bus = slot->dev->bus; | ||
611 | if(i) | ||
612 | wrapped_dev.data = NULL; | ||
613 | else | ||
614 | wrapped_dev.data = (void*) slot; | ||
615 | rc = pci_visit_dev(&configure_functions, &wrapped_dev, &wrapped_bus); | ||
616 | } | ||
617 | } | 328 | } |
618 | 329 | ||
619 | dbg("%s - exit, rc = %d", __FUNCTION__, rc); | 330 | pci_bus_assign_resources(slot->dev->bus); |
620 | return rc; | 331 | |
332 | cpci_enable_device(slot->dev); | ||
333 | |||
334 | dbg("%s - exit", __FUNCTION__); | ||
335 | return 0; | ||
621 | } | 336 | } |
622 | 337 | ||
623 | int cpci_unconfigure_slot(struct slot* slot) | 338 | int cpci_unconfigure_slot(struct slot* slot) |
624 | { | 339 | { |
625 | int rc = 0; | ||
626 | int i; | 340 | int i; |
627 | struct pci_dev_wrapped wrapped_dev; | ||
628 | struct pci_bus_wrapped wrapped_bus; | ||
629 | struct pci_dev *dev; | 341 | struct pci_dev *dev; |
630 | 342 | ||
631 | dbg("%s - enter", __FUNCTION__); | 343 | dbg("%s - enter", __FUNCTION__); |
632 | |||
633 | if(!slot->dev) { | 344 | if(!slot->dev) { |
634 | err("No device for slot %02x\n", slot->number); | 345 | err("No device for slot %02x\n", slot->number); |
635 | return -ENODEV; | 346 | return -ENODEV; |
636 | } | 347 | } |
637 | 348 | ||
638 | memset(&wrapped_dev, 0, sizeof (struct pci_dev_wrapped)); | ||
639 | memset(&wrapped_bus, 0, sizeof (struct pci_bus_wrapped)); | ||
640 | |||
641 | for (i = 0; i < 8; i++) { | 349 | for (i = 0; i < 8; i++) { |
642 | dev = pci_find_slot(slot->bus->number, | 350 | dev = pci_find_slot(slot->bus->number, |
643 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); | 351 | PCI_DEVFN(PCI_SLOT(slot->devfn), i)); |
644 | if(dev) { | 352 | if(dev) { |
645 | wrapped_dev.dev = dev; | 353 | pci_remove_bus_device(dev); |
646 | wrapped_bus.bus = dev->bus; | 354 | slot->dev = NULL; |
647 | if(i) | ||
648 | wrapped_dev.data = NULL; | ||
649 | else | ||
650 | wrapped_dev.data = (void*) slot; | ||
651 | dbg("%s - unconfigure phase 2", __FUNCTION__); | ||
652 | rc = pci_visit_dev(&unconfigure_functions_phase2, | ||
653 | &wrapped_dev, | ||
654 | &wrapped_bus); | ||
655 | if(rc) | ||
656 | break; | ||
657 | } | 355 | } |
658 | } | 356 | } |
659 | dbg("%s - exit, rc = %d", __FUNCTION__, rc); | 357 | dbg("%s - exit", __FUNCTION__); |
660 | return rc; | 358 | return 0; |
661 | } | 359 | } |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index f313121d5141..46b294a12418 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -130,6 +130,7 @@ struct controller { | |||
130 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ | 130 | u8 slot_bus; /* Bus where the slots handled by this controller sit */ |
131 | u8 ctrlcap; | 131 | u8 ctrlcap; |
132 | u16 vendor_id; | 132 | u16 vendor_id; |
133 | u8 cap_base; | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | struct irq_mapping { | 136 | struct irq_mapping { |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index ed1fd8d6178d..df4915dbc321 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -607,7 +607,7 @@ static int pciehp_resume (struct pcie_device *dev) | |||
607 | static struct pcie_port_service_id port_pci_ids[] = { { | 607 | static struct pcie_port_service_id port_pci_ids[] = { { |
608 | .vendor = PCI_ANY_ID, | 608 | .vendor = PCI_ANY_ID, |
609 | .device = PCI_ANY_ID, | 609 | .device = PCI_ANY_ID, |
610 | .port_type = PCIE_RC_PORT, | 610 | .port_type = PCIE_ANY_PORT, |
611 | .service_type = PCIE_PORT_SERVICE_HP, | 611 | .service_type = PCIE_PORT_SERVICE_HP, |
612 | .driver_data = 0, | 612 | .driver_data = 0, |
613 | }, { /* end: all zeroes */ } | 613 | }, { /* end: all zeroes */ } |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9e70c4681f77..1cda30bd6e47 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -109,20 +109,20 @@ enum ctrl_offsets { | |||
109 | }; | 109 | }; |
110 | static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ | 110 | static int pcie_cap_base = 0; /* Base of the PCI Express capability item structure */ |
111 | 111 | ||
112 | #define PCIE_CAP_ID ( pcie_cap_base + PCIECAPID ) | 112 | #define PCIE_CAP_ID(cb) ( cb + PCIECAPID ) |
113 | #define NXT_CAP_PTR ( pcie_cap_base + NXTCAPPTR ) | 113 | #define NXT_CAP_PTR(cb) ( cb + NXTCAPPTR ) |
114 | #define CAP_REG ( pcie_cap_base + CAPREG ) | 114 | #define CAP_REG(cb) ( cb + CAPREG ) |
115 | #define DEV_CAP ( pcie_cap_base + DEVCAP ) | 115 | #define DEV_CAP(cb) ( cb + DEVCAP ) |
116 | #define DEV_CTRL ( pcie_cap_base + DEVCTRL ) | 116 | #define DEV_CTRL(cb) ( cb + DEVCTRL ) |
117 | #define DEV_STATUS ( pcie_cap_base + DEVSTATUS ) | 117 | #define DEV_STATUS(cb) ( cb + DEVSTATUS ) |
118 | #define LNK_CAP ( pcie_cap_base + LNKCAP ) | 118 | #define LNK_CAP(cb) ( cb + LNKCAP ) |
119 | #define LNK_CTRL ( pcie_cap_base + LNKCTRL ) | 119 | #define LNK_CTRL(cb) ( cb + LNKCTRL ) |
120 | #define LNK_STATUS ( pcie_cap_base + LNKSTATUS ) | 120 | #define LNK_STATUS(cb) ( cb + LNKSTATUS ) |
121 | #define SLOT_CAP ( pcie_cap_base + SLOTCAP ) | 121 | #define SLOT_CAP(cb) ( cb + SLOTCAP ) |
122 | #define SLOT_CTRL ( pcie_cap_base + SLOTCTRL ) | 122 | #define SLOT_CTRL(cb) ( cb + SLOTCTRL ) |
123 | #define SLOT_STATUS ( pcie_cap_base + SLOTSTATUS ) | 123 | #define SLOT_STATUS(cb) ( cb + SLOTSTATUS ) |
124 | #define ROOT_CTRL ( pcie_cap_base + ROOTCTRL ) | 124 | #define ROOT_CTRL(cb) ( cb + ROOTCTRL ) |
125 | #define ROOT_STATUS ( pcie_cap_base + ROOTSTATUS ) | 125 | #define ROOT_STATUS(cb) ( cb + ROOTSTATUS ) |
126 | 126 | ||
127 | #define hp_register_read_word(pdev, reg , value) \ | 127 | #define hp_register_read_word(pdev, reg , value) \ |
128 | pci_read_config_word(pdev, reg, &value) | 128 | pci_read_config_word(pdev, reg, &value) |
@@ -303,7 +303,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
303 | return -1; | 303 | return -1; |
304 | } | 304 | } |
305 | 305 | ||
306 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 306 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
307 | if (retval) { | 307 | if (retval) { |
308 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 308 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
309 | return retval; | 309 | return retval; |
@@ -317,7 +317,7 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
317 | } | 317 | } |
318 | 318 | ||
319 | dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); | 319 | dbg("%s: Before hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, cmd); |
320 | retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, cmd | CMD_CMPL_INTR_ENABLE); | 320 | retval = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), cmd | CMD_CMPL_INTR_ENABLE); |
321 | if (retval) { | 321 | if (retval) { |
322 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 322 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
323 | return retval; | 323 | return retval; |
@@ -342,7 +342,7 @@ static int hpc_check_lnk_status(struct controller *ctrl) | |||
342 | return -1; | 342 | return -1; |
343 | } | 343 | } |
344 | 344 | ||
345 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 345 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(ctrl->cap_base), lnk_status); |
346 | 346 | ||
347 | if (retval) { | 347 | if (retval) { |
348 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 348 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -376,14 +376,14 @@ static int hpc_get_attention_status(struct slot *slot, u8 *status) | |||
376 | return -1; | 376 | return -1; |
377 | } | 377 | } |
378 | 378 | ||
379 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 379 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
380 | 380 | ||
381 | if (retval) { | 381 | if (retval) { |
382 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 382 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
383 | return retval; | 383 | return retval; |
384 | } | 384 | } |
385 | 385 | ||
386 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL, slot_ctrl); | 386 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__,SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
387 | 387 | ||
388 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; | 388 | atten_led_state = (slot_ctrl & ATTN_LED_CTRL) >> 6; |
389 | 389 | ||
@@ -423,13 +423,13 @@ static int hpc_get_power_status(struct slot * slot, u8 *status) | |||
423 | return -1; | 423 | return -1; |
424 | } | 424 | } |
425 | 425 | ||
426 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 426 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
427 | 427 | ||
428 | if (retval) { | 428 | if (retval) { |
429 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 429 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
430 | return retval; | 430 | return retval; |
431 | } | 431 | } |
432 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); | 432 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
433 | 433 | ||
434 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; | 434 | pwr_state = (slot_ctrl & PWR_CTRL) >> 10; |
435 | 435 | ||
@@ -463,7 +463,7 @@ static int hpc_get_latch_status(struct slot *slot, u8 *status) | |||
463 | return -1; | 463 | return -1; |
464 | } | 464 | } |
465 | 465 | ||
466 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 466 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
467 | 467 | ||
468 | if (retval) { | 468 | if (retval) { |
469 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 469 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -490,7 +490,7 @@ static int hpc_get_adapter_status(struct slot *slot, u8 *status) | |||
490 | return -1; | 490 | return -1; |
491 | } | 491 | } |
492 | 492 | ||
493 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 493 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
494 | 494 | ||
495 | if (retval) { | 495 | if (retval) { |
496 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 496 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -518,7 +518,7 @@ static int hpc_query_power_fault(struct slot * slot) | |||
518 | return -1; | 518 | return -1; |
519 | } | 519 | } |
520 | 520 | ||
521 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 521 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(slot->ctrl->cap_base), slot_status); |
522 | 522 | ||
523 | if (retval) { | 523 | if (retval) { |
524 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 524 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
@@ -549,7 +549,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
549 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | 549 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); |
550 | return -1; | 550 | return -1; |
551 | } | 551 | } |
552 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 552 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
553 | 553 | ||
554 | if (rc) { | 554 | if (rc) { |
555 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 555 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -574,7 +574,7 @@ static int hpc_set_attention_status(struct slot *slot, u8 value) | |||
574 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 574 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
575 | 575 | ||
576 | pcie_write_cmd(slot, slot_cmd); | 576 | pcie_write_cmd(slot, slot_cmd); |
577 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); | 577 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
578 | 578 | ||
579 | return rc; | 579 | return rc; |
580 | } | 580 | } |
@@ -598,7 +598,7 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
598 | return ; | 598 | return ; |
599 | } | 599 | } |
600 | 600 | ||
601 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 601 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
602 | 602 | ||
603 | if (rc) { | 603 | if (rc) { |
604 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 604 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -611,7 +611,7 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
611 | 611 | ||
612 | pcie_write_cmd(slot, slot_cmd); | 612 | pcie_write_cmd(slot, slot_cmd); |
613 | 613 | ||
614 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 614 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
615 | return; | 615 | return; |
616 | } | 616 | } |
617 | 617 | ||
@@ -633,7 +633,7 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
633 | return ; | 633 | return ; |
634 | } | 634 | } |
635 | 635 | ||
636 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 636 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
637 | 637 | ||
638 | if (rc) { | 638 | if (rc) { |
639 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 639 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -646,7 +646,7 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
646 | if (!pciehp_poll_mode) | 646 | if (!pciehp_poll_mode) |
647 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 647 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
648 | pcie_write_cmd(slot, slot_cmd); | 648 | pcie_write_cmd(slot, slot_cmd); |
649 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL, slot_cmd); | 649 | dbg("%s: SLOT_CTRL %x write cmd %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
650 | 650 | ||
651 | return; | 651 | return; |
652 | } | 652 | } |
@@ -669,7 +669,7 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
669 | return ; | 669 | return ; |
670 | } | 670 | } |
671 | 671 | ||
672 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 672 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
673 | 673 | ||
674 | if (rc) { | 674 | if (rc) { |
675 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 675 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
@@ -683,7 +683,7 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
683 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 683 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
684 | pcie_write_cmd(slot, slot_cmd); | 684 | pcie_write_cmd(slot, slot_cmd); |
685 | 685 | ||
686 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 686 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
687 | return; | 687 | return; |
688 | } | 688 | } |
689 | 689 | ||
@@ -707,7 +707,7 @@ int pcie_get_ctlr_slot_config(struct controller *ctrl, | |||
707 | *first_device_num = 0; | 707 | *first_device_num = 0; |
708 | *num_ctlr_slots = 1; | 708 | *num_ctlr_slots = 1; |
709 | 709 | ||
710 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); | 710 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); |
711 | 711 | ||
712 | if (rc) { | 712 | if (rc) { |
713 | err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); | 713 | err("%s : hp_register_read_dword SLOT_CAP failed\n", __FUNCTION__); |
@@ -793,13 +793,13 @@ static int hpc_power_on_slot(struct slot * slot) | |||
793 | return -1; | 793 | return -1; |
794 | } | 794 | } |
795 | 795 | ||
796 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 796 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
797 | 797 | ||
798 | if (retval) { | 798 | if (retval) { |
799 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 799 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
800 | return retval; | 800 | return retval; |
801 | } | 801 | } |
802 | dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL, | 802 | dbg("%s: SLOT_CTRL %x, value read %xn", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), |
803 | slot_ctrl); | 803 | slot_ctrl); |
804 | 804 | ||
805 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; | 805 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; |
@@ -813,7 +813,7 @@ static int hpc_power_on_slot(struct slot * slot) | |||
813 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); | 813 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); |
814 | return -1; | 814 | return -1; |
815 | } | 815 | } |
816 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 816 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
817 | 817 | ||
818 | DBG_LEAVE_ROUTINE | 818 | DBG_LEAVE_ROUTINE |
819 | 819 | ||
@@ -842,13 +842,13 @@ static int hpc_power_off_slot(struct slot * slot) | |||
842 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); | 842 | err("%s: Invalid HPC slot number!\n", __FUNCTION__); |
843 | return -1; | 843 | return -1; |
844 | } | 844 | } |
845 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 845 | retval = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(slot->ctrl->cap_base), slot_ctrl); |
846 | 846 | ||
847 | if (retval) { | 847 | if (retval) { |
848 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 848 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
849 | return retval; | 849 | return retval; |
850 | } | 850 | } |
851 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL, | 851 | dbg("%s: SLOT_CTRL %x, value read %x\n", __FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), |
852 | slot_ctrl); | 852 | slot_ctrl); |
853 | 853 | ||
854 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; | 854 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; |
@@ -862,7 +862,7 @@ static int hpc_power_off_slot(struct slot * slot) | |||
862 | err("%s: Write command failed!\n", __FUNCTION__); | 862 | err("%s: Write command failed!\n", __FUNCTION__); |
863 | return -1; | 863 | return -1; |
864 | } | 864 | } |
865 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL, slot_cmd); | 865 | dbg("%s: SLOT_CTRL %x write cmd %x\n",__FUNCTION__, SLOT_CTRL(slot->ctrl->cap_base), slot_cmd); |
866 | 866 | ||
867 | DBG_LEAVE_ROUTINE | 867 | DBG_LEAVE_ROUTINE |
868 | 868 | ||
@@ -900,7 +900,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
900 | return IRQ_NONE; | 900 | return IRQ_NONE; |
901 | } | 901 | } |
902 | 902 | ||
903 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 903 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
904 | if (rc) { | 904 | if (rc) { |
905 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 905 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
906 | return IRQ_NONE; | 906 | return IRQ_NONE; |
@@ -918,7 +918,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
918 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 918 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
919 | /* Mask Hot-plug Interrupt Enable */ | 919 | /* Mask Hot-plug Interrupt Enable */ |
920 | if (!pciehp_poll_mode) { | 920 | if (!pciehp_poll_mode) { |
921 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 921 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
922 | if (rc) { | 922 | if (rc) { |
923 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 923 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
924 | return IRQ_NONE; | 924 | return IRQ_NONE; |
@@ -928,14 +928,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
928 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 928 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
929 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 929 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
930 | 930 | ||
931 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 931 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
932 | if (rc) { | 932 | if (rc) { |
933 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 933 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
934 | return IRQ_NONE; | 934 | return IRQ_NONE; |
935 | } | 935 | } |
936 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 936 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
937 | 937 | ||
938 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 938 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
939 | if (rc) { | 939 | if (rc) { |
940 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 940 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
941 | return IRQ_NONE; | 941 | return IRQ_NONE; |
@@ -944,7 +944,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
944 | 944 | ||
945 | /* Clear command complete interrupt caused by this write */ | 945 | /* Clear command complete interrupt caused by this write */ |
946 | temp_word = 0x1f; | 946 | temp_word = 0x1f; |
947 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 947 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
948 | if (rc) { | 948 | if (rc) { |
949 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 949 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
950 | return IRQ_NONE; | 950 | return IRQ_NONE; |
@@ -975,14 +975,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
975 | 975 | ||
976 | /* Clear all events after serving them */ | 976 | /* Clear all events after serving them */ |
977 | temp_word = 0x1F; | 977 | temp_word = 0x1F; |
978 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 978 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
979 | if (rc) { | 979 | if (rc) { |
980 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 980 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
981 | return IRQ_NONE; | 981 | return IRQ_NONE; |
982 | } | 982 | } |
983 | /* Unmask Hot-plug Interrupt Enable */ | 983 | /* Unmask Hot-plug Interrupt Enable */ |
984 | if (!pciehp_poll_mode) { | 984 | if (!pciehp_poll_mode) { |
985 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 985 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
986 | if (rc) { | 986 | if (rc) { |
987 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 987 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
988 | return IRQ_NONE; | 988 | return IRQ_NONE; |
@@ -992,14 +992,14 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
992 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 992 | dbg("%s: hp_register_read_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
993 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; | 993 | temp_word = (temp_word & ~HP_INTR_ENABLE) | HP_INTR_ENABLE; |
994 | 994 | ||
995 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL, temp_word); | 995 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), temp_word); |
996 | if (rc) { | 996 | if (rc) { |
997 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 997 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
998 | return IRQ_NONE; | 998 | return IRQ_NONE; |
999 | } | 999 | } |
1000 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); | 1000 | dbg("%s: hp_register_write_word SLOT_CTRL with value %x\n", __FUNCTION__, temp_word); |
1001 | 1001 | ||
1002 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1002 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1003 | if (rc) { | 1003 | if (rc) { |
1004 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1004 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1005 | return IRQ_NONE; | 1005 | return IRQ_NONE; |
@@ -1008,7 +1008,7 @@ static irqreturn_t pcie_isr(int IRQ, void *dev_id, struct pt_regs *regs) | |||
1008 | 1008 | ||
1009 | /* Clear command complete interrupt caused by this write */ | 1009 | /* Clear command complete interrupt caused by this write */ |
1010 | temp_word = 0x1F; | 1010 | temp_word = 0x1F; |
1011 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1011 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1012 | if (rc) { | 1012 | if (rc) { |
1013 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1013 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1014 | return IRQ_NONE; | 1014 | return IRQ_NONE; |
@@ -1038,7 +1038,7 @@ static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1038 | return -1; | 1038 | return -1; |
1039 | } | 1039 | } |
1040 | 1040 | ||
1041 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); | 1041 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); |
1042 | 1042 | ||
1043 | if (retval) { | 1043 | if (retval) { |
1044 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 1044 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); |
@@ -1079,7 +1079,7 @@ static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value | |||
1079 | return -1; | 1079 | return -1; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP, lnk_cap); | 1082 | retval = hp_register_read_dword(php_ctlr->pci_dev, LNK_CAP(slot->ctrl->cap_base), lnk_cap); |
1083 | 1083 | ||
1084 | if (retval) { | 1084 | if (retval) { |
1085 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); | 1085 | err("%s : hp_register_read_dword LNK_CAP failed\n", __FUNCTION__); |
@@ -1141,7 +1141,7 @@ static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value) | |||
1141 | return -1; | 1141 | return -1; |
1142 | } | 1142 | } |
1143 | 1143 | ||
1144 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 1144 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); |
1145 | 1145 | ||
1146 | if (retval) { | 1146 | if (retval) { |
1147 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 1147 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -1182,7 +1182,7 @@ static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value | |||
1182 | return -1; | 1182 | return -1; |
1183 | } | 1183 | } |
1184 | 1184 | ||
1185 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS, lnk_status); | 1185 | retval = hp_register_read_word(php_ctlr->pci_dev, LNK_STATUS(slot->ctrl->cap_base), lnk_status); |
1186 | 1186 | ||
1187 | if (retval) { | 1187 | if (retval) { |
1188 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); | 1188 | err("%s : hp_register_read_word LNK_STATUS failed\n", __FUNCTION__); |
@@ -1292,47 +1292,48 @@ int pcie_init(struct controller * ctrl, | |||
1292 | goto abort_free_ctlr; | 1292 | goto abort_free_ctlr; |
1293 | } | 1293 | } |
1294 | 1294 | ||
1295 | pcie_cap_base = cap_base; | 1295 | ctrl->cap_base = cap_base; |
1296 | 1296 | ||
1297 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); | 1297 | dbg("%s: pcie_cap_base %x\n", __FUNCTION__, pcie_cap_base); |
1298 | 1298 | ||
1299 | rc = hp_register_read_word(pdev, CAP_REG, cap_reg); | 1299 | rc = hp_register_read_word(pdev, CAP_REG(ctrl->cap_base), cap_reg); |
1300 | if (rc) { | 1300 | if (rc) { |
1301 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1301 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); |
1302 | goto abort_free_ctlr; | 1302 | goto abort_free_ctlr; |
1303 | } | 1303 | } |
1304 | dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG, cap_reg); | 1304 | dbg("%s: CAP_REG offset %x cap_reg %x\n", __FUNCTION__, CAP_REG(ctrl->cap_base), cap_reg); |
1305 | 1305 | ||
1306 | if (((cap_reg & SLOT_IMPL) == 0) || ((cap_reg & DEV_PORT_TYPE) != 0x0040)){ | 1306 | if (((cap_reg & SLOT_IMPL) == 0) || (((cap_reg & DEV_PORT_TYPE) != 0x0040) |
1307 | && ((cap_reg & DEV_PORT_TYPE) != 0x0060))) { | ||
1307 | dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__); | 1308 | dbg("%s : This is not a root port or the port is not connected to a slot\n", __FUNCTION__); |
1308 | goto abort_free_ctlr; | 1309 | goto abort_free_ctlr; |
1309 | } | 1310 | } |
1310 | 1311 | ||
1311 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP, slot_cap); | 1312 | rc = hp_register_read_dword(php_ctlr->pci_dev, SLOT_CAP(ctrl->cap_base), slot_cap); |
1312 | if (rc) { | 1313 | if (rc) { |
1313 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); | 1314 | err("%s : hp_register_read_word CAP_REG failed\n", __FUNCTION__); |
1314 | goto abort_free_ctlr; | 1315 | goto abort_free_ctlr; |
1315 | } | 1316 | } |
1316 | dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP, slot_cap); | 1317 | dbg("%s: SLOT_CAP offset %x slot_cap %x\n", __FUNCTION__, SLOT_CAP(ctrl->cap_base), slot_cap); |
1317 | 1318 | ||
1318 | if (!(slot_cap & HP_CAP)) { | 1319 | if (!(slot_cap & HP_CAP)) { |
1319 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); | 1320 | dbg("%s : This slot is not hot-plug capable\n", __FUNCTION__); |
1320 | goto abort_free_ctlr; | 1321 | goto abort_free_ctlr; |
1321 | } | 1322 | } |
1322 | /* For debugging purpose */ | 1323 | /* For debugging purpose */ |
1323 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1324 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1324 | if (rc) { | 1325 | if (rc) { |
1325 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1326 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1326 | goto abort_free_ctlr; | 1327 | goto abort_free_ctlr; |
1327 | } | 1328 | } |
1328 | dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); | 1329 | dbg("%s: SLOT_STATUS offset %x slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), slot_status); |
1329 | 1330 | ||
1330 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL, slot_ctrl); | 1331 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_CTRL(ctrl->cap_base), slot_ctrl); |
1331 | if (rc) { | 1332 | if (rc) { |
1332 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1333 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1333 | goto abort_free_ctlr; | 1334 | goto abort_free_ctlr; |
1334 | } | 1335 | } |
1335 | dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL, slot_ctrl); | 1336 | dbg("%s: SLOT_CTRL offset %x slot_ctrl %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), slot_ctrl); |
1336 | 1337 | ||
1337 | if (first) { | 1338 | if (first) { |
1338 | spin_lock_init(&hpc_event_lock); | 1339 | spin_lock_init(&hpc_event_lock); |
@@ -1372,36 +1373,37 @@ int pcie_init(struct controller * ctrl, | |||
1372 | php_ctlr->num_slots = 1; | 1373 | php_ctlr->num_slots = 1; |
1373 | 1374 | ||
1374 | /* Mask Hot-plug Interrupt Enable */ | 1375 | /* Mask Hot-plug Interrupt Enable */ |
1375 | rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); | 1376 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1376 | if (rc) { | 1377 | if (rc) { |
1377 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1378 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1378 | goto abort_free_ctlr; | 1379 | goto abort_free_ctlr; |
1379 | } | 1380 | } |
1380 | 1381 | ||
1381 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); | 1382 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); |
1382 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; | 1383 | temp_word = (temp_word & ~HP_INTR_ENABLE & ~CMD_CMPL_INTR_ENABLE) | 0x00; |
1383 | 1384 | ||
1384 | rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); | 1385 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1385 | if (rc) { | 1386 | if (rc) { |
1386 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1387 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
1387 | goto abort_free_ctlr; | 1388 | goto abort_free_ctlr; |
1388 | } | 1389 | } |
1389 | dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); | 1390 | dbg("%s : Mask HPIE hp_register_write_word SLOT_CTRL %x\n", __FUNCTION__, temp_word); |
1390 | 1391 | ||
1391 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1392 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1392 | if (rc) { | 1393 | if (rc) { |
1393 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1394 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1394 | goto abort_free_ctlr; | 1395 | goto abort_free_ctlr; |
1395 | } | 1396 | } |
1396 | dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS, slot_status); | 1397 | dbg("%s: Mask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base) |
1398 | , slot_status); | ||
1397 | 1399 | ||
1398 | temp_word = 0x1F; /* Clear all events */ | 1400 | temp_word = 0x1F; /* Clear all events */ |
1399 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1401 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1400 | if (rc) { | 1402 | if (rc) { |
1401 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1403 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1402 | goto abort_free_ctlr; | 1404 | goto abort_free_ctlr; |
1403 | } | 1405 | } |
1404 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); | 1406 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word); |
1405 | 1407 | ||
1406 | if (pciehp_poll_mode) {/* Install interrupt polling code */ | 1408 | if (pciehp_poll_mode) {/* Install interrupt polling code */ |
1407 | /* Install and start the interrupt polling timer */ | 1409 | /* Install and start the interrupt polling timer */ |
@@ -1417,12 +1419,12 @@ int pcie_init(struct controller * ctrl, | |||
1417 | } | 1419 | } |
1418 | } | 1420 | } |
1419 | 1421 | ||
1420 | rc = hp_register_read_word(pdev, SLOT_CTRL, temp_word); | 1422 | rc = hp_register_read_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1421 | if (rc) { | 1423 | if (rc) { |
1422 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); | 1424 | err("%s : hp_register_read_word SLOT_CTRL failed\n", __FUNCTION__); |
1423 | goto abort_free_ctlr; | 1425 | goto abort_free_ctlr; |
1424 | } | 1426 | } |
1425 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word); | 1427 | dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL(ctrl->cap_base), temp_word); |
1426 | dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap); | 1428 | dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap); |
1427 | 1429 | ||
1428 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; | 1430 | intr_enable = intr_enable | PRSN_DETECT_ENABLE; |
@@ -1446,27 +1448,27 @@ int pcie_init(struct controller * ctrl, | |||
1446 | dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); | 1448 | dbg("%s: temp_word %x\n", __FUNCTION__, temp_word); |
1447 | 1449 | ||
1448 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ | 1450 | /* Unmask Hot-plug Interrupt Enable for the interrupt notification mechanism case */ |
1449 | rc = hp_register_write_word(pdev, SLOT_CTRL, temp_word); | 1451 | rc = hp_register_write_word(pdev, SLOT_CTRL(ctrl->cap_base), temp_word); |
1450 | if (rc) { | 1452 | if (rc) { |
1451 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); | 1453 | err("%s : hp_register_write_word SLOT_CTRL failed\n", __FUNCTION__); |
1452 | goto abort_free_ctlr; | 1454 | goto abort_free_ctlr; |
1453 | } | 1455 | } |
1454 | dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); | 1456 | dbg("%s : Unmask HPIE hp_register_write_word SLOT_CTRL with %x\n", __FUNCTION__, temp_word); |
1455 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS, slot_status); | 1457 | rc = hp_register_read_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), slot_status); |
1456 | if (rc) { | 1458 | if (rc) { |
1457 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); | 1459 | err("%s : hp_register_read_word SLOT_STATUS failed\n", __FUNCTION__); |
1458 | goto abort_free_ctlr; | 1460 | goto abort_free_ctlr; |
1459 | } | 1461 | } |
1460 | dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, | 1462 | dbg("%s: Unmask HPIE SLOT_STATUS offset %x reads slot_status %x\n", __FUNCTION__, |
1461 | SLOT_STATUS, slot_status); | 1463 | SLOT_STATUS(ctrl->cap_base), slot_status); |
1462 | 1464 | ||
1463 | temp_word = 0x1F; /* Clear all events */ | 1465 | temp_word = 0x1F; /* Clear all events */ |
1464 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS, temp_word); | 1466 | rc = hp_register_write_word(php_ctlr->pci_dev, SLOT_STATUS(ctrl->cap_base), temp_word); |
1465 | if (rc) { | 1467 | if (rc) { |
1466 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); | 1468 | err("%s : hp_register_write_word SLOT_STATUS failed\n", __FUNCTION__); |
1467 | goto abort_free_ctlr; | 1469 | goto abort_free_ctlr; |
1468 | } | 1470 | } |
1469 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS, temp_word); | 1471 | dbg("%s: SLOT_STATUS offset %x writes slot_status %x\n", __FUNCTION__, SLOT_STATUS(ctrl->cap_base), temp_word); |
1470 | 1472 | ||
1471 | /* Add this HPC instance into the HPC list */ | 1473 | /* Add this HPC instance into the HPC list */ |
1472 | spin_lock(&list_lock); | 1474 | spin_lock(&list_lock); |
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index f0c53f850aed..a70a5c5705f2 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -95,7 +95,7 @@ static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | |||
95 | */ | 95 | */ |
96 | static void release_slot(struct hotplug_slot *hotplug_slot) | 96 | static void release_slot(struct hotplug_slot *hotplug_slot) |
97 | { | 97 | { |
98 | struct slot *slot = (struct slot *)hotplug_slot->private; | 98 | struct slot *slot = hotplug_slot->private; |
99 | 99 | ||
100 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 100 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
101 | 101 | ||
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index 9f90eb8e6ecd..490a9553a062 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c | |||
@@ -1885,7 +1885,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1885 | func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); | 1885 | func = shpchp_slot_find(p_slot->bus, p_slot->device, 0); |
1886 | if (!func) { | 1886 | if (!func) { |
1887 | dbg("%s: Error! slot NULL\n", __FUNCTION__); | 1887 | dbg("%s: Error! slot NULL\n", __FUNCTION__); |
1888 | return 1; | 1888 | return -ENODEV; |
1889 | } | 1889 | } |
1890 | 1890 | ||
1891 | /* Check to see if (latch closed, card present, power off) */ | 1891 | /* Check to see if (latch closed, card present, power off) */ |
@@ -1894,19 +1894,19 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1894 | if (rc || !getstatus) { | 1894 | if (rc || !getstatus) { |
1895 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 1895 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
1896 | up(&p_slot->ctrl->crit_sect); | 1896 | up(&p_slot->ctrl->crit_sect); |
1897 | return 1; | 1897 | return -ENODEV; |
1898 | } | 1898 | } |
1899 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 1899 | rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
1900 | if (rc || getstatus) { | 1900 | if (rc || getstatus) { |
1901 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 1901 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
1902 | up(&p_slot->ctrl->crit_sect); | 1902 | up(&p_slot->ctrl->crit_sect); |
1903 | return 1; | 1903 | return -ENODEV; |
1904 | } | 1904 | } |
1905 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 1905 | rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
1906 | if (rc || getstatus) { | 1906 | if (rc || getstatus) { |
1907 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); | 1907 | info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number); |
1908 | up(&p_slot->ctrl->crit_sect); | 1908 | up(&p_slot->ctrl->crit_sect); |
1909 | return 1; | 1909 | return -ENODEV; |
1910 | } | 1910 | } |
1911 | up(&p_slot->ctrl->crit_sect); | 1911 | up(&p_slot->ctrl->crit_sect); |
1912 | 1912 | ||
@@ -1914,7 +1914,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1914 | 1914 | ||
1915 | func = shpchp_slot_create(p_slot->bus); | 1915 | func = shpchp_slot_create(p_slot->bus); |
1916 | if (func == NULL) | 1916 | if (func == NULL) |
1917 | return 1; | 1917 | return -ENOMEM; |
1918 | 1918 | ||
1919 | func->bus = p_slot->bus; | 1919 | func->bus = p_slot->bus; |
1920 | func->device = p_slot->device; | 1920 | func->device = p_slot->device; |
@@ -1939,7 +1939,7 @@ int shpchp_enable_slot (struct slot *p_slot) | |||
1939 | /* Setup slot structure with entry for empty slot */ | 1939 | /* Setup slot structure with entry for empty slot */ |
1940 | func = shpchp_slot_create(p_slot->bus); | 1940 | func = shpchp_slot_create(p_slot->bus); |
1941 | if (func == NULL) | 1941 | if (func == NULL) |
1942 | return (1); /* Out of memory */ | 1942 | return -ENOMEM; /* Out of memory */ |
1943 | 1943 | ||
1944 | func->bus = p_slot->bus; | 1944 | func->bus = p_slot->bus; |
1945 | func->device = p_slot->device; | 1945 | func->device = p_slot->device; |
@@ -1972,7 +1972,7 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
1972 | struct pci_func *func; | 1972 | struct pci_func *func; |
1973 | 1973 | ||
1974 | if (!p_slot->ctrl) | 1974 | if (!p_slot->ctrl) |
1975 | return 1; | 1975 | return -ENODEV; |
1976 | 1976 | ||
1977 | pci_bus = p_slot->ctrl->pci_dev->subordinate; | 1977 | pci_bus = p_slot->ctrl->pci_dev->subordinate; |
1978 | 1978 | ||
@@ -1983,19 +1983,19 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
1983 | if (ret || !getstatus) { | 1983 | if (ret || !getstatus) { |
1984 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); | 1984 | info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number); |
1985 | up(&p_slot->ctrl->crit_sect); | 1985 | up(&p_slot->ctrl->crit_sect); |
1986 | return 1; | 1986 | return -ENODEV; |
1987 | } | 1987 | } |
1988 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); | 1988 | ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); |
1989 | if (ret || getstatus) { | 1989 | if (ret || getstatus) { |
1990 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); | 1990 | info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number); |
1991 | up(&p_slot->ctrl->crit_sect); | 1991 | up(&p_slot->ctrl->crit_sect); |
1992 | return 1; | 1992 | return -ENODEV; |
1993 | } | 1993 | } |
1994 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); | 1994 | ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); |
1995 | if (ret || !getstatus) { | 1995 | if (ret || !getstatus) { |
1996 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); | 1996 | info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number); |
1997 | up(&p_slot->ctrl->crit_sect); | 1997 | up(&p_slot->ctrl->crit_sect); |
1998 | return 1; | 1998 | return -ENODEV; |
1999 | } | 1999 | } |
2000 | up(&p_slot->ctrl->crit_sect); | 2000 | up(&p_slot->ctrl->crit_sect); |
2001 | 2001 | ||
@@ -2011,7 +2011,7 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2011 | /* Check the Class Code */ | 2011 | /* Check the Class Code */ |
2012 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); | 2012 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); |
2013 | if (rc) | 2013 | if (rc) |
2014 | return rc; | 2014 | return -ENODEV; |
2015 | 2015 | ||
2016 | if (class_code == PCI_BASE_CLASS_DISPLAY) { | 2016 | if (class_code == PCI_BASE_CLASS_DISPLAY) { |
2017 | /* Display/Video adapter (not supported) */ | 2017 | /* Display/Video adapter (not supported) */ |
@@ -2020,13 +2020,13 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2020 | /* See if it's a bridge */ | 2020 | /* See if it's a bridge */ |
2021 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 2021 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
2022 | if (rc) | 2022 | if (rc) |
2023 | return rc; | 2023 | return -ENODEV; |
2024 | 2024 | ||
2025 | /* If it's a bridge, check the VGA Enable bit */ | 2025 | /* If it's a bridge, check the VGA Enable bit */ |
2026 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | 2026 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
2027 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); | 2027 | rc = pci_bus_read_config_byte (pci_bus, devfn, PCI_BRIDGE_CONTROL, &BCR); |
2028 | if (rc) | 2028 | if (rc) |
2029 | return rc; | 2029 | return -ENODEV; |
2030 | 2030 | ||
2031 | /* If the VGA Enable bit is set, remove isn't supported */ | 2031 | /* If the VGA Enable bit is set, remove isn't supported */ |
2032 | if (BCR & PCI_BRIDGE_CTL_VGA) { | 2032 | if (BCR & PCI_BRIDGE_CTL_VGA) { |
@@ -2042,12 +2042,12 @@ int shpchp_disable_slot (struct slot *p_slot) | |||
2042 | if ((func != NULL) && !rc) { | 2042 | if ((func != NULL) && !rc) { |
2043 | rc = remove_board(func, p_slot->ctrl); | 2043 | rc = remove_board(func, p_slot->ctrl); |
2044 | } else if (!rc) | 2044 | } else if (!rc) |
2045 | rc = 1; | 2045 | rc = -ENODEV; |
2046 | 2046 | ||
2047 | if (p_slot) | 2047 | if (p_slot) |
2048 | update_slot_info(p_slot); | 2048 | update_slot_info(p_slot); |
2049 | 2049 | ||
2050 | return(rc); | 2050 | return rc; |
2051 | } | 2051 | } |
2052 | 2052 | ||
2053 | 2053 | ||
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 8568b207f189..6ca0061137a6 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -73,6 +73,17 @@ resource_show(struct device * dev, char * buf) | |||
73 | return (str - buf); | 73 | return (str - buf); |
74 | } | 74 | } |
75 | 75 | ||
76 | static ssize_t modalias_show(struct device *dev, char *buf) | ||
77 | { | ||
78 | struct pci_dev *pci_dev = to_pci_dev(dev); | ||
79 | |||
80 | return sprintf(buf, "pci:v%08Xd%08Xsv%08Xsd%08Xbc%02Xsc%02Xi%02x\n", | ||
81 | pci_dev->vendor, pci_dev->device, | ||
82 | pci_dev->subsystem_vendor, pci_dev->subsystem_device, | ||
83 | (u8)(pci_dev->class >> 16), (u8)(pci_dev->class >> 8), | ||
84 | (u8)(pci_dev->class)); | ||
85 | } | ||
86 | |||
76 | struct device_attribute pci_dev_attrs[] = { | 87 | struct device_attribute pci_dev_attrs[] = { |
77 | __ATTR_RO(resource), | 88 | __ATTR_RO(resource), |
78 | __ATTR_RO(vendor), | 89 | __ATTR_RO(vendor), |
@@ -82,6 +93,7 @@ struct device_attribute pci_dev_attrs[] = { | |||
82 | __ATTR_RO(class), | 93 | __ATTR_RO(class), |
83 | __ATTR_RO(irq), | 94 | __ATTR_RO(irq), |
84 | __ATTR_RO(local_cpus), | 95 | __ATTR_RO(local_cpus), |
96 | __ATTR_RO(modalias), | ||
85 | __ATTR_NULL, | 97 | __ATTR_NULL, |
86 | }; | 98 | }; |
87 | 99 | ||
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 79cdc16c52c8..744da0d4ae5f 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h | |||
@@ -32,33 +32,6 @@ extern unsigned char pci_max_busnr(void); | |||
32 | extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); | 32 | extern unsigned char pci_bus_max_busnr(struct pci_bus *bus); |
33 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); | 33 | extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); |
34 | 34 | ||
35 | struct pci_dev_wrapped { | ||
36 | struct pci_dev *dev; | ||
37 | void *data; | ||
38 | }; | ||
39 | |||
40 | struct pci_bus_wrapped { | ||
41 | struct pci_bus *bus; | ||
42 | void *data; | ||
43 | }; | ||
44 | |||
45 | struct pci_visit { | ||
46 | int (* pre_visit_pci_bus) (struct pci_bus_wrapped *, | ||
47 | struct pci_dev_wrapped *); | ||
48 | int (* post_visit_pci_bus) (struct pci_bus_wrapped *, | ||
49 | struct pci_dev_wrapped *); | ||
50 | |||
51 | int (* pre_visit_pci_dev) (struct pci_dev_wrapped *, | ||
52 | struct pci_bus_wrapped *); | ||
53 | int (* visit_pci_dev) (struct pci_dev_wrapped *, | ||
54 | struct pci_bus_wrapped *); | ||
55 | int (* post_visit_pci_dev) (struct pci_dev_wrapped *, | ||
56 | struct pci_bus_wrapped *); | ||
57 | }; | ||
58 | |||
59 | extern int pci_visit_dev(struct pci_visit *fn, | ||
60 | struct pci_dev_wrapped *wrapped_dev, | ||
61 | struct pci_bus_wrapped *wrapped_parent); | ||
62 | extern void pci_remove_legacy_files(struct pci_bus *bus); | 35 | extern void pci_remove_legacy_files(struct pci_bus *bus); |
63 | 36 | ||
64 | /* Lock for read/write access to pci device and bus lists */ | 37 | /* Lock for read/write access to pci device and bus lists */ |
diff --git a/drivers/pci/pcie/portdrv_bus.c b/drivers/pci/pcie/portdrv_bus.c index 4037a3e568de..3e84b501e6a4 100644 --- a/drivers/pci/pcie/portdrv_bus.c +++ b/drivers/pci/pcie/portdrv_bus.c | |||
@@ -39,7 +39,8 @@ static int pcie_port_bus_match(struct device *dev, struct device_driver *drv) | |||
39 | driver->id_table->vendor != pciedev->id.vendor) || | 39 | driver->id_table->vendor != pciedev->id.vendor) || |
40 | (driver->id_table->device != PCI_ANY_ID && | 40 | (driver->id_table->device != PCI_ANY_ID && |
41 | driver->id_table->device != pciedev->id.device) || | 41 | driver->id_table->device != pciedev->id.device) || |
42 | driver->id_table->port_type != pciedev->id.port_type || | 42 | (driver->id_table->port_type != PCIE_ANY_PORT && |
43 | driver->id_table->port_type != pciedev->id.port_type) || | ||
43 | driver->id_table->service_type != pciedev->id.service_type ) | 44 | driver->id_table->service_type != pciedev->id.service_type ) |
44 | return 0; | 45 | return 0; |
45 | 46 | ||
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 66150d08b5c7..c4ade288c5da 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -1592,9 +1592,9 @@ static int __init init_pcmcia_bus(void) | |||
1592 | 1592 | ||
1593 | /* Set up character device for user mode clients */ | 1593 | /* Set up character device for user mode clients */ |
1594 | i = register_chrdev(0, "pcmcia", &ds_fops); | 1594 | i = register_chrdev(0, "pcmcia", &ds_fops); |
1595 | if (i == -EBUSY) | 1595 | if (i < 0) |
1596 | printk(KERN_NOTICE "unable to find a free device # for " | 1596 | printk(KERN_NOTICE "unable to find a free device # for " |
1597 | "Driver Services\n"); | 1597 | "Driver Services (error=%d)\n", i); |
1598 | else | 1598 | else |
1599 | major_dev = i; | 1599 | major_dev = i; |
1600 | 1600 | ||
diff --git a/drivers/pcmcia/pd6729.c b/drivers/pcmcia/pd6729.c index 3f4364341d8d..20642f0e7bfe 100644 --- a/drivers/pcmcia/pd6729.c +++ b/drivers/pcmcia/pd6729.c | |||
@@ -744,7 +744,7 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, | |||
744 | 744 | ||
745 | for (i = 0; i < MAX_SOCKETS; i++) { | 745 | for (i = 0; i < MAX_SOCKETS; i++) { |
746 | socket[i].io_base = pci_resource_start(dev, 0); | 746 | socket[i].io_base = pci_resource_start(dev, 0); |
747 | socket[i].socket.features |= SS_CAP_PCCARD; | 747 | socket[i].socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD; |
748 | socket[i].socket.map_size = 0x1000; | 748 | socket[i].socket.map_size = 0x1000; |
749 | socket[i].socket.irq_mask = mask; | 749 | socket[i].socket.irq_mask = mask; |
750 | socket[i].socket.pci_irq = dev->irq; | 750 | socket[i].socket.pci_irq = dev->irq; |
diff --git a/drivers/pcmcia/ti113x.h b/drivers/pcmcia/ti113x.h index 52c073a9d7e4..a8a1d104524a 100644 --- a/drivers/pcmcia/ti113x.h +++ b/drivers/pcmcia/ti113x.h | |||
@@ -442,6 +442,25 @@ out: | |||
442 | } | 442 | } |
443 | 443 | ||
444 | 444 | ||
445 | /* changes the irq of func1 to match that of func0 */ | ||
446 | static int ti12xx_align_irqs(struct yenta_socket *socket, int *old_irq) | ||
447 | { | ||
448 | struct pci_dev *func0; | ||
449 | |||
450 | /* find func0 device */ | ||
451 | func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07); | ||
452 | if (!func0) | ||
453 | return 0; | ||
454 | |||
455 | if (old_irq) | ||
456 | *old_irq = socket->cb_irq; | ||
457 | socket->cb_irq = socket->dev->irq = func0->irq; | ||
458 | |||
459 | pci_dev_put(func0); | ||
460 | |||
461 | return 1; | ||
462 | } | ||
463 | |||
445 | /* | 464 | /* |
446 | * ties INTA and INTB together. also changes the devices irq to that of | 465 | * ties INTA and INTB together. also changes the devices irq to that of |
447 | * the function 0 device. call from func1 only. | 466 | * the function 0 device. call from func1 only. |
@@ -449,26 +468,22 @@ out: | |||
449 | */ | 468 | */ |
450 | static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq) | 469 | static int ti12xx_tie_interrupts(struct yenta_socket *socket, int *old_irq) |
451 | { | 470 | { |
452 | struct pci_dev *func0; | ||
453 | u32 sysctl; | 471 | u32 sysctl; |
472 | int ret; | ||
454 | 473 | ||
455 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | 474 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); |
456 | if (sysctl & TI122X_SCR_INTRTIE) | 475 | if (sysctl & TI122X_SCR_INTRTIE) |
457 | return 0; | 476 | return 0; |
458 | 477 | ||
459 | /* find func0 device */ | 478 | /* align */ |
460 | func0 = pci_get_slot(socket->dev->bus, socket->dev->devfn & ~0x07); | 479 | ret = ti12xx_align_irqs(socket, old_irq); |
461 | if (!func0) | 480 | if (!ret) |
462 | return 0; | 481 | return 0; |
463 | 482 | ||
464 | /* change the interrupt to match func0, tie 'em up */ | 483 | /* tie */ |
465 | *old_irq = socket->cb_irq; | ||
466 | socket->cb_irq = socket->dev->irq = func0->irq; | ||
467 | sysctl |= TI122X_SCR_INTRTIE; | 484 | sysctl |= TI122X_SCR_INTRTIE; |
468 | config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl); | 485 | config_writel(socket, TI113X_SYSTEM_CONTROL, sysctl); |
469 | 486 | ||
470 | pci_dev_put(func0); | ||
471 | |||
472 | return 1; | 487 | return 1; |
473 | } | 488 | } |
474 | 489 | ||
@@ -489,7 +504,7 @@ static void ti12xx_untie_interrupts(struct yenta_socket *socket, int old_irq) | |||
489 | */ | 504 | */ |
490 | static void ti12xx_irqroute_func1(struct yenta_socket *socket) | 505 | static void ti12xx_irqroute_func1(struct yenta_socket *socket) |
491 | { | 506 | { |
492 | u32 mfunc, mfunc_old, devctl; | 507 | u32 mfunc, mfunc_old, devctl, sysctl; |
493 | int pci_irq_status; | 508 | int pci_irq_status; |
494 | 509 | ||
495 | mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); | 510 | mfunc = mfunc_old = config_readl(socket, TI122X_MFUNC); |
@@ -497,6 +512,11 @@ static void ti12xx_irqroute_func1(struct yenta_socket *socket) | |||
497 | printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n", | 512 | printk(KERN_INFO "Yenta TI: socket %s, mfunc 0x%08x, devctl 0x%02x\n", |
498 | pci_name(socket->dev), mfunc, devctl); | 513 | pci_name(socket->dev), mfunc, devctl); |
499 | 514 | ||
515 | /* if IRQs are configured as tied, align irq of func1 with func0 */ | ||
516 | sysctl = config_readl(socket, TI113X_SYSTEM_CONTROL); | ||
517 | if (sysctl & TI122X_SCR_INTRTIE) | ||
518 | ti12xx_align_irqs(socket, NULL); | ||
519 | |||
500 | /* make sure PCI interrupts are enabled before probing */ | 520 | /* make sure PCI interrupts are enabled before probing */ |
501 | ti_init(socket); | 521 | ti_init(socket); |
502 | 522 | ||
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c index 02cfe244e069..ceeb3cf64a16 100644 --- a/drivers/s390/block/dasd.c +++ b/drivers/s390/block/dasd.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * Bugreports.to..: <Linux390@de.ibm.com> | 7 | * Bugreports.to..: <Linux390@de.ibm.com> |
8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 | 8 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001 |
9 | * | 9 | * |
10 | * $Revision: 1.161 $ | 10 | * $Revision: 1.164 $ |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -1766,10 +1766,10 @@ dasd_generic_probe (struct ccw_device *cdev, | |||
1766 | printk(KERN_WARNING | 1766 | printk(KERN_WARNING |
1767 | "dasd_generic_probe: could not add sysfs entries " | 1767 | "dasd_generic_probe: could not add sysfs entries " |
1768 | "for %s\n", cdev->dev.bus_id); | 1768 | "for %s\n", cdev->dev.bus_id); |
1769 | } else { | ||
1770 | cdev->handler = &dasd_int_handler; | ||
1769 | } | 1771 | } |
1770 | 1772 | ||
1771 | cdev->handler = &dasd_int_handler; | ||
1772 | |||
1773 | return ret; | 1773 | return ret; |
1774 | } | 1774 | } |
1775 | 1775 | ||
@@ -1780,6 +1780,8 @@ dasd_generic_remove (struct ccw_device *cdev) | |||
1780 | { | 1780 | { |
1781 | struct dasd_device *device; | 1781 | struct dasd_device *device; |
1782 | 1782 | ||
1783 | cdev->handler = NULL; | ||
1784 | |||
1783 | dasd_remove_sysfs_files(cdev); | 1785 | dasd_remove_sysfs_files(cdev); |
1784 | device = dasd_device_from_cdev(cdev); | 1786 | device = dasd_device_from_cdev(cdev); |
1785 | if (IS_ERR(device)) | 1787 | if (IS_ERR(device)) |
@@ -1810,14 +1812,14 @@ dasd_generic_set_online (struct ccw_device *cdev, | |||
1810 | struct dasd_device *device; | 1812 | struct dasd_device *device; |
1811 | int feature_diag, rc; | 1813 | int feature_diag, rc; |
1812 | 1814 | ||
1813 | feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG); | ||
1814 | if (feature_diag < 0) | ||
1815 | return feature_diag; | ||
1816 | |||
1817 | device = dasd_create_device(cdev); | 1815 | device = dasd_create_device(cdev); |
1818 | if (IS_ERR(device)) | 1816 | if (IS_ERR(device)) |
1819 | return PTR_ERR(device); | 1817 | return PTR_ERR(device); |
1820 | 1818 | ||
1819 | feature_diag = dasd_get_feature(cdev, DASD_FEATURE_USEDIAG); | ||
1820 | if (feature_diag < 0) | ||
1821 | return feature_diag; | ||
1822 | |||
1821 | if (feature_diag) { | 1823 | if (feature_diag) { |
1822 | if (!dasd_diag_discipline_pointer) { | 1824 | if (!dasd_diag_discipline_pointer) { |
1823 | printk (KERN_WARNING | 1825 | printk (KERN_WARNING |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 1f9aeb4accc6..68d151aaa474 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -52,7 +52,7 @@ static inline int zfcp_sg_list_copy_from_user(struct zfcp_sg_list *, | |||
52 | static inline int zfcp_sg_list_copy_to_user(void __user *, | 52 | static inline int zfcp_sg_list_copy_to_user(void __user *, |
53 | struct zfcp_sg_list *, size_t); | 53 | struct zfcp_sg_list *, size_t); |
54 | 54 | ||
55 | static int zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long); | 55 | static long zfcp_cfdc_dev_ioctl(struct file *, unsigned int, unsigned long); |
56 | 56 | ||
57 | #define ZFCP_CFDC_IOC_MAGIC 0xDD | 57 | #define ZFCP_CFDC_IOC_MAGIC 0xDD |
58 | #define ZFCP_CFDC_IOC \ | 58 | #define ZFCP_CFDC_IOC \ |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 0afa1c4696ca..c5daf372f853 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -61,7 +61,6 @@ | |||
61 | #include <linux/mempool.h> | 61 | #include <linux/mempool.h> |
62 | #include <linux/syscalls.h> | 62 | #include <linux/syscalls.h> |
63 | #include <linux/ioctl.h> | 63 | #include <linux/ioctl.h> |
64 | #include <linux/ioctl32.h> | ||
65 | 64 | ||
66 | /************************ DEBUG FLAGS *****************************************/ | 65 | /************************ DEBUG FLAGS *****************************************/ |
67 | 66 | ||
diff --git a/drivers/sbus/char/aurora.c b/drivers/sbus/char/aurora.c index e5fa1703856b..650d5e924f47 100644 --- a/drivers/sbus/char/aurora.c +++ b/drivers/sbus/char/aurora.c | |||
@@ -81,10 +81,6 @@ unsigned char irqs[4] = { | |||
81 | int irqhit=0; | 81 | int irqhit=0; |
82 | #endif | 82 | #endif |
83 | 83 | ||
84 | #ifndef MIN | ||
85 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | ||
86 | #endif | ||
87 | |||
88 | static struct tty_driver *aurora_driver; | 84 | static struct tty_driver *aurora_driver; |
89 | static struct Aurora_board aurora_board[AURORA_NBOARD] = { | 85 | static struct Aurora_board aurora_board[AURORA_NBOARD] = { |
90 | {0,}, | 86 | {0,}, |
@@ -594,7 +590,7 @@ static void aurora_transmit(struct Aurora_board const * bp, int chip) | |||
594 | &bp->r[chip]->r[CD180_TDR]); | 590 | &bp->r[chip]->r[CD180_TDR]); |
595 | port->COR2 &= ~COR2_ETC; | 591 | port->COR2 &= ~COR2_ETC; |
596 | } | 592 | } |
597 | count = MIN(port->break_length, 0xff); | 593 | count = min(port->break_length, 0xff); |
598 | sbus_writeb(CD180_C_ESC, | 594 | sbus_writeb(CD180_C_ESC, |
599 | &bp->r[chip]->r[CD180_TDR]); | 595 | &bp->r[chip]->r[CD180_TDR]); |
600 | sbus_writeb(CD180_C_DELAY, | 596 | sbus_writeb(CD180_C_DELAY, |
@@ -1575,7 +1571,7 @@ static int aurora_write(struct tty_struct * tty, | |||
1575 | save_flags(flags); | 1571 | save_flags(flags); |
1576 | while (1) { | 1572 | while (1) { |
1577 | cli(); | 1573 | cli(); |
1578 | c = MIN(count, MIN(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, | 1574 | c = min(count, min(SERIAL_XMIT_SIZE - port->xmit_cnt - 1, |
1579 | SERIAL_XMIT_SIZE - port->xmit_head)); | 1575 | SERIAL_XMIT_SIZE - port->xmit_head)); |
1580 | if (c <= 0) { | 1576 | if (c <= 0) { |
1581 | restore_flags(flags); | 1577 | restore_flags(flags); |
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 3c86655a5f33..74b93564a258 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c | |||
@@ -1824,7 +1824,10 @@ static int esp_do_data(struct NCR_ESP *esp, struct ESP_regs *eregs) | |||
1824 | /* loop */ | 1824 | /* loop */ |
1825 | while (hmuch) { | 1825 | while (hmuch) { |
1826 | int j, fifo_stuck = 0, newphase; | 1826 | int j, fifo_stuck = 0, newphase; |
1827 | unsigned long flags, timeout; | 1827 | unsigned long timeout; |
1828 | #if 0 | ||
1829 | unsigned long flags; | ||
1830 | #endif | ||
1828 | #if 0 | 1831 | #if 0 |
1829 | if ( i % 10 ) | 1832 | if ( i % 10 ) |
1830 | ESPDATA(("\r")); | 1833 | ESPDATA(("\r")); |
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index c9b82687ba1a..242fa77513f5 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c | |||
@@ -450,7 +450,7 @@ static int aac_cfg_open(struct inode *inode, struct file *file) | |||
450 | } | 450 | } |
451 | } | 451 | } |
452 | 452 | ||
453 | return 0; | 453 | return err; |
454 | } | 454 | } |
455 | 455 | ||
456 | /** | 456 | /** |
diff --git a/drivers/scsi/aic7xxx/aic7770_osm.c b/drivers/scsi/aic7xxx/aic7770_osm.c index c2b47f2bdffd..682ca0b32b44 100644 --- a/drivers/scsi/aic7xxx/aic7770_osm.c +++ b/drivers/scsi/aic7xxx/aic7770_osm.c | |||
@@ -41,7 +41,6 @@ | |||
41 | 41 | ||
42 | #include "aic7xxx_osm.h" | 42 | #include "aic7xxx_osm.h" |
43 | 43 | ||
44 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
45 | #include <linux/device.h> | 44 | #include <linux/device.h> |
46 | #include <linux/eisa.h> | 45 | #include <linux/eisa.h> |
47 | 46 | ||
@@ -62,13 +61,6 @@ static struct eisa_driver aic7770_driver = { | |||
62 | }; | 61 | }; |
63 | 62 | ||
64 | typedef struct device *aic7770_dev_t; | 63 | typedef struct device *aic7770_dev_t; |
65 | #else | ||
66 | #define MINSLOT 1 | ||
67 | #define NUMSLOTS 16 | ||
68 | #define IDOFFSET 0x80 | ||
69 | |||
70 | typedef void *aic7770_dev_t; | ||
71 | #endif | ||
72 | 64 | ||
73 | static int aic7770_linux_config(struct aic7770_identity *entry, | 65 | static int aic7770_linux_config(struct aic7770_identity *entry, |
74 | aic7770_dev_t dev, u_int eisaBase); | 66 | aic7770_dev_t dev, u_int eisaBase); |
@@ -76,7 +68,6 @@ static int aic7770_linux_config(struct aic7770_identity *entry, | |||
76 | int | 68 | int |
77 | ahc_linux_eisa_init(void) | 69 | ahc_linux_eisa_init(void) |
78 | { | 70 | { |
79 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
80 | struct eisa_device_id *eid; | 71 | struct eisa_device_id *eid; |
81 | struct aic7770_identity *id; | 72 | struct aic7770_identity *id; |
82 | int i; | 73 | int i; |
@@ -110,44 +101,6 @@ ahc_linux_eisa_init(void) | |||
110 | eid->sig[0] = 0; | 101 | eid->sig[0] = 0; |
111 | 102 | ||
112 | return eisa_driver_register(&aic7770_driver); | 103 | return eisa_driver_register(&aic7770_driver); |
113 | #else /* LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) */ | ||
114 | struct aic7770_identity *entry; | ||
115 | u_int slot; | ||
116 | u_int eisaBase; | ||
117 | u_int i; | ||
118 | int ret = -ENODEV; | ||
119 | |||
120 | if (aic7xxx_probe_eisa_vl == 0) | ||
121 | return ret; | ||
122 | |||
123 | eisaBase = 0x1000 + AHC_EISA_SLOT_OFFSET; | ||
124 | for (slot = 1; slot < NUMSLOTS; eisaBase+=0x1000, slot++) { | ||
125 | uint32_t eisa_id; | ||
126 | size_t id_size; | ||
127 | |||
128 | if (request_region(eisaBase, AHC_EISA_IOSIZE, "aic7xxx") == 0) | ||
129 | continue; | ||
130 | |||
131 | eisa_id = 0; | ||
132 | id_size = sizeof(eisa_id); | ||
133 | for (i = 0; i < 4; i++) { | ||
134 | /* VLcards require priming*/ | ||
135 | outb(0x80 + i, eisaBase + IDOFFSET); | ||
136 | eisa_id |= inb(eisaBase + IDOFFSET + i) | ||
137 | << ((id_size-i-1) * 8); | ||
138 | } | ||
139 | release_region(eisaBase, AHC_EISA_IOSIZE); | ||
140 | if (eisa_id & 0x80000000) | ||
141 | continue; /* no EISA card in slot */ | ||
142 | |||
143 | entry = aic7770_find_device(eisa_id); | ||
144 | if (entry != NULL) { | ||
145 | aic7770_linux_config(entry, NULL, eisaBase); | ||
146 | ret = 0; | ||
147 | } | ||
148 | } | ||
149 | return ret; | ||
150 | #endif | ||
151 | } | 104 | } |
152 | 105 | ||
153 | void | 106 | void |
@@ -187,11 +140,10 @@ aic7770_linux_config(struct aic7770_identity *entry, aic7770_dev_t dev, | |||
187 | ahc_free(ahc); | 140 | ahc_free(ahc); |
188 | return (error); | 141 | return (error); |
189 | } | 142 | } |
190 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | 143 | |
191 | dev->driver_data = (void *)ahc; | 144 | dev->driver_data = (void *)ahc; |
192 | if (aic7xxx_detect_complete) | 145 | if (aic7xxx_detect_complete) |
193 | error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); | 146 | error = ahc_linux_register_host(ahc, &aic7xxx_driver_template); |
194 | #endif | ||
195 | return (error); | 147 | return (error); |
196 | } | 148 | } |
197 | 149 | ||
@@ -225,7 +177,6 @@ aic7770_map_int(struct ahc_softc *ahc, u_int irq) | |||
225 | return (-error); | 177 | return (-error); |
226 | } | 178 | } |
227 | 179 | ||
228 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
229 | static int | 180 | static int |
230 | aic7770_eisa_dev_probe(struct device *dev) | 181 | aic7770_eisa_dev_probe(struct device *dev) |
231 | { | 182 | { |
@@ -261,4 +212,3 @@ aic7770_eisa_dev_remove(struct device *dev) | |||
261 | 212 | ||
262 | return (0); | 213 | return (0); |
263 | } | 214 | } |
264 | #endif | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index e60f9338e44a..f90efa265ba2 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c | |||
@@ -134,11 +134,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; | |||
134 | #include "aiclib.c" | 134 | #include "aiclib.c" |
135 | 135 | ||
136 | #include <linux/init.h> /* __setup */ | 136 | #include <linux/init.h> /* __setup */ |
137 | |||
138 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
139 | #include "sd.h" /* For geometry detection */ | ||
140 | #endif | ||
141 | |||
142 | #include <linux/mm.h> /* For fetching system memory size */ | 137 | #include <linux/mm.h> /* For fetching system memory size */ |
143 | #include <linux/blkdev.h> /* For block_size() */ | 138 | #include <linux/blkdev.h> /* For block_size() */ |
144 | #include <linux/delay.h> /* For ssleep/msleep */ | 139 | #include <linux/delay.h> /* For ssleep/msleep */ |
@@ -148,11 +143,6 @@ static struct scsi_transport_template *ahc_linux_transport_template = NULL; | |||
148 | */ | 143 | */ |
149 | spinlock_t ahc_list_spinlock; | 144 | spinlock_t ahc_list_spinlock; |
150 | 145 | ||
151 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
152 | /* For dynamic sglist size calculation. */ | ||
153 | u_int ahc_linux_nseg; | ||
154 | #endif | ||
155 | |||
156 | /* | 146 | /* |
157 | * Set this to the delay in seconds after SCSI bus reset. | 147 | * Set this to the delay in seconds after SCSI bus reset. |
158 | * Note, we honor this only for the initial bus reset. | 148 | * Note, we honor this only for the initial bus reset. |
@@ -436,15 +426,12 @@ static void ahc_linux_handle_scsi_status(struct ahc_softc *, | |||
436 | struct ahc_linux_device *, | 426 | struct ahc_linux_device *, |
437 | struct scb *); | 427 | struct scb *); |
438 | static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, | 428 | static void ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, |
439 | Scsi_Cmnd *cmd); | 429 | struct scsi_cmnd *cmd); |
440 | static void ahc_linux_sem_timeout(u_long arg); | 430 | static void ahc_linux_sem_timeout(u_long arg); |
441 | static void ahc_linux_freeze_simq(struct ahc_softc *ahc); | 431 | static void ahc_linux_freeze_simq(struct ahc_softc *ahc); |
442 | static void ahc_linux_release_simq(u_long arg); | 432 | static void ahc_linux_release_simq(u_long arg); |
443 | static void ahc_linux_dev_timed_unfreeze(u_long arg); | 433 | static int ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag); |
444 | static int ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag); | ||
445 | static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); | 434 | static void ahc_linux_initialize_scsi_bus(struct ahc_softc *ahc); |
446 | static void ahc_linux_size_nseg(void); | ||
447 | static void ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc); | ||
448 | static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, | 435 | static u_int ahc_linux_user_tagdepth(struct ahc_softc *ahc, |
449 | struct ahc_devinfo *devinfo); | 436 | struct ahc_devinfo *devinfo); |
450 | static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, | 437 | static void ahc_linux_device_queue_depth(struct ahc_softc *ahc, |
@@ -458,54 +445,27 @@ static struct ahc_linux_device* ahc_linux_alloc_device(struct ahc_softc*, | |||
458 | u_int); | 445 | u_int); |
459 | static void ahc_linux_free_device(struct ahc_softc*, | 446 | static void ahc_linux_free_device(struct ahc_softc*, |
460 | struct ahc_linux_device*); | 447 | struct ahc_linux_device*); |
461 | static void ahc_linux_run_device_queue(struct ahc_softc*, | 448 | static int ahc_linux_run_command(struct ahc_softc*, |
462 | struct ahc_linux_device*); | 449 | struct ahc_linux_device *, |
450 | struct scsi_cmnd *); | ||
463 | static void ahc_linux_setup_tag_info_global(char *p); | 451 | static void ahc_linux_setup_tag_info_global(char *p); |
464 | static aic_option_callback_t ahc_linux_setup_tag_info; | 452 | static aic_option_callback_t ahc_linux_setup_tag_info; |
465 | static int aic7xxx_setup(char *s); | 453 | static int aic7xxx_setup(char *s); |
466 | static int ahc_linux_next_unit(void); | 454 | static int ahc_linux_next_unit(void); |
467 | static void ahc_runq_tasklet(unsigned long data); | ||
468 | static struct ahc_cmd *ahc_linux_run_complete_queue(struct ahc_softc *ahc); | ||
469 | 455 | ||
470 | /********************************* Inlines ************************************/ | 456 | /********************************* Inlines ************************************/ |
471 | static __inline void ahc_schedule_runq(struct ahc_softc *ahc); | ||
472 | static __inline struct ahc_linux_device* | 457 | static __inline struct ahc_linux_device* |
473 | ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, | 458 | ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, |
474 | u_int target, u_int lun, int alloc); | 459 | u_int target, u_int lun); |
475 | static __inline void ahc_schedule_completeq(struct ahc_softc *ahc); | ||
476 | static __inline void ahc_linux_check_device_queue(struct ahc_softc *ahc, | ||
477 | struct ahc_linux_device *dev); | ||
478 | static __inline struct ahc_linux_device * | ||
479 | ahc_linux_next_device_to_run(struct ahc_softc *ahc); | ||
480 | static __inline void ahc_linux_run_device_queues(struct ahc_softc *ahc); | ||
481 | static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); | 460 | static __inline void ahc_linux_unmap_scb(struct ahc_softc*, struct scb*); |
482 | 461 | ||
483 | static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, | 462 | static __inline int ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, |
484 | struct ahc_dma_seg *sg, | 463 | struct ahc_dma_seg *sg, |
485 | dma_addr_t addr, bus_size_t len); | 464 | dma_addr_t addr, bus_size_t len); |
486 | 465 | ||
487 | static __inline void | ||
488 | ahc_schedule_completeq(struct ahc_softc *ahc) | ||
489 | { | ||
490 | if ((ahc->platform_data->flags & AHC_RUN_CMPLT_Q_TIMER) == 0) { | ||
491 | ahc->platform_data->flags |= AHC_RUN_CMPLT_Q_TIMER; | ||
492 | ahc->platform_data->completeq_timer.expires = jiffies; | ||
493 | add_timer(&ahc->platform_data->completeq_timer); | ||
494 | } | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Must be called with our lock held. | ||
499 | */ | ||
500 | static __inline void | ||
501 | ahc_schedule_runq(struct ahc_softc *ahc) | ||
502 | { | ||
503 | tasklet_schedule(&ahc->platform_data->runq_tasklet); | ||
504 | } | ||
505 | |||
506 | static __inline struct ahc_linux_device* | 466 | static __inline struct ahc_linux_device* |
507 | ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, | 467 | ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, |
508 | u_int lun, int alloc) | 468 | u_int lun) |
509 | { | 469 | { |
510 | struct ahc_linux_target *targ; | 470 | struct ahc_linux_target *targ; |
511 | struct ahc_linux_device *dev; | 471 | struct ahc_linux_device *dev; |
@@ -515,102 +475,15 @@ ahc_linux_get_device(struct ahc_softc *ahc, u_int channel, u_int target, | |||
515 | if (channel != 0) | 475 | if (channel != 0) |
516 | target_offset += 8; | 476 | target_offset += 8; |
517 | targ = ahc->platform_data->targets[target_offset]; | 477 | targ = ahc->platform_data->targets[target_offset]; |
518 | if (targ == NULL) { | 478 | BUG_ON(targ == NULL); |
519 | if (alloc != 0) { | ||
520 | targ = ahc_linux_alloc_target(ahc, channel, target); | ||
521 | if (targ == NULL) | ||
522 | return (NULL); | ||
523 | } else | ||
524 | return (NULL); | ||
525 | } | ||
526 | dev = targ->devices[lun]; | 479 | dev = targ->devices[lun]; |
527 | if (dev == NULL && alloc != 0) | 480 | return dev; |
528 | dev = ahc_linux_alloc_device(ahc, targ, lun); | ||
529 | return (dev); | ||
530 | } | ||
531 | |||
532 | #define AHC_LINUX_MAX_RETURNED_ERRORS 4 | ||
533 | static struct ahc_cmd * | ||
534 | ahc_linux_run_complete_queue(struct ahc_softc *ahc) | ||
535 | { | ||
536 | struct ahc_cmd *acmd; | ||
537 | u_long done_flags; | ||
538 | int with_errors; | ||
539 | |||
540 | with_errors = 0; | ||
541 | ahc_done_lock(ahc, &done_flags); | ||
542 | while ((acmd = TAILQ_FIRST(&ahc->platform_data->completeq)) != NULL) { | ||
543 | Scsi_Cmnd *cmd; | ||
544 | |||
545 | if (with_errors > AHC_LINUX_MAX_RETURNED_ERRORS) { | ||
546 | /* | ||
547 | * Linux uses stack recursion to requeue | ||
548 | * commands that need to be retried. Avoid | ||
549 | * blowing out the stack by "spoon feeding" | ||
550 | * commands that completed with error back | ||
551 | * the operating system in case they are going | ||
552 | * to be retried. "ick" | ||
553 | */ | ||
554 | ahc_schedule_completeq(ahc); | ||
555 | break; | ||
556 | } | ||
557 | TAILQ_REMOVE(&ahc->platform_data->completeq, | ||
558 | acmd, acmd_links.tqe); | ||
559 | cmd = &acmd_scsi_cmd(acmd); | ||
560 | cmd->host_scribble = NULL; | ||
561 | if (ahc_cmd_get_transaction_status(cmd) != DID_OK | ||
562 | || (cmd->result & 0xFF) != SCSI_STATUS_OK) | ||
563 | with_errors++; | ||
564 | |||
565 | cmd->scsi_done(cmd); | ||
566 | } | ||
567 | ahc_done_unlock(ahc, &done_flags); | ||
568 | return (acmd); | ||
569 | } | ||
570 | |||
571 | static __inline void | ||
572 | ahc_linux_check_device_queue(struct ahc_softc *ahc, | ||
573 | struct ahc_linux_device *dev) | ||
574 | { | ||
575 | if ((dev->flags & AHC_DEV_FREEZE_TIL_EMPTY) != 0 | ||
576 | && dev->active == 0) { | ||
577 | dev->flags &= ~AHC_DEV_FREEZE_TIL_EMPTY; | ||
578 | dev->qfrozen--; | ||
579 | } | ||
580 | |||
581 | if (TAILQ_FIRST(&dev->busyq) == NULL | ||
582 | || dev->openings == 0 || dev->qfrozen != 0) | ||
583 | return; | ||
584 | |||
585 | ahc_linux_run_device_queue(ahc, dev); | ||
586 | } | ||
587 | |||
588 | static __inline struct ahc_linux_device * | ||
589 | ahc_linux_next_device_to_run(struct ahc_softc *ahc) | ||
590 | { | ||
591 | |||
592 | if ((ahc->flags & AHC_RESOURCE_SHORTAGE) != 0 | ||
593 | || (ahc->platform_data->qfrozen != 0)) | ||
594 | return (NULL); | ||
595 | return (TAILQ_FIRST(&ahc->platform_data->device_runq)); | ||
596 | } | ||
597 | |||
598 | static __inline void | ||
599 | ahc_linux_run_device_queues(struct ahc_softc *ahc) | ||
600 | { | ||
601 | struct ahc_linux_device *dev; | ||
602 | |||
603 | while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { | ||
604 | TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); | ||
605 | dev->flags &= ~AHC_DEV_ON_RUN_LIST; | ||
606 | ahc_linux_check_device_queue(ahc, dev); | ||
607 | } | ||
608 | } | 481 | } |
609 | 482 | ||
610 | static __inline void | 483 | static __inline void |
611 | ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) | 484 | ahc_linux_unmap_scb(struct ahc_softc *ahc, struct scb *scb) |
612 | { | 485 | { |
613 | Scsi_Cmnd *cmd; | 486 | struct scsi_cmnd *cmd; |
614 | 487 | ||
615 | cmd = scb->io_ctx; | 488 | cmd = scb->io_ctx; |
616 | ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE); | 489 | ahc_sync_sglist(ahc, scb, BUS_DMASYNC_POSTWRITE); |
@@ -650,109 +523,15 @@ ahc_linux_map_seg(struct ahc_softc *ahc, struct scb *scb, | |||
650 | return (consumed); | 523 | return (consumed); |
651 | } | 524 | } |
652 | 525 | ||
653 | /************************ Host template entry points *************************/ | ||
654 | static int ahc_linux_detect(Scsi_Host_Template *); | ||
655 | static int ahc_linux_queue(Scsi_Cmnd *, void (*)(Scsi_Cmnd *)); | ||
656 | static const char *ahc_linux_info(struct Scsi_Host *); | ||
657 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
658 | static int ahc_linux_slave_alloc(Scsi_Device *); | ||
659 | static int ahc_linux_slave_configure(Scsi_Device *); | ||
660 | static void ahc_linux_slave_destroy(Scsi_Device *); | ||
661 | #if defined(__i386__) | ||
662 | static int ahc_linux_biosparam(struct scsi_device*, | ||
663 | struct block_device*, | ||
664 | sector_t, int[]); | ||
665 | #endif | ||
666 | #else | ||
667 | static int ahc_linux_release(struct Scsi_Host *); | ||
668 | static void ahc_linux_select_queue_depth(struct Scsi_Host *host, | ||
669 | Scsi_Device *scsi_devs); | ||
670 | #if defined(__i386__) | ||
671 | static int ahc_linux_biosparam(Disk *, kdev_t, int[]); | ||
672 | #endif | ||
673 | #endif | ||
674 | static int ahc_linux_bus_reset(Scsi_Cmnd *); | ||
675 | static int ahc_linux_dev_reset(Scsi_Cmnd *); | ||
676 | static int ahc_linux_abort(Scsi_Cmnd *); | ||
677 | |||
678 | /* | ||
679 | * Calculate a safe value for AHC_NSEG (as expressed through ahc_linux_nseg). | ||
680 | * | ||
681 | * In pre-2.5.X... | ||
682 | * The midlayer allocates an S/G array dynamically when a command is issued | ||
683 | * using SCSI malloc. This array, which is in an OS dependent format that | ||
684 | * must later be copied to our private S/G list, is sized to house just the | ||
685 | * number of segments needed for the current transfer. Since the code that | ||
686 | * sizes the SCSI malloc pool does not take into consideration fragmentation | ||
687 | * of the pool, executing transactions numbering just a fraction of our | ||
688 | * concurrent transaction limit with list lengths aproaching AHC_NSEG will | ||
689 | * quickly depleat the SCSI malloc pool of usable space. Unfortunately, the | ||
690 | * mid-layer does not properly handle this scsi malloc failures for the S/G | ||
691 | * array and the result can be a lockup of the I/O subsystem. We try to size | ||
692 | * our S/G list so that it satisfies our drivers allocation requirements in | ||
693 | * addition to avoiding fragmentation of the SCSI malloc pool. | ||
694 | */ | ||
695 | static void | ||
696 | ahc_linux_size_nseg(void) | ||
697 | { | ||
698 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
699 | u_int cur_size; | ||
700 | u_int best_size; | ||
701 | |||
702 | /* | ||
703 | * The SCSI allocator rounds to the nearest 512 bytes | ||
704 | * an cannot allocate across a page boundary. Our algorithm | ||
705 | * is to start at 1K of scsi malloc space per-command and | ||
706 | * loop through all factors of the PAGE_SIZE and pick the best. | ||
707 | */ | ||
708 | best_size = 0; | ||
709 | for (cur_size = 1024; cur_size <= PAGE_SIZE; cur_size *= 2) { | ||
710 | u_int nseg; | ||
711 | |||
712 | nseg = cur_size / sizeof(struct scatterlist); | ||
713 | if (nseg < AHC_LINUX_MIN_NSEG) | ||
714 | continue; | ||
715 | |||
716 | if (best_size == 0) { | ||
717 | best_size = cur_size; | ||
718 | ahc_linux_nseg = nseg; | ||
719 | } else { | ||
720 | u_int best_rem; | ||
721 | u_int cur_rem; | ||
722 | |||
723 | /* | ||
724 | * Compare the traits of the current "best_size" | ||
725 | * with the current size to determine if the | ||
726 | * current size is a better size. | ||
727 | */ | ||
728 | best_rem = best_size % sizeof(struct scatterlist); | ||
729 | cur_rem = cur_size % sizeof(struct scatterlist); | ||
730 | if (cur_rem < best_rem) { | ||
731 | best_size = cur_size; | ||
732 | ahc_linux_nseg = nseg; | ||
733 | } | ||
734 | } | ||
735 | } | ||
736 | #endif | ||
737 | } | ||
738 | |||
739 | /* | 526 | /* |
740 | * Try to detect an Adaptec 7XXX controller. | 527 | * Try to detect an Adaptec 7XXX controller. |
741 | */ | 528 | */ |
742 | static int | 529 | static int |
743 | ahc_linux_detect(Scsi_Host_Template *template) | 530 | ahc_linux_detect(struct scsi_host_template *template) |
744 | { | 531 | { |
745 | struct ahc_softc *ahc; | 532 | struct ahc_softc *ahc; |
746 | int found = 0; | 533 | int found = 0; |
747 | 534 | ||
748 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
749 | /* | ||
750 | * It is a bug that the upper layer takes | ||
751 | * this lock just prior to calling us. | ||
752 | */ | ||
753 | spin_unlock_irq(&io_request_lock); | ||
754 | #endif | ||
755 | |||
756 | /* | 535 | /* |
757 | * Sanity checking of Linux SCSI data structures so | 536 | * Sanity checking of Linux SCSI data structures so |
758 | * that some of our hacks^H^H^H^H^Hassumptions aren't | 537 | * that some of our hacks^H^H^H^H^Hassumptions aren't |
@@ -764,7 +543,6 @@ ahc_linux_detect(Scsi_Host_Template *template) | |||
764 | printf("ahc_linux_detect: Unable to attach\n"); | 543 | printf("ahc_linux_detect: Unable to attach\n"); |
765 | return (0); | 544 | return (0); |
766 | } | 545 | } |
767 | ahc_linux_size_nseg(); | ||
768 | /* | 546 | /* |
769 | * If we've been passed any parameters, process them now. | 547 | * If we've been passed any parameters, process them now. |
770 | */ | 548 | */ |
@@ -793,48 +571,11 @@ ahc_linux_detect(Scsi_Host_Template *template) | |||
793 | found++; | 571 | found++; |
794 | } | 572 | } |
795 | 573 | ||
796 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
797 | spin_lock_irq(&io_request_lock); | ||
798 | #endif | ||
799 | aic7xxx_detect_complete++; | 574 | aic7xxx_detect_complete++; |
800 | 575 | ||
801 | return (found); | 576 | return (found); |
802 | } | 577 | } |
803 | 578 | ||
804 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
805 | /* | ||
806 | * Free the passed in Scsi_Host memory structures prior to unloading the | ||
807 | * module. | ||
808 | */ | ||
809 | int | ||
810 | ahc_linux_release(struct Scsi_Host * host) | ||
811 | { | ||
812 | struct ahc_softc *ahc; | ||
813 | u_long l; | ||
814 | |||
815 | ahc_list_lock(&l); | ||
816 | if (host != NULL) { | ||
817 | |||
818 | /* | ||
819 | * We should be able to just perform | ||
820 | * the free directly, but check our | ||
821 | * list for extra sanity. | ||
822 | */ | ||
823 | ahc = ahc_find_softc(*(struct ahc_softc **)host->hostdata); | ||
824 | if (ahc != NULL) { | ||
825 | u_long s; | ||
826 | |||
827 | ahc_lock(ahc, &s); | ||
828 | ahc_intr_enable(ahc, FALSE); | ||
829 | ahc_unlock(ahc, &s); | ||
830 | ahc_free(ahc); | ||
831 | } | ||
832 | } | ||
833 | ahc_list_unlock(&l); | ||
834 | return (0); | ||
835 | } | ||
836 | #endif | ||
837 | |||
838 | /* | 579 | /* |
839 | * Return a string describing the driver. | 580 | * Return a string describing the driver. |
840 | */ | 581 | */ |
@@ -867,11 +608,10 @@ ahc_linux_info(struct Scsi_Host *host) | |||
867 | * Queue an SCB to the controller. | 608 | * Queue an SCB to the controller. |
868 | */ | 609 | */ |
869 | static int | 610 | static int |
870 | ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) | 611 | ahc_linux_queue(struct scsi_cmnd * cmd, void (*scsi_done) (struct scsi_cmnd *)) |
871 | { | 612 | { |
872 | struct ahc_softc *ahc; | 613 | struct ahc_softc *ahc; |
873 | struct ahc_linux_device *dev; | 614 | struct ahc_linux_device *dev; |
874 | u_long flags; | ||
875 | 615 | ||
876 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; | 616 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; |
877 | 617 | ||
@@ -880,205 +620,149 @@ ahc_linux_queue(Scsi_Cmnd * cmd, void (*scsi_done) (Scsi_Cmnd *)) | |||
880 | */ | 620 | */ |
881 | cmd->scsi_done = scsi_done; | 621 | cmd->scsi_done = scsi_done; |
882 | 622 | ||
883 | ahc_midlayer_entrypoint_lock(ahc, &flags); | ||
884 | |||
885 | /* | 623 | /* |
886 | * Close the race of a command that was in the process of | 624 | * Close the race of a command that was in the process of |
887 | * being queued to us just as our simq was frozen. Let | 625 | * being queued to us just as our simq was frozen. Let |
888 | * DV commands through so long as we are only frozen to | 626 | * DV commands through so long as we are only frozen to |
889 | * perform DV. | 627 | * perform DV. |
890 | */ | 628 | */ |
891 | if (ahc->platform_data->qfrozen != 0) { | 629 | if (ahc->platform_data->qfrozen != 0) |
630 | return SCSI_MLQUEUE_HOST_BUSY; | ||
892 | 631 | ||
893 | ahc_cmd_set_transaction_status(cmd, CAM_REQUEUE_REQ); | ||
894 | ahc_linux_queue_cmd_complete(ahc, cmd); | ||
895 | ahc_schedule_completeq(ahc); | ||
896 | ahc_midlayer_entrypoint_unlock(ahc, &flags); | ||
897 | return (0); | ||
898 | } | ||
899 | dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, | 632 | dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, |
900 | cmd->device->lun, /*alloc*/TRUE); | 633 | cmd->device->lun); |
901 | if (dev == NULL) { | 634 | BUG_ON(dev == NULL); |
902 | ahc_cmd_set_transaction_status(cmd, CAM_RESRC_UNAVAIL); | 635 | |
903 | ahc_linux_queue_cmd_complete(ahc, cmd); | ||
904 | ahc_schedule_completeq(ahc); | ||
905 | ahc_midlayer_entrypoint_unlock(ahc, &flags); | ||
906 | printf("%s: aic7xxx_linux_queue - Unable to allocate device!\n", | ||
907 | ahc_name(ahc)); | ||
908 | return (0); | ||
909 | } | ||
910 | cmd->result = CAM_REQ_INPROG << 16; | 636 | cmd->result = CAM_REQ_INPROG << 16; |
911 | TAILQ_INSERT_TAIL(&dev->busyq, (struct ahc_cmd *)cmd, acmd_links.tqe); | 637 | |
912 | if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { | 638 | return ahc_linux_run_command(ahc, dev, cmd); |
913 | TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); | ||
914 | dev->flags |= AHC_DEV_ON_RUN_LIST; | ||
915 | ahc_linux_run_device_queues(ahc); | ||
916 | } | ||
917 | ahc_midlayer_entrypoint_unlock(ahc, &flags); | ||
918 | return (0); | ||
919 | } | 639 | } |
920 | 640 | ||
921 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
922 | static int | 641 | static int |
923 | ahc_linux_slave_alloc(Scsi_Device *device) | 642 | ahc_linux_slave_alloc(struct scsi_device *device) |
924 | { | 643 | { |
925 | struct ahc_softc *ahc; | 644 | struct ahc_softc *ahc; |
645 | struct ahc_linux_target *targ; | ||
646 | struct scsi_target *starget = device->sdev_target; | ||
647 | struct ahc_linux_device *dev; | ||
648 | unsigned int target_offset; | ||
649 | unsigned long flags; | ||
650 | int retval = -ENOMEM; | ||
651 | |||
652 | target_offset = starget->id; | ||
653 | if (starget->channel != 0) | ||
654 | target_offset += 8; | ||
926 | 655 | ||
927 | ahc = *((struct ahc_softc **)device->host->hostdata); | 656 | ahc = *((struct ahc_softc **)device->host->hostdata); |
928 | if (bootverbose) | 657 | if (bootverbose) |
929 | printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); | 658 | printf("%s: Slave Alloc %d\n", ahc_name(ahc), device->id); |
930 | return (0); | 659 | ahc_lock(ahc, &flags); |
660 | targ = ahc->platform_data->targets[target_offset]; | ||
661 | if (targ == NULL) { | ||
662 | targ = ahc_linux_alloc_target(ahc, starget->channel, starget->id); | ||
663 | struct seeprom_config *sc = ahc->seep_config; | ||
664 | if (targ == NULL) | ||
665 | goto out; | ||
666 | |||
667 | if (sc) { | ||
668 | unsigned short scsirate; | ||
669 | struct ahc_devinfo devinfo; | ||
670 | struct ahc_initiator_tinfo *tinfo; | ||
671 | struct ahc_tmode_tstate *tstate; | ||
672 | char channel = starget->channel + 'A'; | ||
673 | unsigned int our_id = ahc->our_id; | ||
674 | |||
675 | if (starget->channel) | ||
676 | our_id = ahc->our_id_b; | ||
677 | |||
678 | if ((ahc->features & AHC_ULTRA2) != 0) { | ||
679 | scsirate = sc->device_flags[target_offset] & CFXFER; | ||
680 | } else { | ||
681 | scsirate = (sc->device_flags[target_offset] & CFXFER) << 4; | ||
682 | if (sc->device_flags[target_offset] & CFSYNCH) | ||
683 | scsirate |= SOFS; | ||
684 | } | ||
685 | if (sc->device_flags[target_offset] & CFWIDEB) { | ||
686 | scsirate |= WIDEXFER; | ||
687 | spi_max_width(starget) = 1; | ||
688 | } else | ||
689 | spi_max_width(starget) = 0; | ||
690 | spi_min_period(starget) = | ||
691 | ahc_find_period(ahc, scsirate, AHC_SYNCRATE_DT); | ||
692 | tinfo = ahc_fetch_transinfo(ahc, channel, ahc->our_id, | ||
693 | targ->target, &tstate); | ||
694 | ahc_compile_devinfo(&devinfo, our_id, targ->target, | ||
695 | CAM_LUN_WILDCARD, channel, | ||
696 | ROLE_INITIATOR); | ||
697 | ahc_set_syncrate(ahc, &devinfo, NULL, 0, 0, 0, | ||
698 | AHC_TRANS_GOAL, /*paused*/FALSE); | ||
699 | ahc_set_width(ahc, &devinfo, MSG_EXT_WDTR_BUS_8_BIT, | ||
700 | AHC_TRANS_GOAL, /*paused*/FALSE); | ||
701 | } | ||
702 | |||
703 | } | ||
704 | dev = targ->devices[device->lun]; | ||
705 | if (dev == NULL) { | ||
706 | dev = ahc_linux_alloc_device(ahc, targ, device->lun); | ||
707 | if (dev == NULL) | ||
708 | goto out; | ||
709 | } | ||
710 | retval = 0; | ||
711 | |||
712 | out: | ||
713 | ahc_unlock(ahc, &flags); | ||
714 | return retval; | ||
931 | } | 715 | } |
932 | 716 | ||
933 | static int | 717 | static int |
934 | ahc_linux_slave_configure(Scsi_Device *device) | 718 | ahc_linux_slave_configure(struct scsi_device *device) |
935 | { | 719 | { |
936 | struct ahc_softc *ahc; | 720 | struct ahc_softc *ahc; |
937 | struct ahc_linux_device *dev; | 721 | struct ahc_linux_device *dev; |
938 | u_long flags; | ||
939 | 722 | ||
940 | ahc = *((struct ahc_softc **)device->host->hostdata); | 723 | ahc = *((struct ahc_softc **)device->host->hostdata); |
724 | |||
941 | if (bootverbose) | 725 | if (bootverbose) |
942 | printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); | 726 | printf("%s: Slave Configure %d\n", ahc_name(ahc), device->id); |
943 | ahc_midlayer_entrypoint_lock(ahc, &flags); | 727 | |
944 | /* | 728 | dev = ahc_linux_get_device(ahc, device->channel, device->id, |
945 | * Since Linux has attached to the device, configure | 729 | device->lun); |
946 | * it so we don't free and allocate the device | 730 | dev->scsi_device = device; |
947 | * structure on every command. | 731 | ahc_linux_device_queue_depth(ahc, dev); |
948 | */ | ||
949 | dev = ahc_linux_get_device(ahc, device->channel, | ||
950 | device->id, device->lun, | ||
951 | /*alloc*/TRUE); | ||
952 | if (dev != NULL) { | ||
953 | dev->flags &= ~AHC_DEV_UNCONFIGURED; | ||
954 | dev->scsi_device = device; | ||
955 | ahc_linux_device_queue_depth(ahc, dev); | ||
956 | } | ||
957 | ahc_midlayer_entrypoint_unlock(ahc, &flags); | ||
958 | 732 | ||
959 | /* Initial Domain Validation */ | 733 | /* Initial Domain Validation */ |
960 | if (!spi_initial_dv(device->sdev_target)) | 734 | if (!spi_initial_dv(device->sdev_target)) |
961 | spi_dv_device(device); | 735 | spi_dv_device(device); |
962 | 736 | ||
963 | return (0); | 737 | return 0; |
964 | } | 738 | } |
965 | 739 | ||
966 | static void | 740 | static void |
967 | ahc_linux_slave_destroy(Scsi_Device *device) | 741 | ahc_linux_slave_destroy(struct scsi_device *device) |
968 | { | 742 | { |
969 | struct ahc_softc *ahc; | 743 | struct ahc_softc *ahc; |
970 | struct ahc_linux_device *dev; | 744 | struct ahc_linux_device *dev; |
971 | u_long flags; | ||
972 | 745 | ||
973 | ahc = *((struct ahc_softc **)device->host->hostdata); | 746 | ahc = *((struct ahc_softc **)device->host->hostdata); |
974 | if (bootverbose) | 747 | if (bootverbose) |
975 | printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); | 748 | printf("%s: Slave Destroy %d\n", ahc_name(ahc), device->id); |
976 | ahc_midlayer_entrypoint_lock(ahc, &flags); | ||
977 | dev = ahc_linux_get_device(ahc, device->channel, | 749 | dev = ahc_linux_get_device(ahc, device->channel, |
978 | device->id, device->lun, | 750 | device->id, device->lun); |
979 | /*alloc*/FALSE); | ||
980 | /* | ||
981 | * Filter out "silly" deletions of real devices by only | ||
982 | * deleting devices that have had slave_configure() | ||
983 | * called on them. All other devices that have not | ||
984 | * been configured will automatically be deleted by | ||
985 | * the refcounting process. | ||
986 | */ | ||
987 | if (dev != NULL | ||
988 | && (dev->flags & AHC_DEV_SLAVE_CONFIGURED) != 0) { | ||
989 | dev->flags |= AHC_DEV_UNCONFIGURED; | ||
990 | if (TAILQ_EMPTY(&dev->busyq) | ||
991 | && dev->active == 0 | ||
992 | && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) | ||
993 | ahc_linux_free_device(ahc, dev); | ||
994 | } | ||
995 | ahc_midlayer_entrypoint_unlock(ahc, &flags); | ||
996 | } | ||
997 | #else | ||
998 | /* | ||
999 | * Sets the queue depth for each SCSI device hanging | ||
1000 | * off the input host adapter. | ||
1001 | */ | ||
1002 | static void | ||
1003 | ahc_linux_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs) | ||
1004 | { | ||
1005 | Scsi_Device *device; | ||
1006 | Scsi_Device *ldev; | ||
1007 | struct ahc_softc *ahc; | ||
1008 | u_long flags; | ||
1009 | 751 | ||
1010 | ahc = *((struct ahc_softc **)host->hostdata); | 752 | BUG_ON(dev->active); |
1011 | ahc_lock(ahc, &flags); | ||
1012 | for (device = scsi_devs; device != NULL; device = device->next) { | ||
1013 | 753 | ||
1014 | /* | 754 | ahc_linux_free_device(ahc, dev); |
1015 | * Watch out for duplicate devices. This works around | ||
1016 | * some quirks in how the SCSI scanning code does its | ||
1017 | * device management. | ||
1018 | */ | ||
1019 | for (ldev = scsi_devs; ldev != device; ldev = ldev->next) { | ||
1020 | if (ldev->host == device->host | ||
1021 | && ldev->channel == device->channel | ||
1022 | && ldev->id == device->id | ||
1023 | && ldev->lun == device->lun) | ||
1024 | break; | ||
1025 | } | ||
1026 | /* Skip duplicate. */ | ||
1027 | if (ldev != device) | ||
1028 | continue; | ||
1029 | |||
1030 | if (device->host == host) { | ||
1031 | struct ahc_linux_device *dev; | ||
1032 | |||
1033 | /* | ||
1034 | * Since Linux has attached to the device, configure | ||
1035 | * it so we don't free and allocate the device | ||
1036 | * structure on every command. | ||
1037 | */ | ||
1038 | dev = ahc_linux_get_device(ahc, device->channel, | ||
1039 | device->id, device->lun, | ||
1040 | /*alloc*/TRUE); | ||
1041 | if (dev != NULL) { | ||
1042 | dev->flags &= ~AHC_DEV_UNCONFIGURED; | ||
1043 | dev->scsi_device = device; | ||
1044 | ahc_linux_device_queue_depth(ahc, dev); | ||
1045 | device->queue_depth = dev->openings | ||
1046 | + dev->active; | ||
1047 | if ((dev->flags & (AHC_DEV_Q_BASIC | ||
1048 | | AHC_DEV_Q_TAGGED)) == 0) { | ||
1049 | /* | ||
1050 | * We allow the OS to queue 2 untagged | ||
1051 | * transactions to us at any time even | ||
1052 | * though we can only execute them | ||
1053 | * serially on the controller/device. | ||
1054 | * This should remove some latency. | ||
1055 | */ | ||
1056 | device->queue_depth = 2; | ||
1057 | } | ||
1058 | } | ||
1059 | } | ||
1060 | } | ||
1061 | ahc_unlock(ahc, &flags); | ||
1062 | } | 755 | } |
1063 | #endif | ||
1064 | 756 | ||
1065 | #if defined(__i386__) | 757 | #if defined(__i386__) |
1066 | /* | 758 | /* |
1067 | * Return the disk geometry for the given SCSI device. | 759 | * Return the disk geometry for the given SCSI device. |
1068 | */ | 760 | */ |
1069 | static int | 761 | static int |
1070 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1071 | ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, | 762 | ahc_linux_biosparam(struct scsi_device *sdev, struct block_device *bdev, |
1072 | sector_t capacity, int geom[]) | 763 | sector_t capacity, int geom[]) |
1073 | { | 764 | { |
1074 | uint8_t *bh; | 765 | uint8_t *bh; |
1075 | #else | ||
1076 | ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) | ||
1077 | { | ||
1078 | struct scsi_device *sdev = disk->device; | ||
1079 | u_long capacity = disk->capacity; | ||
1080 | struct buffer_head *bh; | ||
1081 | #endif | ||
1082 | int heads; | 766 | int heads; |
1083 | int sectors; | 767 | int sectors; |
1084 | int cylinders; | 768 | int cylinders; |
@@ -1090,22 +774,11 @@ ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) | |||
1090 | ahc = *((struct ahc_softc **)sdev->host->hostdata); | 774 | ahc = *((struct ahc_softc **)sdev->host->hostdata); |
1091 | channel = sdev->channel; | 775 | channel = sdev->channel; |
1092 | 776 | ||
1093 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1094 | bh = scsi_bios_ptable(bdev); | 777 | bh = scsi_bios_ptable(bdev); |
1095 | #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,17) | ||
1096 | bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, block_size(dev)); | ||
1097 | #else | ||
1098 | bh = bread(MKDEV(MAJOR(dev), MINOR(dev) & ~0xf), 0, 1024); | ||
1099 | #endif | ||
1100 | |||
1101 | if (bh) { | 778 | if (bh) { |
1102 | ret = scsi_partsize(bh, capacity, | 779 | ret = scsi_partsize(bh, capacity, |
1103 | &geom[2], &geom[0], &geom[1]); | 780 | &geom[2], &geom[0], &geom[1]); |
1104 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1105 | kfree(bh); | 781 | kfree(bh); |
1106 | #else | ||
1107 | brelse(bh); | ||
1108 | #endif | ||
1109 | if (ret != -1) | 782 | if (ret != -1) |
1110 | return (ret); | 783 | return (ret); |
1111 | } | 784 | } |
@@ -1135,7 +808,7 @@ ahc_linux_biosparam(Disk *disk, kdev_t dev, int geom[]) | |||
1135 | * Abort the current SCSI command(s). | 808 | * Abort the current SCSI command(s). |
1136 | */ | 809 | */ |
1137 | static int | 810 | static int |
1138 | ahc_linux_abort(Scsi_Cmnd *cmd) | 811 | ahc_linux_abort(struct scsi_cmnd *cmd) |
1139 | { | 812 | { |
1140 | int error; | 813 | int error; |
1141 | 814 | ||
@@ -1149,7 +822,7 @@ ahc_linux_abort(Scsi_Cmnd *cmd) | |||
1149 | * Attempt to send a target reset message to the device that timed out. | 822 | * Attempt to send a target reset message to the device that timed out. |
1150 | */ | 823 | */ |
1151 | static int | 824 | static int |
1152 | ahc_linux_dev_reset(Scsi_Cmnd *cmd) | 825 | ahc_linux_dev_reset(struct scsi_cmnd *cmd) |
1153 | { | 826 | { |
1154 | int error; | 827 | int error; |
1155 | 828 | ||
@@ -1163,18 +836,14 @@ ahc_linux_dev_reset(Scsi_Cmnd *cmd) | |||
1163 | * Reset the SCSI bus. | 836 | * Reset the SCSI bus. |
1164 | */ | 837 | */ |
1165 | static int | 838 | static int |
1166 | ahc_linux_bus_reset(Scsi_Cmnd *cmd) | 839 | ahc_linux_bus_reset(struct scsi_cmnd *cmd) |
1167 | { | 840 | { |
1168 | struct ahc_softc *ahc; | 841 | struct ahc_softc *ahc; |
1169 | u_long s; | ||
1170 | int found; | 842 | int found; |
1171 | 843 | ||
1172 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; | 844 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; |
1173 | ahc_midlayer_entrypoint_lock(ahc, &s); | ||
1174 | found = ahc_reset_channel(ahc, cmd->device->channel + 'A', | 845 | found = ahc_reset_channel(ahc, cmd->device->channel + 'A', |
1175 | /*initiate reset*/TRUE); | 846 | /*initiate reset*/TRUE); |
1176 | ahc_linux_run_complete_queue(ahc); | ||
1177 | ahc_midlayer_entrypoint_unlock(ahc, &s); | ||
1178 | 847 | ||
1179 | if (bootverbose) | 848 | if (bootverbose) |
1180 | printf("%s: SCSI bus reset delivered. " | 849 | printf("%s: SCSI bus reset delivered. " |
@@ -1183,7 +852,7 @@ ahc_linux_bus_reset(Scsi_Cmnd *cmd) | |||
1183 | return SUCCESS; | 852 | return SUCCESS; |
1184 | } | 853 | } |
1185 | 854 | ||
1186 | Scsi_Host_Template aic7xxx_driver_template = { | 855 | struct scsi_host_template aic7xxx_driver_template = { |
1187 | .module = THIS_MODULE, | 856 | .module = THIS_MODULE, |
1188 | .name = "aic7xxx", | 857 | .name = "aic7xxx", |
1189 | .proc_info = ahc_linux_proc_info, | 858 | .proc_info = ahc_linux_proc_info, |
@@ -1206,33 +875,6 @@ Scsi_Host_Template aic7xxx_driver_template = { | |||
1206 | 875 | ||
1207 | /**************************** Tasklet Handler *********************************/ | 876 | /**************************** Tasklet Handler *********************************/ |
1208 | 877 | ||
1209 | /* | ||
1210 | * In 2.4.X and above, this routine is called from a tasklet, | ||
1211 | * so we must re-acquire our lock prior to executing this code. | ||
1212 | * In all prior kernels, ahc_schedule_runq() calls this routine | ||
1213 | * directly and ahc_schedule_runq() is called with our lock held. | ||
1214 | */ | ||
1215 | static void | ||
1216 | ahc_runq_tasklet(unsigned long data) | ||
1217 | { | ||
1218 | struct ahc_softc* ahc; | ||
1219 | struct ahc_linux_device *dev; | ||
1220 | u_long flags; | ||
1221 | |||
1222 | ahc = (struct ahc_softc *)data; | ||
1223 | ahc_lock(ahc, &flags); | ||
1224 | while ((dev = ahc_linux_next_device_to_run(ahc)) != NULL) { | ||
1225 | |||
1226 | TAILQ_REMOVE(&ahc->platform_data->device_runq, dev, links); | ||
1227 | dev->flags &= ~AHC_DEV_ON_RUN_LIST; | ||
1228 | ahc_linux_check_device_queue(ahc, dev); | ||
1229 | /* Yeild to our interrupt handler */ | ||
1230 | ahc_unlock(ahc, &flags); | ||
1231 | ahc_lock(ahc, &flags); | ||
1232 | } | ||
1233 | ahc_unlock(ahc, &flags); | ||
1234 | } | ||
1235 | |||
1236 | /******************************** Macros **************************************/ | 878 | /******************************** Macros **************************************/ |
1237 | #define BUILD_SCSIID(ahc, cmd) \ | 879 | #define BUILD_SCSIID(ahc, cmd) \ |
1238 | ((((cmd)->device->id << TID_SHIFT) & TID) \ | 880 | ((((cmd)->device->id << TID_SHIFT) & TID) \ |
@@ -1278,37 +920,11 @@ int | |||
1278 | ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, | 920 | ahc_dmamem_alloc(struct ahc_softc *ahc, bus_dma_tag_t dmat, void** vaddr, |
1279 | int flags, bus_dmamap_t *mapp) | 921 | int flags, bus_dmamap_t *mapp) |
1280 | { | 922 | { |
1281 | bus_dmamap_t map; | ||
1282 | |||
1283 | map = malloc(sizeof(*map), M_DEVBUF, M_NOWAIT); | ||
1284 | if (map == NULL) | ||
1285 | return (ENOMEM); | ||
1286 | /* | ||
1287 | * Although we can dma data above 4GB, our | ||
1288 | * "consistent" memory is below 4GB for | ||
1289 | * space efficiency reasons (only need a 4byte | ||
1290 | * address). For this reason, we have to reset | ||
1291 | * our dma mask when doing allocations. | ||
1292 | */ | ||
1293 | if (ahc->dev_softc != NULL) | ||
1294 | if (pci_set_dma_mask(ahc->dev_softc, 0xFFFFFFFF)) { | ||
1295 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); | ||
1296 | kfree(map); | ||
1297 | return (ENODEV); | ||
1298 | } | ||
1299 | *vaddr = pci_alloc_consistent(ahc->dev_softc, | 923 | *vaddr = pci_alloc_consistent(ahc->dev_softc, |
1300 | dmat->maxsize, &map->bus_addr); | 924 | dmat->maxsize, mapp); |
1301 | if (ahc->dev_softc != NULL) | ||
1302 | if (pci_set_dma_mask(ahc->dev_softc, | ||
1303 | ahc->platform_data->hw_dma_mask)) { | ||
1304 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); | ||
1305 | kfree(map); | ||
1306 | return (ENODEV); | ||
1307 | } | ||
1308 | if (*vaddr == NULL) | 925 | if (*vaddr == NULL) |
1309 | return (ENOMEM); | 926 | return ENOMEM; |
1310 | *mapp = map; | 927 | return 0; |
1311 | return(0); | ||
1312 | } | 928 | } |
1313 | 929 | ||
1314 | void | 930 | void |
@@ -1316,7 +932,7 @@ ahc_dmamem_free(struct ahc_softc *ahc, bus_dma_tag_t dmat, | |||
1316 | void* vaddr, bus_dmamap_t map) | 932 | void* vaddr, bus_dmamap_t map) |
1317 | { | 933 | { |
1318 | pci_free_consistent(ahc->dev_softc, dmat->maxsize, | 934 | pci_free_consistent(ahc->dev_softc, dmat->maxsize, |
1319 | vaddr, map->bus_addr); | 935 | vaddr, map); |
1320 | } | 936 | } |
1321 | 937 | ||
1322 | int | 938 | int |
@@ -1330,7 +946,7 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, | |||
1330 | */ | 946 | */ |
1331 | bus_dma_segment_t stack_sg; | 947 | bus_dma_segment_t stack_sg; |
1332 | 948 | ||
1333 | stack_sg.ds_addr = map->bus_addr; | 949 | stack_sg.ds_addr = map; |
1334 | stack_sg.ds_len = dmat->maxsize; | 950 | stack_sg.ds_len = dmat->maxsize; |
1335 | cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); | 951 | cb(cb_arg, &stack_sg, /*nseg*/1, /*error*/0); |
1336 | return (0); | 952 | return (0); |
@@ -1339,12 +955,6 @@ ahc_dmamap_load(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map, | |||
1339 | void | 955 | void |
1340 | ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) | 956 | ahc_dmamap_destroy(struct ahc_softc *ahc, bus_dma_tag_t dmat, bus_dmamap_t map) |
1341 | { | 957 | { |
1342 | /* | ||
1343 | * The map may is NULL in our < 2.3.X implementation. | ||
1344 | * Now it's 2.6.5, but just in case... | ||
1345 | */ | ||
1346 | BUG_ON(map == NULL); | ||
1347 | free(map, M_DEVBUF); | ||
1348 | } | 958 | } |
1349 | 959 | ||
1350 | int | 960 | int |
@@ -1550,7 +1160,7 @@ __setup("aic7xxx=", aic7xxx_setup); | |||
1550 | uint32_t aic7xxx_verbose; | 1160 | uint32_t aic7xxx_verbose; |
1551 | 1161 | ||
1552 | int | 1162 | int |
1553 | ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) | 1163 | ahc_linux_register_host(struct ahc_softc *ahc, struct scsi_host_template *template) |
1554 | { | 1164 | { |
1555 | char buf[80]; | 1165 | char buf[80]; |
1556 | struct Scsi_Host *host; | 1166 | struct Scsi_Host *host; |
@@ -1564,11 +1174,7 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) | |||
1564 | 1174 | ||
1565 | *((struct ahc_softc **)host->hostdata) = ahc; | 1175 | *((struct ahc_softc **)host->hostdata) = ahc; |
1566 | ahc_lock(ahc, &s); | 1176 | ahc_lock(ahc, &s); |
1567 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1568 | scsi_assign_lock(host, &ahc->platform_data->spin_lock); | 1177 | scsi_assign_lock(host, &ahc->platform_data->spin_lock); |
1569 | #elif AHC_SCSI_HAS_HOST_LOCK != 0 | ||
1570 | host->lock = &ahc->platform_data->spin_lock; | ||
1571 | #endif | ||
1572 | ahc->platform_data->host = host; | 1178 | ahc->platform_data->host = host; |
1573 | host->can_queue = AHC_MAX_QUEUE; | 1179 | host->can_queue = AHC_MAX_QUEUE; |
1574 | host->cmd_per_lun = 2; | 1180 | host->cmd_per_lun = 2; |
@@ -1587,19 +1193,14 @@ ahc_linux_register_host(struct ahc_softc *ahc, Scsi_Host_Template *template) | |||
1587 | ahc_set_name(ahc, new_name); | 1193 | ahc_set_name(ahc, new_name); |
1588 | } | 1194 | } |
1589 | host->unique_id = ahc->unit; | 1195 | host->unique_id = ahc->unit; |
1590 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
1591 | scsi_set_pci_device(host, ahc->dev_softc); | ||
1592 | #endif | ||
1593 | ahc_linux_initialize_scsi_bus(ahc); | 1196 | ahc_linux_initialize_scsi_bus(ahc); |
1594 | ahc_intr_enable(ahc, TRUE); | 1197 | ahc_intr_enable(ahc, TRUE); |
1595 | ahc_unlock(ahc, &s); | 1198 | ahc_unlock(ahc, &s); |
1596 | 1199 | ||
1597 | host->transportt = ahc_linux_transport_template; | 1200 | host->transportt = ahc_linux_transport_template; |
1598 | 1201 | ||
1599 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1600 | scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */ | 1202 | scsi_add_host(host, (ahc->dev_softc ? &ahc->dev_softc->dev : NULL)); /* XXX handle failure */ |
1601 | scsi_scan_host(host); | 1203 | scsi_scan_host(host); |
1602 | #endif | ||
1603 | return (0); | 1204 | return (0); |
1604 | } | 1205 | } |
1605 | 1206 | ||
@@ -1717,19 +1318,9 @@ ahc_platform_alloc(struct ahc_softc *ahc, void *platform_arg) | |||
1717 | if (ahc->platform_data == NULL) | 1318 | if (ahc->platform_data == NULL) |
1718 | return (ENOMEM); | 1319 | return (ENOMEM); |
1719 | memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); | 1320 | memset(ahc->platform_data, 0, sizeof(struct ahc_platform_data)); |
1720 | TAILQ_INIT(&ahc->platform_data->completeq); | ||
1721 | TAILQ_INIT(&ahc->platform_data->device_runq); | ||
1722 | ahc->platform_data->irq = AHC_LINUX_NOIRQ; | 1321 | ahc->platform_data->irq = AHC_LINUX_NOIRQ; |
1723 | ahc->platform_data->hw_dma_mask = 0xFFFFFFFF; | ||
1724 | ahc_lockinit(ahc); | 1322 | ahc_lockinit(ahc); |
1725 | ahc_done_lockinit(ahc); | ||
1726 | init_timer(&ahc->platform_data->completeq_timer); | ||
1727 | ahc->platform_data->completeq_timer.data = (u_long)ahc; | ||
1728 | ahc->platform_data->completeq_timer.function = | ||
1729 | (ahc_linux_callback_t *)ahc_linux_thread_run_complete_queue; | ||
1730 | init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); | 1323 | init_MUTEX_LOCKED(&ahc->platform_data->eh_sem); |
1731 | tasklet_init(&ahc->platform_data->runq_tasklet, ahc_runq_tasklet, | ||
1732 | (unsigned long)ahc); | ||
1733 | ahc->seltime = (aic7xxx_seltime & 0x3) << 4; | 1324 | ahc->seltime = (aic7xxx_seltime & 0x3) << 4; |
1734 | ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; | 1325 | ahc->seltime_b = (aic7xxx_seltime & 0x3) << 4; |
1735 | if (aic7xxx_pci_parity == 0) | 1326 | if (aic7xxx_pci_parity == 0) |
@@ -1746,12 +1337,8 @@ ahc_platform_free(struct ahc_softc *ahc) | |||
1746 | int i, j; | 1337 | int i, j; |
1747 | 1338 | ||
1748 | if (ahc->platform_data != NULL) { | 1339 | if (ahc->platform_data != NULL) { |
1749 | del_timer_sync(&ahc->platform_data->completeq_timer); | ||
1750 | tasklet_kill(&ahc->platform_data->runq_tasklet); | ||
1751 | if (ahc->platform_data->host != NULL) { | 1340 | if (ahc->platform_data->host != NULL) { |
1752 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1753 | scsi_remove_host(ahc->platform_data->host); | 1341 | scsi_remove_host(ahc->platform_data->host); |
1754 | #endif | ||
1755 | scsi_host_put(ahc->platform_data->host); | 1342 | scsi_host_put(ahc->platform_data->host); |
1756 | } | 1343 | } |
1757 | 1344 | ||
@@ -1787,16 +1374,7 @@ ahc_platform_free(struct ahc_softc *ahc) | |||
1787 | release_mem_region(ahc->platform_data->mem_busaddr, | 1374 | release_mem_region(ahc->platform_data->mem_busaddr, |
1788 | 0x1000); | 1375 | 0x1000); |
1789 | } | 1376 | } |
1790 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | 1377 | |
1791 | /* | ||
1792 | * In 2.4 we detach from the scsi midlayer before the PCI | ||
1793 | * layer invokes our remove callback. No per-instance | ||
1794 | * detach is provided, so we must reach inside the PCI | ||
1795 | * subsystem's internals and detach our driver manually. | ||
1796 | */ | ||
1797 | if (ahc->dev_softc != NULL) | ||
1798 | ahc->dev_softc->driver = NULL; | ||
1799 | #endif | ||
1800 | free(ahc->platform_data, M_DEVBUF); | 1378 | free(ahc->platform_data, M_DEVBUF); |
1801 | } | 1379 | } |
1802 | } | 1380 | } |
@@ -1820,7 +1398,7 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1820 | 1398 | ||
1821 | dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', | 1399 | dev = ahc_linux_get_device(ahc, devinfo->channel - 'A', |
1822 | devinfo->target, | 1400 | devinfo->target, |
1823 | devinfo->lun, /*alloc*/FALSE); | 1401 | devinfo->lun); |
1824 | if (dev == NULL) | 1402 | if (dev == NULL) |
1825 | return; | 1403 | return; |
1826 | was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); | 1404 | was_queuing = dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED); |
@@ -1873,7 +1451,6 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1873 | dev->maxtags = 0; | 1451 | dev->maxtags = 0; |
1874 | dev->openings = 1 - dev->active; | 1452 | dev->openings = 1 - dev->active; |
1875 | } | 1453 | } |
1876 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
1877 | if (dev->scsi_device != NULL) { | 1454 | if (dev->scsi_device != NULL) { |
1878 | switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { | 1455 | switch ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED))) { |
1879 | case AHC_DEV_Q_BASIC: | 1456 | case AHC_DEV_Q_BASIC: |
@@ -1899,90 +1476,13 @@ ahc_platform_set_tags(struct ahc_softc *ahc, struct ahc_devinfo *devinfo, | |||
1899 | break; | 1476 | break; |
1900 | } | 1477 | } |
1901 | } | 1478 | } |
1902 | #endif | ||
1903 | } | 1479 | } |
1904 | 1480 | ||
1905 | int | 1481 | int |
1906 | ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, | 1482 | ahc_platform_abort_scbs(struct ahc_softc *ahc, int target, char channel, |
1907 | int lun, u_int tag, role_t role, uint32_t status) | 1483 | int lun, u_int tag, role_t role, uint32_t status) |
1908 | { | 1484 | { |
1909 | int chan; | 1485 | return 0; |
1910 | int maxchan; | ||
1911 | int targ; | ||
1912 | int maxtarg; | ||
1913 | int clun; | ||
1914 | int maxlun; | ||
1915 | int count; | ||
1916 | |||
1917 | if (tag != SCB_LIST_NULL) | ||
1918 | return (0); | ||
1919 | |||
1920 | chan = 0; | ||
1921 | if (channel != ALL_CHANNELS) { | ||
1922 | chan = channel - 'A'; | ||
1923 | maxchan = chan + 1; | ||
1924 | } else { | ||
1925 | maxchan = (ahc->features & AHC_TWIN) ? 2 : 1; | ||
1926 | } | ||
1927 | targ = 0; | ||
1928 | if (target != CAM_TARGET_WILDCARD) { | ||
1929 | targ = target; | ||
1930 | maxtarg = targ + 1; | ||
1931 | } else { | ||
1932 | maxtarg = (ahc->features & AHC_WIDE) ? 16 : 8; | ||
1933 | } | ||
1934 | clun = 0; | ||
1935 | if (lun != CAM_LUN_WILDCARD) { | ||
1936 | clun = lun; | ||
1937 | maxlun = clun + 1; | ||
1938 | } else { | ||
1939 | maxlun = AHC_NUM_LUNS; | ||
1940 | } | ||
1941 | |||
1942 | count = 0; | ||
1943 | for (; chan < maxchan; chan++) { | ||
1944 | |||
1945 | for (; targ < maxtarg; targ++) { | ||
1946 | |||
1947 | for (; clun < maxlun; clun++) { | ||
1948 | struct ahc_linux_device *dev; | ||
1949 | struct ahc_busyq *busyq; | ||
1950 | struct ahc_cmd *acmd; | ||
1951 | |||
1952 | dev = ahc_linux_get_device(ahc, chan, | ||
1953 | targ, clun, | ||
1954 | /*alloc*/FALSE); | ||
1955 | if (dev == NULL) | ||
1956 | continue; | ||
1957 | |||
1958 | busyq = &dev->busyq; | ||
1959 | while ((acmd = TAILQ_FIRST(busyq)) != NULL) { | ||
1960 | Scsi_Cmnd *cmd; | ||
1961 | |||
1962 | cmd = &acmd_scsi_cmd(acmd); | ||
1963 | TAILQ_REMOVE(busyq, acmd, | ||
1964 | acmd_links.tqe); | ||
1965 | count++; | ||
1966 | cmd->result = status << 16; | ||
1967 | ahc_linux_queue_cmd_complete(ahc, cmd); | ||
1968 | } | ||
1969 | } | ||
1970 | } | ||
1971 | } | ||
1972 | |||
1973 | return (count); | ||
1974 | } | ||
1975 | |||
1976 | static void | ||
1977 | ahc_linux_thread_run_complete_queue(struct ahc_softc *ahc) | ||
1978 | { | ||
1979 | u_long flags; | ||
1980 | |||
1981 | ahc_lock(ahc, &flags); | ||
1982 | del_timer(&ahc->platform_data->completeq_timer); | ||
1983 | ahc->platform_data->flags &= ~AHC_RUN_CMPLT_Q_TIMER; | ||
1984 | ahc_linux_run_complete_queue(ahc); | ||
1985 | ahc_unlock(ahc, &flags); | ||
1986 | } | 1486 | } |
1987 | 1487 | ||
1988 | static u_int | 1488 | static u_int |
@@ -2045,213 +1545,200 @@ ahc_linux_device_queue_depth(struct ahc_softc *ahc, | |||
2045 | } | 1545 | } |
2046 | } | 1546 | } |
2047 | 1547 | ||
2048 | static void | 1548 | static int |
2049 | ahc_linux_run_device_queue(struct ahc_softc *ahc, struct ahc_linux_device *dev) | 1549 | ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev, |
1550 | struct scsi_cmnd *cmd) | ||
2050 | { | 1551 | { |
2051 | struct ahc_cmd *acmd; | ||
2052 | struct scsi_cmnd *cmd; | ||
2053 | struct scb *scb; | 1552 | struct scb *scb; |
2054 | struct hardware_scb *hscb; | 1553 | struct hardware_scb *hscb; |
2055 | struct ahc_initiator_tinfo *tinfo; | 1554 | struct ahc_initiator_tinfo *tinfo; |
2056 | struct ahc_tmode_tstate *tstate; | 1555 | struct ahc_tmode_tstate *tstate; |
2057 | uint16_t mask; | 1556 | uint16_t mask; |
1557 | struct scb_tailq *untagged_q = NULL; | ||
2058 | 1558 | ||
2059 | if ((dev->flags & AHC_DEV_ON_RUN_LIST) != 0) | 1559 | /* |
2060 | panic("running device on run list"); | 1560 | * Schedule us to run later. The only reason we are not |
1561 | * running is because the whole controller Q is frozen. | ||
1562 | */ | ||
1563 | if (ahc->platform_data->qfrozen != 0) | ||
1564 | return SCSI_MLQUEUE_HOST_BUSY; | ||
2061 | 1565 | ||
2062 | while ((acmd = TAILQ_FIRST(&dev->busyq)) != NULL | 1566 | /* |
2063 | && dev->openings > 0 && dev->qfrozen == 0) { | 1567 | * We only allow one untagged transaction |
1568 | * per target in the initiator role unless | ||
1569 | * we are storing a full busy target *lun* | ||
1570 | * table in SCB space. | ||
1571 | */ | ||
1572 | if (!blk_rq_tagged(cmd->request) | ||
1573 | && (ahc->features & AHC_SCB_BTT) == 0) { | ||
1574 | int target_offset; | ||
2064 | 1575 | ||
2065 | /* | 1576 | target_offset = cmd->device->id + cmd->device->channel * 8; |
2066 | * Schedule us to run later. The only reason we are not | 1577 | untagged_q = &(ahc->untagged_queues[target_offset]); |
2067 | * running is because the whole controller Q is frozen. | 1578 | if (!TAILQ_EMPTY(untagged_q)) |
2068 | */ | 1579 | /* if we're already executing an untagged command |
2069 | if (ahc->platform_data->qfrozen != 0) { | 1580 | * we're busy to another */ |
2070 | TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, | 1581 | return SCSI_MLQUEUE_DEVICE_BUSY; |
2071 | dev, links); | 1582 | } |
2072 | dev->flags |= AHC_DEV_ON_RUN_LIST; | ||
2073 | return; | ||
2074 | } | ||
2075 | /* | ||
2076 | * Get an scb to use. | ||
2077 | */ | ||
2078 | if ((scb = ahc_get_scb(ahc)) == NULL) { | ||
2079 | TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, | ||
2080 | dev, links); | ||
2081 | dev->flags |= AHC_DEV_ON_RUN_LIST; | ||
2082 | ahc->flags |= AHC_RESOURCE_SHORTAGE; | ||
2083 | return; | ||
2084 | } | ||
2085 | TAILQ_REMOVE(&dev->busyq, acmd, acmd_links.tqe); | ||
2086 | cmd = &acmd_scsi_cmd(acmd); | ||
2087 | scb->io_ctx = cmd; | ||
2088 | scb->platform_data->dev = dev; | ||
2089 | hscb = scb->hscb; | ||
2090 | cmd->host_scribble = (char *)scb; | ||
2091 | 1583 | ||
2092 | /* | 1584 | /* |
2093 | * Fill out basics of the HSCB. | 1585 | * Get an scb to use. |
2094 | */ | 1586 | */ |
2095 | hscb->control = 0; | 1587 | if ((scb = ahc_get_scb(ahc)) == NULL) { |
2096 | hscb->scsiid = BUILD_SCSIID(ahc, cmd); | 1588 | ahc->flags |= AHC_RESOURCE_SHORTAGE; |
2097 | hscb->lun = cmd->device->lun; | 1589 | return SCSI_MLQUEUE_HOST_BUSY; |
2098 | mask = SCB_GET_TARGET_MASK(ahc, scb); | 1590 | } |
2099 | tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), | ||
2100 | SCB_GET_OUR_ID(scb), | ||
2101 | SCB_GET_TARGET(ahc, scb), &tstate); | ||
2102 | hscb->scsirate = tinfo->scsirate; | ||
2103 | hscb->scsioffset = tinfo->curr.offset; | ||
2104 | if ((tstate->ultraenb & mask) != 0) | ||
2105 | hscb->control |= ULTRAENB; | ||
2106 | |||
2107 | if ((ahc->user_discenable & mask) != 0) | ||
2108 | hscb->control |= DISCENB; | ||
2109 | |||
2110 | if ((tstate->auto_negotiate & mask) != 0) { | ||
2111 | scb->flags |= SCB_AUTO_NEGOTIATE; | ||
2112 | scb->hscb->control |= MK_MESSAGE; | ||
2113 | } | ||
2114 | 1591 | ||
2115 | if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { | 1592 | scb->io_ctx = cmd; |
2116 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | 1593 | scb->platform_data->dev = dev; |
2117 | int msg_bytes; | 1594 | hscb = scb->hscb; |
2118 | uint8_t tag_msgs[2]; | 1595 | cmd->host_scribble = (char *)scb; |
2119 | 1596 | ||
2120 | msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); | 1597 | /* |
2121 | if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { | 1598 | * Fill out basics of the HSCB. |
2122 | hscb->control |= tag_msgs[0]; | 1599 | */ |
2123 | if (tag_msgs[0] == MSG_ORDERED_TASK) | 1600 | hscb->control = 0; |
2124 | dev->commands_since_idle_or_otag = 0; | 1601 | hscb->scsiid = BUILD_SCSIID(ahc, cmd); |
2125 | } else | 1602 | hscb->lun = cmd->device->lun; |
2126 | #endif | 1603 | mask = SCB_GET_TARGET_MASK(ahc, scb); |
2127 | if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH | 1604 | tinfo = ahc_fetch_transinfo(ahc, SCB_GET_CHANNEL(ahc, scb), |
2128 | && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { | 1605 | SCB_GET_OUR_ID(scb), |
2129 | hscb->control |= MSG_ORDERED_TASK; | 1606 | SCB_GET_TARGET(ahc, scb), &tstate); |
1607 | hscb->scsirate = tinfo->scsirate; | ||
1608 | hscb->scsioffset = tinfo->curr.offset; | ||
1609 | if ((tstate->ultraenb & mask) != 0) | ||
1610 | hscb->control |= ULTRAENB; | ||
1611 | |||
1612 | if ((ahc->user_discenable & mask) != 0) | ||
1613 | hscb->control |= DISCENB; | ||
1614 | |||
1615 | if ((tstate->auto_negotiate & mask) != 0) { | ||
1616 | scb->flags |= SCB_AUTO_NEGOTIATE; | ||
1617 | scb->hscb->control |= MK_MESSAGE; | ||
1618 | } | ||
1619 | |||
1620 | if ((dev->flags & (AHC_DEV_Q_TAGGED|AHC_DEV_Q_BASIC)) != 0) { | ||
1621 | int msg_bytes; | ||
1622 | uint8_t tag_msgs[2]; | ||
1623 | |||
1624 | msg_bytes = scsi_populate_tag_msg(cmd, tag_msgs); | ||
1625 | if (msg_bytes && tag_msgs[0] != MSG_SIMPLE_TASK) { | ||
1626 | hscb->control |= tag_msgs[0]; | ||
1627 | if (tag_msgs[0] == MSG_ORDERED_TASK) | ||
2130 | dev->commands_since_idle_or_otag = 0; | 1628 | dev->commands_since_idle_or_otag = 0; |
2131 | } else { | 1629 | } else if (dev->commands_since_idle_or_otag == AHC_OTAG_THRESH |
2132 | hscb->control |= MSG_SIMPLE_TASK; | 1630 | && (dev->flags & AHC_DEV_Q_TAGGED) != 0) { |
2133 | } | 1631 | hscb->control |= MSG_ORDERED_TASK; |
2134 | } | 1632 | dev->commands_since_idle_or_otag = 0; |
2135 | |||
2136 | hscb->cdb_len = cmd->cmd_len; | ||
2137 | if (hscb->cdb_len <= 12) { | ||
2138 | memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len); | ||
2139 | } else { | 1633 | } else { |
2140 | memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len); | 1634 | hscb->control |= MSG_SIMPLE_TASK; |
2141 | scb->flags |= SCB_CDB32_PTR; | ||
2142 | } | 1635 | } |
1636 | } | ||
2143 | 1637 | ||
2144 | scb->platform_data->xfer_len = 0; | 1638 | hscb->cdb_len = cmd->cmd_len; |
2145 | ahc_set_residual(scb, 0); | 1639 | if (hscb->cdb_len <= 12) { |
2146 | ahc_set_sense_residual(scb, 0); | 1640 | memcpy(hscb->shared_data.cdb, cmd->cmnd, hscb->cdb_len); |
2147 | scb->sg_count = 0; | 1641 | } else { |
2148 | if (cmd->use_sg != 0) { | 1642 | memcpy(hscb->cdb32, cmd->cmnd, hscb->cdb_len); |
2149 | struct ahc_dma_seg *sg; | 1643 | scb->flags |= SCB_CDB32_PTR; |
2150 | struct scatterlist *cur_seg; | 1644 | } |
2151 | struct scatterlist *end_seg; | ||
2152 | int nseg; | ||
2153 | |||
2154 | cur_seg = (struct scatterlist *)cmd->request_buffer; | ||
2155 | nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg, | ||
2156 | cmd->sc_data_direction); | ||
2157 | end_seg = cur_seg + nseg; | ||
2158 | /* Copy the segments into the SG list. */ | ||
2159 | sg = scb->sg_list; | ||
2160 | /* | ||
2161 | * The sg_count may be larger than nseg if | ||
2162 | * a transfer crosses a 32bit page. | ||
2163 | */ | ||
2164 | while (cur_seg < end_seg) { | ||
2165 | dma_addr_t addr; | ||
2166 | bus_size_t len; | ||
2167 | int consumed; | ||
2168 | |||
2169 | addr = sg_dma_address(cur_seg); | ||
2170 | len = sg_dma_len(cur_seg); | ||
2171 | consumed = ahc_linux_map_seg(ahc, scb, | ||
2172 | sg, addr, len); | ||
2173 | sg += consumed; | ||
2174 | scb->sg_count += consumed; | ||
2175 | cur_seg++; | ||
2176 | } | ||
2177 | sg--; | ||
2178 | sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); | ||
2179 | |||
2180 | /* | ||
2181 | * Reset the sg list pointer. | ||
2182 | */ | ||
2183 | scb->hscb->sgptr = | ||
2184 | ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); | ||
2185 | 1645 | ||
2186 | /* | 1646 | scb->platform_data->xfer_len = 0; |
2187 | * Copy the first SG into the "current" | 1647 | ahc_set_residual(scb, 0); |
2188 | * data pointer area. | 1648 | ahc_set_sense_residual(scb, 0); |
2189 | */ | 1649 | scb->sg_count = 0; |
2190 | scb->hscb->dataptr = scb->sg_list->addr; | 1650 | if (cmd->use_sg != 0) { |
2191 | scb->hscb->datacnt = scb->sg_list->len; | 1651 | struct ahc_dma_seg *sg; |
2192 | } else if (cmd->request_bufflen != 0) { | 1652 | struct scatterlist *cur_seg; |
2193 | struct ahc_dma_seg *sg; | 1653 | struct scatterlist *end_seg; |
1654 | int nseg; | ||
1655 | |||
1656 | cur_seg = (struct scatterlist *)cmd->request_buffer; | ||
1657 | nseg = pci_map_sg(ahc->dev_softc, cur_seg, cmd->use_sg, | ||
1658 | cmd->sc_data_direction); | ||
1659 | end_seg = cur_seg + nseg; | ||
1660 | /* Copy the segments into the SG list. */ | ||
1661 | sg = scb->sg_list; | ||
1662 | /* | ||
1663 | * The sg_count may be larger than nseg if | ||
1664 | * a transfer crosses a 32bit page. | ||
1665 | */ | ||
1666 | while (cur_seg < end_seg) { | ||
2194 | dma_addr_t addr; | 1667 | dma_addr_t addr; |
2195 | 1668 | bus_size_t len; | |
2196 | sg = scb->sg_list; | 1669 | int consumed; |
2197 | addr = pci_map_single(ahc->dev_softc, | 1670 | |
2198 | cmd->request_buffer, | 1671 | addr = sg_dma_address(cur_seg); |
2199 | cmd->request_bufflen, | 1672 | len = sg_dma_len(cur_seg); |
2200 | cmd->sc_data_direction); | 1673 | consumed = ahc_linux_map_seg(ahc, scb, |
2201 | scb->platform_data->buf_busaddr = addr; | 1674 | sg, addr, len); |
2202 | scb->sg_count = ahc_linux_map_seg(ahc, scb, | 1675 | sg += consumed; |
2203 | sg, addr, | 1676 | scb->sg_count += consumed; |
2204 | cmd->request_bufflen); | 1677 | cur_seg++; |
2205 | sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); | ||
2206 | |||
2207 | /* | ||
2208 | * Reset the sg list pointer. | ||
2209 | */ | ||
2210 | scb->hscb->sgptr = | ||
2211 | ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); | ||
2212 | |||
2213 | /* | ||
2214 | * Copy the first SG into the "current" | ||
2215 | * data pointer area. | ||
2216 | */ | ||
2217 | scb->hscb->dataptr = sg->addr; | ||
2218 | scb->hscb->datacnt = sg->len; | ||
2219 | } else { | ||
2220 | scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL); | ||
2221 | scb->hscb->dataptr = 0; | ||
2222 | scb->hscb->datacnt = 0; | ||
2223 | scb->sg_count = 0; | ||
2224 | } | 1678 | } |
1679 | sg--; | ||
1680 | sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); | ||
2225 | 1681 | ||
2226 | ahc_sync_sglist(ahc, scb, BUS_DMASYNC_PREWRITE); | 1682 | /* |
2227 | LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); | 1683 | * Reset the sg list pointer. |
2228 | dev->openings--; | 1684 | */ |
2229 | dev->active++; | 1685 | scb->hscb->sgptr = |
2230 | dev->commands_issued++; | 1686 | ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); |
2231 | if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0) | 1687 | |
2232 | dev->commands_since_idle_or_otag++; | 1688 | /* |
1689 | * Copy the first SG into the "current" | ||
1690 | * data pointer area. | ||
1691 | */ | ||
1692 | scb->hscb->dataptr = scb->sg_list->addr; | ||
1693 | scb->hscb->datacnt = scb->sg_list->len; | ||
1694 | } else if (cmd->request_bufflen != 0) { | ||
1695 | struct ahc_dma_seg *sg; | ||
1696 | dma_addr_t addr; | ||
1697 | |||
1698 | sg = scb->sg_list; | ||
1699 | addr = pci_map_single(ahc->dev_softc, | ||
1700 | cmd->request_buffer, | ||
1701 | cmd->request_bufflen, | ||
1702 | cmd->sc_data_direction); | ||
1703 | scb->platform_data->buf_busaddr = addr; | ||
1704 | scb->sg_count = ahc_linux_map_seg(ahc, scb, | ||
1705 | sg, addr, | ||
1706 | cmd->request_bufflen); | ||
1707 | sg->len |= ahc_htole32(AHC_DMA_LAST_SEG); | ||
2233 | 1708 | ||
2234 | /* | 1709 | /* |
2235 | * We only allow one untagged transaction | 1710 | * Reset the sg list pointer. |
2236 | * per target in the initiator role unless | ||
2237 | * we are storing a full busy target *lun* | ||
2238 | * table in SCB space. | ||
2239 | */ | 1711 | */ |
2240 | if ((scb->hscb->control & (TARGET_SCB|TAG_ENB)) == 0 | 1712 | scb->hscb->sgptr = |
2241 | && (ahc->features & AHC_SCB_BTT) == 0) { | 1713 | ahc_htole32(scb->sg_list_phys | SG_FULL_RESID); |
2242 | struct scb_tailq *untagged_q; | 1714 | |
2243 | int target_offset; | 1715 | /* |
2244 | 1716 | * Copy the first SG into the "current" | |
2245 | target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); | 1717 | * data pointer area. |
2246 | untagged_q = &(ahc->untagged_queues[target_offset]); | 1718 | */ |
2247 | TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); | 1719 | scb->hscb->dataptr = sg->addr; |
2248 | scb->flags |= SCB_UNTAGGEDQ; | 1720 | scb->hscb->datacnt = sg->len; |
2249 | if (TAILQ_FIRST(untagged_q) != scb) | 1721 | } else { |
2250 | continue; | 1722 | scb->hscb->sgptr = ahc_htole32(SG_LIST_NULL); |
2251 | } | 1723 | scb->hscb->dataptr = 0; |
2252 | scb->flags |= SCB_ACTIVE; | 1724 | scb->hscb->datacnt = 0; |
2253 | ahc_queue_scb(ahc, scb); | 1725 | scb->sg_count = 0; |
2254 | } | 1726 | } |
1727 | |||
1728 | LIST_INSERT_HEAD(&ahc->pending_scbs, scb, pending_links); | ||
1729 | dev->openings--; | ||
1730 | dev->active++; | ||
1731 | dev->commands_issued++; | ||
1732 | if ((dev->flags & AHC_DEV_PERIODIC_OTAG) != 0) | ||
1733 | dev->commands_since_idle_or_otag++; | ||
1734 | |||
1735 | scb->flags |= SCB_ACTIVE; | ||
1736 | if (untagged_q) { | ||
1737 | TAILQ_INSERT_TAIL(untagged_q, scb, links.tqe); | ||
1738 | scb->flags |= SCB_UNTAGGEDQ; | ||
1739 | } | ||
1740 | ahc_queue_scb(ahc, scb); | ||
1741 | return 0; | ||
2255 | } | 1742 | } |
2256 | 1743 | ||
2257 | /* | 1744 | /* |
@@ -2267,9 +1754,6 @@ ahc_linux_isr(int irq, void *dev_id, struct pt_regs * regs) | |||
2267 | ahc = (struct ahc_softc *) dev_id; | 1754 | ahc = (struct ahc_softc *) dev_id; |
2268 | ahc_lock(ahc, &flags); | 1755 | ahc_lock(ahc, &flags); |
2269 | ours = ahc_intr(ahc); | 1756 | ours = ahc_intr(ahc); |
2270 | if (ahc_linux_next_device_to_run(ahc) != NULL) | ||
2271 | ahc_schedule_runq(ahc); | ||
2272 | ahc_linux_run_complete_queue(ahc); | ||
2273 | ahc_unlock(ahc, &flags); | 1757 | ahc_unlock(ahc, &flags); |
2274 | return IRQ_RETVAL(ours); | 1758 | return IRQ_RETVAL(ours); |
2275 | } | 1759 | } |
@@ -2278,8 +1762,6 @@ void | |||
2278 | ahc_platform_flushwork(struct ahc_softc *ahc) | 1762 | ahc_platform_flushwork(struct ahc_softc *ahc) |
2279 | { | 1763 | { |
2280 | 1764 | ||
2281 | while (ahc_linux_run_complete_queue(ahc) != NULL) | ||
2282 | ; | ||
2283 | } | 1765 | } |
2284 | 1766 | ||
2285 | static struct ahc_linux_target* | 1767 | static struct ahc_linux_target* |
@@ -2335,8 +1817,6 @@ ahc_linux_free_target(struct ahc_softc *ahc, struct ahc_linux_target *targ) | |||
2335 | AHC_TRANS_GOAL, /*paused*/FALSE); | 1817 | AHC_TRANS_GOAL, /*paused*/FALSE); |
2336 | ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS); | 1818 | ahc_update_neg_request(ahc, &devinfo, tstate, tinfo, AHC_NEG_ALWAYS); |
2337 | ahc->platform_data->targets[target_offset] = NULL; | 1819 | ahc->platform_data->targets[target_offset] = NULL; |
2338 | if (targ->inq_data != NULL) | ||
2339 | free(targ->inq_data, M_DEVBUF); | ||
2340 | free(targ, M_DEVBUF); | 1820 | free(targ, M_DEVBUF); |
2341 | } | 1821 | } |
2342 | 1822 | ||
@@ -2350,9 +1830,6 @@ ahc_linux_alloc_device(struct ahc_softc *ahc, | |||
2350 | if (dev == NULL) | 1830 | if (dev == NULL) |
2351 | return (NULL); | 1831 | return (NULL); |
2352 | memset(dev, 0, sizeof(*dev)); | 1832 | memset(dev, 0, sizeof(*dev)); |
2353 | init_timer(&dev->timer); | ||
2354 | TAILQ_INIT(&dev->busyq); | ||
2355 | dev->flags = AHC_DEV_UNCONFIGURED; | ||
2356 | dev->lun = lun; | 1833 | dev->lun = lun; |
2357 | dev->target = targ; | 1834 | dev->target = targ; |
2358 | 1835 | ||
@@ -2375,7 +1852,7 @@ ahc_linux_alloc_device(struct ahc_softc *ahc, | |||
2375 | } | 1852 | } |
2376 | 1853 | ||
2377 | static void | 1854 | static void |
2378 | __ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) | 1855 | ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) |
2379 | { | 1856 | { |
2380 | struct ahc_linux_target *targ; | 1857 | struct ahc_linux_target *targ; |
2381 | 1858 | ||
@@ -2387,13 +1864,6 @@ __ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) | |||
2387 | ahc_linux_free_target(ahc, targ); | 1864 | ahc_linux_free_target(ahc, targ); |
2388 | } | 1865 | } |
2389 | 1866 | ||
2390 | static void | ||
2391 | ahc_linux_free_device(struct ahc_softc *ahc, struct ahc_linux_device *dev) | ||
2392 | { | ||
2393 | del_timer_sync(&dev->timer); | ||
2394 | __ahc_linux_free_device(ahc, dev); | ||
2395 | } | ||
2396 | |||
2397 | void | 1867 | void |
2398 | ahc_send_async(struct ahc_softc *ahc, char channel, | 1868 | ahc_send_async(struct ahc_softc *ahc, char channel, |
2399 | u_int target, u_int lun, ac_code code, void *arg) | 1869 | u_int target, u_int lun, ac_code code, void *arg) |
@@ -2465,28 +1935,9 @@ ahc_send_async(struct ahc_softc *ahc, char channel, | |||
2465 | } | 1935 | } |
2466 | case AC_SENT_BDR: | 1936 | case AC_SENT_BDR: |
2467 | { | 1937 | { |
2468 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
2469 | WARN_ON(lun != CAM_LUN_WILDCARD); | 1938 | WARN_ON(lun != CAM_LUN_WILDCARD); |
2470 | scsi_report_device_reset(ahc->platform_data->host, | 1939 | scsi_report_device_reset(ahc->platform_data->host, |
2471 | channel - 'A', target); | 1940 | channel - 'A', target); |
2472 | #else | ||
2473 | Scsi_Device *scsi_dev; | ||
2474 | |||
2475 | /* | ||
2476 | * Find the SCSI device associated with this | ||
2477 | * request and indicate that a UA is expected. | ||
2478 | */ | ||
2479 | for (scsi_dev = ahc->platform_data->host->host_queue; | ||
2480 | scsi_dev != NULL; scsi_dev = scsi_dev->next) { | ||
2481 | if (channel - 'A' == scsi_dev->channel | ||
2482 | && target == scsi_dev->id | ||
2483 | && (lun == CAM_LUN_WILDCARD | ||
2484 | || lun == scsi_dev->lun)) { | ||
2485 | scsi_dev->was_reset = 1; | ||
2486 | scsi_dev->expecting_cc_ua = 1; | ||
2487 | } | ||
2488 | } | ||
2489 | #endif | ||
2490 | break; | 1941 | break; |
2491 | } | 1942 | } |
2492 | case AC_BUS_RESET: | 1943 | case AC_BUS_RESET: |
@@ -2506,7 +1957,7 @@ ahc_send_async(struct ahc_softc *ahc, char channel, | |||
2506 | void | 1957 | void |
2507 | ahc_done(struct ahc_softc *ahc, struct scb *scb) | 1958 | ahc_done(struct ahc_softc *ahc, struct scb *scb) |
2508 | { | 1959 | { |
2509 | Scsi_Cmnd *cmd; | 1960 | struct scsi_cmnd *cmd; |
2510 | struct ahc_linux_device *dev; | 1961 | struct ahc_linux_device *dev; |
2511 | 1962 | ||
2512 | LIST_REMOVE(scb, pending_links); | 1963 | LIST_REMOVE(scb, pending_links); |
@@ -2517,7 +1968,7 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) | |||
2517 | target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); | 1968 | target_offset = SCB_GET_TARGET_OFFSET(ahc, scb); |
2518 | untagged_q = &(ahc->untagged_queues[target_offset]); | 1969 | untagged_q = &(ahc->untagged_queues[target_offset]); |
2519 | TAILQ_REMOVE(untagged_q, scb, links.tqe); | 1970 | TAILQ_REMOVE(untagged_q, scb, links.tqe); |
2520 | ahc_run_untagged_queue(ahc, untagged_q); | 1971 | BUG_ON(!TAILQ_EMPTY(untagged_q)); |
2521 | } | 1972 | } |
2522 | 1973 | ||
2523 | if ((scb->flags & SCB_ACTIVE) == 0) { | 1974 | if ((scb->flags & SCB_ACTIVE) == 0) { |
@@ -2585,8 +2036,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) | |||
2585 | } | 2036 | } |
2586 | } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { | 2037 | } else if (ahc_get_transaction_status(scb) == CAM_SCSI_STATUS_ERROR) { |
2587 | ahc_linux_handle_scsi_status(ahc, dev, scb); | 2038 | ahc_linux_handle_scsi_status(ahc, dev, scb); |
2588 | } else if (ahc_get_transaction_status(scb) == CAM_SEL_TIMEOUT) { | ||
2589 | dev->flags |= AHC_DEV_UNCONFIGURED; | ||
2590 | } | 2039 | } |
2591 | 2040 | ||
2592 | if (dev->openings == 1 | 2041 | if (dev->openings == 1 |
@@ -2608,16 +2057,6 @@ ahc_done(struct ahc_softc *ahc, struct scb *scb) | |||
2608 | if (dev->active == 0) | 2057 | if (dev->active == 0) |
2609 | dev->commands_since_idle_or_otag = 0; | 2058 | dev->commands_since_idle_or_otag = 0; |
2610 | 2059 | ||
2611 | if (TAILQ_EMPTY(&dev->busyq)) { | ||
2612 | if ((dev->flags & AHC_DEV_UNCONFIGURED) != 0 | ||
2613 | && dev->active == 0 | ||
2614 | && (dev->flags & AHC_DEV_TIMER_ACTIVE) == 0) | ||
2615 | ahc_linux_free_device(ahc, dev); | ||
2616 | } else if ((dev->flags & AHC_DEV_ON_RUN_LIST) == 0) { | ||
2617 | TAILQ_INSERT_TAIL(&ahc->platform_data->device_runq, dev, links); | ||
2618 | dev->flags |= AHC_DEV_ON_RUN_LIST; | ||
2619 | } | ||
2620 | |||
2621 | if ((scb->flags & SCB_RECOVERY_SCB) != 0) { | 2060 | if ((scb->flags & SCB_RECOVERY_SCB) != 0) { |
2622 | printf("Recovery SCB completes\n"); | 2061 | printf("Recovery SCB completes\n"); |
2623 | if (ahc_get_transaction_status(scb) == CAM_BDR_SENT | 2062 | if (ahc_get_transaction_status(scb) == CAM_BDR_SENT |
@@ -2661,7 +2100,7 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, | |||
2661 | case SCSI_STATUS_CHECK_COND: | 2100 | case SCSI_STATUS_CHECK_COND: |
2662 | case SCSI_STATUS_CMD_TERMINATED: | 2101 | case SCSI_STATUS_CMD_TERMINATED: |
2663 | { | 2102 | { |
2664 | Scsi_Cmnd *cmd; | 2103 | struct scsi_cmnd *cmd; |
2665 | 2104 | ||
2666 | /* | 2105 | /* |
2667 | * Copy sense information to the OS's cmd | 2106 | * Copy sense information to the OS's cmd |
@@ -2756,52 +2195,15 @@ ahc_linux_handle_scsi_status(struct ahc_softc *ahc, | |||
2756 | ahc_platform_set_tags(ahc, &devinfo, | 2195 | ahc_platform_set_tags(ahc, &devinfo, |
2757 | (dev->flags & AHC_DEV_Q_BASIC) | 2196 | (dev->flags & AHC_DEV_Q_BASIC) |
2758 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); | 2197 | ? AHC_QUEUE_BASIC : AHC_QUEUE_TAGGED); |
2759 | /* FALLTHROUGH */ | ||
2760 | } | ||
2761 | case SCSI_STATUS_BUSY: | ||
2762 | { | ||
2763 | /* | ||
2764 | * Set a short timer to defer sending commands for | ||
2765 | * a bit since Linux will not delay in this case. | ||
2766 | */ | ||
2767 | if ((dev->flags & AHC_DEV_TIMER_ACTIVE) != 0) { | ||
2768 | printf("%s:%c:%d: Device Timer still active during " | ||
2769 | "busy processing\n", ahc_name(ahc), | ||
2770 | dev->target->channel, dev->target->target); | ||
2771 | break; | ||
2772 | } | ||
2773 | dev->flags |= AHC_DEV_TIMER_ACTIVE; | ||
2774 | dev->qfrozen++; | ||
2775 | init_timer(&dev->timer); | ||
2776 | dev->timer.data = (u_long)dev; | ||
2777 | dev->timer.expires = jiffies + (HZ/2); | ||
2778 | dev->timer.function = ahc_linux_dev_timed_unfreeze; | ||
2779 | add_timer(&dev->timer); | ||
2780 | break; | 2198 | break; |
2781 | } | 2199 | } |
2782 | } | 2200 | } |
2783 | } | 2201 | } |
2784 | 2202 | ||
2785 | static void | 2203 | static void |
2786 | ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) | 2204 | ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, struct scsi_cmnd *cmd) |
2787 | { | 2205 | { |
2788 | /* | 2206 | /* |
2789 | * Typically, the complete queue has very few entries | ||
2790 | * queued to it before the queue is emptied by | ||
2791 | * ahc_linux_run_complete_queue, so sorting the entries | ||
2792 | * by generation number should be inexpensive. | ||
2793 | * We perform the sort so that commands that complete | ||
2794 | * with an error are retuned in the order origionally | ||
2795 | * queued to the controller so that any subsequent retries | ||
2796 | * are performed in order. The underlying ahc routines do | ||
2797 | * not guarantee the order that aborted commands will be | ||
2798 | * returned to us. | ||
2799 | */ | ||
2800 | struct ahc_completeq *completeq; | ||
2801 | struct ahc_cmd *list_cmd; | ||
2802 | struct ahc_cmd *acmd; | ||
2803 | |||
2804 | /* | ||
2805 | * Map CAM error codes into Linux Error codes. We | 2207 | * Map CAM error codes into Linux Error codes. We |
2806 | * avoid the conversion so that the DV code has the | 2208 | * avoid the conversion so that the DV code has the |
2807 | * full error information available when making | 2209 | * full error information available when making |
@@ -2854,26 +2256,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) | |||
2854 | new_status = DID_ERROR; | 2256 | new_status = DID_ERROR; |
2855 | break; | 2257 | break; |
2856 | case CAM_REQUEUE_REQ: | 2258 | case CAM_REQUEUE_REQ: |
2857 | /* | 2259 | new_status = DID_REQUEUE; |
2858 | * If we want the request requeued, make sure there | ||
2859 | * are sufficent retries. In the old scsi error code, | ||
2860 | * we used to be able to specify a result code that | ||
2861 | * bypassed the retry count. Now we must use this | ||
2862 | * hack. We also "fake" a check condition with | ||
2863 | * a sense code of ABORTED COMMAND. This seems to | ||
2864 | * evoke a retry even if this command is being sent | ||
2865 | * via the eh thread. Ick! Ick! Ick! | ||
2866 | */ | ||
2867 | if (cmd->retries > 0) | ||
2868 | cmd->retries--; | ||
2869 | new_status = DID_OK; | ||
2870 | ahc_cmd_set_scsi_status(cmd, SCSI_STATUS_CHECK_COND); | ||
2871 | cmd->result |= (DRIVER_SENSE << 24); | ||
2872 | memset(cmd->sense_buffer, 0, | ||
2873 | sizeof(cmd->sense_buffer)); | ||
2874 | cmd->sense_buffer[0] = SSD_ERRCODE_VALID | ||
2875 | | SSD_CURRENT_ERROR; | ||
2876 | cmd->sense_buffer[2] = SSD_KEY_ABORTED_COMMAND; | ||
2877 | break; | 2260 | break; |
2878 | default: | 2261 | default: |
2879 | /* We should never get here */ | 2262 | /* We should never get here */ |
@@ -2884,17 +2267,7 @@ ahc_linux_queue_cmd_complete(struct ahc_softc *ahc, Scsi_Cmnd *cmd) | |||
2884 | ahc_cmd_set_transaction_status(cmd, new_status); | 2267 | ahc_cmd_set_transaction_status(cmd, new_status); |
2885 | } | 2268 | } |
2886 | 2269 | ||
2887 | completeq = &ahc->platform_data->completeq; | 2270 | cmd->scsi_done(cmd); |
2888 | list_cmd = TAILQ_FIRST(completeq); | ||
2889 | acmd = (struct ahc_cmd *)cmd; | ||
2890 | while (list_cmd != NULL | ||
2891 | && acmd_scsi_cmd(list_cmd).serial_number | ||
2892 | < acmd_scsi_cmd(acmd).serial_number) | ||
2893 | list_cmd = TAILQ_NEXT(list_cmd, acmd_links.tqe); | ||
2894 | if (list_cmd != NULL) | ||
2895 | TAILQ_INSERT_BEFORE(list_cmd, acmd, acmd_links.tqe); | ||
2896 | else | ||
2897 | TAILQ_INSERT_TAIL(completeq, acmd, acmd_links.tqe); | ||
2898 | } | 2271 | } |
2899 | 2272 | ||
2900 | static void | 2273 | static void |
@@ -2942,7 +2315,6 @@ ahc_linux_release_simq(u_long arg) | |||
2942 | ahc->platform_data->qfrozen--; | 2315 | ahc->platform_data->qfrozen--; |
2943 | if (ahc->platform_data->qfrozen == 0) | 2316 | if (ahc->platform_data->qfrozen == 0) |
2944 | unblock_reqs = 1; | 2317 | unblock_reqs = 1; |
2945 | ahc_schedule_runq(ahc); | ||
2946 | ahc_unlock(ahc, &s); | 2318 | ahc_unlock(ahc, &s); |
2947 | /* | 2319 | /* |
2948 | * There is still a race here. The mid-layer | 2320 | * There is still a race here. The mid-layer |
@@ -2954,37 +2326,12 @@ ahc_linux_release_simq(u_long arg) | |||
2954 | scsi_unblock_requests(ahc->platform_data->host); | 2326 | scsi_unblock_requests(ahc->platform_data->host); |
2955 | } | 2327 | } |
2956 | 2328 | ||
2957 | static void | ||
2958 | ahc_linux_dev_timed_unfreeze(u_long arg) | ||
2959 | { | ||
2960 | struct ahc_linux_device *dev; | ||
2961 | struct ahc_softc *ahc; | ||
2962 | u_long s; | ||
2963 | |||
2964 | dev = (struct ahc_linux_device *)arg; | ||
2965 | ahc = dev->target->ahc; | ||
2966 | ahc_lock(ahc, &s); | ||
2967 | dev->flags &= ~AHC_DEV_TIMER_ACTIVE; | ||
2968 | if (dev->qfrozen > 0) | ||
2969 | dev->qfrozen--; | ||
2970 | if (dev->qfrozen == 0 | ||
2971 | && (dev->flags & AHC_DEV_ON_RUN_LIST) == 0) | ||
2972 | ahc_linux_run_device_queue(ahc, dev); | ||
2973 | if (TAILQ_EMPTY(&dev->busyq) | ||
2974 | && dev->active == 0) | ||
2975 | __ahc_linux_free_device(ahc, dev); | ||
2976 | ahc_unlock(ahc, &s); | ||
2977 | } | ||
2978 | |||
2979 | static int | 2329 | static int |
2980 | ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) | 2330 | ahc_linux_queue_recovery_cmd(struct scsi_cmnd *cmd, scb_flag flag) |
2981 | { | 2331 | { |
2982 | struct ahc_softc *ahc; | 2332 | struct ahc_softc *ahc; |
2983 | struct ahc_cmd *acmd; | ||
2984 | struct ahc_cmd *list_acmd; | ||
2985 | struct ahc_linux_device *dev; | 2333 | struct ahc_linux_device *dev; |
2986 | struct scb *pending_scb; | 2334 | struct scb *pending_scb; |
2987 | u_long s; | ||
2988 | u_int saved_scbptr; | 2335 | u_int saved_scbptr; |
2989 | u_int active_scb_index; | 2336 | u_int active_scb_index; |
2990 | u_int last_phase; | 2337 | u_int last_phase; |
@@ -3000,7 +2347,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) | |||
3000 | paused = FALSE; | 2347 | paused = FALSE; |
3001 | wait = FALSE; | 2348 | wait = FALSE; |
3002 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; | 2349 | ahc = *(struct ahc_softc **)cmd->device->host->hostdata; |
3003 | acmd = (struct ahc_cmd *)cmd; | ||
3004 | 2350 | ||
3005 | printf("%s:%d:%d:%d: Attempting to queue a%s message\n", | 2351 | printf("%s:%d:%d:%d: Attempting to queue a%s message\n", |
3006 | ahc_name(ahc), cmd->device->channel, | 2352 | ahc_name(ahc), cmd->device->channel, |
@@ -3013,22 +2359,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) | |||
3013 | printf("\n"); | 2359 | printf("\n"); |
3014 | 2360 | ||
3015 | /* | 2361 | /* |
3016 | * In all versions of Linux, we have to work around | ||
3017 | * a major flaw in how the mid-layer is locked down | ||
3018 | * if we are to sleep successfully in our error handler | ||
3019 | * while allowing our interrupt handler to run. Since | ||
3020 | * the midlayer acquires either the io_request_lock or | ||
3021 | * our lock prior to calling us, we must use the | ||
3022 | * spin_unlock_irq() method for unlocking our lock. | ||
3023 | * This will force interrupts to be enabled on the | ||
3024 | * current CPU. Since the EH thread should not have | ||
3025 | * been running with CPU interrupts disabled other than | ||
3026 | * by acquiring either the io_request_lock or our own | ||
3027 | * lock, this *should* be safe. | ||
3028 | */ | ||
3029 | ahc_midlayer_entrypoint_lock(ahc, &s); | ||
3030 | |||
3031 | /* | ||
3032 | * First determine if we currently own this command. | 2362 | * First determine if we currently own this command. |
3033 | * Start by searching the device queue. If not found | 2363 | * Start by searching the device queue. If not found |
3034 | * there, check the pending_scb list. If not found | 2364 | * there, check the pending_scb list. If not found |
@@ -3036,7 +2366,7 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) | |||
3036 | * command, return success. | 2366 | * command, return success. |
3037 | */ | 2367 | */ |
3038 | dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, | 2368 | dev = ahc_linux_get_device(ahc, cmd->device->channel, cmd->device->id, |
3039 | cmd->device->lun, /*alloc*/FALSE); | 2369 | cmd->device->lun); |
3040 | 2370 | ||
3041 | if (dev == NULL) { | 2371 | if (dev == NULL) { |
3042 | /* | 2372 | /* |
@@ -3050,24 +2380,6 @@ ahc_linux_queue_recovery_cmd(Scsi_Cmnd *cmd, scb_flag flag) | |||
3050 | goto no_cmd; | 2380 | goto no_cmd; |
3051 | } | 2381 | } |
3052 | 2382 | ||
3053 | TAILQ_FOREACH(list_acmd, &dev->busyq, acmd_links.tqe) { | ||
3054 | if (list_acmd == acmd) | ||
3055 | break; | ||
3056 | } | ||
3057 | |||
3058 | if (list_acmd != NULL) { | ||
3059 | printf("%s:%d:%d:%d: Command found on device queue\n", | ||
3060 | ahc_name(ahc), cmd->device->channel, cmd->device->id, | ||
3061 | cmd->device->lun); | ||
3062 | if (flag == SCB_ABORT) { | ||
3063 | TAILQ_REMOVE(&dev->busyq, list_acmd, acmd_links.tqe); | ||
3064 | cmd->result = DID_ABORT << 16; | ||
3065 | ahc_linux_queue_cmd_complete(ahc, cmd); | ||
3066 | retval = SUCCESS; | ||
3067 | goto done; | ||
3068 | } | ||
3069 | } | ||
3070 | |||
3071 | if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 | 2383 | if ((dev->flags & (AHC_DEV_Q_BASIC|AHC_DEV_Q_TAGGED)) == 0 |
3072 | && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, | 2384 | && ahc_search_untagged_queues(ahc, cmd, cmd->device->id, |
3073 | cmd->device->channel + 'A', | 2385 | cmd->device->channel + 'A', |
@@ -3301,53 +2613,42 @@ done: | |||
3301 | } | 2613 | } |
3302 | spin_lock_irq(&ahc->platform_data->spin_lock); | 2614 | spin_lock_irq(&ahc->platform_data->spin_lock); |
3303 | } | 2615 | } |
3304 | ahc_schedule_runq(ahc); | ||
3305 | ahc_linux_run_complete_queue(ahc); | ||
3306 | ahc_midlayer_entrypoint_unlock(ahc, &s); | ||
3307 | return (retval); | 2616 | return (retval); |
3308 | } | 2617 | } |
3309 | 2618 | ||
3310 | void | 2619 | void |
3311 | ahc_platform_dump_card_state(struct ahc_softc *ahc) | 2620 | ahc_platform_dump_card_state(struct ahc_softc *ahc) |
3312 | { | 2621 | { |
3313 | struct ahc_linux_device *dev; | 2622 | } |
3314 | int channel; | ||
3315 | int maxchannel; | ||
3316 | int target; | ||
3317 | int maxtarget; | ||
3318 | int lun; | ||
3319 | int i; | ||
3320 | |||
3321 | maxchannel = (ahc->features & AHC_TWIN) ? 1 : 0; | ||
3322 | maxtarget = (ahc->features & AHC_WIDE) ? 15 : 7; | ||
3323 | for (channel = 0; channel <= maxchannel; channel++) { | ||
3324 | 2623 | ||
3325 | for (target = 0; target <=maxtarget; target++) { | 2624 | static void ahc_linux_exit(void); |
3326 | 2625 | ||
3327 | for (lun = 0; lun < AHC_NUM_LUNS; lun++) { | 2626 | static void ahc_linux_get_width(struct scsi_target *starget) |
3328 | struct ahc_cmd *acmd; | 2627 | { |
2628 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
2629 | struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); | ||
2630 | struct ahc_tmode_tstate *tstate; | ||
2631 | struct ahc_initiator_tinfo *tinfo | ||
2632 | = ahc_fetch_transinfo(ahc, | ||
2633 | starget->channel + 'A', | ||
2634 | shost->this_id, starget->id, &tstate); | ||
2635 | spi_width(starget) = tinfo->curr.width; | ||
2636 | } | ||
3329 | 2637 | ||
3330 | dev = ahc_linux_get_device(ahc, channel, target, | 2638 | static void ahc_linux_set_width(struct scsi_target *starget, int width) |
3331 | lun, /*alloc*/FALSE); | 2639 | { |
3332 | if (dev == NULL) | 2640 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
3333 | continue; | 2641 | struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); |
2642 | struct ahc_devinfo devinfo; | ||
2643 | unsigned long flags; | ||
3334 | 2644 | ||
3335 | printf("DevQ(%d:%d:%d): ", | 2645 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
3336 | channel, target, lun); | 2646 | starget->channel + 'A', ROLE_INITIATOR); |
3337 | i = 0; | 2647 | ahc_lock(ahc, &flags); |
3338 | TAILQ_FOREACH(acmd, &dev->busyq, | 2648 | ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE); |
3339 | acmd_links.tqe) { | 2649 | ahc_unlock(ahc, &flags); |
3340 | if (i++ > AHC_SCB_MAX) | ||
3341 | break; | ||
3342 | } | ||
3343 | printf("%d waiting\n", i); | ||
3344 | } | ||
3345 | } | ||
3346 | } | ||
3347 | } | 2650 | } |
3348 | 2651 | ||
3349 | static void ahc_linux_exit(void); | ||
3350 | |||
3351 | static void ahc_linux_get_period(struct scsi_target *starget) | 2652 | static void ahc_linux_get_period(struct scsi_target *starget) |
3352 | { | 2653 | { |
3353 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 2654 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
@@ -3378,8 +2679,21 @@ static void ahc_linux_set_period(struct scsi_target *starget, int period) | |||
3378 | if (offset == 0) | 2679 | if (offset == 0) |
3379 | offset = MAX_OFFSET; | 2680 | offset = MAX_OFFSET; |
3380 | 2681 | ||
2682 | if (period < 9) | ||
2683 | period = 9; /* 12.5ns is our minimum */ | ||
2684 | if (period == 9) | ||
2685 | ppr_options |= MSG_EXT_PPR_DT_REQ; | ||
2686 | |||
3381 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2687 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
3382 | starget->channel + 'A', ROLE_INITIATOR); | 2688 | starget->channel + 'A', ROLE_INITIATOR); |
2689 | |||
2690 | /* all PPR requests apart from QAS require wide transfers */ | ||
2691 | if (ppr_options & ~MSG_EXT_PPR_QAS_REQ) { | ||
2692 | ahc_linux_get_width(starget); | ||
2693 | if (spi_width(starget) == 0) | ||
2694 | ppr_options &= MSG_EXT_PPR_QAS_REQ; | ||
2695 | } | ||
2696 | |||
3383 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); | 2697 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); |
3384 | ahc_lock(ahc, &flags); | 2698 | ahc_lock(ahc, &flags); |
3385 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, | 2699 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, offset, |
@@ -3427,32 +2741,6 @@ static void ahc_linux_set_offset(struct scsi_target *starget, int offset) | |||
3427 | ahc_unlock(ahc, &flags); | 2741 | ahc_unlock(ahc, &flags); |
3428 | } | 2742 | } |
3429 | 2743 | ||
3430 | static void ahc_linux_get_width(struct scsi_target *starget) | ||
3431 | { | ||
3432 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
3433 | struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); | ||
3434 | struct ahc_tmode_tstate *tstate; | ||
3435 | struct ahc_initiator_tinfo *tinfo | ||
3436 | = ahc_fetch_transinfo(ahc, | ||
3437 | starget->channel + 'A', | ||
3438 | shost->this_id, starget->id, &tstate); | ||
3439 | spi_width(starget) = tinfo->curr.width; | ||
3440 | } | ||
3441 | |||
3442 | static void ahc_linux_set_width(struct scsi_target *starget, int width) | ||
3443 | { | ||
3444 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
3445 | struct ahc_softc *ahc = *((struct ahc_softc **)shost->hostdata); | ||
3446 | struct ahc_devinfo devinfo; | ||
3447 | unsigned long flags; | ||
3448 | |||
3449 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | ||
3450 | starget->channel + 'A', ROLE_INITIATOR); | ||
3451 | ahc_lock(ahc, &flags); | ||
3452 | ahc_set_width(ahc, &devinfo, width, AHC_TRANS_GOAL, FALSE); | ||
3453 | ahc_unlock(ahc, &flags); | ||
3454 | } | ||
3455 | |||
3456 | static void ahc_linux_get_dt(struct scsi_target *starget) | 2744 | static void ahc_linux_get_dt(struct scsi_target *starget) |
3457 | { | 2745 | { |
3458 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | 2746 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); |
@@ -3481,10 +2769,15 @@ static void ahc_linux_set_dt(struct scsi_target *starget, int dt) | |||
3481 | unsigned long flags; | 2769 | unsigned long flags; |
3482 | struct ahc_syncrate *syncrate; | 2770 | struct ahc_syncrate *syncrate; |
3483 | 2771 | ||
2772 | if (dt) { | ||
2773 | period = 9; /* 12.5ns is the only period valid for DT */ | ||
2774 | ppr_options |= MSG_EXT_PPR_DT_REQ; | ||
2775 | } else if (period == 9) | ||
2776 | period = 10; /* if resetting DT, period must be >= 25ns */ | ||
2777 | |||
3484 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2778 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
3485 | starget->channel + 'A', ROLE_INITIATOR); | 2779 | starget->channel + 'A', ROLE_INITIATOR); |
3486 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, | 2780 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options,AHC_SYNCRATE_DT); |
3487 | dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); | ||
3488 | ahc_lock(ahc, &flags); | 2781 | ahc_lock(ahc, &flags); |
3489 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, | 2782 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, |
3490 | ppr_options, AHC_TRANS_GOAL, FALSE); | 2783 | ppr_options, AHC_TRANS_GOAL, FALSE); |
@@ -3516,7 +2809,6 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) | |||
3516 | unsigned int ppr_options = tinfo->curr.ppr_options | 2809 | unsigned int ppr_options = tinfo->curr.ppr_options |
3517 | & ~MSG_EXT_PPR_QAS_REQ; | 2810 | & ~MSG_EXT_PPR_QAS_REQ; |
3518 | unsigned int period = tinfo->curr.period; | 2811 | unsigned int period = tinfo->curr.period; |
3519 | unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ; | ||
3520 | unsigned long flags; | 2812 | unsigned long flags; |
3521 | struct ahc_syncrate *syncrate; | 2813 | struct ahc_syncrate *syncrate; |
3522 | 2814 | ||
@@ -3525,8 +2817,7 @@ static void ahc_linux_set_qas(struct scsi_target *starget, int qas) | |||
3525 | 2817 | ||
3526 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2818 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
3527 | starget->channel + 'A', ROLE_INITIATOR); | 2819 | starget->channel + 'A', ROLE_INITIATOR); |
3528 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, | 2820 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); |
3529 | dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); | ||
3530 | ahc_lock(ahc, &flags); | 2821 | ahc_lock(ahc, &flags); |
3531 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, | 2822 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, |
3532 | ppr_options, AHC_TRANS_GOAL, FALSE); | 2823 | ppr_options, AHC_TRANS_GOAL, FALSE); |
@@ -3558,7 +2849,6 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) | |||
3558 | unsigned int ppr_options = tinfo->curr.ppr_options | 2849 | unsigned int ppr_options = tinfo->curr.ppr_options |
3559 | & ~MSG_EXT_PPR_IU_REQ; | 2850 | & ~MSG_EXT_PPR_IU_REQ; |
3560 | unsigned int period = tinfo->curr.period; | 2851 | unsigned int period = tinfo->curr.period; |
3561 | unsigned int dt = ppr_options & MSG_EXT_PPR_DT_REQ; | ||
3562 | unsigned long flags; | 2852 | unsigned long flags; |
3563 | struct ahc_syncrate *syncrate; | 2853 | struct ahc_syncrate *syncrate; |
3564 | 2854 | ||
@@ -3567,8 +2857,7 @@ static void ahc_linux_set_iu(struct scsi_target *starget, int iu) | |||
3567 | 2857 | ||
3568 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, | 2858 | ahc_compile_devinfo(&devinfo, shost->this_id, starget->id, 0, |
3569 | starget->channel + 'A', ROLE_INITIATOR); | 2859 | starget->channel + 'A', ROLE_INITIATOR); |
3570 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, | 2860 | syncrate = ahc_find_syncrate(ahc, &period, &ppr_options, AHC_SYNCRATE_DT); |
3571 | dt ? AHC_SYNCRATE_DT : AHC_SYNCRATE_ULTRA2); | ||
3572 | ahc_lock(ahc, &flags); | 2861 | ahc_lock(ahc, &flags); |
3573 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, | 2862 | ahc_set_syncrate(ahc, &devinfo, syncrate, period, tinfo->curr.offset, |
3574 | ppr_options, AHC_TRANS_GOAL, FALSE); | 2863 | ppr_options, AHC_TRANS_GOAL, FALSE); |
@@ -3601,7 +2890,6 @@ static struct spi_function_template ahc_linux_transport_functions = { | |||
3601 | static int __init | 2890 | static int __init |
3602 | ahc_linux_init(void) | 2891 | ahc_linux_init(void) |
3603 | { | 2892 | { |
3604 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
3605 | ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions); | 2893 | ahc_linux_transport_template = spi_attach_transport(&ahc_linux_transport_functions); |
3606 | if (!ahc_linux_transport_template) | 2894 | if (!ahc_linux_transport_template) |
3607 | return -ENODEV; | 2895 | return -ENODEV; |
@@ -3610,29 +2898,11 @@ ahc_linux_init(void) | |||
3610 | spi_release_transport(ahc_linux_transport_template); | 2898 | spi_release_transport(ahc_linux_transport_template); |
3611 | ahc_linux_exit(); | 2899 | ahc_linux_exit(); |
3612 | return -ENODEV; | 2900 | return -ENODEV; |
3613 | #else | ||
3614 | scsi_register_module(MODULE_SCSI_HA, &aic7xxx_driver_template); | ||
3615 | if (aic7xxx_driver_template.present == 0) { | ||
3616 | scsi_unregister_module(MODULE_SCSI_HA, | ||
3617 | &aic7xxx_driver_template); | ||
3618 | return (-ENODEV); | ||
3619 | } | ||
3620 | |||
3621 | return (0); | ||
3622 | #endif | ||
3623 | } | 2901 | } |
3624 | 2902 | ||
3625 | static void | 2903 | static void |
3626 | ahc_linux_exit(void) | 2904 | ahc_linux_exit(void) |
3627 | { | 2905 | { |
3628 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
3629 | /* | ||
3630 | * In 2.4 we have to unregister from the PCI core _after_ | ||
3631 | * unregistering from the scsi midlayer to avoid dangling | ||
3632 | * references. | ||
3633 | */ | ||
3634 | scsi_unregister_module(MODULE_SCSI_HA, &aic7xxx_driver_template); | ||
3635 | #endif | ||
3636 | ahc_linux_pci_exit(); | 2906 | ahc_linux_pci_exit(); |
3637 | ahc_linux_eisa_exit(); | 2907 | ahc_linux_eisa_exit(); |
3638 | spi_release_transport(ahc_linux_transport_template); | 2908 | spi_release_transport(ahc_linux_transport_template); |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index c401537067b6..30c200d5bcd5 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h | |||
@@ -59,6 +59,7 @@ | |||
59 | #ifndef _AIC7XXX_LINUX_H_ | 59 | #ifndef _AIC7XXX_LINUX_H_ |
60 | #define _AIC7XXX_LINUX_H_ | 60 | #define _AIC7XXX_LINUX_H_ |
61 | 61 | ||
62 | #include <linux/config.h> | ||
62 | #include <linux/types.h> | 63 | #include <linux/types.h> |
63 | #include <linux/blkdev.h> | 64 | #include <linux/blkdev.h> |
64 | #include <linux/delay.h> | 65 | #include <linux/delay.h> |
@@ -66,18 +67,21 @@ | |||
66 | #include <linux/pci.h> | 67 | #include <linux/pci.h> |
67 | #include <linux/smp_lock.h> | 68 | #include <linux/smp_lock.h> |
68 | #include <linux/version.h> | 69 | #include <linux/version.h> |
70 | #include <linux/interrupt.h> | ||
69 | #include <linux/module.h> | 71 | #include <linux/module.h> |
72 | #include <linux/slab.h> | ||
70 | #include <asm/byteorder.h> | 73 | #include <asm/byteorder.h> |
71 | #include <asm/io.h> | 74 | #include <asm/io.h> |
72 | 75 | ||
73 | #include <linux/interrupt.h> /* For tasklet support. */ | 76 | #include <scsi/scsi.h> |
74 | #include <linux/config.h> | 77 | #include <scsi/scsi_cmnd.h> |
75 | #include <linux/slab.h> | 78 | #include <scsi/scsi_eh.h> |
79 | #include <scsi/scsi_device.h> | ||
80 | #include <scsi/scsi_host.h> | ||
81 | #include <scsi/scsi_tcq.h> | ||
76 | 82 | ||
77 | /* Core SCSI definitions */ | 83 | /* Core SCSI definitions */ |
78 | #define AIC_LIB_PREFIX ahc | 84 | #define AIC_LIB_PREFIX ahc |
79 | #include "scsi.h" | ||
80 | #include <scsi/scsi_host.h> | ||
81 | 85 | ||
82 | /* Name space conflict with BSD queue macros */ | 86 | /* Name space conflict with BSD queue macros */ |
83 | #ifdef LIST_HEAD | 87 | #ifdef LIST_HEAD |
@@ -106,7 +110,7 @@ | |||
106 | /************************* Forward Declarations *******************************/ | 110 | /************************* Forward Declarations *******************************/ |
107 | struct ahc_softc; | 111 | struct ahc_softc; |
108 | typedef struct pci_dev *ahc_dev_softc_t; | 112 | typedef struct pci_dev *ahc_dev_softc_t; |
109 | typedef Scsi_Cmnd *ahc_io_ctx_t; | 113 | typedef struct scsi_cmnd *ahc_io_ctx_t; |
110 | 114 | ||
111 | /******************************* Byte Order ***********************************/ | 115 | /******************************* Byte Order ***********************************/ |
112 | #define ahc_htobe16(x) cpu_to_be16(x) | 116 | #define ahc_htobe16(x) cpu_to_be16(x) |
@@ -144,7 +148,7 @@ typedef Scsi_Cmnd *ahc_io_ctx_t; | |||
144 | extern u_int aic7xxx_no_probe; | 148 | extern u_int aic7xxx_no_probe; |
145 | extern u_int aic7xxx_allow_memio; | 149 | extern u_int aic7xxx_allow_memio; |
146 | extern int aic7xxx_detect_complete; | 150 | extern int aic7xxx_detect_complete; |
147 | extern Scsi_Host_Template aic7xxx_driver_template; | 151 | extern struct scsi_host_template aic7xxx_driver_template; |
148 | 152 | ||
149 | /***************************** Bus Space/DMA **********************************/ | 153 | /***************************** Bus Space/DMA **********************************/ |
150 | 154 | ||
@@ -174,11 +178,7 @@ struct ahc_linux_dma_tag | |||
174 | }; | 178 | }; |
175 | typedef struct ahc_linux_dma_tag* bus_dma_tag_t; | 179 | typedef struct ahc_linux_dma_tag* bus_dma_tag_t; |
176 | 180 | ||
177 | struct ahc_linux_dmamap | 181 | typedef dma_addr_t bus_dmamap_t; |
178 | { | ||
179 | dma_addr_t bus_addr; | ||
180 | }; | ||
181 | typedef struct ahc_linux_dmamap* bus_dmamap_t; | ||
182 | 182 | ||
183 | typedef int bus_dma_filter_t(void*, dma_addr_t); | 183 | typedef int bus_dma_filter_t(void*, dma_addr_t); |
184 | typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); | 184 | typedef void bus_dmamap_callback_t(void *, bus_dma_segment_t *, int, int); |
@@ -281,12 +281,6 @@ ahc_scb_timer_reset(struct scb *scb, u_int usec) | |||
281 | /***************************** SMP support ************************************/ | 281 | /***************************** SMP support ************************************/ |
282 | #include <linux/spinlock.h> | 282 | #include <linux/spinlock.h> |
283 | 283 | ||
284 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) || defined(SCSI_HAS_HOST_LOCK)) | ||
285 | #define AHC_SCSI_HAS_HOST_LOCK 1 | ||
286 | #else | ||
287 | #define AHC_SCSI_HAS_HOST_LOCK 0 | ||
288 | #endif | ||
289 | |||
290 | #define AIC7XXX_DRIVER_VERSION "6.2.36" | 284 | #define AIC7XXX_DRIVER_VERSION "6.2.36" |
291 | 285 | ||
292 | /**************************** Front End Queues ********************************/ | 286 | /**************************** Front End Queues ********************************/ |
@@ -328,20 +322,15 @@ struct ahc_cmd { | |||
328 | */ | 322 | */ |
329 | TAILQ_HEAD(ahc_busyq, ahc_cmd); | 323 | TAILQ_HEAD(ahc_busyq, ahc_cmd); |
330 | typedef enum { | 324 | typedef enum { |
331 | AHC_DEV_UNCONFIGURED = 0x01, | ||
332 | AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ | 325 | AHC_DEV_FREEZE_TIL_EMPTY = 0x02, /* Freeze queue until active == 0 */ |
333 | AHC_DEV_TIMER_ACTIVE = 0x04, /* Our timer is active */ | ||
334 | AHC_DEV_ON_RUN_LIST = 0x08, /* Queued to be run later */ | ||
335 | AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ | 326 | AHC_DEV_Q_BASIC = 0x10, /* Allow basic device queuing */ |
336 | AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ | 327 | AHC_DEV_Q_TAGGED = 0x20, /* Allow full SCSI2 command queueing */ |
337 | AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ | 328 | AHC_DEV_PERIODIC_OTAG = 0x40, /* Send OTAG to prevent starvation */ |
338 | AHC_DEV_SLAVE_CONFIGURED = 0x80 /* slave_configure() has been called */ | ||
339 | } ahc_linux_dev_flags; | 329 | } ahc_linux_dev_flags; |
340 | 330 | ||
341 | struct ahc_linux_target; | 331 | struct ahc_linux_target; |
342 | struct ahc_linux_device { | 332 | struct ahc_linux_device { |
343 | TAILQ_ENTRY(ahc_linux_device) links; | 333 | TAILQ_ENTRY(ahc_linux_device) links; |
344 | struct ahc_busyq busyq; | ||
345 | 334 | ||
346 | /* | 335 | /* |
347 | * The number of transactions currently | 336 | * The number of transactions currently |
@@ -382,11 +371,6 @@ struct ahc_linux_device { | |||
382 | ahc_linux_dev_flags flags; | 371 | ahc_linux_dev_flags flags; |
383 | 372 | ||
384 | /* | 373 | /* |
385 | * Per device timer. | ||
386 | */ | ||
387 | struct timer_list timer; | ||
388 | |||
389 | /* | ||
390 | * The high limit for the tags variable. | 374 | * The high limit for the tags variable. |
391 | */ | 375 | */ |
392 | u_int maxtags; | 376 | u_int maxtags; |
@@ -419,14 +403,10 @@ struct ahc_linux_device { | |||
419 | #define AHC_OTAG_THRESH 500 | 403 | #define AHC_OTAG_THRESH 500 |
420 | 404 | ||
421 | int lun; | 405 | int lun; |
422 | Scsi_Device *scsi_device; | 406 | struct scsi_device *scsi_device; |
423 | struct ahc_linux_target *target; | 407 | struct ahc_linux_target *target; |
424 | }; | 408 | }; |
425 | 409 | ||
426 | typedef enum { | ||
427 | AHC_INQ_VALID = 0x02, | ||
428 | } ahc_linux_targ_flags; | ||
429 | |||
430 | struct ahc_linux_target { | 410 | struct ahc_linux_target { |
431 | struct ahc_linux_device *devices[AHC_NUM_LUNS]; | 411 | struct ahc_linux_device *devices[AHC_NUM_LUNS]; |
432 | int channel; | 412 | int channel; |
@@ -434,8 +414,6 @@ struct ahc_linux_target { | |||
434 | int refcount; | 414 | int refcount; |
435 | struct ahc_transinfo last_tinfo; | 415 | struct ahc_transinfo last_tinfo; |
436 | struct ahc_softc *ahc; | 416 | struct ahc_softc *ahc; |
437 | ahc_linux_targ_flags flags; | ||
438 | struct scsi_inquiry_data *inq_data; | ||
439 | }; | 417 | }; |
440 | 418 | ||
441 | /********************* Definitions Required by the Core ***********************/ | 419 | /********************* Definitions Required by the Core ***********************/ |
@@ -445,32 +423,16 @@ struct ahc_linux_target { | |||
445 | * manner and are allocated below 4GB, the number of S/G segments is | 423 | * manner and are allocated below 4GB, the number of S/G segments is |
446 | * unrestricted. | 424 | * unrestricted. |
447 | */ | 425 | */ |
448 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
449 | /* | ||
450 | * We dynamically adjust the number of segments in pre-2.5 kernels to | ||
451 | * avoid fragmentation issues in the SCSI mid-layer's private memory | ||
452 | * allocator. See aic7xxx_osm.c ahc_linux_size_nseg() for details. | ||
453 | */ | ||
454 | extern u_int ahc_linux_nseg; | ||
455 | #define AHC_NSEG ahc_linux_nseg | ||
456 | #define AHC_LINUX_MIN_NSEG 64 | ||
457 | #else | ||
458 | #define AHC_NSEG 128 | 426 | #define AHC_NSEG 128 |
459 | #endif | ||
460 | 427 | ||
461 | /* | 428 | /* |
462 | * Per-SCB OSM storage. | 429 | * Per-SCB OSM storage. |
463 | */ | 430 | */ |
464 | typedef enum { | ||
465 | AHC_UP_EH_SEMAPHORE = 0x1 | ||
466 | } ahc_linux_scb_flags; | ||
467 | |||
468 | struct scb_platform_data { | 431 | struct scb_platform_data { |
469 | struct ahc_linux_device *dev; | 432 | struct ahc_linux_device *dev; |
470 | dma_addr_t buf_busaddr; | 433 | dma_addr_t buf_busaddr; |
471 | uint32_t xfer_len; | 434 | uint32_t xfer_len; |
472 | uint32_t sense_resid; /* Auto-Sense residual */ | 435 | uint32_t sense_resid; /* Auto-Sense residual */ |
473 | ahc_linux_scb_flags flags; | ||
474 | }; | 436 | }; |
475 | 437 | ||
476 | /* | 438 | /* |
@@ -479,39 +441,24 @@ struct scb_platform_data { | |||
479 | * alignment restrictions of the various platforms supported by | 441 | * alignment restrictions of the various platforms supported by |
480 | * this driver. | 442 | * this driver. |
481 | */ | 443 | */ |
482 | typedef enum { | ||
483 | AHC_RUN_CMPLT_Q_TIMER = 0x10 | ||
484 | } ahc_linux_softc_flags; | ||
485 | |||
486 | TAILQ_HEAD(ahc_completeq, ahc_cmd); | ||
487 | |||
488 | struct ahc_platform_data { | 444 | struct ahc_platform_data { |
489 | /* | 445 | /* |
490 | * Fields accessed from interrupt context. | 446 | * Fields accessed from interrupt context. |
491 | */ | 447 | */ |
492 | struct ahc_linux_target *targets[AHC_NUM_TARGETS]; | 448 | struct ahc_linux_target *targets[AHC_NUM_TARGETS]; |
493 | TAILQ_HEAD(, ahc_linux_device) device_runq; | ||
494 | struct ahc_completeq completeq; | ||
495 | 449 | ||
496 | spinlock_t spin_lock; | 450 | spinlock_t spin_lock; |
497 | struct tasklet_struct runq_tasklet; | ||
498 | u_int qfrozen; | 451 | u_int qfrozen; |
499 | pid_t dv_pid; | ||
500 | struct timer_list completeq_timer; | ||
501 | struct timer_list reset_timer; | 452 | struct timer_list reset_timer; |
502 | struct semaphore eh_sem; | 453 | struct semaphore eh_sem; |
503 | struct semaphore dv_sem; | ||
504 | struct semaphore dv_cmd_sem; /* XXX This needs to be in | ||
505 | * the target struct | ||
506 | */ | ||
507 | struct scsi_device *dv_scsi_dev; | ||
508 | struct Scsi_Host *host; /* pointer to scsi host */ | 454 | struct Scsi_Host *host; /* pointer to scsi host */ |
509 | #define AHC_LINUX_NOIRQ ((uint32_t)~0) | 455 | #define AHC_LINUX_NOIRQ ((uint32_t)~0) |
510 | uint32_t irq; /* IRQ for this adapter */ | 456 | uint32_t irq; /* IRQ for this adapter */ |
511 | uint32_t bios_address; | 457 | uint32_t bios_address; |
512 | uint32_t mem_busaddr; /* Mem Base Addr */ | 458 | uint32_t mem_busaddr; /* Mem Base Addr */ |
513 | uint64_t hw_dma_mask; | 459 | |
514 | ahc_linux_softc_flags flags; | 460 | #define AHC_UP_EH_SEMAPHORE 0x1 |
461 | uint32_t flags; | ||
515 | }; | 462 | }; |
516 | 463 | ||
517 | /************************** OS Utility Wrappers *******************************/ | 464 | /************************** OS Utility Wrappers *******************************/ |
@@ -600,7 +547,7 @@ ahc_insb(struct ahc_softc * ahc, long port, uint8_t *array, int count) | |||
600 | 547 | ||
601 | /**************************** Initialization **********************************/ | 548 | /**************************** Initialization **********************************/ |
602 | int ahc_linux_register_host(struct ahc_softc *, | 549 | int ahc_linux_register_host(struct ahc_softc *, |
603 | Scsi_Host_Template *); | 550 | struct scsi_host_template *); |
604 | 551 | ||
605 | uint64_t ahc_linux_get_memsize(void); | 552 | uint64_t ahc_linux_get_memsize(void); |
606 | 553 | ||
@@ -621,17 +568,6 @@ static __inline void ahc_lockinit(struct ahc_softc *); | |||
621 | static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags); | 568 | static __inline void ahc_lock(struct ahc_softc *, unsigned long *flags); |
622 | static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags); | 569 | static __inline void ahc_unlock(struct ahc_softc *, unsigned long *flags); |
623 | 570 | ||
624 | /* Lock acquisition and release of the above lock in midlayer entry points. */ | ||
625 | static __inline void ahc_midlayer_entrypoint_lock(struct ahc_softc *, | ||
626 | unsigned long *flags); | ||
627 | static __inline void ahc_midlayer_entrypoint_unlock(struct ahc_softc *, | ||
628 | unsigned long *flags); | ||
629 | |||
630 | /* Lock held during command compeletion to the upper layer */ | ||
631 | static __inline void ahc_done_lockinit(struct ahc_softc *); | ||
632 | static __inline void ahc_done_lock(struct ahc_softc *, unsigned long *flags); | ||
633 | static __inline void ahc_done_unlock(struct ahc_softc *, unsigned long *flags); | ||
634 | |||
635 | /* Lock held during ahc_list manipulation and ahc softc frees */ | 571 | /* Lock held during ahc_list manipulation and ahc softc frees */ |
636 | extern spinlock_t ahc_list_spinlock; | 572 | extern spinlock_t ahc_list_spinlock; |
637 | static __inline void ahc_list_lockinit(void); | 573 | static __inline void ahc_list_lockinit(void); |
@@ -657,57 +593,6 @@ ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) | |||
657 | } | 593 | } |
658 | 594 | ||
659 | static __inline void | 595 | static __inline void |
660 | ahc_midlayer_entrypoint_lock(struct ahc_softc *ahc, unsigned long *flags) | ||
661 | { | ||
662 | /* | ||
663 | * In 2.5.X and some 2.4.X versions, the midlayer takes our | ||
664 | * lock just before calling us, so we avoid locking again. | ||
665 | * For other kernel versions, the io_request_lock is taken | ||
666 | * just before our entry point is called. In this case, we | ||
667 | * trade the io_request_lock for our per-softc lock. | ||
668 | */ | ||
669 | #if AHC_SCSI_HAS_HOST_LOCK == 0 | ||
670 | spin_unlock(&io_request_lock); | ||
671 | spin_lock(&ahc->platform_data->spin_lock); | ||
672 | #endif | ||
673 | } | ||
674 | |||
675 | static __inline void | ||
676 | ahc_midlayer_entrypoint_unlock(struct ahc_softc *ahc, unsigned long *flags) | ||
677 | { | ||
678 | #if AHC_SCSI_HAS_HOST_LOCK == 0 | ||
679 | spin_unlock(&ahc->platform_data->spin_lock); | ||
680 | spin_lock(&io_request_lock); | ||
681 | #endif | ||
682 | } | ||
683 | |||
684 | static __inline void | ||
685 | ahc_done_lockinit(struct ahc_softc *ahc) | ||
686 | { | ||
687 | /* | ||
688 | * In 2.5.X, our own lock is held during completions. | ||
689 | * In previous versions, the io_request_lock is used. | ||
690 | * In either case, we can't initialize this lock again. | ||
691 | */ | ||
692 | } | ||
693 | |||
694 | static __inline void | ||
695 | ahc_done_lock(struct ahc_softc *ahc, unsigned long *flags) | ||
696 | { | ||
697 | #if AHC_SCSI_HAS_HOST_LOCK == 0 | ||
698 | spin_lock_irqsave(&io_request_lock, *flags); | ||
699 | #endif | ||
700 | } | ||
701 | |||
702 | static __inline void | ||
703 | ahc_done_unlock(struct ahc_softc *ahc, unsigned long *flags) | ||
704 | { | ||
705 | #if AHC_SCSI_HAS_HOST_LOCK == 0 | ||
706 | spin_unlock_irqrestore(&io_request_lock, *flags); | ||
707 | #endif | ||
708 | } | ||
709 | |||
710 | static __inline void | ||
711 | ahc_list_lockinit(void) | 596 | ahc_list_lockinit(void) |
712 | { | 597 | { |
713 | spin_lock_init(&ahc_list_spinlock); | 598 | spin_lock_init(&ahc_list_spinlock); |
@@ -773,12 +658,6 @@ typedef enum | |||
773 | } ahc_power_state; | 658 | } ahc_power_state; |
774 | 659 | ||
775 | /**************************** VL/EISA Routines ********************************/ | 660 | /**************************** VL/EISA Routines ********************************/ |
776 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) \ | ||
777 | && (defined(__i386__) || defined(__alpha__)) \ | ||
778 | && (!defined(CONFIG_EISA))) | ||
779 | #define CONFIG_EISA | ||
780 | #endif | ||
781 | |||
782 | #ifdef CONFIG_EISA | 661 | #ifdef CONFIG_EISA |
783 | extern uint32_t aic7xxx_probe_eisa_vl; | 662 | extern uint32_t aic7xxx_probe_eisa_vl; |
784 | int ahc_linux_eisa_init(void); | 663 | int ahc_linux_eisa_init(void); |
@@ -894,22 +773,18 @@ ahc_flush_device_writes(struct ahc_softc *ahc) | |||
894 | } | 773 | } |
895 | 774 | ||
896 | /**************************** Proc FS Support *********************************/ | 775 | /**************************** Proc FS Support *********************************/ |
897 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
898 | int ahc_linux_proc_info(char *, char **, off_t, int, int, int); | ||
899 | #else | ||
900 | int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, | 776 | int ahc_linux_proc_info(struct Scsi_Host *, char *, char **, |
901 | off_t, int, int); | 777 | off_t, int, int); |
902 | #endif | ||
903 | 778 | ||
904 | /*************************** Domain Validation ********************************/ | 779 | /*************************** Domain Validation ********************************/ |
905 | /*********************** Transaction Access Wrappers *************************/ | 780 | /*********************** Transaction Access Wrappers *************************/ |
906 | static __inline void ahc_cmd_set_transaction_status(Scsi_Cmnd *, uint32_t); | 781 | static __inline void ahc_cmd_set_transaction_status(struct scsi_cmnd *, uint32_t); |
907 | static __inline void ahc_set_transaction_status(struct scb *, uint32_t); | 782 | static __inline void ahc_set_transaction_status(struct scb *, uint32_t); |
908 | static __inline void ahc_cmd_set_scsi_status(Scsi_Cmnd *, uint32_t); | 783 | static __inline void ahc_cmd_set_scsi_status(struct scsi_cmnd *, uint32_t); |
909 | static __inline void ahc_set_scsi_status(struct scb *, uint32_t); | 784 | static __inline void ahc_set_scsi_status(struct scb *, uint32_t); |
910 | static __inline uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd); | 785 | static __inline uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd); |
911 | static __inline uint32_t ahc_get_transaction_status(struct scb *); | 786 | static __inline uint32_t ahc_get_transaction_status(struct scb *); |
912 | static __inline uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd); | 787 | static __inline uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd); |
913 | static __inline uint32_t ahc_get_scsi_status(struct scb *); | 788 | static __inline uint32_t ahc_get_scsi_status(struct scb *); |
914 | static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); | 789 | static __inline void ahc_set_transaction_tag(struct scb *, int, u_int); |
915 | static __inline u_long ahc_get_transfer_length(struct scb *); | 790 | static __inline u_long ahc_get_transfer_length(struct scb *); |
@@ -928,7 +803,7 @@ static __inline void ahc_platform_scb_free(struct ahc_softc *ahc, | |||
928 | static __inline void ahc_freeze_scb(struct scb *scb); | 803 | static __inline void ahc_freeze_scb(struct scb *scb); |
929 | 804 | ||
930 | static __inline | 805 | static __inline |
931 | void ahc_cmd_set_transaction_status(Scsi_Cmnd *cmd, uint32_t status) | 806 | void ahc_cmd_set_transaction_status(struct scsi_cmnd *cmd, uint32_t status) |
932 | { | 807 | { |
933 | cmd->result &= ~(CAM_STATUS_MASK << 16); | 808 | cmd->result &= ~(CAM_STATUS_MASK << 16); |
934 | cmd->result |= status << 16; | 809 | cmd->result |= status << 16; |
@@ -941,7 +816,7 @@ void ahc_set_transaction_status(struct scb *scb, uint32_t status) | |||
941 | } | 816 | } |
942 | 817 | ||
943 | static __inline | 818 | static __inline |
944 | void ahc_cmd_set_scsi_status(Scsi_Cmnd *cmd, uint32_t status) | 819 | void ahc_cmd_set_scsi_status(struct scsi_cmnd *cmd, uint32_t status) |
945 | { | 820 | { |
946 | cmd->result &= ~0xFFFF; | 821 | cmd->result &= ~0xFFFF; |
947 | cmd->result |= status; | 822 | cmd->result |= status; |
@@ -954,7 +829,7 @@ void ahc_set_scsi_status(struct scb *scb, uint32_t status) | |||
954 | } | 829 | } |
955 | 830 | ||
956 | static __inline | 831 | static __inline |
957 | uint32_t ahc_cmd_get_transaction_status(Scsi_Cmnd *cmd) | 832 | uint32_t ahc_cmd_get_transaction_status(struct scsi_cmnd *cmd) |
958 | { | 833 | { |
959 | return ((cmd->result >> 16) & CAM_STATUS_MASK); | 834 | return ((cmd->result >> 16) & CAM_STATUS_MASK); |
960 | } | 835 | } |
@@ -966,7 +841,7 @@ uint32_t ahc_get_transaction_status(struct scb *scb) | |||
966 | } | 841 | } |
967 | 842 | ||
968 | static __inline | 843 | static __inline |
969 | uint32_t ahc_cmd_get_scsi_status(Scsi_Cmnd *cmd) | 844 | uint32_t ahc_cmd_get_scsi_status(struct scsi_cmnd *cmd) |
970 | { | 845 | { |
971 | return (cmd->result & 0xFFFF); | 846 | return (cmd->result & 0xFFFF); |
972 | } | 847 | } |
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c index 6f6674aa31ef..2a0ebce83e7a 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm_pci.c | |||
@@ -221,13 +221,11 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
221 | && ahc_linux_get_memsize() > 0x80000000 | 221 | && ahc_linux_get_memsize() > 0x80000000 |
222 | && pci_set_dma_mask(pdev, mask_39bit) == 0) { | 222 | && pci_set_dma_mask(pdev, mask_39bit) == 0) { |
223 | ahc->flags |= AHC_39BIT_ADDRESSING; | 223 | ahc->flags |= AHC_39BIT_ADDRESSING; |
224 | ahc->platform_data->hw_dma_mask = mask_39bit; | ||
225 | } else { | 224 | } else { |
226 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 225 | if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
227 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); | 226 | printk(KERN_WARNING "aic7xxx: No suitable DMA available.\n"); |
228 | return (-ENODEV); | 227 | return (-ENODEV); |
229 | } | 228 | } |
230 | ahc->platform_data->hw_dma_mask = DMA_32BIT_MASK; | ||
231 | } | 229 | } |
232 | ahc->dev_softc = pci; | 230 | ahc->dev_softc = pci; |
233 | error = ahc_pci_config(ahc, entry); | 231 | error = ahc_pci_config(ahc, entry); |
@@ -236,15 +234,8 @@ ahc_linux_pci_dev_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
236 | return (-error); | 234 | return (-error); |
237 | } | 235 | } |
238 | pci_set_drvdata(pdev, ahc); | 236 | pci_set_drvdata(pdev, ahc); |
239 | if (aic7xxx_detect_complete) { | 237 | if (aic7xxx_detect_complete) |
240 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) | ||
241 | ahc_linux_register_host(ahc, &aic7xxx_driver_template); | 238 | ahc_linux_register_host(ahc, &aic7xxx_driver_template); |
242 | #else | ||
243 | printf("aic7xxx: ignoring PCI device found after " | ||
244 | "initialization\n"); | ||
245 | return (-ENODEV); | ||
246 | #endif | ||
247 | } | ||
248 | return (0); | 239 | return (0); |
249 | } | 240 | } |
250 | 241 | ||
diff --git a/drivers/scsi/aic7xxx/aic7xxx_proc.c b/drivers/scsi/aic7xxx/aic7xxx_proc.c index 85e80eecc9d0..5fece859fbd9 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_proc.c +++ b/drivers/scsi/aic7xxx/aic7xxx_proc.c | |||
@@ -289,13 +289,8 @@ done: | |||
289 | * Return information to handle /proc support for the driver. | 289 | * Return information to handle /proc support for the driver. |
290 | */ | 290 | */ |
291 | int | 291 | int |
292 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
293 | ahc_linux_proc_info(char *buffer, char **start, off_t offset, | ||
294 | int length, int hostno, int inout) | ||
295 | #else | ||
296 | ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | 292 | ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, |
297 | off_t offset, int length, int inout) | 293 | off_t offset, int length, int inout) |
298 | #endif | ||
299 | { | 294 | { |
300 | struct ahc_softc *ahc; | 295 | struct ahc_softc *ahc; |
301 | struct info_str info; | 296 | struct info_str info; |
@@ -307,15 +302,7 @@ ahc_linux_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | |||
307 | 302 | ||
308 | retval = -EINVAL; | 303 | retval = -EINVAL; |
309 | ahc_list_lock(&s); | 304 | ahc_list_lock(&s); |
310 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) | ||
311 | TAILQ_FOREACH(ahc, &ahc_tailq, links) { | ||
312 | if (ahc->platform_data->host->host_no == hostno) | ||
313 | break; | ||
314 | } | ||
315 | #else | ||
316 | ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata); | 305 | ahc = ahc_find_softc(*(struct ahc_softc **)shost->hostdata); |
317 | #endif | ||
318 | |||
319 | if (ahc == NULL) | 306 | if (ahc == NULL) |
320 | goto done; | 307 | goto done; |
321 | 308 | ||
diff --git a/drivers/scsi/aic7xxx/aiclib.c b/drivers/scsi/aic7xxx/aiclib.c index 79bfd9efd8ed..7c5a6db0e672 100644 --- a/drivers/scsi/aic7xxx/aiclib.c +++ b/drivers/scsi/aic7xxx/aiclib.c | |||
@@ -35,7 +35,6 @@ | |||
35 | #include <linux/version.h> | 35 | #include <linux/version.h> |
36 | 36 | ||
37 | /* Core SCSI definitions */ | 37 | /* Core SCSI definitions */ |
38 | #include "scsi.h" | ||
39 | #include <scsi/scsi_host.h> | 38 | #include <scsi/scsi_host.h> |
40 | #include "aiclib.h" | 39 | #include "aiclib.h" |
41 | #include "cam.h" | 40 | #include "cam.h" |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 0b5d3a5b7eda..ee9b96da841e 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1253,11 +1253,11 @@ void __sata_phy_reset(struct ata_port *ap) | |||
1253 | unsigned long timeout = jiffies + (HZ * 5); | 1253 | unsigned long timeout = jiffies + (HZ * 5); |
1254 | 1254 | ||
1255 | if (ap->flags & ATA_FLAG_SATA_RESET) { | 1255 | if (ap->flags & ATA_FLAG_SATA_RESET) { |
1256 | scr_write(ap, SCR_CONTROL, 0x301); /* issue phy wake/reset */ | 1256 | /* issue phy wake/reset */ |
1257 | scr_read(ap, SCR_STATUS); /* dummy read; flush */ | 1257 | scr_write_flush(ap, SCR_CONTROL, 0x301); |
1258 | udelay(400); /* FIXME: a guess */ | 1258 | udelay(400); /* FIXME: a guess */ |
1259 | } | 1259 | } |
1260 | scr_write(ap, SCR_CONTROL, 0x300); /* issue phy wake/clear reset */ | 1260 | scr_write_flush(ap, SCR_CONTROL, 0x300); /* phy wake/clear reset */ |
1261 | 1261 | ||
1262 | /* wait for phy to become ready, if necessary */ | 1262 | /* wait for phy to become ready, if necessary */ |
1263 | do { | 1263 | do { |
@@ -2539,7 +2539,7 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
2539 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); | 2539 | ata_sg_init_one(qc, cmd->sense_buffer, sizeof(cmd->sense_buffer)); |
2540 | qc->dma_dir = DMA_FROM_DEVICE; | 2540 | qc->dma_dir = DMA_FROM_DEVICE; |
2541 | 2541 | ||
2542 | memset(&qc->cdb, 0, sizeof(ap->cdb_len)); | 2542 | memset(&qc->cdb, 0, ap->cdb_len); |
2543 | qc->cdb[0] = REQUEST_SENSE; | 2543 | qc->cdb[0] = REQUEST_SENSE; |
2544 | qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; | 2544 | qc->cdb[4] = SCSI_SENSE_BUFFERSIZE; |
2545 | 2545 | ||
@@ -2811,6 +2811,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
2811 | 2811 | ||
2812 | /* call completion callback */ | 2812 | /* call completion callback */ |
2813 | rc = qc->complete_fn(qc, drv_stat); | 2813 | rc = qc->complete_fn(qc, drv_stat); |
2814 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | ||
2814 | 2815 | ||
2815 | /* if callback indicates not to complete command (non-zero), | 2816 | /* if callback indicates not to complete command (non-zero), |
2816 | * return immediately | 2817 | * return immediately |
@@ -3229,7 +3230,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
3229 | struct ata_queued_cmd *qc; | 3230 | struct ata_queued_cmd *qc; |
3230 | 3231 | ||
3231 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3232 | qc = ata_qc_from_tag(ap, ap->active_tag); |
3232 | if (qc && (!(qc->tf.ctl & ATA_NIEN))) | 3233 | if (qc && (!(qc->tf.ctl & ATA_NIEN)) && |
3234 | (qc->flags & ATA_QCFLAG_ACTIVE)) | ||
3233 | handled |= ata_host_intr(ap, qc); | 3235 | handled |= ata_host_intr(ap, qc); |
3234 | } | 3236 | } |
3235 | } | 3237 | } |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 4c96df060c3b..416ba67ba9ee 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -347,7 +347,10 @@ int ata_scsi_slave_config(struct scsi_device *sdev) | |||
347 | */ | 347 | */ |
348 | if ((dev->flags & ATA_DFLAG_LBA48) && | 348 | if ((dev->flags & ATA_DFLAG_LBA48) && |
349 | ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { | 349 | ((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { |
350 | sdev->host->max_sectors = 2048; | 350 | /* |
351 | * do not overwrite sdev->host->max_sectors, since | ||
352 | * other drives on this host may not support LBA48 | ||
353 | */ | ||
351 | blk_queue_max_sectors(sdev->request_queue, 2048); | 354 | blk_queue_max_sectors(sdev->request_queue, 2048); |
352 | } | 355 | } |
353 | } | 356 | } |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 2240a0cde583..9bc1f153f7ea 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -300,7 +300,7 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | |||
300 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 300 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; |
301 | } | 301 | } |
302 | 302 | ||
303 | static struct fc_function_template qla2xxx_transport_functions = { | 303 | struct fc_function_template qla2xxx_transport_functions = { |
304 | 304 | ||
305 | .show_host_node_name = 1, | 305 | .show_host_node_name = 1, |
306 | .show_host_port_name = 1, | 306 | .show_host_port_name = 1, |
@@ -322,12 +322,6 @@ static struct fc_function_template qla2xxx_transport_functions = { | |||
322 | 322 | ||
323 | }; | 323 | }; |
324 | 324 | ||
325 | struct scsi_transport_template * | ||
326 | qla2x00_alloc_transport_tmpl(void) | ||
327 | { | ||
328 | return (fc_attach_transport(&qla2xxx_transport_functions)); | ||
329 | } | ||
330 | |||
331 | void | 325 | void |
332 | qla2x00_init_host_attr(scsi_qla_host_t *ha) | 326 | qla2x00_init_host_attr(scsi_qla_host_t *ha) |
333 | { | 327 | { |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index e4bfe4d5bbe4..2efec6c24d60 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -24,7 +24,6 @@ | |||
24 | #define __QLA_GBL_H | 24 | #define __QLA_GBL_H |
25 | 25 | ||
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <scsi/scsi_transport.h> | ||
28 | 27 | ||
29 | extern void qla2x00_remove_one(struct pci_dev *); | 28 | extern void qla2x00_remove_one(struct pci_dev *); |
30 | extern int qla2x00_probe_one(struct pci_dev *, struct qla_board_info *); | 29 | extern int qla2x00_probe_one(struct pci_dev *, struct qla_board_info *); |
@@ -248,9 +247,10 @@ extern void qla2x00_cancel_io_descriptors(scsi_qla_host_t *); | |||
248 | /* | 247 | /* |
249 | * Global Function Prototypes in qla_attr.c source file. | 248 | * Global Function Prototypes in qla_attr.c source file. |
250 | */ | 249 | */ |
250 | struct fc_function_template; | ||
251 | extern struct fc_function_template qla2xxx_transport_functions; | ||
251 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | 252 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); |
252 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); | 253 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); |
253 | extern struct scsi_transport_template *qla2x00_alloc_transport_tmpl(void); | ||
254 | extern void qla2x00_init_host_attr(scsi_qla_host_t *); | 254 | extern void qla2x00_init_host_attr(scsi_qla_host_t *); |
255 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); | 255 | extern void qla2x00_alloc_sysfs_attr(scsi_qla_host_t *); |
256 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); | 256 | extern void qla2x00_free_sysfs_attr(scsi_qla_host_t *); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 84db911318c6..579448222d69 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -2350,7 +2350,8 @@ qla2x00_module_init(void) | |||
2350 | #if DEBUG_QLA2100 | 2350 | #if DEBUG_QLA2100 |
2351 | strcat(qla2x00_version_str, "-debug"); | 2351 | strcat(qla2x00_version_str, "-debug"); |
2352 | #endif | 2352 | #endif |
2353 | qla2xxx_transport_template = qla2x00_alloc_transport_tmpl(); | 2353 | qla2xxx_transport_template = |
2354 | fc_attach_transport(&qla2xxx_transport_functions); | ||
2354 | if (!qla2xxx_transport_template) | 2355 | if (!qla2xxx_transport_template) |
2355 | return -ENODEV; | 2356 | return -ENODEV; |
2356 | 2357 | ||
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 8d1a5d25c053..05075bd3a893 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -395,7 +395,7 @@ static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *e | |||
395 | 395 | ||
396 | /* Clear a magic bit in SCR1 according to Darwin, those help | 396 | /* Clear a magic bit in SCR1 according to Darwin, those help |
397 | * some funky seagate drives (though so far, those were already | 397 | * some funky seagate drives (though so far, those were already |
398 | * set by the firmware on the machines I had access to | 398 | * set by the firmware on the machines I had access to) |
399 | */ | 399 | */ |
400 | writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000, | 400 | writel(readl(mmio_base + K2_SATA_SICR1_OFFSET) & ~0x00040000, |
401 | mmio_base + K2_SATA_SICR1_OFFSET); | 401 | mmio_base + K2_SATA_SICR1_OFFSET); |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 05d2bd075fd4..184bcaeaf812 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -542,7 +542,7 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd) | |||
542 | * that the device is no longer present */ | 542 | * that the device is no longer present */ |
543 | cmd->result = DID_NO_CONNECT << 16; | 543 | cmd->result = DID_NO_CONNECT << 16; |
544 | atomic_inc(&cmd->device->iorequest_cnt); | 544 | atomic_inc(&cmd->device->iorequest_cnt); |
545 | scsi_done(cmd); | 545 | __scsi_done(cmd); |
546 | /* return 0 (because the command has been processed) */ | 546 | /* return 0 (because the command has been processed) */ |
547 | goto out; | 547 | goto out; |
548 | } | 548 | } |
diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 303d7656f710..67c6cc40ce16 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/blkdev.h> | ||
25 | #include <asm/semaphore.h> | 26 | #include <asm/semaphore.h> |
26 | #include <scsi/scsi.h> | 27 | #include <scsi/scsi.h> |
27 | #include "scsi_priv.h" | 28 | #include "scsi_priv.h" |
@@ -34,13 +35,18 @@ | |||
34 | 35 | ||
35 | #define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) | 36 | #define SPI_PRINTK(x, l, f, a...) dev_printk(l, &(x)->dev, f , ##a) |
36 | 37 | ||
37 | #define SPI_NUM_ATTRS 10 /* increase this if you add attributes */ | 38 | #define SPI_NUM_ATTRS 13 /* increase this if you add attributes */ |
38 | #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always | 39 | #define SPI_OTHER_ATTRS 1 /* Increase this if you add "always |
39 | * on" attributes */ | 40 | * on" attributes */ |
40 | #define SPI_HOST_ATTRS 1 | 41 | #define SPI_HOST_ATTRS 1 |
41 | 42 | ||
42 | #define SPI_MAX_ECHO_BUFFER_SIZE 4096 | 43 | #define SPI_MAX_ECHO_BUFFER_SIZE 4096 |
43 | 44 | ||
45 | #define DV_LOOPS 3 | ||
46 | #define DV_TIMEOUT (10*HZ) | ||
47 | #define DV_RETRIES 3 /* should only need at most | ||
48 | * two cc/ua clears */ | ||
49 | |||
44 | /* Private data accessors (keep these out of the header file) */ | 50 | /* Private data accessors (keep these out of the header file) */ |
45 | #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) | 51 | #define spi_dv_pending(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_pending) |
46 | #define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem) | 52 | #define spi_dv_sem(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dv_sem) |
@@ -100,6 +106,29 @@ static int sprint_frac(char *dest, int value, int denom) | |||
100 | return result; | 106 | return result; |
101 | } | 107 | } |
102 | 108 | ||
109 | /* Modification of scsi_wait_req that will clear UNIT ATTENTION conditions | ||
110 | * resulting from (likely) bus and device resets */ | ||
111 | static void spi_wait_req(struct scsi_request *sreq, const void *cmd, | ||
112 | void *buffer, unsigned bufflen) | ||
113 | { | ||
114 | int i; | ||
115 | |||
116 | for(i = 0; i < DV_RETRIES; i++) { | ||
117 | sreq->sr_request->flags |= REQ_FAILFAST; | ||
118 | |||
119 | scsi_wait_req(sreq, cmd, buffer, bufflen, | ||
120 | DV_TIMEOUT, /* retries */ 1); | ||
121 | if (sreq->sr_result & DRIVER_SENSE) { | ||
122 | struct scsi_sense_hdr sshdr; | ||
123 | |||
124 | if (scsi_request_normalize_sense(sreq, &sshdr) | ||
125 | && sshdr.sense_key == UNIT_ATTENTION) | ||
126 | continue; | ||
127 | } | ||
128 | break; | ||
129 | } | ||
130 | } | ||
131 | |||
103 | static struct { | 132 | static struct { |
104 | enum spi_signal_type value; | 133 | enum spi_signal_type value; |
105 | char *name; | 134 | char *name; |
@@ -190,8 +219,11 @@ static int spi_setup_transport_attrs(struct device *dev) | |||
190 | struct scsi_target *starget = to_scsi_target(dev); | 219 | struct scsi_target *starget = to_scsi_target(dev); |
191 | 220 | ||
192 | spi_period(starget) = -1; /* illegal value */ | 221 | spi_period(starget) = -1; /* illegal value */ |
222 | spi_min_period(starget) = 0; | ||
193 | spi_offset(starget) = 0; /* async */ | 223 | spi_offset(starget) = 0; /* async */ |
224 | spi_max_offset(starget) = 255; | ||
194 | spi_width(starget) = 0; /* narrow */ | 225 | spi_width(starget) = 0; /* narrow */ |
226 | spi_max_width(starget) = 1; | ||
195 | spi_iu(starget) = 0; /* no IU */ | 227 | spi_iu(starget) = 0; /* no IU */ |
196 | spi_dt(starget) = 0; /* ST */ | 228 | spi_dt(starget) = 0; /* ST */ |
197 | spi_qas(starget) = 0; | 229 | spi_qas(starget) = 0; |
@@ -206,6 +238,34 @@ static int spi_setup_transport_attrs(struct device *dev) | |||
206 | return 0; | 238 | return 0; |
207 | } | 239 | } |
208 | 240 | ||
241 | #define spi_transport_show_simple(field, format_string) \ | ||
242 | \ | ||
243 | static ssize_t \ | ||
244 | show_spi_transport_##field(struct class_device *cdev, char *buf) \ | ||
245 | { \ | ||
246 | struct scsi_target *starget = transport_class_to_starget(cdev); \ | ||
247 | struct spi_transport_attrs *tp; \ | ||
248 | \ | ||
249 | tp = (struct spi_transport_attrs *)&starget->starget_data; \ | ||
250 | return snprintf(buf, 20, format_string, tp->field); \ | ||
251 | } | ||
252 | |||
253 | #define spi_transport_store_simple(field, format_string) \ | ||
254 | \ | ||
255 | static ssize_t \ | ||
256 | store_spi_transport_##field(struct class_device *cdev, const char *buf, \ | ||
257 | size_t count) \ | ||
258 | { \ | ||
259 | int val; \ | ||
260 | struct scsi_target *starget = transport_class_to_starget(cdev); \ | ||
261 | struct spi_transport_attrs *tp; \ | ||
262 | \ | ||
263 | tp = (struct spi_transport_attrs *)&starget->starget_data; \ | ||
264 | val = simple_strtoul(buf, NULL, 0); \ | ||
265 | tp->field = val; \ | ||
266 | return count; \ | ||
267 | } | ||
268 | |||
209 | #define spi_transport_show_function(field, format_string) \ | 269 | #define spi_transport_show_function(field, format_string) \ |
210 | \ | 270 | \ |
211 | static ssize_t \ | 271 | static ssize_t \ |
@@ -232,6 +292,25 @@ store_spi_transport_##field(struct class_device *cdev, const char *buf, \ | |||
232 | struct spi_internal *i = to_spi_internal(shost->transportt); \ | 292 | struct spi_internal *i = to_spi_internal(shost->transportt); \ |
233 | \ | 293 | \ |
234 | val = simple_strtoul(buf, NULL, 0); \ | 294 | val = simple_strtoul(buf, NULL, 0); \ |
295 | i->f->set_##field(starget, val); \ | ||
296 | return count; \ | ||
297 | } | ||
298 | |||
299 | #define spi_transport_store_max(field, format_string) \ | ||
300 | static ssize_t \ | ||
301 | store_spi_transport_##field(struct class_device *cdev, const char *buf, \ | ||
302 | size_t count) \ | ||
303 | { \ | ||
304 | int val; \ | ||
305 | struct scsi_target *starget = transport_class_to_starget(cdev); \ | ||
306 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); \ | ||
307 | struct spi_internal *i = to_spi_internal(shost->transportt); \ | ||
308 | struct spi_transport_attrs *tp \ | ||
309 | = (struct spi_transport_attrs *)&starget->starget_data; \ | ||
310 | \ | ||
311 | val = simple_strtoul(buf, NULL, 0); \ | ||
312 | if (val > tp->max_##field) \ | ||
313 | val = tp->max_##field; \ | ||
235 | i->f->set_##field(starget, val); \ | 314 | i->f->set_##field(starget, val); \ |
236 | return count; \ | 315 | return count; \ |
237 | } | 316 | } |
@@ -243,9 +322,24 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ | |||
243 | show_spi_transport_##field, \ | 322 | show_spi_transport_##field, \ |
244 | store_spi_transport_##field); | 323 | store_spi_transport_##field); |
245 | 324 | ||
325 | #define spi_transport_simple_attr(field, format_string) \ | ||
326 | spi_transport_show_simple(field, format_string) \ | ||
327 | spi_transport_store_simple(field, format_string) \ | ||
328 | static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ | ||
329 | show_spi_transport_##field, \ | ||
330 | store_spi_transport_##field); | ||
331 | |||
332 | #define spi_transport_max_attr(field, format_string) \ | ||
333 | spi_transport_show_function(field, format_string) \ | ||
334 | spi_transport_store_max(field, format_string) \ | ||
335 | spi_transport_simple_attr(max_##field, format_string) \ | ||
336 | static CLASS_DEVICE_ATTR(field, S_IRUGO | S_IWUSR, \ | ||
337 | show_spi_transport_##field, \ | ||
338 | store_spi_transport_##field); | ||
339 | |||
246 | /* The Parallel SCSI Tranport Attributes: */ | 340 | /* The Parallel SCSI Tranport Attributes: */ |
247 | spi_transport_rd_attr(offset, "%d\n"); | 341 | spi_transport_max_attr(offset, "%d\n"); |
248 | spi_transport_rd_attr(width, "%d\n"); | 342 | spi_transport_max_attr(width, "%d\n"); |
249 | spi_transport_rd_attr(iu, "%d\n"); | 343 | spi_transport_rd_attr(iu, "%d\n"); |
250 | spi_transport_rd_attr(dt, "%d\n"); | 344 | spi_transport_rd_attr(dt, "%d\n"); |
251 | spi_transport_rd_attr(qas, "%d\n"); | 345 | spi_transport_rd_attr(qas, "%d\n"); |
@@ -271,26 +365,18 @@ static CLASS_DEVICE_ATTR(revalidate, S_IWUSR, NULL, store_spi_revalidate); | |||
271 | 365 | ||
272 | /* Translate the period into ns according to the current spec | 366 | /* Translate the period into ns according to the current spec |
273 | * for SDTR/PPR messages */ | 367 | * for SDTR/PPR messages */ |
274 | static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) | 368 | static ssize_t |
275 | 369 | show_spi_transport_period_helper(struct class_device *cdev, char *buf, | |
370 | int period) | ||
276 | { | 371 | { |
277 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
278 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
279 | struct spi_transport_attrs *tp; | ||
280 | int len, picosec; | 372 | int len, picosec; |
281 | struct spi_internal *i = to_spi_internal(shost->transportt); | ||
282 | |||
283 | tp = (struct spi_transport_attrs *)&starget->starget_data; | ||
284 | 373 | ||
285 | if (i->f->get_period) | 374 | if (period < 0 || period > 0xff) { |
286 | i->f->get_period(starget); | ||
287 | |||
288 | if (tp->period < 0 || tp->period > 0xff) { | ||
289 | picosec = -1; | 375 | picosec = -1; |
290 | } else if (tp->period <= SPI_STATIC_PPR) { | 376 | } else if (period <= SPI_STATIC_PPR) { |
291 | picosec = ppr_to_ps[tp->period]; | 377 | picosec = ppr_to_ps[period]; |
292 | } else { | 378 | } else { |
293 | picosec = tp->period * 4000; | 379 | picosec = period * 4000; |
294 | } | 380 | } |
295 | 381 | ||
296 | if (picosec == -1) { | 382 | if (picosec == -1) { |
@@ -305,12 +391,9 @@ static ssize_t show_spi_transport_period(struct class_device *cdev, char *buf) | |||
305 | } | 391 | } |
306 | 392 | ||
307 | static ssize_t | 393 | static ssize_t |
308 | store_spi_transport_period(struct class_device *cdev, const char *buf, | 394 | store_spi_transport_period_helper(struct class_device *cdev, const char *buf, |
309 | size_t count) | 395 | size_t count, int *periodp) |
310 | { | 396 | { |
311 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
312 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
313 | struct spi_internal *i = to_spi_internal(shost->transportt); | ||
314 | int j, picosec, period = -1; | 397 | int j, picosec, period = -1; |
315 | char *endp; | 398 | char *endp; |
316 | 399 | ||
@@ -339,15 +422,79 @@ store_spi_transport_period(struct class_device *cdev, const char *buf, | |||
339 | if (period > 0xff) | 422 | if (period > 0xff) |
340 | period = 0xff; | 423 | period = 0xff; |
341 | 424 | ||
342 | i->f->set_period(starget, period); | 425 | *periodp = period; |
343 | 426 | ||
344 | return count; | 427 | return count; |
345 | } | 428 | } |
346 | 429 | ||
430 | static ssize_t | ||
431 | show_spi_transport_period(struct class_device *cdev, char *buf) | ||
432 | { | ||
433 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
434 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
435 | struct spi_internal *i = to_spi_internal(shost->transportt); | ||
436 | struct spi_transport_attrs *tp = | ||
437 | (struct spi_transport_attrs *)&starget->starget_data; | ||
438 | |||
439 | if (i->f->get_period) | ||
440 | i->f->get_period(starget); | ||
441 | |||
442 | return show_spi_transport_period_helper(cdev, buf, tp->period); | ||
443 | } | ||
444 | |||
445 | static ssize_t | ||
446 | store_spi_transport_period(struct class_device *cdev, const char *buf, | ||
447 | size_t count) | ||
448 | { | ||
449 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
450 | struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); | ||
451 | struct spi_internal *i = to_spi_internal(shost->transportt); | ||
452 | struct spi_transport_attrs *tp = | ||
453 | (struct spi_transport_attrs *)&starget->starget_data; | ||
454 | int period, retval; | ||
455 | |||
456 | retval = store_spi_transport_period_helper(cdev, buf, count, &period); | ||
457 | |||
458 | if (period < tp->min_period) | ||
459 | period = tp->min_period; | ||
460 | |||
461 | i->f->set_period(starget, period); | ||
462 | |||
463 | return retval; | ||
464 | } | ||
465 | |||
347 | static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, | 466 | static CLASS_DEVICE_ATTR(period, S_IRUGO | S_IWUSR, |
348 | show_spi_transport_period, | 467 | show_spi_transport_period, |
349 | store_spi_transport_period); | 468 | store_spi_transport_period); |
350 | 469 | ||
470 | static ssize_t | ||
471 | show_spi_transport_min_period(struct class_device *cdev, char *buf) | ||
472 | { | ||
473 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
474 | struct spi_transport_attrs *tp = | ||
475 | (struct spi_transport_attrs *)&starget->starget_data; | ||
476 | |||
477 | return show_spi_transport_period_helper(cdev, buf, tp->min_period); | ||
478 | } | ||
479 | |||
480 | static ssize_t | ||
481 | store_spi_transport_min_period(struct class_device *cdev, const char *buf, | ||
482 | size_t count) | ||
483 | { | ||
484 | struct scsi_target *starget = transport_class_to_starget(cdev); | ||
485 | struct spi_transport_attrs *tp = | ||
486 | (struct spi_transport_attrs *)&starget->starget_data; | ||
487 | |||
488 | return store_spi_transport_period_helper(cdev, buf, count, | ||
489 | &tp->min_period); | ||
490 | } | ||
491 | |||
492 | |||
493 | static CLASS_DEVICE_ATTR(min_period, S_IRUGO | S_IWUSR, | ||
494 | show_spi_transport_min_period, | ||
495 | store_spi_transport_min_period); | ||
496 | |||
497 | |||
351 | static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf) | 498 | static ssize_t show_spi_host_signalling(struct class_device *cdev, char *buf) |
352 | { | 499 | { |
353 | struct Scsi_Host *shost = transport_class_to_shost(cdev); | 500 | struct Scsi_Host *shost = transport_class_to_shost(cdev); |
@@ -378,11 +525,6 @@ static CLASS_DEVICE_ATTR(signalling, S_IRUGO | S_IWUSR, | |||
378 | if(i->f->set_##x) \ | 525 | if(i->f->set_##x) \ |
379 | i->f->set_##x(sdev->sdev_target, y) | 526 | i->f->set_##x(sdev->sdev_target, y) |
380 | 527 | ||
381 | #define DV_LOOPS 3 | ||
382 | #define DV_TIMEOUT (10*HZ) | ||
383 | #define DV_RETRIES 3 /* should only need at most | ||
384 | * two cc/ua clears */ | ||
385 | |||
386 | enum spi_compare_returns { | 528 | enum spi_compare_returns { |
387 | SPI_COMPARE_SUCCESS, | 529 | SPI_COMPARE_SUCCESS, |
388 | SPI_COMPARE_FAILURE, | 530 | SPI_COMPARE_FAILURE, |
@@ -446,8 +588,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, | |||
446 | for (r = 0; r < retries; r++) { | 588 | for (r = 0; r < retries; r++) { |
447 | sreq->sr_cmd_len = 0; /* wait_req to fill in */ | 589 | sreq->sr_cmd_len = 0; /* wait_req to fill in */ |
448 | sreq->sr_data_direction = DMA_TO_DEVICE; | 590 | sreq->sr_data_direction = DMA_TO_DEVICE; |
449 | scsi_wait_req(sreq, spi_write_buffer, buffer, len, | 591 | spi_wait_req(sreq, spi_write_buffer, buffer, len); |
450 | DV_TIMEOUT, DV_RETRIES); | ||
451 | if(sreq->sr_result || !scsi_device_online(sdev)) { | 592 | if(sreq->sr_result || !scsi_device_online(sdev)) { |
452 | struct scsi_sense_hdr sshdr; | 593 | struct scsi_sense_hdr sshdr; |
453 | 594 | ||
@@ -471,8 +612,7 @@ spi_dv_device_echo_buffer(struct scsi_request *sreq, u8 *buffer, | |||
471 | memset(ptr, 0, len); | 612 | memset(ptr, 0, len); |
472 | sreq->sr_cmd_len = 0; /* wait_req to fill in */ | 613 | sreq->sr_cmd_len = 0; /* wait_req to fill in */ |
473 | sreq->sr_data_direction = DMA_FROM_DEVICE; | 614 | sreq->sr_data_direction = DMA_FROM_DEVICE; |
474 | scsi_wait_req(sreq, spi_read_buffer, ptr, len, | 615 | spi_wait_req(sreq, spi_read_buffer, ptr, len); |
475 | DV_TIMEOUT, DV_RETRIES); | ||
476 | scsi_device_set_state(sdev, SDEV_QUIESCE); | 616 | scsi_device_set_state(sdev, SDEV_QUIESCE); |
477 | 617 | ||
478 | if (memcmp(buffer, ptr, len) != 0) | 618 | if (memcmp(buffer, ptr, len) != 0) |
@@ -500,8 +640,7 @@ spi_dv_device_compare_inquiry(struct scsi_request *sreq, u8 *buffer, | |||
500 | 640 | ||
501 | memset(ptr, 0, len); | 641 | memset(ptr, 0, len); |
502 | 642 | ||
503 | scsi_wait_req(sreq, spi_inquiry, ptr, len, | 643 | spi_wait_req(sreq, spi_inquiry, ptr, len); |
504 | DV_TIMEOUT, DV_RETRIES); | ||
505 | 644 | ||
506 | if(sreq->sr_result || !scsi_device_online(sdev)) { | 645 | if(sreq->sr_result || !scsi_device_online(sdev)) { |
507 | scsi_device_set_state(sdev, SDEV_QUIESCE); | 646 | scsi_device_set_state(sdev, SDEV_QUIESCE); |
@@ -593,8 +732,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer) | |||
593 | * (reservation conflict, device not ready, etc) just | 732 | * (reservation conflict, device not ready, etc) just |
594 | * skip the write tests */ | 733 | * skip the write tests */ |
595 | for (l = 0; ; l++) { | 734 | for (l = 0; ; l++) { |
596 | scsi_wait_req(sreq, spi_test_unit_ready, NULL, 0, | 735 | spi_wait_req(sreq, spi_test_unit_ready, NULL, 0); |
597 | DV_TIMEOUT, DV_RETRIES); | ||
598 | 736 | ||
599 | if(sreq->sr_result) { | 737 | if(sreq->sr_result) { |
600 | if(l >= 3) | 738 | if(l >= 3) |
@@ -608,8 +746,7 @@ spi_dv_device_get_echo_buffer(struct scsi_request *sreq, u8 *buffer) | |||
608 | sreq->sr_cmd_len = 0; | 746 | sreq->sr_cmd_len = 0; |
609 | sreq->sr_data_direction = DMA_FROM_DEVICE; | 747 | sreq->sr_data_direction = DMA_FROM_DEVICE; |
610 | 748 | ||
611 | scsi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4, | 749 | spi_wait_req(sreq, spi_read_buffer_descriptor, buffer, 4); |
612 | DV_TIMEOUT, DV_RETRIES); | ||
613 | 750 | ||
614 | if (sreq->sr_result) | 751 | if (sreq->sr_result) |
615 | /* Device has no echo buffer */ | 752 | /* Device has no echo buffer */ |
@@ -623,6 +760,7 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) | |||
623 | { | 760 | { |
624 | struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); | 761 | struct spi_internal *i = to_spi_internal(sreq->sr_host->transportt); |
625 | struct scsi_device *sdev = sreq->sr_device; | 762 | struct scsi_device *sdev = sreq->sr_device; |
763 | struct scsi_target *starget = sdev->sdev_target; | ||
626 | int len = sdev->inquiry_len; | 764 | int len = sdev->inquiry_len; |
627 | /* first set us up for narrow async */ | 765 | /* first set us up for narrow async */ |
628 | DV_SET(offset, 0); | 766 | DV_SET(offset, 0); |
@@ -636,9 +774,11 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) | |||
636 | } | 774 | } |
637 | 775 | ||
638 | /* test width */ | 776 | /* test width */ |
639 | if (i->f->set_width && sdev->wdtr) { | 777 | if (i->f->set_width && spi_max_width(starget) && sdev->wdtr) { |
640 | i->f->set_width(sdev->sdev_target, 1); | 778 | i->f->set_width(sdev->sdev_target, 1); |
641 | 779 | ||
780 | printk("WIDTH IS %d\n", spi_max_width(starget)); | ||
781 | |||
642 | if (spi_dv_device_compare_inquiry(sreq, buffer, | 782 | if (spi_dv_device_compare_inquiry(sreq, buffer, |
643 | buffer + len, | 783 | buffer + len, |
644 | DV_LOOPS) | 784 | DV_LOOPS) |
@@ -665,8 +805,8 @@ spi_dv_device_internal(struct scsi_request *sreq, u8 *buffer) | |||
665 | retry: | 805 | retry: |
666 | 806 | ||
667 | /* now set up to the maximum */ | 807 | /* now set up to the maximum */ |
668 | DV_SET(offset, 255); | 808 | DV_SET(offset, spi_max_offset(starget)); |
669 | DV_SET(period, 1); | 809 | DV_SET(period, spi_min_period(starget)); |
670 | 810 | ||
671 | if (len == 0) { | 811 | if (len == 0) { |
672 | SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); | 812 | SPI_PRINTK(sdev->sdev_target, KERN_INFO, "Domain Validation skipping write tests\n"); |
@@ -873,6 +1013,16 @@ EXPORT_SYMBOL(spi_display_xfer_agreement); | |||
873 | if (i->f->show_##field) \ | 1013 | if (i->f->show_##field) \ |
874 | count++ | 1014 | count++ |
875 | 1015 | ||
1016 | #define SETUP_RELATED_ATTRIBUTE(field, rel_field) \ | ||
1017 | i->private_attrs[count] = class_device_attr_##field; \ | ||
1018 | if (!i->f->set_##rel_field) { \ | ||
1019 | i->private_attrs[count].attr.mode = S_IRUGO; \ | ||
1020 | i->private_attrs[count].store = NULL; \ | ||
1021 | } \ | ||
1022 | i->attrs[count] = &i->private_attrs[count]; \ | ||
1023 | if (i->f->show_##rel_field) \ | ||
1024 | count++ | ||
1025 | |||
876 | #define SETUP_HOST_ATTRIBUTE(field) \ | 1026 | #define SETUP_HOST_ATTRIBUTE(field) \ |
877 | i->private_host_attrs[count] = class_device_attr_##field; \ | 1027 | i->private_host_attrs[count] = class_device_attr_##field; \ |
878 | if (!i->f->set_##field) { \ | 1028 | if (!i->f->set_##field) { \ |
@@ -956,8 +1106,11 @@ spi_attach_transport(struct spi_function_template *ft) | |||
956 | i->f = ft; | 1106 | i->f = ft; |
957 | 1107 | ||
958 | SETUP_ATTRIBUTE(period); | 1108 | SETUP_ATTRIBUTE(period); |
1109 | SETUP_RELATED_ATTRIBUTE(min_period, period); | ||
959 | SETUP_ATTRIBUTE(offset); | 1110 | SETUP_ATTRIBUTE(offset); |
1111 | SETUP_RELATED_ATTRIBUTE(max_offset, offset); | ||
960 | SETUP_ATTRIBUTE(width); | 1112 | SETUP_ATTRIBUTE(width); |
1113 | SETUP_RELATED_ATTRIBUTE(max_width, width); | ||
961 | SETUP_ATTRIBUTE(iu); | 1114 | SETUP_ATTRIBUTE(iu); |
962 | SETUP_ATTRIBUTE(dt); | 1115 | SETUP_ATTRIBUTE(dt); |
963 | SETUP_ATTRIBUTE(qas); | 1116 | SETUP_ATTRIBUTE(qas); |
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 3471be05779a..82d68fdb1548 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
@@ -281,6 +281,9 @@ int sr_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn) | |||
281 | char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); | 281 | char *buffer = kmalloc(32, GFP_KERNEL | SR_GFP_DMA(cd)); |
282 | int result; | 282 | int result; |
283 | 283 | ||
284 | if (!buffer) | ||
285 | return -ENOMEM; | ||
286 | |||
284 | memset(&cgc, 0, sizeof(struct packet_command)); | 287 | memset(&cgc, 0, sizeof(struct packet_command)); |
285 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; | 288 | cgc.cmd[0] = GPCMD_READ_SUBCHANNEL; |
286 | cgc.cmd[2] = 0x40; /* I do want the subchannel info */ | 289 | cgc.cmd[2] = 0x40; /* I do want the subchannel info */ |
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c index f26c3a29e631..ebfddd40ce67 100644 --- a/drivers/scsi/sym53c416.c +++ b/drivers/scsi/sym53c416.c | |||
@@ -809,7 +809,7 @@ static int sym53c416_host_reset(Scsi_Cmnd *SCpnt) | |||
809 | /* printk("sym53c416_reset\n"); */ | 809 | /* printk("sym53c416_reset\n"); */ |
810 | base = SCpnt->device->host->io_port; | 810 | base = SCpnt->device->host->io_port; |
811 | /* search scsi_id - fixme, we shouldnt need to iterate for this! */ | 811 | /* search scsi_id - fixme, we shouldnt need to iterate for this! */ |
812 | for(i = 0; i < host_index && scsi_id != -1; i++) | 812 | for(i = 0; i < host_index && scsi_id == -1; i++) |
813 | if(hosts[i].base == base) | 813 | if(hosts[i].base == base) |
814 | scsi_id = hosts[i].scsi_id; | 814 | scsi_id = hosts[i].scsi_id; |
815 | outb(RESET_CHIP, base + COMMAND_REG); | 815 | outb(RESET_CHIP, base + COMMAND_REG); |
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 5ff83d214f12..5b07c6ec3ecc 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c | |||
@@ -2038,8 +2038,9 @@ static void sym2_set_period(struct scsi_target *starget, int period) | |||
2038 | struct sym_hcb *np = sym_get_hcb(shost); | 2038 | struct sym_hcb *np = sym_get_hcb(shost); |
2039 | struct sym_tcb *tp = &np->target[starget->id]; | 2039 | struct sym_tcb *tp = &np->target[starget->id]; |
2040 | 2040 | ||
2041 | /* have to have DT for these transfers */ | 2041 | /* have to have DT for these transfers, but DT will also |
2042 | if (period <= np->minsync) | 2042 | * set width, so check that this is allowed */ |
2043 | if (period <= np->minsync && spi_width(starget)) | ||
2043 | tp->tgoal.dt = 1; | 2044 | tp->tgoal.dt = 1; |
2044 | 2045 | ||
2045 | tp->tgoal.period = period; | 2046 | tp->tgoal.period = period; |
diff --git a/drivers/serial/21285.c b/drivers/serial/21285.c index 33fbda79f350..0b10169961eb 100644 --- a/drivers/serial/21285.c +++ b/drivers/serial/21285.c | |||
@@ -126,18 +126,8 @@ static irqreturn_t serial21285_rx_chars(int irq, void *dev_id, struct pt_regs *r | |||
126 | flag = TTY_FRAME; | 126 | flag = TTY_FRAME; |
127 | } | 127 | } |
128 | 128 | ||
129 | if ((rxs & port->ignore_status_mask) == 0) { | 129 | uart_insert_char(port, rxs, RXSTAT_OVERRUN, ch, flag); |
130 | tty_insert_flip_char(tty, ch, flag); | 130 | |
131 | } | ||
132 | if ((rxs & RXSTAT_OVERRUN) && | ||
133 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
134 | /* | ||
135 | * Overrun is special, since it's reported | ||
136 | * immediately, and doesn't affect the current | ||
137 | * character. | ||
138 | */ | ||
139 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
140 | } | ||
141 | status = *CSR_UARTFLG; | 131 | status = *CSR_UARTFLG; |
142 | } | 132 | } |
143 | tty_flip_buffer_push(tty); | 133 | tty_flip_buffer_push(tty); |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 0d9358608fdf..3bbf0cc6e53f 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c | |||
@@ -1122,18 +1122,9 @@ receive_chars(struct uart_8250_port *up, int *status, struct pt_regs *regs) | |||
1122 | } | 1122 | } |
1123 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 1123 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
1124 | goto ignore_char; | 1124 | goto ignore_char; |
1125 | if ((lsr & up->port.ignore_status_mask) == 0) { | 1125 | |
1126 | tty_insert_flip_char(tty, ch, flag); | 1126 | uart_insert_char(&up->port, lsr, UART_LSR_OE, ch, flag); |
1127 | } | 1127 | |
1128 | if ((lsr & UART_LSR_OE) && | ||
1129 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
1130 | /* | ||
1131 | * Overrun is special, since it's reported | ||
1132 | * immediately, and doesn't affect the current | ||
1133 | * character. | ||
1134 | */ | ||
1135 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
1136 | } | ||
1137 | ignore_char: | 1128 | ignore_char: |
1138 | lsr = serial_inp(up, UART_LSR); | 1129 | lsr = serial_inp(up, UART_LSR); |
1139 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); | 1130 | } while ((lsr & UART_LSR_DR) && (max_count-- > 0)); |
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index f8d90d0ecfea..de54bdc5398b 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c | |||
@@ -1009,6 +1009,8 @@ get_pci_irq(struct pci_dev *dev, struct pci_board *board, int idx) | |||
1009 | * n = number of serial ports | 1009 | * n = number of serial ports |
1010 | * baud = baud rate | 1010 | * baud = baud rate |
1011 | * | 1011 | * |
1012 | * This table is sorted by (in order): baud, bt, bn, n. | ||
1013 | * | ||
1012 | * Please note: in theory if n = 1, _bt infix should make no difference. | 1014 | * Please note: in theory if n = 1, _bt infix should make no difference. |
1013 | * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200 | 1015 | * ie, pbn_b0_1_115200 is the same as pbn_b0_bt_1_115200 |
1014 | */ | 1016 | */ |
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index f2a5e2933c47..2884b310e54d 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
@@ -198,18 +198,8 @@ pl010_rx_chars(struct uart_port *port) | |||
198 | if (uart_handle_sysrq_char(port, ch, regs)) | 198 | if (uart_handle_sysrq_char(port, ch, regs)) |
199 | goto ignore_char; | 199 | goto ignore_char; |
200 | 200 | ||
201 | if ((rsr & port->ignore_status_mask) == 0) { | 201 | uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); |
202 | tty_insert_flip_char(tty, ch, flag); | 202 | |
203 | } | ||
204 | if ((rsr & UART01x_RSR_OE) && | ||
205 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
206 | /* | ||
207 | * Overrun is special, since it's reported | ||
208 | * immediately, and doesn't affect the current | ||
209 | * character | ||
210 | */ | ||
211 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
212 | } | ||
213 | ignore_char: | 203 | ignore_char: |
214 | status = UART_GET_FR(port); | 204 | status = UART_GET_FR(port); |
215 | } | 205 | } |
diff --git a/drivers/serial/amba-pl011.c b/drivers/serial/amba-pl011.c index d5cbef3fe8b6..7db88ee18f75 100644 --- a/drivers/serial/amba-pl011.c +++ b/drivers/serial/amba-pl011.c | |||
@@ -163,18 +163,8 @@ pl011_rx_chars(struct uart_amba_port *uap) | |||
163 | if (uart_handle_sysrq_char(&uap->port, ch, regs)) | 163 | if (uart_handle_sysrq_char(&uap->port, ch, regs)) |
164 | goto ignore_char; | 164 | goto ignore_char; |
165 | 165 | ||
166 | if ((rsr & uap->port.ignore_status_mask) == 0) { | 166 | uart_insert_char(&uap->port, rsr, UART01x_RSR_OE, ch, flag); |
167 | tty_insert_flip_char(tty, ch, flag); | 167 | |
168 | } | ||
169 | if ((rsr & UART01x_RSR_OE) && | ||
170 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
171 | /* | ||
172 | * Overrun is special, since it's reported | ||
173 | * immediately, and doesn't affect the current | ||
174 | * character | ||
175 | */ | ||
176 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
177 | } | ||
178 | ignore_char: | 168 | ignore_char: |
179 | status = readw(uap->port.membase + UART01x_FR); | 169 | status = readw(uap->port.membase + UART01x_FR); |
180 | } | 170 | } |
diff --git a/drivers/serial/clps711x.c b/drivers/serial/clps711x.c index 6242f3090a96..e92522b33c48 100644 --- a/drivers/serial/clps711x.c +++ b/drivers/serial/clps711x.c | |||
@@ -143,10 +143,7 @@ static irqreturn_t clps711xuart_int_rx(int irq, void *dev_id, struct pt_regs *re | |||
143 | * CHECK: does overrun affect the current character? | 143 | * CHECK: does overrun affect the current character? |
144 | * ASSUMPTION: it does not. | 144 | * ASSUMPTION: it does not. |
145 | */ | 145 | */ |
146 | if ((ch & port->ignore_status_mask & ~RXSTAT_OVERRUN) == 0) | 146 | uart_insert_char(port, ch, UARTDR_OVERR, ch, flg); |
147 | tty_insert_flip_char(tty, ch, flg); | ||
148 | if ((ch & ~port->ignore_status_mask & RXSTAT_OVERRUN) == 0) | ||
149 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
150 | 147 | ||
151 | ignore_char: | 148 | ignore_char: |
152 | status = clps_readl(SYSFLG(port)); | 149 | status = clps_readl(SYSFLG(port)); |
diff --git a/drivers/serial/pxa.c b/drivers/serial/pxa.c index 51d8a49f4477..9dc151d8fa61 100644 --- a/drivers/serial/pxa.c +++ b/drivers/serial/pxa.c | |||
@@ -161,20 +161,12 @@ receive_chars(struct uart_pxa_port *up, int *status, struct pt_regs *regs) | |||
161 | else if (*status & UART_LSR_FE) | 161 | else if (*status & UART_LSR_FE) |
162 | flag = TTY_FRAME; | 162 | flag = TTY_FRAME; |
163 | } | 163 | } |
164 | |||
164 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 165 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
165 | goto ignore_char; | 166 | goto ignore_char; |
166 | if ((*status & up->port.ignore_status_mask) == 0) { | 167 | |
167 | tty_insert_flip_char(tty, ch, flag); | 168 | uart_insert_char(&up->port, *status, UART_LSR_OE, ch, flag); |
168 | } | 169 | |
169 | if ((*status & UART_LSR_OE) && | ||
170 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
171 | /* | ||
172 | * Overrun is special, since it's reported | ||
173 | * immediately, and doesn't affect the current | ||
174 | * character. | ||
175 | */ | ||
176 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
177 | } | ||
178 | ignore_char: | 170 | ignore_char: |
179 | *status = serial_in(up, UART_LSR); | 171 | *status = serial_in(up, UART_LSR); |
180 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); | 172 | } while ((*status & UART_LSR_DR) && (max_count-- > 0)); |
diff --git a/drivers/serial/s3c2410.c b/drivers/serial/s3c2410.c index 435750d40a47..2a9f7ade2c9d 100644 --- a/drivers/serial/s3c2410.c +++ b/drivers/serial/s3c2410.c | |||
@@ -394,20 +394,7 @@ s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs) | |||
394 | if (uart_handle_sysrq_char(port, ch, regs)) | 394 | if (uart_handle_sysrq_char(port, ch, regs)) |
395 | goto ignore_char; | 395 | goto ignore_char; |
396 | 396 | ||
397 | if ((uerstat & port->ignore_status_mask) == 0) { | 397 | uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); |
398 | tty_insert_flip_char(tty, ch, flag); | ||
399 | } | ||
400 | |||
401 | if ((uerstat & S3C2410_UERSTAT_OVERRUN) && | ||
402 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
403 | /* | ||
404 | * Overrun is special, since it's reported | ||
405 | * immediately, and doesn't affect the current | ||
406 | * character. | ||
407 | */ | ||
408 | |||
409 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
410 | } | ||
411 | 398 | ||
412 | ignore_char: | 399 | ignore_char: |
413 | continue; | 400 | continue; |
diff --git a/drivers/serial/sa1100.c b/drivers/serial/sa1100.c index 157218bc6c6f..22565a67a57c 100644 --- a/drivers/serial/sa1100.c +++ b/drivers/serial/sa1100.c | |||
@@ -237,10 +237,7 @@ sa1100_rx_chars(struct sa1100_port *sport, struct pt_regs *regs) | |||
237 | if (uart_handle_sysrq_char(&sport->port, ch, regs)) | 237 | if (uart_handle_sysrq_char(&sport->port, ch, regs)) |
238 | goto ignore_char; | 238 | goto ignore_char; |
239 | 239 | ||
240 | if ((status & port->ignore_status_mask & ~UTSR1_TO_SM(UTSR1_ROR)) == 0) | 240 | uart_insert_char(&sport->port, status, UTSR1_TO_SM(UTSR1_ROR), ch, flg); |
241 | tty_insert_flip_char(tty, ch, flg); | ||
242 | if (status & ~port->ignore_status_mask & UTSR1_TO_SM(UTSR1_ROR)) | ||
243 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
244 | 241 | ||
245 | ignore_char: | 242 | ignore_char: |
246 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | | 243 | status = UTSR1_TO_SM(UART_GET_UTSR1(sport)) | |
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c index 6eeb48f6a482..0d7b65f93e8d 100644 --- a/drivers/serial/serial_cs.c +++ b/drivers/serial/serial_cs.c | |||
@@ -661,10 +661,10 @@ void serial_config(dev_link_t * link) | |||
661 | /* Is this a multiport card? */ | 661 | /* Is this a multiport card? */ |
662 | tuple->DesiredTuple = CISTPL_MANFID; | 662 | tuple->DesiredTuple = CISTPL_MANFID; |
663 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { | 663 | if (first_tuple(handle, tuple, parse) == CS_SUCCESS) { |
664 | info->manfid = le16_to_cpu(buf[0]); | 664 | info->manfid = parse->manfid.manf; |
665 | for (i = 0; i < MULTI_COUNT; i++) | 665 | for (i = 0; i < MULTI_COUNT; i++) |
666 | if ((info->manfid == multi_id[i].manfid) && | 666 | if ((info->manfid == multi_id[i].manfid) && |
667 | (le16_to_cpu(buf[1]) == multi_id[i].prodid)) | 667 | (parse->manfid.card == multi_id[i].prodid)) |
668 | break; | 668 | break; |
669 | if (i < MULTI_COUNT) | 669 | if (i < MULTI_COUNT) |
670 | info->multi = multi_id[i].multi; | 670 | info->multi = multi_id[i].multi; |
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c index 85cfa08d3bad..56f269b6bfb1 100644 --- a/drivers/serial/serial_lh7a40x.c +++ b/drivers/serial/serial_lh7a40x.c | |||
@@ -190,18 +190,7 @@ lh7a40xuart_rx_chars (struct uart_port* port) | |||
190 | if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) | 190 | if (uart_handle_sysrq_char (port, (unsigned char) data, regs)) |
191 | continue; | 191 | continue; |
192 | 192 | ||
193 | if ((data & port->ignore_status_mask) == 0) { | 193 | uart_insert_char(port, data, RxOverrunError, data, flag); |
194 | tty_insert_flip_char(tty, data, flag); | ||
195 | } | ||
196 | if ((data & RxOverrunError) | ||
197 | && tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
198 | /* | ||
199 | * Overrun is special, since it's reported | ||
200 | * immediately, and doesn't affect the current | ||
201 | * character | ||
202 | */ | ||
203 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
204 | } | ||
205 | } | 194 | } |
206 | tty_flip_buffer_push (tty); | 195 | tty_flip_buffer_push (tty); |
207 | return; | 196 | return; |
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index 37b2ef297cbe..3f1051a4a13f 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c | |||
@@ -350,18 +350,9 @@ receive_chars(struct uart_txx9_port *up, unsigned int *status, struct pt_regs *r | |||
350 | } | 350 | } |
351 | if (uart_handle_sysrq_char(&up->port, ch, regs)) | 351 | if (uart_handle_sysrq_char(&up->port, ch, regs)) |
352 | goto ignore_char; | 352 | goto ignore_char; |
353 | if ((disr & up->port.ignore_status_mask) == 0) { | 353 | |
354 | tty_insert_flip_char(tty, ch, flag); | 354 | uart_insert_char(&up->port, disr, TXX9_SIDISR_UOER, ch, flag); |
355 | } | 355 | |
356 | if ((disr & TXX9_SIDISR_UOER) && | ||
357 | tty->flip.count < TTY_FLIPBUF_SIZE) { | ||
358 | /* | ||
359 | * Overrun is special, since it's reported | ||
360 | * immediately, and doesn't affect the current | ||
361 | * character. | ||
362 | */ | ||
363 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
364 | } | ||
365 | ignore_char: | 356 | ignore_char: |
366 | disr = sio_in(up, TXX9_SIDISR); | 357 | disr = sio_in(up, TXX9_SIDISR); |
367 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); | 358 | } while (!(disr & TXX9_SIDISR_UVALID) && (max_count-- > 0)); |
diff --git a/drivers/serial/sunsab.c b/drivers/serial/sunsab.c index 39b788d95e39..10e2990a40d4 100644 --- a/drivers/serial/sunsab.c +++ b/drivers/serial/sunsab.c | |||
@@ -61,6 +61,16 @@ struct uart_sunsab_port { | |||
61 | unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ | 61 | unsigned char pvr_dtr_bit; /* Which PVR bit is DTR */ |
62 | unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ | 62 | unsigned char pvr_dsr_bit; /* Which PVR bit is DSR */ |
63 | int type; /* SAB82532 version */ | 63 | int type; /* SAB82532 version */ |
64 | |||
65 | /* Setting configuration bits while the transmitter is active | ||
66 | * can cause garbage characters to get emitted by the chip. | ||
67 | * Therefore, we cache such writes here and do the real register | ||
68 | * write the next time the transmitter becomes idle. | ||
69 | */ | ||
70 | unsigned int cached_ebrg; | ||
71 | unsigned char cached_mode; | ||
72 | unsigned char cached_pvr; | ||
73 | unsigned char cached_dafo; | ||
64 | }; | 74 | }; |
65 | 75 | ||
66 | /* | 76 | /* |
@@ -236,6 +246,7 @@ receive_chars(struct uart_sunsab_port *up, | |||
236 | } | 246 | } |
237 | 247 | ||
238 | static void sunsab_stop_tx(struct uart_port *, unsigned int); | 248 | static void sunsab_stop_tx(struct uart_port *, unsigned int); |
249 | static void sunsab_tx_idle(struct uart_sunsab_port *); | ||
239 | 250 | ||
240 | static void transmit_chars(struct uart_sunsab_port *up, | 251 | static void transmit_chars(struct uart_sunsab_port *up, |
241 | union sab82532_irq_status *stat) | 252 | union sab82532_irq_status *stat) |
@@ -258,6 +269,7 @@ static void transmit_chars(struct uart_sunsab_port *up, | |||
258 | return; | 269 | return; |
259 | 270 | ||
260 | set_bit(SAB82532_XPR, &up->irqflags); | 271 | set_bit(SAB82532_XPR, &up->irqflags); |
272 | sunsab_tx_idle(up); | ||
261 | 273 | ||
262 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { | 274 | if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { |
263 | up->interrupt_mask1 |= SAB82532_IMR1_XPR; | 275 | up->interrupt_mask1 |= SAB82532_IMR1_XPR; |
@@ -397,21 +409,21 @@ static void sunsab_set_mctrl(struct uart_port *port, unsigned int mctrl) | |||
397 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 409 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
398 | 410 | ||
399 | if (mctrl & TIOCM_RTS) { | 411 | if (mctrl & TIOCM_RTS) { |
400 | writeb(readb(&up->regs->rw.mode) & ~SAB82532_MODE_FRTS, | 412 | up->cached_mode &= ~SAB82532_MODE_FRTS; |
401 | &up->regs->rw.mode); | 413 | up->cached_mode |= SAB82532_MODE_RTS; |
402 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, | ||
403 | &up->regs->rw.mode); | ||
404 | } else { | 414 | } else { |
405 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, | 415 | up->cached_mode |= (SAB82532_MODE_FRTS | |
406 | &up->regs->rw.mode); | 416 | SAB82532_MODE_RTS); |
407 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, | ||
408 | &up->regs->rw.mode); | ||
409 | } | 417 | } |
410 | if (mctrl & TIOCM_DTR) { | 418 | if (mctrl & TIOCM_DTR) { |
411 | writeb(readb(&up->regs->rw.pvr) & ~(up->pvr_dtr_bit), &up->regs->rw.pvr); | 419 | up->cached_pvr &= ~(up->pvr_dtr_bit); |
412 | } else { | 420 | } else { |
413 | writeb(readb(&up->regs->rw.pvr) | up->pvr_dtr_bit, &up->regs->rw.pvr); | 421 | up->cached_pvr |= up->pvr_dtr_bit; |
414 | } | 422 | } |
423 | |||
424 | set_bit(SAB82532_REGS_PENDING, &up->irqflags); | ||
425 | if (test_bit(SAB82532_XPR, &up->irqflags)) | ||
426 | sunsab_tx_idle(up); | ||
415 | } | 427 | } |
416 | 428 | ||
417 | /* port->lock is not held. */ | 429 | /* port->lock is not held. */ |
@@ -450,6 +462,25 @@ static void sunsab_stop_tx(struct uart_port *port, unsigned int tty_stop) | |||
450 | } | 462 | } |
451 | 463 | ||
452 | /* port->lock held by caller. */ | 464 | /* port->lock held by caller. */ |
465 | static void sunsab_tx_idle(struct uart_sunsab_port *up) | ||
466 | { | ||
467 | if (test_bit(SAB82532_REGS_PENDING, &up->irqflags)) { | ||
468 | u8 tmp; | ||
469 | |||
470 | clear_bit(SAB82532_REGS_PENDING, &up->irqflags); | ||
471 | writeb(up->cached_mode, &up->regs->rw.mode); | ||
472 | writeb(up->cached_pvr, &up->regs->rw.pvr); | ||
473 | writeb(up->cached_dafo, &up->regs->w.dafo); | ||
474 | |||
475 | writeb(up->cached_ebrg & 0xff, &up->regs->w.bgr); | ||
476 | tmp = readb(&up->regs->rw.ccr2); | ||
477 | tmp &= ~0xc0; | ||
478 | tmp |= (up->cached_ebrg >> 2) & 0xc0; | ||
479 | writeb(tmp, &up->regs->rw.ccr2); | ||
480 | } | ||
481 | } | ||
482 | |||
483 | /* port->lock held by caller. */ | ||
453 | static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) | 484 | static void sunsab_start_tx(struct uart_port *port, unsigned int tty_start) |
454 | { | 485 | { |
455 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 486 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
@@ -517,12 +548,16 @@ static void sunsab_break_ctl(struct uart_port *port, int break_state) | |||
517 | 548 | ||
518 | spin_lock_irqsave(&up->port.lock, flags); | 549 | spin_lock_irqsave(&up->port.lock, flags); |
519 | 550 | ||
520 | val = readb(&up->regs->rw.dafo); | 551 | val = up->cached_dafo; |
521 | if (break_state) | 552 | if (break_state) |
522 | val |= SAB82532_DAFO_XBRK; | 553 | val |= SAB82532_DAFO_XBRK; |
523 | else | 554 | else |
524 | val &= ~SAB82532_DAFO_XBRK; | 555 | val &= ~SAB82532_DAFO_XBRK; |
525 | writeb(val, &up->regs->rw.dafo); | 556 | up->cached_dafo = val; |
557 | |||
558 | set_bit(SAB82532_REGS_PENDING, &up->irqflags); | ||
559 | if (test_bit(SAB82532_XPR, &up->irqflags)) | ||
560 | sunsab_tx_idle(up); | ||
526 | 561 | ||
527 | spin_unlock_irqrestore(&up->port.lock, flags); | 562 | spin_unlock_irqrestore(&up->port.lock, flags); |
528 | } | 563 | } |
@@ -566,8 +601,9 @@ static int sunsab_startup(struct uart_port *port) | |||
566 | SAB82532_CCR2_TOE, &up->regs->w.ccr2); | 601 | SAB82532_CCR2_TOE, &up->regs->w.ccr2); |
567 | writeb(0, &up->regs->w.ccr3); | 602 | writeb(0, &up->regs->w.ccr3); |
568 | writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4); | 603 | writeb(SAB82532_CCR4_MCK4 | SAB82532_CCR4_EBRG, &up->regs->w.ccr4); |
569 | writeb(SAB82532_MODE_RTS | SAB82532_MODE_FCTS | | 604 | up->cached_mode = (SAB82532_MODE_RTS | SAB82532_MODE_FCTS | |
570 | SAB82532_MODE_RAC, &up->regs->w.mode); | 605 | SAB82532_MODE_RAC); |
606 | writeb(up->cached_mode, &up->regs->w.mode); | ||
571 | writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc); | 607 | writeb(SAB82532_RFC_DPS|SAB82532_RFC_RFTH_32, &up->regs->w.rfc); |
572 | 608 | ||
573 | tmp = readb(&up->regs->rw.ccr0); | 609 | tmp = readb(&up->regs->rw.ccr0); |
@@ -598,7 +634,6 @@ static void sunsab_shutdown(struct uart_port *port) | |||
598 | { | 634 | { |
599 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; | 635 | struct uart_sunsab_port *up = (struct uart_sunsab_port *) port; |
600 | unsigned long flags; | 636 | unsigned long flags; |
601 | unsigned char tmp; | ||
602 | 637 | ||
603 | spin_lock_irqsave(&up->port.lock, flags); | 638 | spin_lock_irqsave(&up->port.lock, flags); |
604 | 639 | ||
@@ -609,14 +644,13 @@ static void sunsab_shutdown(struct uart_port *port) | |||
609 | writeb(up->interrupt_mask1, &up->regs->w.imr1); | 644 | writeb(up->interrupt_mask1, &up->regs->w.imr1); |
610 | 645 | ||
611 | /* Disable break condition */ | 646 | /* Disable break condition */ |
612 | tmp = readb(&up->regs->rw.dafo); | 647 | up->cached_dafo = readb(&up->regs->rw.dafo); |
613 | tmp &= ~SAB82532_DAFO_XBRK; | 648 | up->cached_dafo &= ~SAB82532_DAFO_XBRK; |
614 | writeb(tmp, &up->regs->rw.dafo); | 649 | writeb(up->cached_dafo, &up->regs->rw.dafo); |
615 | 650 | ||
616 | /* Disable Receiver */ | 651 | /* Disable Receiver */ |
617 | tmp = readb(&up->regs->rw.mode); | 652 | up->cached_mode &= ~SAB82532_MODE_RAC; |
618 | tmp &= ~SAB82532_MODE_RAC; | 653 | writeb(up->cached_mode, &up->regs->rw.mode); |
619 | writeb(tmp, &up->regs->rw.mode); | ||
620 | 654 | ||
621 | /* | 655 | /* |
622 | * XXX FIXME | 656 | * XXX FIXME |
@@ -685,7 +719,6 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla | |||
685 | unsigned int iflag, unsigned int baud, | 719 | unsigned int iflag, unsigned int baud, |
686 | unsigned int quot) | 720 | unsigned int quot) |
687 | { | 721 | { |
688 | unsigned int ebrg; | ||
689 | unsigned char dafo; | 722 | unsigned char dafo; |
690 | int bits, n, m; | 723 | int bits, n, m; |
691 | 724 | ||
@@ -714,10 +747,11 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla | |||
714 | } else { | 747 | } else { |
715 | dafo |= SAB82532_DAFO_PAR_EVEN; | 748 | dafo |= SAB82532_DAFO_PAR_EVEN; |
716 | } | 749 | } |
750 | up->cached_dafo = dafo; | ||
717 | 751 | ||
718 | calc_ebrg(baud, &n, &m); | 752 | calc_ebrg(baud, &n, &m); |
719 | 753 | ||
720 | ebrg = n | (m << 6); | 754 | up->cached_ebrg = n | (m << 6); |
721 | 755 | ||
722 | up->tec_timeout = (10 * 1000000) / baud; | 756 | up->tec_timeout = (10 * 1000000) / baud; |
723 | up->cec_timeout = up->tec_timeout >> 2; | 757 | up->cec_timeout = up->tec_timeout >> 2; |
@@ -770,16 +804,13 @@ static void sunsab_convert_to_sab(struct uart_sunsab_port *up, unsigned int cfla | |||
770 | uart_update_timeout(&up->port, cflag, | 804 | uart_update_timeout(&up->port, cflag, |
771 | (up->port.uartclk / (16 * quot))); | 805 | (up->port.uartclk / (16 * quot))); |
772 | 806 | ||
773 | /* Now bang the new settings into the chip. */ | 807 | /* Now schedule a register update when the chip's |
774 | sunsab_cec_wait(up); | 808 | * transmitter is idle. |
775 | sunsab_tec_wait(up); | 809 | */ |
776 | writeb(dafo, &up->regs->w.dafo); | 810 | up->cached_mode |= SAB82532_MODE_RAC; |
777 | writeb(ebrg & 0xff, &up->regs->w.bgr); | 811 | set_bit(SAB82532_REGS_PENDING, &up->irqflags); |
778 | writeb((readb(&up->regs->rw.ccr2) & ~0xc0) | ((ebrg >> 2) & 0xc0), | 812 | if (test_bit(SAB82532_XPR, &up->irqflags)) |
779 | &up->regs->rw.ccr2); | 813 | sunsab_tx_idle(up); |
780 | |||
781 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RAC, &up->regs->rw.mode); | ||
782 | |||
783 | } | 814 | } |
784 | 815 | ||
785 | /* port->lock is not held. */ | 816 | /* port->lock is not held. */ |
@@ -1084,11 +1115,13 @@ static void __init sunsab_init_hw(void) | |||
1084 | up->pvr_dsr_bit = (1 << 3); | 1115 | up->pvr_dsr_bit = (1 << 3); |
1085 | up->pvr_dtr_bit = (1 << 2); | 1116 | up->pvr_dtr_bit = (1 << 2); |
1086 | } | 1117 | } |
1087 | writeb((1 << 1) | (1 << 2) | (1 << 4), &up->regs->w.pvr); | 1118 | up->cached_pvr = (1 << 1) | (1 << 2) | (1 << 4); |
1088 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_FRTS, | 1119 | writeb(up->cached_pvr, &up->regs->w.pvr); |
1089 | &up->regs->rw.mode); | 1120 | up->cached_mode = readb(&up->regs->rw.mode); |
1090 | writeb(readb(&up->regs->rw.mode) | SAB82532_MODE_RTS, | 1121 | up->cached_mode |= SAB82532_MODE_FRTS; |
1091 | &up->regs->rw.mode); | 1122 | writeb(up->cached_mode, &up->regs->rw.mode); |
1123 | up->cached_mode |= SAB82532_MODE_RTS; | ||
1124 | writeb(up->cached_mode, &up->regs->rw.mode); | ||
1092 | 1125 | ||
1093 | up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; | 1126 | up->tec_timeout = SAB82532_MAX_TEC_TIMEOUT; |
1094 | up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; | 1127 | up->cec_timeout = SAB82532_MAX_CEC_TIMEOUT; |
diff --git a/drivers/serial/sunsab.h b/drivers/serial/sunsab.h index 686086fcbbf5..b78e1f7b8050 100644 --- a/drivers/serial/sunsab.h +++ b/drivers/serial/sunsab.h | |||
@@ -126,6 +126,7 @@ union sab82532_irq_status { | |||
126 | /* irqflags bits */ | 126 | /* irqflags bits */ |
127 | #define SAB82532_ALLS 0x00000001 | 127 | #define SAB82532_ALLS 0x00000001 |
128 | #define SAB82532_XPR 0x00000002 | 128 | #define SAB82532_XPR 0x00000002 |
129 | #define SAB82532_REGS_PENDING 0x00000004 | ||
129 | 130 | ||
130 | /* RFIFO Status Byte */ | 131 | /* RFIFO Status Byte */ |
131 | #define SAB82532_RSTAT_PE 0x80 | 132 | #define SAB82532_RSTAT_PE 0x80 |
diff --git a/drivers/serial/vr41xx_siu.c b/drivers/serial/vr41xx_siu.c index 307886199f2f..5d2ceb623e6f 100644 --- a/drivers/serial/vr41xx_siu.c +++ b/drivers/serial/vr41xx_siu.c | |||
@@ -412,10 +412,8 @@ static inline void receive_chars(struct uart_port *port, uint8_t *status, | |||
412 | 412 | ||
413 | if (uart_handle_sysrq_char(port, ch, regs)) | 413 | if (uart_handle_sysrq_char(port, ch, regs)) |
414 | goto ignore_char; | 414 | goto ignore_char; |
415 | if ((lsr & port->ignore_status_mask) == 0) | 415 | |
416 | tty_insert_flip_char(tty, ch, flag); | 416 | uart_insert_char(port, lsr, UART_LSR_OE, ch, flag); |
417 | if ((lsr & UART_LSR_OE) && (tty->flip.count < TTY_FLIPBUF_SIZE)) | ||
418 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
419 | 417 | ||
420 | ignore_char: | 418 | ignore_char: |
421 | lsr = siu_read(port, UART_LSR); | 419 | lsr = siu_read(port, UART_LSR); |
diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 5538756f13ba..d5863b8b56ee 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c | |||
@@ -41,9 +41,6 @@ | |||
41 | * | 41 | * |
42 | ***************************************************************************/ | 42 | ***************************************************************************/ |
43 | 43 | ||
44 | static char ixj_c_rcsid[] = "$Id: ixj.c,v 4.7 2001/08/13 06:19:33 craigs Exp $"; | ||
45 | static char ixj_c_revision[] = "$Revision: 4.7 $"; | ||
46 | |||
47 | /* | 44 | /* |
48 | * $Log: ixj.c,v $ | 45 | * $Log: ixj.c,v $ |
49 | * | 46 | * |
@@ -6172,8 +6169,14 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, | |||
6172 | retval = j->serial; | 6169 | retval = j->serial; |
6173 | break; | 6170 | break; |
6174 | case IXJCTL_VERSION: | 6171 | case IXJCTL_VERSION: |
6175 | if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision))) | 6172 | { |
6176 | retval = -EFAULT; | 6173 | char arg_str[100]; |
6174 | snprintf(arg_str, sizeof(arg_str), | ||
6175 | "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, | ||
6176 | IXJ_VER_MINOR, IXJ_BLD_VER); | ||
6177 | if (copy_to_user(argp, arg_str, strlen(arg_str))) | ||
6178 | retval = -EFAULT; | ||
6179 | } | ||
6177 | break; | 6180 | break; |
6178 | case PHONE_RING_CADENCE: | 6181 | case PHONE_RING_CADENCE: |
6179 | j->ring_cadence = arg; | 6182 | j->ring_cadence = arg; |
@@ -7168,9 +7171,6 @@ static int ixj_get_status_proc(char *buf) | |||
7168 | int cnt; | 7171 | int cnt; |
7169 | IXJ *j; | 7172 | IXJ *j; |
7170 | len = 0; | 7173 | len = 0; |
7171 | len += sprintf(buf + len, "%s", ixj_c_rcsid); | ||
7172 | len += sprintf(buf + len, "\n%s", ixj_h_rcsid); | ||
7173 | len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid); | ||
7174 | len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); | 7174 | len += sprintf(buf + len, "\nDriver version %i.%i.%i", IXJ_VER_MAJOR, IXJ_VER_MINOR, IXJ_BLD_VER); |
7175 | len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ)); | 7175 | len += sprintf(buf + len, "\nsizeof IXJ struct %Zd bytes", sizeof(IXJ)); |
7176 | len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS)); | 7176 | len += sprintf(buf + len, "\nsizeof DAA struct %Zd bytes", sizeof(DAA_REGS)); |
@@ -7790,7 +7790,7 @@ static int __init ixj_init(void) | |||
7790 | if ((probe = ixj_probe_pci(&cnt)) < 0) { | 7790 | if ((probe = ixj_probe_pci(&cnt)) < 0) { |
7791 | return probe; | 7791 | return probe; |
7792 | } | 7792 | } |
7793 | printk("%s\n", ixj_c_rcsid); | 7793 | printk(KERN_INFO "ixj driver initialized.\n"); |
7794 | create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL); | 7794 | create_proc_read_entry ("ixj", 0, NULL, ixj_read_proc, NULL); |
7795 | return probe; | 7795 | return probe; |
7796 | } | 7796 | } |
diff --git a/drivers/telephony/ixj.h b/drivers/telephony/ixj.h index 143818a56121..51e3f7f6597b 100644 --- a/drivers/telephony/ixj.h +++ b/drivers/telephony/ixj.h | |||
@@ -38,8 +38,6 @@ | |||
38 | * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | 38 | * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
39 | * | 39 | * |
40 | *****************************************************************************/ | 40 | *****************************************************************************/ |
41 | static char ixj_h_rcsid[] = "$Id: ixj.h,v 4.1 2001/08/04 14:49:27 craigs Exp $"; | ||
42 | |||
43 | #define IXJ_VERSION 3031 | 41 | #define IXJ_VERSION 3031 |
44 | 42 | ||
45 | #include <linux/version.h> | 43 | #include <linux/version.h> |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index ec9b3bde8ae5..4ab50009291d 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -286,6 +286,39 @@ static ssize_t show_interface_string(struct device *dev, char *buf) | |||
286 | } | 286 | } |
287 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); | 287 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); |
288 | 288 | ||
289 | static ssize_t show_modalias(struct device *dev, char *buf) | ||
290 | { | ||
291 | struct usb_interface *intf; | ||
292 | struct usb_device *udev; | ||
293 | |||
294 | intf = to_usb_interface(dev); | ||
295 | udev = interface_to_usbdev(intf); | ||
296 | if (udev->descriptor.bDeviceClass == 0) { | ||
297 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
298 | |||
299 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", | ||
300 | le16_to_cpu(udev->descriptor.idVendor), | ||
301 | le16_to_cpu(udev->descriptor.idProduct), | ||
302 | le16_to_cpu(udev->descriptor.bcdDevice), | ||
303 | udev->descriptor.bDeviceClass, | ||
304 | udev->descriptor.bDeviceSubClass, | ||
305 | udev->descriptor.bDeviceProtocol, | ||
306 | alt->desc.bInterfaceClass, | ||
307 | alt->desc.bInterfaceSubClass, | ||
308 | alt->desc.bInterfaceProtocol); | ||
309 | } else { | ||
310 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n", | ||
311 | le16_to_cpu(udev->descriptor.idVendor), | ||
312 | le16_to_cpu(udev->descriptor.idProduct), | ||
313 | le16_to_cpu(udev->descriptor.bcdDevice), | ||
314 | udev->descriptor.bDeviceClass, | ||
315 | udev->descriptor.bDeviceSubClass, | ||
316 | udev->descriptor.bDeviceProtocol); | ||
317 | } | ||
318 | |||
319 | } | ||
320 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | ||
321 | |||
289 | static struct attribute *intf_attrs[] = { | 322 | static struct attribute *intf_attrs[] = { |
290 | &dev_attr_bInterfaceNumber.attr, | 323 | &dev_attr_bInterfaceNumber.attr, |
291 | &dev_attr_bAlternateSetting.attr, | 324 | &dev_attr_bAlternateSetting.attr, |
@@ -293,6 +326,7 @@ static struct attribute *intf_attrs[] = { | |||
293 | &dev_attr_bInterfaceClass.attr, | 326 | &dev_attr_bInterfaceClass.attr, |
294 | &dev_attr_bInterfaceSubClass.attr, | 327 | &dev_attr_bInterfaceSubClass.attr, |
295 | &dev_attr_bInterfaceProtocol.attr, | 328 | &dev_attr_bInterfaceProtocol.attr, |
329 | &dev_attr_modalias.attr, | ||
296 | NULL, | 330 | NULL, |
297 | }; | 331 | }; |
298 | static struct attribute_group intf_attr_grp = { | 332 | static struct attribute_group intf_attr_grp = { |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 02fefab3501e..429330bc38de 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -72,6 +72,7 @@ static int ehci_hub_suspend (struct usb_hcd *hcd) | |||
72 | } | 72 | } |
73 | 73 | ||
74 | /* turn off now-idle HC */ | 74 | /* turn off now-idle HC */ |
75 | del_timer_sync (&ehci->watchdog); | ||
75 | ehci_halt (ehci); | 76 | ehci_halt (ehci); |
76 | hcd->state = HC_STATE_SUSPENDED; | 77 | hcd->state = HC_STATE_SUSPENDED; |
77 | 78 | ||
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index db64c908d4a7..b104430e2c6a 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig | |||
@@ -219,17 +219,21 @@ config USB_EPSON2888 | |||
219 | by some sample firmware from Epson. | 219 | by some sample firmware from Epson. |
220 | 220 | ||
221 | config USB_ZAURUS | 221 | config USB_ZAURUS |
222 | boolean "Sharp Zaurus (stock ROMs)" | 222 | boolean "Sharp Zaurus (stock ROMs) and compatible" |
223 | depends on USB_USBNET | 223 | depends on USB_USBNET |
224 | select CRC32 | 224 | select CRC32 |
225 | default y | 225 | default y |
226 | help | 226 | help |
227 | Choose this option to support the usb networking links used by | 227 | Choose this option to support the usb networking links used by |
228 | Zaurus models like the SL-5000D, SL-5500, SL-5600, A-300, B-500. | 228 | Zaurus models like the SL-5000D, SL-5500, SL-5600, A-300, B-500. |
229 | 229 | This also supports some related device firmware, as used in some | |
230 | If you install an alternate ROM image, you may no longer need | 230 | PDAs from Olympus and some cell phones from Motorola. |
231 | to support this protocol. Only the "eth-fd" driver really needs | 231 | |
232 | this non-conformant variant of CDC Ethernet protocol. | 232 | If you install an alternate ROM image, such as the Linux 2.6 based |
233 | versions of OpenZaurus, you should no longer need to support this | ||
234 | protocol. Only the "eth-fd" or "net_fd" drivers in these devices | ||
235 | really need this non-conformant variant of CDC Ethernet (or in | ||
236 | some cases CDC MDLM) protocol, not "g_ether". | ||
233 | 237 | ||
234 | config USB_CDCETHER | 238 | config USB_CDCETHER |
235 | boolean "CDC Ethernet support (smart devices such as cable modems)" | 239 | boolean "CDC Ethernet support (smart devices such as cable modems)" |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index f6bc6b3b333c..85476e76b244 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -1517,6 +1517,26 @@ static void cdc_unbind (struct usbnet *dev, struct usb_interface *intf) | |||
1517 | } | 1517 | } |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | #endif /* NEED_GENERIC_CDC */ | ||
1521 | |||
1522 | |||
1523 | #ifdef CONFIG_USB_CDCETHER | ||
1524 | #define HAVE_HARDWARE | ||
1525 | |||
1526 | /*------------------------------------------------------------------------- | ||
1527 | * | ||
1528 | * Communications Device Class, Ethernet Control model | ||
1529 | * | ||
1530 | * Takes two interfaces. The DATA interface is inactive till an altsetting | ||
1531 | * is selected. Configuration data includes class descriptors. | ||
1532 | * | ||
1533 | * This should interop with whatever the 2.4 "CDCEther.c" driver | ||
1534 | * (by Brad Hards) talked with. | ||
1535 | * | ||
1536 | *-------------------------------------------------------------------------*/ | ||
1537 | |||
1538 | #include <linux/ctype.h> | ||
1539 | |||
1520 | 1540 | ||
1521 | static void dumpspeed (struct usbnet *dev, __le32 *speeds) | 1541 | static void dumpspeed (struct usbnet *dev, __le32 *speeds) |
1522 | { | 1542 | { |
@@ -1567,26 +1587,6 @@ static void cdc_status (struct usbnet *dev, struct urb *urb) | |||
1567 | } | 1587 | } |
1568 | } | 1588 | } |
1569 | 1589 | ||
1570 | #endif /* NEED_GENERIC_CDC */ | ||
1571 | |||
1572 | |||
1573 | #ifdef CONFIG_USB_CDCETHER | ||
1574 | #define HAVE_HARDWARE | ||
1575 | |||
1576 | /*------------------------------------------------------------------------- | ||
1577 | * | ||
1578 | * Communications Device Class, Ethernet Control model | ||
1579 | * | ||
1580 | * Takes two interfaces. The DATA interface is inactive till an altsetting | ||
1581 | * is selected. Configuration data includes class descriptors. | ||
1582 | * | ||
1583 | * This should interop with whatever the 2.4 "CDCEther.c" driver | ||
1584 | * (by Brad Hards) talked with. | ||
1585 | * | ||
1586 | *-------------------------------------------------------------------------*/ | ||
1587 | |||
1588 | #include <linux/ctype.h> | ||
1589 | |||
1590 | static u8 nibble (unsigned char c) | 1590 | static u8 nibble (unsigned char c) |
1591 | { | 1591 | { |
1592 | if (likely (isdigit (c))) | 1592 | if (likely (isdigit (c))) |
@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) | |||
2765 | } | 2765 | } |
2766 | /* expect bcdVersion 1.0, ignore */ | 2766 | /* expect bcdVersion 1.0, ignore */ |
2767 | if (memcmp(&desc->bGUID, blan_guid, 16) | 2767 | if (memcmp(&desc->bGUID, blan_guid, 16) |
2768 | || memcmp(&desc->bGUID, blan_guid, 16) ) { | 2768 | && memcmp(&desc->bGUID, blan_guid, 16) ) { |
2769 | /* hey, this one might _really_ be MDLM! */ | 2769 | /* hey, this one might _really_ be MDLM! */ |
2770 | dev_dbg (&intf->dev, "MDLM guid\n"); | 2770 | dev_dbg (&intf->dev, "MDLM guid\n"); |
2771 | goto bad_desc; | 2771 | goto bad_desc; |
@@ -2797,11 +2797,13 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) | |||
2797 | * - bPad (ignored, for PADAFTER -- BLAN-only) | 2797 | * - bPad (ignored, for PADAFTER -- BLAN-only) |
2798 | * bits are: | 2798 | * bits are: |
2799 | * - 0x01 -- Zaurus framing (add CRC) | 2799 | * - 0x01 -- Zaurus framing (add CRC) |
2800 | * - 0x02 -- PADBEFORE | 2800 | * - 0x02 -- PADBEFORE (CRC includes some padding) |
2801 | * - 0x04 -- PADAFTER | 2801 | * - 0x04 -- PADAFTER (some padding after CRC) |
2802 | * - 0x08 -- "fermat" packet mangling (for hw bugs) | 2802 | * - 0x08 -- "fermat" packet mangling (for hw bugs) |
2803 | * the PADBEFORE appears not to matter; we interop | ||
2804 | * with devices that use it and those that don't. | ||
2803 | */ | 2805 | */ |
2804 | if (detail->bDetailData[1] != 0x01) { | 2806 | if ((detail->bDetailData[1] & ~02) != 0x01) { |
2805 | /* bmDataCapabilites == 0 would be fine too, | 2807 | /* bmDataCapabilites == 0 would be fine too, |
2806 | * but framing is minidriver-coupled for now. | 2808 | * but framing is minidriver-coupled for now. |
2807 | */ | 2809 | */ |
@@ -4071,9 +4073,6 @@ static const struct usb_device_id products [] = { | |||
4071 | USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader | 4073 | USB_DEVICE (0x8086, 0x07d3), // "blob" bootloader |
4072 | .driver_info = (unsigned long) &blob_info, | 4074 | .driver_info = (unsigned long) &blob_info, |
4073 | }, { | 4075 | }, { |
4074 | USB_DEVICE (0x22b8, 0x600c), // USBNET Motorola E680 | ||
4075 | .driver_info = (unsigned long) &linuxdev_info, | ||
4076 | }, { | ||
4077 | // Linux Ethernet/RNDIS gadget on pxa210/25x/26x | 4076 | // Linux Ethernet/RNDIS gadget on pxa210/25x/26x |
4078 | // e.g. Gumstix, current OpenZaurus, ... | 4077 | // e.g. Gumstix, current OpenZaurus, ... |
4079 | USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203), | 4078 | USB_DEVICE_VER (0x0525, 0xa4a2, 0x0203, 0x0203), |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index f34a9bb6a219..012e63e05806 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -89,6 +89,7 @@ static int interval; | |||
89 | 89 | ||
90 | static struct usb_device_id id_table_earthmate [] = { | 90 | static struct usb_device_id id_table_earthmate [] = { |
91 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 91 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
92 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, | ||
92 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
93 | }; | 94 | }; |
94 | 95 | ||
@@ -99,6 +100,7 @@ static struct usb_device_id id_table_cyphidcomrs232 [] = { | |||
99 | 100 | ||
100 | static struct usb_device_id id_table_combined [] = { | 101 | static struct usb_device_id id_table_combined [] = { |
101 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, | 102 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB) }, |
103 | { USB_DEVICE(VENDOR_ID_DELORME, PRODUCT_ID_EARTHMATEUSB_LT20) }, | ||
102 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, | 104 | { USB_DEVICE(VENDOR_ID_CYPRESS, PRODUCT_ID_CYPHIDCOM) }, |
103 | { } /* Terminating entry */ | 105 | { } /* Terminating entry */ |
104 | }; | 106 | }; |
diff --git a/drivers/usb/serial/cypress_m8.h b/drivers/usb/serial/cypress_m8.h index 1012ee6b19ce..1fa119efe41a 100644 --- a/drivers/usb/serial/cypress_m8.h +++ b/drivers/usb/serial/cypress_m8.h | |||
@@ -13,6 +13,7 @@ | |||
13 | /* DeLorme Earthmate USB - a GPS device */ | 13 | /* DeLorme Earthmate USB - a GPS device */ |
14 | #define VENDOR_ID_DELORME 0x1163 | 14 | #define VENDOR_ID_DELORME 0x1163 |
15 | #define PRODUCT_ID_EARTHMATEUSB 0x0100 | 15 | #define PRODUCT_ID_EARTHMATEUSB 0x0100 |
16 | #define PRODUCT_ID_EARTHMATEUSB_LT20 0x0200 | ||
16 | 17 | ||
17 | /* Cypress HID->COM RS232 Adapter */ | 18 | /* Cypress HID->COM RS232 Adapter */ |
18 | #define VENDOR_ID_CYPRESS 0x04b4 | 19 | #define VENDOR_ID_CYPRESS 0x04b4 |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 208a68ceb63b..7705070191d9 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -1312,7 +1312,7 @@ int fb_get_options(char *name, char **option) | |||
1312 | * Returns zero. | 1312 | * Returns zero. |
1313 | * | 1313 | * |
1314 | */ | 1314 | */ |
1315 | int __init video_setup(char *options) | 1315 | static int __init video_setup(char *options) |
1316 | { | 1316 | { |
1317 | int i, global = 0; | 1317 | int i, global = 0; |
1318 | 1318 | ||
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbsysfs.c index 2bdda4010b81..c78a2c5961d3 100644 --- a/drivers/video/fbsysfs.c +++ b/drivers/video/fbsysfs.c | |||
@@ -354,7 +354,7 @@ static ssize_t show_pan(struct class_device *class_device, char *buf) | |||
354 | fb_info->var.xoffset); | 354 | fb_info->var.xoffset); |
355 | } | 355 | } |
356 | 356 | ||
357 | struct class_device_attribute class_device_attrs[] = { | 357 | static struct class_device_attribute class_device_attrs[] = { |
358 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), | 358 | __ATTR(bits_per_pixel, S_IRUGO|S_IWUSR, show_bpp, store_bpp), |
359 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), | 359 | __ATTR(blank, S_IRUGO|S_IWUSR, show_blank, store_blank), |
360 | __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap), | 360 | __ATTR(color_map, S_IRUGO|S_IWUSR, show_cmap, store_cmap), |
diff --git a/drivers/video/sis/init.c b/drivers/video/sis/init.c index 1994054d45ff..ecfd72178dbb 100644 --- a/drivers/video/sis/init.c +++ b/drivers/video/sis/init.c | |||
@@ -1384,7 +1384,7 @@ SiSInitPCIetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | |||
1384 | /* HELPER: SetLVDSetc */ | 1384 | /* HELPER: SetLVDSetc */ |
1385 | /*********************************************/ | 1385 | /*********************************************/ |
1386 | 1386 | ||
1387 | void | 1387 | static void |
1388 | SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | 1388 | SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) |
1389 | { | 1389 | { |
1390 | USHORT temp; | 1390 | USHORT temp; |
@@ -1625,7 +1625,7 @@ SiS_ResetSegmentRegisters(SiS_Private *SiS_Pr,PSIS_HW_INFO HwInfo) | |||
1625 | /* HELPER: GetVBType */ | 1625 | /* HELPER: GetVBType */ |
1626 | /*********************************************/ | 1626 | /*********************************************/ |
1627 | 1627 | ||
1628 | void | 1628 | static void |
1629 | SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | 1629 | SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) |
1630 | { | 1630 | { |
1631 | USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27; | 1631 | USHORT flag=0, rev=0, nolcd=0, p4_0f, p4_25, p4_27; |
diff --git a/drivers/video/sis/init.h b/drivers/video/sis/init.h index 35030d300431..7e36b7ac1470 100644 --- a/drivers/video/sis/init.h +++ b/drivers/video/sis/init.h | |||
@@ -2394,11 +2394,9 @@ void SiS_SetRegOR(SISIOADDRESS Port,USHORT Index, USHORT DataOR); | |||
2394 | void SiS_DisplayOn(SiS_Private *SiS_Pr); | 2394 | void SiS_DisplayOn(SiS_Private *SiS_Pr); |
2395 | void SiS_DisplayOff(SiS_Private *SiS_Pr); | 2395 | void SiS_DisplayOff(SiS_Private *SiS_Pr); |
2396 | void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); | 2396 | void SiSRegInit(SiS_Private *SiS_Pr, SISIOADDRESS BaseAddr); |
2397 | void SiSSetLVDSetc(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | ||
2398 | BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 2397 | BOOLEAN SiSDetermineROMLayout661(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
2399 | void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); | 2398 | void SiS_SetEnableDstn(SiS_Private *SiS_Pr, int enable); |
2400 | void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); | 2399 | void SiS_SetEnableFstn(SiS_Private *SiS_Pr, int enable); |
2401 | void SiS_GetVBType(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | ||
2402 | BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex); | 2400 | BOOLEAN SiS_SearchModeID(SiS_Private *SiS_Pr, USHORT *ModeNo, USHORT *ModeIdIndex); |
2403 | UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex); | 2401 | UCHAR SiS_GetModePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex); |
2404 | USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex); | 2402 | USHORT SiS_GetColorDepth(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex); |
@@ -2444,7 +2442,6 @@ extern void SiS_GetLCDResInfo(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT Mod | |||
2444 | extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 2442 | extern void SiS_SetYPbPr(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
2445 | extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); | 2443 | extern void SiS_SetTVMode(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); |
2446 | extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 2444 | extern void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
2447 | extern void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | ||
2448 | extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO); | 2445 | extern void SiS_DisableBridge(SiS_Private *, PSIS_HW_INFO); |
2449 | extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT); | 2446 | extern BOOLEAN SiS_SetCRT2Group(SiS_Private *, PSIS_HW_INFO, USHORT); |
2450 | extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, | 2447 | extern USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, |
diff --git a/drivers/video/sis/init301.c b/drivers/video/sis/init301.c index 2bc5b8097910..274dacd54bb8 100644 --- a/drivers/video/sis/init301.c +++ b/drivers/video/sis/init301.c | |||
@@ -86,6 +86,7 @@ | |||
86 | #define SiS_I2CDELAYSHORT 150 | 86 | #define SiS_I2CDELAYSHORT 150 |
87 | 87 | ||
88 | static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr); | 88 | static USHORT SiS_GetBIOSLCDResInfo(SiS_Private *SiS_Pr); |
89 | static void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx); | ||
89 | 90 | ||
90 | /*********************************************/ | 91 | /*********************************************/ |
91 | /* HELPER: Lock/Unlock CRT2 */ | 92 | /* HELPER: Lock/Unlock CRT2 */ |
@@ -100,7 +101,7 @@ SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | |||
100 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); | 101 | SiS_SetRegOR(SiS_Pr->SiS_Part1Port,0x24,0x01); |
101 | } | 102 | } |
102 | 103 | ||
103 | void | 104 | static void |
104 | SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | 105 | SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) |
105 | { | 106 | { |
106 | if(HwInfo->jChipType >= SIS_315H) | 107 | if(HwInfo->jChipType >= SIS_315H) |
@@ -4236,7 +4237,7 @@ SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | |||
4236 | * from outside the context of a mode switch! | 4237 | * from outside the context of a mode switch! |
4237 | * MUST call getVBType before calling this | 4238 | * MUST call getVBType before calling this |
4238 | */ | 4239 | */ |
4239 | void | 4240 | static void |
4240 | SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) | 4241 | SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo) |
4241 | { | 4242 | { |
4242 | USHORT temp=0,tempah; | 4243 | USHORT temp=0,tempah; |
@@ -9219,7 +9220,7 @@ SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) | |||
9219 | SiS_SetChReg(SiS_Pr, tempbx, 0); | 9220 | SiS_SetChReg(SiS_Pr, tempbx, 0); |
9220 | } | 9221 | } |
9221 | 9222 | ||
9222 | void | 9223 | static void |
9223 | SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) | 9224 | SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) |
9224 | { | 9225 | { |
9225 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) | 9226 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) |
@@ -9323,7 +9324,7 @@ SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempbx) | |||
9323 | 9324 | ||
9324 | /* Read from Chrontel 70xx */ | 9325 | /* Read from Chrontel 70xx */ |
9325 | /* Parameter is [Register no (S7-S0)] */ | 9326 | /* Parameter is [Register no (S7-S0)] */ |
9326 | USHORT | 9327 | static USHORT |
9327 | SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) | 9328 | SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempbx) |
9328 | { | 9329 | { |
9329 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) | 9330 | if(SiS_Pr->SiS_IF_DEF_CH70xx == 1) |
diff --git a/drivers/video/sis/init301.h b/drivers/video/sis/init301.h index f05aebc994b4..f84eb54164a5 100644 --- a/drivers/video/sis/init301.h +++ b/drivers/video/sis/init301.h | |||
@@ -293,7 +293,6 @@ static UCHAR SiS300_TrumpionData[7][80] = { | |||
293 | #endif | 293 | #endif |
294 | 294 | ||
295 | void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 295 | void SiS_UnLockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
296 | void SiS_LockCRT2(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | ||
297 | void SiS_EnableCRT2(SiS_Private *SiS_Pr); | 296 | void SiS_EnableCRT2(SiS_Private *SiS_Pr); |
298 | USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); | 297 | USHORT SiS_GetRatePtr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, PSIS_HW_INFO HwInfo); |
299 | void SiS_WaitRetrace1(SiS_Private *SiS_Pr); | 298 | void SiS_WaitRetrace1(SiS_Private *SiS_Pr); |
@@ -310,7 +309,6 @@ USHORT SiS_GetVCLK2Ptr(SiS_Private *SiS_Pr, USHORT ModeNo, USHORT ModeIdIndex, | |||
310 | USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo); | 309 | USHORT RefreshRateTableIndex, PSIS_HW_INFO HwInfo); |
311 | USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex); | 310 | USHORT SiS_GetResInfo(SiS_Private *SiS_Pr,USHORT ModeNo,USHORT ModeIdIndex); |
312 | void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 311 | void SiS_DisableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
313 | void SiS_EnableBridge(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | ||
314 | BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo); | 312 | BOOLEAN SiS_SetCRT2Group(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo, USHORT ModeNo); |
315 | void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 313 | void SiS_SiS30xBLOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
316 | void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 314 | void SiS_SiS30xBLOff(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
@@ -319,8 +317,6 @@ void SiS_SetCH700x(SiS_Private *SiS_Pr, USHORT tempax); | |||
319 | USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax); | 317 | USHORT SiS_GetCH700x(SiS_Private *SiS_Pr, USHORT tempax); |
320 | void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax); | 318 | void SiS_SetCH701x(SiS_Private *SiS_Pr, USHORT tempax); |
321 | USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax); | 319 | USHORT SiS_GetCH701x(SiS_Private *SiS_Pr, USHORT tempax); |
322 | void SiS_SetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); | ||
323 | USHORT SiS_GetCH70xx(SiS_Private *SiS_Pr, USHORT tempax); | ||
324 | void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); | 320 | void SiS_SetCH70xxANDOR(SiS_Private *SiS_Pr, USHORT tempax,USHORT tempbh); |
325 | #ifdef SIS315H | 321 | #ifdef SIS315H |
326 | static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); | 322 | static void SiS_Chrontel701xOn(SiS_Private *SiS_Pr, PSIS_HW_INFO HwInfo); |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index b773c98f6513..698266036819 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -4762,7 +4762,8 @@ static void __devinit sisfb_post_sis315330(struct pci_dev *pdev) | |||
4762 | #endif | 4762 | #endif |
4763 | 4763 | ||
4764 | 4764 | ||
4765 | int __devinit sisfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 4765 | static int __devinit sisfb_probe(struct pci_dev *pdev, |
4766 | const struct pci_device_id *ent) | ||
4766 | { | 4767 | { |
4767 | struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data]; | 4768 | struct sisfb_chip_info *chipinfo = &sisfb_chip_info[ent->driver_data]; |
4768 | struct sis_video_info *ivideo = NULL; | 4769 | struct sis_video_info *ivideo = NULL; |
@@ -5940,7 +5941,7 @@ MODULE_PARM_DESC(videoram, | |||
5940 | #endif | 5941 | #endif |
5941 | #endif | 5942 | #endif |
5942 | 5943 | ||
5943 | int __devinit sisfb_init_module(void) | 5944 | static int __devinit sisfb_init_module(void) |
5944 | { | 5945 | { |
5945 | sisfb_setdefaultparms(); | 5946 | sisfb_setdefaultparms(); |
5946 | 5947 | ||
diff --git a/fs/bad_inode.c b/fs/bad_inode.c index 672a31924f3c..e172180a1d8c 100644 --- a/fs/bad_inode.c +++ b/fs/bad_inode.c | |||
@@ -47,7 +47,7 @@ static struct file_operations bad_file_ops = | |||
47 | .get_unmapped_area = EIO_ERROR, | 47 | .get_unmapped_area = EIO_ERROR, |
48 | }; | 48 | }; |
49 | 49 | ||
50 | struct inode_operations bad_inode_ops = | 50 | static struct inode_operations bad_inode_ops = |
51 | { | 51 | { |
52 | .create = EIO_ERROR, | 52 | .create = EIO_ERROR, |
53 | .lookup = EIO_ERROR, | 53 | .lookup = EIO_ERROR, |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index ce9423bb2de3..c374be51b041 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -251,7 +251,7 @@ create_elf_tables(struct linux_binprm *bprm, struct elfhdr * exec, | |||
251 | } | 251 | } |
252 | 252 | ||
253 | /* Populate argv and envp */ | 253 | /* Populate argv and envp */ |
254 | p = current->mm->arg_start; | 254 | p = current->mm->arg_end = current->mm->arg_start; |
255 | while (argc-- > 0) { | 255 | while (argc-- > 0) { |
256 | size_t len; | 256 | size_t len; |
257 | __put_user((elf_addr_t)p, argv++); | 257 | __put_user((elf_addr_t)p, argv++); |
@@ -1301,7 +1301,7 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1301 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | 1301 | static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, |
1302 | struct mm_struct *mm) | 1302 | struct mm_struct *mm) |
1303 | { | 1303 | { |
1304 | int i, len; | 1304 | unsigned int i, len; |
1305 | 1305 | ||
1306 | /* first copy the parameters from user space */ | 1306 | /* first copy the parameters from user space */ |
1307 | memset(psinfo, 0, sizeof(struct elf_prpsinfo)); | 1307 | memset(psinfo, 0, sizeof(struct elf_prpsinfo)); |
diff --git a/fs/block_dev.c b/fs/block_dev.c index d19d07c49ad3..c0cbd1bc1a02 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -530,7 +530,7 @@ int check_disk_change(struct block_device *bdev) | |||
530 | if (!bdops->media_changed(bdev->bd_disk)) | 530 | if (!bdops->media_changed(bdev->bd_disk)) |
531 | return 0; | 531 | return 0; |
532 | 532 | ||
533 | if (__invalidate_device(bdev, 0)) | 533 | if (__invalidate_device(bdev)) |
534 | printk("VFS: busy inodes on changed media.\n"); | 534 | printk("VFS: busy inodes on changed media.\n"); |
535 | 535 | ||
536 | if (bdops->revalidate_disk) | 536 | if (bdops->revalidate_disk) |
diff --git a/fs/buffer.c b/fs/buffer.c index 5f525b3c6d9f..7e9e409feaa7 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -1210,7 +1210,7 @@ grow_buffers(struct block_device *bdev, sector_t block, int size) | |||
1210 | return 1; | 1210 | return 1; |
1211 | } | 1211 | } |
1212 | 1212 | ||
1213 | struct buffer_head * | 1213 | static struct buffer_head * |
1214 | __getblk_slow(struct block_device *bdev, sector_t block, int size) | 1214 | __getblk_slow(struct block_device *bdev, sector_t block, int size) |
1215 | { | 1215 | { |
1216 | /* Size must be multiple of hard sectorsize */ | 1216 | /* Size must be multiple of hard sectorsize */ |
@@ -1809,7 +1809,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page, | |||
1809 | } while (bh != head); | 1809 | } while (bh != head); |
1810 | 1810 | ||
1811 | do { | 1811 | do { |
1812 | get_bh(bh); | ||
1813 | if (!buffer_mapped(bh)) | 1812 | if (!buffer_mapped(bh)) |
1814 | continue; | 1813 | continue; |
1815 | /* | 1814 | /* |
@@ -1838,7 +1837,6 @@ static int __block_write_full_page(struct inode *inode, struct page *page, | |||
1838 | */ | 1837 | */ |
1839 | BUG_ON(PageWriteback(page)); | 1838 | BUG_ON(PageWriteback(page)); |
1840 | set_page_writeback(page); | 1839 | set_page_writeback(page); |
1841 | unlock_page(page); | ||
1842 | 1840 | ||
1843 | do { | 1841 | do { |
1844 | struct buffer_head *next = bh->b_this_page; | 1842 | struct buffer_head *next = bh->b_this_page; |
@@ -1846,9 +1844,9 @@ static int __block_write_full_page(struct inode *inode, struct page *page, | |||
1846 | submit_bh(WRITE, bh); | 1844 | submit_bh(WRITE, bh); |
1847 | nr_underway++; | 1845 | nr_underway++; |
1848 | } | 1846 | } |
1849 | put_bh(bh); | ||
1850 | bh = next; | 1847 | bh = next; |
1851 | } while (bh != head); | 1848 | } while (bh != head); |
1849 | unlock_page(page); | ||
1852 | 1850 | ||
1853 | err = 0; | 1851 | err = 0; |
1854 | done: | 1852 | done: |
@@ -1887,7 +1885,6 @@ recover: | |||
1887 | bh = head; | 1885 | bh = head; |
1888 | /* Recovery: lock and submit the mapped buffers */ | 1886 | /* Recovery: lock and submit the mapped buffers */ |
1889 | do { | 1887 | do { |
1890 | get_bh(bh); | ||
1891 | if (buffer_mapped(bh) && buffer_dirty(bh)) { | 1888 | if (buffer_mapped(bh) && buffer_dirty(bh)) { |
1892 | lock_buffer(bh); | 1889 | lock_buffer(bh); |
1893 | mark_buffer_async_write(bh); | 1890 | mark_buffer_async_write(bh); |
@@ -1910,7 +1907,6 @@ recover: | |||
1910 | submit_bh(WRITE, bh); | 1907 | submit_bh(WRITE, bh); |
1911 | nr_underway++; | 1908 | nr_underway++; |
1912 | } | 1909 | } |
1913 | put_bh(bh); | ||
1914 | bh = next; | 1910 | bh = next; |
1915 | } while (bh != head); | 1911 | } while (bh != head); |
1916 | goto done; | 1912 | goto done; |
@@ -1953,7 +1949,7 @@ static int __block_prepare_write(struct inode *inode, struct page *page, | |||
1953 | if (!buffer_mapped(bh)) { | 1949 | if (!buffer_mapped(bh)) { |
1954 | err = get_block(inode, block, bh, 1); | 1950 | err = get_block(inode, block, bh, 1); |
1955 | if (err) | 1951 | if (err) |
1956 | goto out; | 1952 | break; |
1957 | if (buffer_new(bh)) { | 1953 | if (buffer_new(bh)) { |
1958 | clear_buffer_new(bh); | 1954 | clear_buffer_new(bh); |
1959 | unmap_underlying_metadata(bh->b_bdev, | 1955 | unmap_underlying_metadata(bh->b_bdev, |
@@ -1995,10 +1991,12 @@ static int __block_prepare_write(struct inode *inode, struct page *page, | |||
1995 | while(wait_bh > wait) { | 1991 | while(wait_bh > wait) { |
1996 | wait_on_buffer(*--wait_bh); | 1992 | wait_on_buffer(*--wait_bh); |
1997 | if (!buffer_uptodate(*wait_bh)) | 1993 | if (!buffer_uptodate(*wait_bh)) |
1998 | return -EIO; | 1994 | err = -EIO; |
1999 | } | 1995 | } |
2000 | return 0; | 1996 | if (!err) |
2001 | out: | 1997 | return err; |
1998 | |||
1999 | /* Error case: */ | ||
2002 | /* | 2000 | /* |
2003 | * Zero out any newly allocated blocks to avoid exposing stale | 2001 | * Zero out any newly allocated blocks to avoid exposing stale |
2004 | * data. If BH_New is set, we know that the block was newly | 2002 | * data. If BH_New is set, we know that the block was newly |
@@ -2096,9 +2094,12 @@ int block_read_full_page(struct page *page, get_block_t *get_block) | |||
2096 | continue; | 2094 | continue; |
2097 | 2095 | ||
2098 | if (!buffer_mapped(bh)) { | 2096 | if (!buffer_mapped(bh)) { |
2097 | int err = 0; | ||
2098 | |||
2099 | fully_mapped = 0; | 2099 | fully_mapped = 0; |
2100 | if (iblock < lblock) { | 2100 | if (iblock < lblock) { |
2101 | if (get_block(inode, iblock, bh, 0)) | 2101 | err = get_block(inode, iblock, bh, 0); |
2102 | if (err) | ||
2102 | SetPageError(page); | 2103 | SetPageError(page); |
2103 | } | 2104 | } |
2104 | if (!buffer_mapped(bh)) { | 2105 | if (!buffer_mapped(bh)) { |
@@ -2106,7 +2107,8 @@ int block_read_full_page(struct page *page, get_block_t *get_block) | |||
2106 | memset(kaddr + i * blocksize, 0, blocksize); | 2107 | memset(kaddr + i * blocksize, 0, blocksize); |
2107 | flush_dcache_page(page); | 2108 | flush_dcache_page(page); |
2108 | kunmap_atomic(kaddr, KM_USER0); | 2109 | kunmap_atomic(kaddr, KM_USER0); |
2109 | set_buffer_uptodate(bh); | 2110 | if (!err) |
2111 | set_buffer_uptodate(bh); | ||
2110 | continue; | 2112 | continue; |
2111 | } | 2113 | } |
2112 | /* | 2114 | /* |
@@ -3115,7 +3117,7 @@ void __init buffer_init(void) | |||
3115 | 3117 | ||
3116 | bh_cachep = kmem_cache_create("buffer_head", | 3118 | bh_cachep = kmem_cache_create("buffer_head", |
3117 | sizeof(struct buffer_head), 0, | 3119 | sizeof(struct buffer_head), 0, |
3118 | SLAB_PANIC, init_buffer_head, NULL); | 3120 | SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_buffer_head, NULL); |
3119 | 3121 | ||
3120 | /* | 3122 | /* |
3121 | * Limit the bh occupancy to 10% of ZONE_NORMAL | 3123 | * Limit the bh occupancy to 10% of ZONE_NORMAL |
diff --git a/fs/char_dev.c b/fs/char_dev.c index a745b1d9e545..c1e3537909fc 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -328,7 +328,7 @@ void cd_forget(struct inode *inode) | |||
328 | spin_unlock(&cdev_lock); | 328 | spin_unlock(&cdev_lock); |
329 | } | 329 | } |
330 | 330 | ||
331 | void cdev_purge(struct cdev *cdev) | 331 | static void cdev_purge(struct cdev *cdev) |
332 | { | 332 | { |
333 | spin_lock(&cdev_lock); | 333 | spin_lock(&cdev_lock); |
334 | while (!list_empty(&cdev->list)) { | 334 | while (!list_empty(&cdev->list)) { |
diff --git a/fs/cifs/README b/fs/cifs/README index 7b4ac096cd11..e74df0c73256 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -32,9 +32,9 @@ the cifs download to your kernel build directory e.g. | |||
32 | 6) make modules (or "make" if CIFS VFS not to be built as a module) | 32 | 6) make modules (or "make" if CIFS VFS not to be built as a module) |
33 | 33 | ||
34 | For Linux 2.6: | 34 | For Linux 2.6: |
35 | 1) Download the kernel (e.g. from http://www.kernel.org or from bitkeeper | 35 | 1) Download the kernel (e.g. from http://www.kernel.org) |
36 | at bk://linux.bkbits.net/linux-2.5) and change directory into the top | 36 | and change directory into the top of the kernel directory tree |
37 | of the kernel directory tree (e.g. /usr/src/linux-2.5.73) | 37 | (e.g. /usr/src/linux-2.5.73) |
38 | 2) make menuconfig (or make xconfig) | 38 | 2) make menuconfig (or make xconfig) |
39 | 3) select cifs from within the network filesystem choices | 39 | 3) select cifs from within the network filesystem choices |
40 | 4) save and exit | 40 | 4) save and exit |
diff --git a/fs/dcache.c b/fs/dcache.c index 496a4e08369c..3aa8a7e980d8 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -39,7 +39,7 @@ int sysctl_vfs_cache_pressure = 100; | |||
39 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); | 39 | EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); |
40 | 40 | ||
41 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); | 41 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); |
42 | seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; | 42 | static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; |
43 | 43 | ||
44 | EXPORT_SYMBOL(dcache_lock); | 44 | EXPORT_SYMBOL(dcache_lock); |
45 | 45 | ||
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 05b966cd6f76..9900e333655a 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -320,7 +320,7 @@ static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type, | |||
320 | /* | 320 | /* |
321 | * This semaphore is used to serialize ep_free() and eventpoll_release_file(). | 321 | * This semaphore is used to serialize ep_free() and eventpoll_release_file(). |
322 | */ | 322 | */ |
323 | struct semaphore epsem; | 323 | static struct semaphore epsem; |
324 | 324 | ||
325 | /* Safe wake up implementation */ | 325 | /* Safe wake up implementation */ |
326 | static struct poll_safewake psw; | 326 | static struct poll_safewake psw; |
@@ -197,7 +197,8 @@ static int count(char __user * __user * argv, int max) | |||
197 | * memory to free pages in kernel mem. These are in a format ready | 197 | * memory to free pages in kernel mem. These are in a format ready |
198 | * to be put directly into the top of new user memory. | 198 | * to be put directly into the top of new user memory. |
199 | */ | 199 | */ |
200 | int copy_strings(int argc,char __user * __user * argv, struct linux_binprm *bprm) | 200 | static int copy_strings(int argc, char __user * __user * argv, |
201 | struct linux_binprm *bprm) | ||
201 | { | 202 | { |
202 | struct page *kmapped_page = NULL; | 203 | struct page *kmapped_page = NULL; |
203 | char *kaddr = NULL; | 204 | char *kaddr = NULL; |
@@ -868,9 +869,11 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
868 | if (current->euid == current->uid && current->egid == current->gid) | 869 | if (current->euid == current->uid && current->egid == current->gid) |
869 | current->mm->dumpable = 1; | 870 | current->mm->dumpable = 1; |
870 | name = bprm->filename; | 871 | name = bprm->filename; |
872 | |||
873 | /* Copies the binary name from after last slash */ | ||
871 | for (i=0; (ch = *(name++)) != '\0';) { | 874 | for (i=0; (ch = *(name++)) != '\0';) { |
872 | if (ch == '/') | 875 | if (ch == '/') |
873 | i = 0; | 876 | i = 0; /* overwrite what we wrote */ |
874 | else | 877 | else |
875 | if (i < (sizeof(tcomm) - 1)) | 878 | if (i < (sizeof(tcomm) - 1)) |
876 | tcomm[i++] = ch; | 879 | tcomm[i++] = ch; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index ea5888688f94..0d5fa73b18dc 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -844,12 +844,6 @@ get_block: | |||
844 | return ret; | 844 | return ret; |
845 | } | 845 | } |
846 | 846 | ||
847 | static int ext3_writepages_get_block(struct inode *inode, sector_t iblock, | ||
848 | struct buffer_head *bh, int create) | ||
849 | { | ||
850 | return ext3_direct_io_get_blocks(inode, iblock, 1, bh, create); | ||
851 | } | ||
852 | |||
853 | /* | 847 | /* |
854 | * `handle' can be NULL if create is zero | 848 | * `handle' can be NULL if create is zero |
855 | */ | 849 | */ |
@@ -1323,45 +1317,6 @@ out_fail: | |||
1323 | return ret; | 1317 | return ret; |
1324 | } | 1318 | } |
1325 | 1319 | ||
1326 | static int | ||
1327 | ext3_writeback_writepage_helper(struct page *page, | ||
1328 | struct writeback_control *wbc) | ||
1329 | { | ||
1330 | return block_write_full_page(page, ext3_get_block, wbc); | ||
1331 | } | ||
1332 | |||
1333 | static int | ||
1334 | ext3_writeback_writepages(struct address_space *mapping, | ||
1335 | struct writeback_control *wbc) | ||
1336 | { | ||
1337 | struct inode *inode = mapping->host; | ||
1338 | handle_t *handle = NULL; | ||
1339 | int err, ret = 0; | ||
1340 | |||
1341 | if (!mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) | ||
1342 | return ret; | ||
1343 | |||
1344 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); | ||
1345 | if (IS_ERR(handle)) { | ||
1346 | ret = PTR_ERR(handle); | ||
1347 | return ret; | ||
1348 | } | ||
1349 | |||
1350 | ret = __mpage_writepages(mapping, wbc, ext3_writepages_get_block, | ||
1351 | ext3_writeback_writepage_helper); | ||
1352 | |||
1353 | /* | ||
1354 | * Need to reaquire the handle since ext3_writepages_get_block() | ||
1355 | * can restart the handle | ||
1356 | */ | ||
1357 | handle = journal_current_handle(); | ||
1358 | |||
1359 | err = ext3_journal_stop(handle); | ||
1360 | if (!ret) | ||
1361 | ret = err; | ||
1362 | return ret; | ||
1363 | } | ||
1364 | |||
1365 | static int ext3_writeback_writepage(struct page *page, | 1320 | static int ext3_writeback_writepage(struct page *page, |
1366 | struct writeback_control *wbc) | 1321 | struct writeback_control *wbc) |
1367 | { | 1322 | { |
@@ -1599,7 +1554,6 @@ static struct address_space_operations ext3_writeback_aops = { | |||
1599 | .readpage = ext3_readpage, | 1554 | .readpage = ext3_readpage, |
1600 | .readpages = ext3_readpages, | 1555 | .readpages = ext3_readpages, |
1601 | .writepage = ext3_writeback_writepage, | 1556 | .writepage = ext3_writeback_writepage, |
1602 | .writepages = ext3_writeback_writepages, | ||
1603 | .sync_page = block_sync_page, | 1557 | .sync_page = block_sync_page, |
1604 | .prepare_write = ext3_prepare_write, | 1558 | .prepare_write = ext3_prepare_write, |
1605 | .commit_write = ext3_writeback_commit_write, | 1559 | .commit_write = ext3_writeback_commit_write, |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 545b440a2d2f..981ccb233ef5 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -225,8 +225,16 @@ void __ext3_std_error (struct super_block * sb, const char * function, | |||
225 | int errno) | 225 | int errno) |
226 | { | 226 | { |
227 | char nbuf[16]; | 227 | char nbuf[16]; |
228 | const char *errstr = ext3_decode_error(sb, errno, nbuf); | 228 | const char *errstr; |
229 | |||
230 | /* Special case: if the error is EROFS, and we're not already | ||
231 | * inside a transaction, then there's really no point in logging | ||
232 | * an error. */ | ||
233 | if (errno == -EROFS && journal_current_handle() == NULL && | ||
234 | (sb->s_flags & MS_RDONLY)) | ||
235 | return; | ||
229 | 236 | ||
237 | errstr = ext3_decode_error(sb, errno, nbuf); | ||
230 | printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", | 238 | printk (KERN_CRIT "EXT3-fs error (device %s) in %s: %s\n", |
231 | sb->s_id, function, errstr); | 239 | sb->s_id, function, errstr); |
232 | 240 | ||
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e6c63d9cac7b..14a0d339d036 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -991,13 +991,17 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
991 | goto out_put; | 991 | goto out_put; |
992 | 992 | ||
993 | err = read_inode(root_inode); | 993 | err = read_inode(root_inode); |
994 | if(err) | 994 | if(err){ |
995 | goto out_put; | 995 | /* No iput in this case because the dput does that for us */ |
996 | dput(sb->s_root); | ||
997 | sb->s_root = NULL; | ||
998 | goto out_free; | ||
999 | } | ||
996 | 1000 | ||
997 | return(0); | 1001 | return(0); |
998 | 1002 | ||
999 | out_put: | 1003 | out_put: |
1000 | iput(root_inode); | 1004 | iput(root_inode); |
1001 | out_free: | 1005 | out_free: |
1002 | kfree(name); | 1006 | kfree(name); |
1003 | out: | 1007 | out: |
diff --git a/fs/inode.c b/fs/inode.c index af8fd78d2099..801fe7f36280 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -26,7 +26,6 @@ | |||
26 | * This is needed for the following functions: | 26 | * This is needed for the following functions: |
27 | * - inode_has_buffers | 27 | * - inode_has_buffers |
28 | * - invalidate_inode_buffers | 28 | * - invalidate_inode_buffers |
29 | * - fsync_bdev | ||
30 | * - invalidate_bdev | 29 | * - invalidate_bdev |
31 | * | 30 | * |
32 | * FIXME: remove all knowledge of the buffer layer from this file | 31 | * FIXME: remove all knowledge of the buffer layer from this file |
@@ -332,14 +331,6 @@ static int invalidate_list(struct list_head *head, struct list_head *dispose) | |||
332 | return busy; | 331 | return busy; |
333 | } | 332 | } |
334 | 333 | ||
335 | /* | ||
336 | * This is a two-stage process. First we collect all | ||
337 | * offending inodes onto the throw-away list, and in | ||
338 | * the second stage we actually dispose of them. This | ||
339 | * is because we don't want to sleep while messing | ||
340 | * with the global lists.. | ||
341 | */ | ||
342 | |||
343 | /** | 334 | /** |
344 | * invalidate_inodes - discard the inodes on a device | 335 | * invalidate_inodes - discard the inodes on a device |
345 | * @sb: superblock | 336 | * @sb: superblock |
@@ -366,16 +357,11 @@ int invalidate_inodes(struct super_block * sb) | |||
366 | 357 | ||
367 | EXPORT_SYMBOL(invalidate_inodes); | 358 | EXPORT_SYMBOL(invalidate_inodes); |
368 | 359 | ||
369 | int __invalidate_device(struct block_device *bdev, int do_sync) | 360 | int __invalidate_device(struct block_device *bdev) |
370 | { | 361 | { |
371 | struct super_block *sb; | 362 | struct super_block *sb = get_super(bdev); |
372 | int res; | 363 | int res = 0; |
373 | 364 | ||
374 | if (do_sync) | ||
375 | fsync_bdev(bdev); | ||
376 | |||
377 | res = 0; | ||
378 | sb = get_super(bdev); | ||
379 | if (sb) { | 365 | if (sb) { |
380 | /* | 366 | /* |
381 | * no need to lock the super, get_super holds the | 367 | * no need to lock the super, get_super holds the |
@@ -390,7 +376,6 @@ int __invalidate_device(struct block_device *bdev, int do_sync) | |||
390 | invalidate_bdev(bdev, 0); | 376 | invalidate_bdev(bdev, 0); |
391 | return res; | 377 | return res; |
392 | } | 378 | } |
393 | |||
394 | EXPORT_SYMBOL(__invalidate_device); | 379 | EXPORT_SYMBOL(__invalidate_device); |
395 | 380 | ||
396 | static int can_unuse(struct inode *inode) | 381 | static int can_unuse(struct inode *inode) |
@@ -1336,7 +1321,7 @@ void __init inode_init(unsigned long mempages) | |||
1336 | 1321 | ||
1337 | /* inode slab cache */ | 1322 | /* inode slab cache */ |
1338 | inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode), | 1323 | inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode), |
1339 | 0, SLAB_PANIC, init_once, NULL); | 1324 | 0, SLAB_RECLAIM_ACCOUNT|SLAB_PANIC, init_once, NULL); |
1340 | set_shrinker(DEFAULT_SEEKS, shrink_icache_memory); | 1325 | set_shrinker(DEFAULT_SEEKS, shrink_icache_memory); |
1341 | 1326 | ||
1342 | /* Hash may have been set up in inode_init_early */ | 1327 | /* Hash may have been set up in inode_init_early */ |
diff --git a/fs/jffs2/compr_rubin.c b/fs/jffs2/compr_rubin.c index 450d6624181f..09422388fb96 100644 --- a/fs/jffs2/compr_rubin.c +++ b/fs/jffs2/compr_rubin.c | |||
@@ -228,8 +228,10 @@ int jffs2_rubinmips_compress(unsigned char *data_in, unsigned char *cpage_out, | |||
228 | return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); | 228 | return rubin_do_compress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); |
229 | } | 229 | } |
230 | #endif | 230 | #endif |
231 | int jffs2_dynrubin_compress(unsigned char *data_in, unsigned char *cpage_out, | 231 | static int jffs2_dynrubin_compress(unsigned char *data_in, |
232 | uint32_t *sourcelen, uint32_t *dstlen, void *model) | 232 | unsigned char *cpage_out, |
233 | uint32_t *sourcelen, uint32_t *dstlen, | ||
234 | void *model) | ||
233 | { | 235 | { |
234 | int bits[8]; | 236 | int bits[8]; |
235 | unsigned char histo[256]; | 237 | unsigned char histo[256]; |
@@ -306,15 +308,19 @@ static void rubin_do_decompress(int bit_divider, int *bits, unsigned char *cdata | |||
306 | } | 308 | } |
307 | 309 | ||
308 | 310 | ||
309 | int jffs2_rubinmips_decompress(unsigned char *data_in, unsigned char *cpage_out, | 311 | static int jffs2_rubinmips_decompress(unsigned char *data_in, |
310 | uint32_t sourcelen, uint32_t dstlen, void *model) | 312 | unsigned char *cpage_out, |
313 | uint32_t sourcelen, uint32_t dstlen, | ||
314 | void *model) | ||
311 | { | 315 | { |
312 | rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); | 316 | rubin_do_decompress(BIT_DIVIDER_MIPS, bits_mips, data_in, cpage_out, sourcelen, dstlen); |
313 | return 0; | 317 | return 0; |
314 | } | 318 | } |
315 | 319 | ||
316 | int jffs2_dynrubin_decompress(unsigned char *data_in, unsigned char *cpage_out, | 320 | static int jffs2_dynrubin_decompress(unsigned char *data_in, |
317 | uint32_t sourcelen, uint32_t dstlen, void *model) | 321 | unsigned char *cpage_out, |
322 | uint32_t sourcelen, uint32_t dstlen, | ||
323 | void *model) | ||
318 | { | 324 | { |
319 | int bits[8]; | 325 | int bits[8]; |
320 | int c; | 326 | int c; |
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c index 9f9932c22adb..078a30e406b5 100644 --- a/fs/jffs2/compr_zlib.c +++ b/fs/jffs2/compr_zlib.c | |||
@@ -69,8 +69,10 @@ static void free_workspaces(void) | |||
69 | #define free_workspaces() do { } while(0) | 69 | #define free_workspaces() do { } while(0) |
70 | #endif /* __KERNEL__ */ | 70 | #endif /* __KERNEL__ */ |
71 | 71 | ||
72 | int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, | 72 | static int jffs2_zlib_compress(unsigned char *data_in, |
73 | uint32_t *sourcelen, uint32_t *dstlen, void *model) | 73 | unsigned char *cpage_out, |
74 | uint32_t *sourcelen, uint32_t *dstlen, | ||
75 | void *model) | ||
74 | { | 76 | { |
75 | int ret; | 77 | int ret; |
76 | 78 | ||
@@ -135,8 +137,10 @@ int jffs2_zlib_compress(unsigned char *data_in, unsigned char *cpage_out, | |||
135 | return ret; | 137 | return ret; |
136 | } | 138 | } |
137 | 139 | ||
138 | int jffs2_zlib_decompress(unsigned char *data_in, unsigned char *cpage_out, | 140 | static int jffs2_zlib_decompress(unsigned char *data_in, |
139 | uint32_t srclen, uint32_t destlen, void *model) | 141 | unsigned char *cpage_out, |
142 | uint32_t srclen, uint32_t destlen, | ||
143 | void *model) | ||
140 | { | 144 | { |
141 | int ret; | 145 | int ret; |
142 | int wbits = MAX_WBITS; | 146 | int wbits = MAX_WBITS; |
diff --git a/fs/locks.c b/fs/locks.c index 1792ce547af7..3fa6a7ce57a7 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -406,12 +406,12 @@ static void lease_release_private_callback(struct file_lock *fl) | |||
406 | fl->fl_file->f_owner.signum = 0; | 406 | fl->fl_file->f_owner.signum = 0; |
407 | } | 407 | } |
408 | 408 | ||
409 | int lease_mylease_callback(struct file_lock *fl, struct file_lock *try) | 409 | static int lease_mylease_callback(struct file_lock *fl, struct file_lock *try) |
410 | { | 410 | { |
411 | return fl->fl_file == try->fl_file; | 411 | return fl->fl_file == try->fl_file; |
412 | } | 412 | } |
413 | 413 | ||
414 | struct lock_manager_operations lease_manager_ops = { | 414 | static struct lock_manager_operations lease_manager_ops = { |
415 | .fl_break = lease_break_callback, | 415 | .fl_break = lease_break_callback, |
416 | .fl_release_private = lease_release_private_callback, | 416 | .fl_release_private = lease_release_private_callback, |
417 | .fl_mylease = lease_mylease_callback, | 417 | .fl_mylease = lease_mylease_callback, |
@@ -1274,7 +1274,7 @@ int fcntl_getlease(struct file *filp) | |||
1274 | * | 1274 | * |
1275 | * Called with kernel lock held. | 1275 | * Called with kernel lock held. |
1276 | */ | 1276 | */ |
1277 | int __setlease(struct file *filp, long arg, struct file_lock **flp) | 1277 | static int __setlease(struct file *filp, long arg, struct file_lock **flp) |
1278 | { | 1278 | { |
1279 | struct file_lock *fl, **before, **my_before = NULL, *lease = *flp; | 1279 | struct file_lock *fl, **before, **my_before = NULL, *lease = *flp; |
1280 | struct dentry *dentry = filp->f_dentry; | 1280 | struct dentry *dentry = filp->f_dentry; |
diff --git a/fs/mbcache.c b/fs/mbcache.c index f9e4d2700cd8..c7170b9221a3 100644 --- a/fs/mbcache.c +++ b/fs/mbcache.c | |||
@@ -57,7 +57,7 @@ | |||
57 | 57 | ||
58 | #define MB_CACHE_WRITER ((unsigned short)~0U >> 1) | 58 | #define MB_CACHE_WRITER ((unsigned short)~0U >> 1) |
59 | 59 | ||
60 | DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue); | 60 | static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue); |
61 | 61 | ||
62 | MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>"); | 62 | MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>"); |
63 | MODULE_DESCRIPTION("Meta block cache (for extended attributes)"); | 63 | MODULE_DESCRIPTION("Meta block cache (for extended attributes)"); |
diff --git a/fs/mpage.c b/fs/mpage.c index 32c7c8fcfce7..b92c0e64aefa 100644 --- a/fs/mpage.c +++ b/fs/mpage.c | |||
@@ -87,7 +87,7 @@ static int mpage_end_io_write(struct bio *bio, unsigned int bytes_done, int err) | |||
87 | return 0; | 87 | return 0; |
88 | } | 88 | } |
89 | 89 | ||
90 | struct bio *mpage_bio_submit(int rw, struct bio *bio) | 90 | static struct bio *mpage_bio_submit(int rw, struct bio *bio) |
91 | { | 91 | { |
92 | bio->bi_end_io = mpage_end_io_read; | 92 | bio->bi_end_io = mpage_end_io_read; |
93 | if (rw == WRITE) | 93 | if (rw == WRITE) |
@@ -627,15 +627,6 @@ int | |||
627 | mpage_writepages(struct address_space *mapping, | 627 | mpage_writepages(struct address_space *mapping, |
628 | struct writeback_control *wbc, get_block_t get_block) | 628 | struct writeback_control *wbc, get_block_t get_block) |
629 | { | 629 | { |
630 | return __mpage_writepages(mapping, wbc, get_block, | ||
631 | mapping->a_ops->writepage); | ||
632 | } | ||
633 | |||
634 | int | ||
635 | __mpage_writepages(struct address_space *mapping, | ||
636 | struct writeback_control *wbc, get_block_t get_block, | ||
637 | writepage_t writepage_fn) | ||
638 | { | ||
639 | struct backing_dev_info *bdi = mapping->backing_dev_info; | 630 | struct backing_dev_info *bdi = mapping->backing_dev_info; |
640 | struct bio *bio = NULL; | 631 | struct bio *bio = NULL; |
641 | sector_t last_block_in_bio = 0; | 632 | sector_t last_block_in_bio = 0; |
@@ -725,7 +716,7 @@ retry: | |||
725 | } else { | 716 | } else { |
726 | bio = __mpage_writepage(bio, page, get_block, | 717 | bio = __mpage_writepage(bio, page, get_block, |
727 | &last_block_in_bio, &ret, wbc, | 718 | &last_block_in_bio, &ret, wbc, |
728 | writepage_fn); | 719 | page->mapping->a_ops->writepage); |
729 | } | 720 | } |
730 | if (unlikely(ret == WRITEPAGE_ACTIVATE)) | 721 | if (unlikely(ret == WRITEPAGE_ACTIVATE)) |
731 | unlock_page(page); | 722 | unlock_page(page); |
@@ -755,7 +746,6 @@ retry: | |||
755 | return ret; | 746 | return ret; |
756 | } | 747 | } |
757 | EXPORT_SYMBOL(mpage_writepages); | 748 | EXPORT_SYMBOL(mpage_writepages); |
758 | EXPORT_SYMBOL(__mpage_writepages); | ||
759 | 749 | ||
760 | int mpage_writepage(struct page *page, get_block_t get_block, | 750 | int mpage_writepage(struct page *page, get_block_t get_block, |
761 | struct writeback_control *wbc) | 751 | struct writeback_control *wbc) |
diff --git a/fs/namei.c b/fs/namei.c index 0f76fd75591b..dd78f01b6de8 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1580,6 +1580,7 @@ enoent: | |||
1580 | fail: | 1580 | fail: |
1581 | return dentry; | 1581 | return dentry; |
1582 | } | 1582 | } |
1583 | EXPORT_SYMBOL_GPL(lookup_create); | ||
1583 | 1584 | ||
1584 | int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) | 1585 | int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) |
1585 | { | 1586 | { |
@@ -2071,8 +2072,8 @@ exit: | |||
2071 | * ->i_sem on parents, which works but leads to some truely excessive | 2072 | * ->i_sem on parents, which works but leads to some truely excessive |
2072 | * locking]. | 2073 | * locking]. |
2073 | */ | 2074 | */ |
2074 | int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | 2075 | static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, |
2075 | struct inode *new_dir, struct dentry *new_dentry) | 2076 | struct inode *new_dir, struct dentry *new_dentry) |
2076 | { | 2077 | { |
2077 | int error = 0; | 2078 | int error = 0; |
2078 | struct inode *target; | 2079 | struct inode *target; |
@@ -2116,8 +2117,8 @@ int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2116 | return error; | 2117 | return error; |
2117 | } | 2118 | } |
2118 | 2119 | ||
2119 | int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | 2120 | static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, |
2120 | struct inode *new_dir, struct dentry *new_dentry) | 2121 | struct inode *new_dir, struct dentry *new_dentry) |
2121 | { | 2122 | { |
2122 | struct inode *target; | 2123 | struct inode *target; |
2123 | int error; | 2124 | int error; |
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index b74c4e3a64e2..87f4f9aeac86 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -79,7 +79,7 @@ static ssize_t idmap_pipe_upcall(struct file *, struct rpc_pipe_msg *, | |||
79 | char __user *, size_t); | 79 | char __user *, size_t); |
80 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, | 80 | static ssize_t idmap_pipe_downcall(struct file *, const char __user *, |
81 | size_t); | 81 | size_t); |
82 | void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); | 82 | static void idmap_pipe_destroy_msg(struct rpc_pipe_msg *); |
83 | 83 | ||
84 | static unsigned int fnvhash32(const void *, size_t); | 84 | static unsigned int fnvhash32(const void *, size_t); |
85 | 85 | ||
@@ -434,7 +434,7 @@ out: | |||
434 | return ret; | 434 | return ret; |
435 | } | 435 | } |
436 | 436 | ||
437 | void | 437 | static void |
438 | idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) | 438 | idmap_pipe_destroy_msg(struct rpc_pipe_msg *msg) |
439 | { | 439 | { |
440 | struct idmap_msg *im = msg->data; | 440 | struct idmap_msg *im = msg->data; |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 6345f26e87ee..f2317f3e29f9 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1904,7 +1904,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | |||
1904 | } | 1904 | } |
1905 | } | 1905 | } |
1906 | 1906 | ||
1907 | int nfs_init_inodecache(void) | 1907 | static int nfs_init_inodecache(void) |
1908 | { | 1908 | { |
1909 | nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", | 1909 | nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", |
1910 | sizeof(struct nfs_inode), | 1910 | sizeof(struct nfs_inode), |
@@ -1916,7 +1916,7 @@ int nfs_init_inodecache(void) | |||
1916 | return 0; | 1916 | return 0; |
1917 | } | 1917 | } |
1918 | 1918 | ||
1919 | void nfs_destroy_inodecache(void) | 1919 | static void nfs_destroy_inodecache(void) |
1920 | { | 1920 | { |
1921 | if (kmem_cache_destroy(nfs_inode_cachep)) | 1921 | if (kmem_cache_destroy(nfs_inode_cachep)) |
1922 | printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n"); | 1922 | printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n"); |
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c index 897512796edb..a912debcd20b 100644 --- a/fs/nls/nls_base.c +++ b/fs/nls/nls_base.c | |||
@@ -243,7 +243,7 @@ void unload_nls(struct nls_table *nls) | |||
243 | module_put(nls->owner); | 243 | module_put(nls->owner); |
244 | } | 244 | } |
245 | 245 | ||
246 | wchar_t charset2uni[256] = { | 246 | static wchar_t charset2uni[256] = { |
247 | /* 0x00*/ | 247 | /* 0x00*/ |
248 | 0x0000, 0x0001, 0x0002, 0x0003, | 248 | 0x0000, 0x0001, 0x0002, 0x0003, |
249 | 0x0004, 0x0005, 0x0006, 0x0007, | 249 | 0x0004, 0x0005, 0x0006, 0x0007, |
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c index 17ee1b4ff087..584a27b2bbd5 100644 --- a/fs/partitions/msdos.c +++ b/fs/partitions/msdos.c | |||
@@ -114,9 +114,6 @@ parse_extended(struct parsed_partitions *state, struct block_device *bdev, | |||
114 | */ | 114 | */ |
115 | for (i=0; i<4; i++, p++) { | 115 | for (i=0; i<4; i++, p++) { |
116 | u32 offs, size, next; | 116 | u32 offs, size, next; |
117 | |||
118 | if (SYS_IND(p) == 0) | ||
119 | continue; | ||
120 | if (!NR_SECTS(p) || is_extended_partition(p)) | 117 | if (!NR_SECTS(p) || is_extended_partition(p)) |
121 | continue; | 118 | continue; |
122 | 119 | ||
@@ -433,8 +430,6 @@ int msdos_partition(struct parsed_partitions *state, struct block_device *bdev) | |||
433 | for (slot = 1 ; slot <= 4 ; slot++, p++) { | 430 | for (slot = 1 ; slot <= 4 ; slot++, p++) { |
434 | u32 start = START_SECT(p)*sector_size; | 431 | u32 start = START_SECT(p)*sector_size; |
435 | u32 size = NR_SECTS(p)*sector_size; | 432 | u32 size = NR_SECTS(p)*sector_size; |
436 | if (SYS_IND(p) == 0) | ||
437 | continue; | ||
438 | if (!size) | 433 | if (!size) |
439 | continue; | 434 | continue; |
440 | if (is_extended_partition(p)) { | 435 | if (is_extended_partition(p)) { |
diff --git a/fs/proc/mmu.c b/fs/proc/mmu.c index a7041038ad56..25d2d9c6e329 100644 --- a/fs/proc/mmu.c +++ b/fs/proc/mmu.c | |||
@@ -50,13 +50,23 @@ void get_vmalloc_info(struct vmalloc_info *vmi) | |||
50 | read_lock(&vmlist_lock); | 50 | read_lock(&vmlist_lock); |
51 | 51 | ||
52 | for (vma = vmlist; vma; vma = vma->next) { | 52 | for (vma = vmlist; vma; vma = vma->next) { |
53 | unsigned long addr = (unsigned long) vma->addr; | ||
54 | |||
55 | /* | ||
56 | * Some archs keep another range for modules in vmlist | ||
57 | */ | ||
58 | if (addr < VMALLOC_START) | ||
59 | continue; | ||
60 | if (addr >= VMALLOC_END) | ||
61 | break; | ||
62 | |||
53 | vmi->used += vma->size; | 63 | vmi->used += vma->size; |
54 | 64 | ||
55 | free_area_size = (unsigned long) vma->addr - prev_end; | 65 | free_area_size = addr - prev_end; |
56 | if (vmi->largest_chunk < free_area_size) | 66 | if (vmi->largest_chunk < free_area_size) |
57 | vmi->largest_chunk = free_area_size; | 67 | vmi->largest_chunk = free_area_size; |
58 | 68 | ||
59 | prev_end = vma->size + (unsigned long) vma->addr; | 69 | prev_end = vma->size + addr; |
60 | } | 70 | } |
61 | 71 | ||
62 | if (VMALLOC_END - prev_end > vmi->largest_chunk) | 72 | if (VMALLOC_END - prev_end > vmi->largest_chunk) |
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index 80e92d9b81cb..7d4dc5f5aa8b 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c | |||
@@ -608,7 +608,7 @@ static int reiserfs_create (struct inode * dir, struct dentry *dentry, int mode, | |||
608 | goto out_failed; | 608 | goto out_failed; |
609 | } | 609 | } |
610 | 610 | ||
611 | retval = reiserfs_new_inode (&th, dir, mode, 0, 0/*i_size*/, dentry, inode); | 611 | retval = reiserfs_new_inode (&th, dir, mode, NULL, 0/*i_size*/, dentry, inode); |
612 | if (retval) | 612 | if (retval) |
613 | goto out_failed; | 613 | goto out_failed; |
614 | 614 | ||
diff --git a/fs/select.c b/fs/select.c index 25b1ccac2f2c..b80e7eb0ac0d 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -55,7 +55,8 @@ struct poll_table_page { | |||
55 | * as all select/poll functions have to call it to add an entry to the | 55 | * as all select/poll functions have to call it to add an entry to the |
56 | * poll table. | 56 | * poll table. |
57 | */ | 57 | */ |
58 | void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *p); | 58 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, |
59 | poll_table *p); | ||
59 | 60 | ||
60 | void poll_initwait(struct poll_wqueues *pwq) | 61 | void poll_initwait(struct poll_wqueues *pwq) |
61 | { | 62 | { |
@@ -87,7 +88,8 @@ void poll_freewait(struct poll_wqueues *pwq) | |||
87 | 88 | ||
88 | EXPORT_SYMBOL(poll_freewait); | 89 | EXPORT_SYMBOL(poll_freewait); |
89 | 90 | ||
90 | void __pollwait(struct file *filp, wait_queue_head_t *wait_address, poll_table *_p) | 91 | static void __pollwait(struct file *filp, wait_queue_head_t *wait_address, |
92 | poll_table *_p) | ||
91 | { | 93 | { |
92 | struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt); | 94 | struct poll_wqueues *p = container_of(_p, struct poll_wqueues, pt); |
93 | struct poll_table_page *table = p->table; | 95 | struct poll_table_page *table = p->table; |
diff --git a/fs/udf/udftime.c b/fs/udf/udftime.c index c2634bda6b50..457a8fe28575 100644 --- a/fs/udf/udftime.c +++ b/fs/udf/udftime.c | |||
@@ -103,7 +103,7 @@ udf_stamp_to_time(time_t *dest, long *dest_usec, kernel_timestamp src) | |||
103 | offset = 0; | 103 | offset = 0; |
104 | 104 | ||
105 | if ((src.year < EPOCH_YEAR) || | 105 | if ((src.year < EPOCH_YEAR) || |
106 | (src.year > EPOCH_YEAR+MAX_YEAR_SECONDS)) | 106 | (src.year >= EPOCH_YEAR+MAX_YEAR_SECONDS)) |
107 | { | 107 | { |
108 | *dest = -1; | 108 | *dest = -1; |
109 | *dest_usec = -1; | 109 | *dest_usec = -1; |
diff --git a/fs/xfs/Makefile b/fs/xfs/Makefile index 554e4a18c152..d3ff78354638 100644 --- a/fs/xfs/Makefile +++ b/fs/xfs/Makefile | |||
@@ -49,7 +49,7 @@ ifeq ($(CONFIG_XFS_TRACE),y) | |||
49 | EXTRA_CFLAGS += -DXFS_LOG_TRACE | 49 | EXTRA_CFLAGS += -DXFS_LOG_TRACE |
50 | EXTRA_CFLAGS += -DXFS_RW_TRACE | 50 | EXTRA_CFLAGS += -DXFS_RW_TRACE |
51 | EXTRA_CFLAGS += -DPAGEBUF_TRACE | 51 | EXTRA_CFLAGS += -DPAGEBUF_TRACE |
52 | # EXTRA_CFLAGS += -DXFS_VNODE_TRACE | 52 | EXTRA_CFLAGS += -DXFS_VNODE_TRACE |
53 | endif | 53 | endif |
54 | 54 | ||
55 | obj-$(CONFIG_XFS_FS) += xfs.o | 55 | obj-$(CONFIG_XFS_FS) += xfs.o |
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 76a84758073a..9278e9aba9ba 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c | |||
@@ -558,7 +558,8 @@ xfs_submit_page( | |||
558 | int i; | 558 | int i; |
559 | 559 | ||
560 | BUG_ON(PageWriteback(page)); | 560 | BUG_ON(PageWriteback(page)); |
561 | set_page_writeback(page); | 561 | if (bh_count) |
562 | set_page_writeback(page); | ||
562 | if (clear_dirty) | 563 | if (clear_dirty) |
563 | clear_page_dirty(page); | 564 | clear_page_dirty(page); |
564 | unlock_page(page); | 565 | unlock_page(page); |
@@ -578,9 +579,6 @@ xfs_submit_page( | |||
578 | 579 | ||
579 | if (probed_page && clear_dirty) | 580 | if (probed_page && clear_dirty) |
580 | wbc->nr_to_write--; /* Wrote an "extra" page */ | 581 | wbc->nr_to_write--; /* Wrote an "extra" page */ |
581 | } else { | ||
582 | end_page_writeback(page); | ||
583 | wbc->pages_skipped++; /* We didn't write this page */ | ||
584 | } | 582 | } |
585 | } | 583 | } |
586 | 584 | ||
@@ -602,21 +600,26 @@ xfs_convert_page( | |||
602 | { | 600 | { |
603 | struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; | 601 | struct buffer_head *bh_arr[MAX_BUF_PER_PAGE], *bh, *head; |
604 | xfs_iomap_t *mp = iomapp, *tmp; | 602 | xfs_iomap_t *mp = iomapp, *tmp; |
605 | unsigned long end, offset; | 603 | unsigned long offset, end_offset; |
606 | pgoff_t end_index; | 604 | int index = 0; |
607 | int i = 0, index = 0; | ||
608 | int bbits = inode->i_blkbits; | 605 | int bbits = inode->i_blkbits; |
606 | int len, page_dirty; | ||
609 | 607 | ||
610 | end_index = i_size_read(inode) >> PAGE_CACHE_SHIFT; | 608 | end_offset = (i_size_read(inode) & (PAGE_CACHE_SIZE - 1)); |
611 | if (page->index < end_index) { | 609 | |
612 | end = PAGE_CACHE_SIZE; | 610 | /* |
613 | } else { | 611 | * page_dirty is initially a count of buffers on the page before |
614 | end = i_size_read(inode) & (PAGE_CACHE_SIZE-1); | 612 | * EOF and is decrememted as we move each into a cleanable state. |
615 | } | 613 | */ |
614 | len = 1 << inode->i_blkbits; | ||
615 | end_offset = max(end_offset, PAGE_CACHE_SIZE); | ||
616 | end_offset = roundup(end_offset, len); | ||
617 | page_dirty = end_offset / len; | ||
618 | |||
619 | offset = 0; | ||
616 | bh = head = page_buffers(page); | 620 | bh = head = page_buffers(page); |
617 | do { | 621 | do { |
618 | offset = i << bbits; | 622 | if (offset >= end_offset) |
619 | if (offset >= end) | ||
620 | break; | 623 | break; |
621 | if (!(PageUptodate(page) || buffer_uptodate(bh))) | 624 | if (!(PageUptodate(page) || buffer_uptodate(bh))) |
622 | continue; | 625 | continue; |
@@ -625,6 +628,7 @@ xfs_convert_page( | |||
625 | if (startio) { | 628 | if (startio) { |
626 | lock_buffer(bh); | 629 | lock_buffer(bh); |
627 | bh_arr[index++] = bh; | 630 | bh_arr[index++] = bh; |
631 | page_dirty--; | ||
628 | } | 632 | } |
629 | continue; | 633 | continue; |
630 | } | 634 | } |
@@ -657,10 +661,11 @@ xfs_convert_page( | |||
657 | unlock_buffer(bh); | 661 | unlock_buffer(bh); |
658 | mark_buffer_dirty(bh); | 662 | mark_buffer_dirty(bh); |
659 | } | 663 | } |
660 | } while (i++, (bh = bh->b_this_page) != head); | 664 | page_dirty--; |
665 | } while (offset += len, (bh = bh->b_this_page) != head); | ||
661 | 666 | ||
662 | if (startio) { | 667 | if (startio && index) { |
663 | xfs_submit_page(page, wbc, bh_arr, index, 1, index == i); | 668 | xfs_submit_page(page, wbc, bh_arr, index, 1, !page_dirty); |
664 | } else { | 669 | } else { |
665 | unlock_page(page); | 670 | unlock_page(page); |
666 | } | 671 | } |
@@ -725,8 +730,11 @@ xfs_page_state_convert( | |||
725 | __uint64_t end_offset; | 730 | __uint64_t end_offset; |
726 | pgoff_t end_index, last_index, tlast; | 731 | pgoff_t end_index, last_index, tlast; |
727 | int len, err, i, cnt = 0, uptodate = 1; | 732 | int len, err, i, cnt = 0, uptodate = 1; |
728 | int flags = startio ? 0 : BMAPI_TRYLOCK; | 733 | int flags; |
729 | int page_dirty, delalloc = 0; | 734 | int page_dirty; |
735 | |||
736 | /* wait for other IO threads? */ | ||
737 | flags = (startio && wbc->sync_mode != WB_SYNC_NONE) ? 0 : BMAPI_TRYLOCK; | ||
730 | 738 | ||
731 | /* Is this page beyond the end of the file? */ | 739 | /* Is this page beyond the end of the file? */ |
732 | offset = i_size_read(inode); | 740 | offset = i_size_read(inode); |
@@ -740,19 +748,22 @@ xfs_page_state_convert( | |||
740 | } | 748 | } |
741 | } | 749 | } |
742 | 750 | ||
743 | offset = (loff_t)page->index << PAGE_CACHE_SHIFT; | ||
744 | end_offset = min_t(unsigned long long, | 751 | end_offset = min_t(unsigned long long, |
745 | offset + PAGE_CACHE_SIZE, i_size_read(inode)); | 752 | (loff_t)(page->index + 1) << PAGE_CACHE_SHIFT, offset); |
746 | 753 | offset = (loff_t)page->index << PAGE_CACHE_SHIFT; | |
747 | bh = head = page_buffers(page); | ||
748 | iomp = NULL; | ||
749 | 754 | ||
750 | /* | 755 | /* |
751 | * page_dirty is initially a count of buffers on the page and | 756 | * page_dirty is initially a count of buffers on the page before |
752 | * is decrememted as we move each into a cleanable state. | 757 | * EOF and is decrememted as we move each into a cleanable state. |
753 | */ | 758 | */ |
754 | len = bh->b_size; | 759 | len = 1 << inode->i_blkbits; |
755 | page_dirty = PAGE_CACHE_SIZE / len; | 760 | p_offset = max(p_offset, PAGE_CACHE_SIZE); |
761 | p_offset = roundup(p_offset, len); | ||
762 | page_dirty = p_offset / len; | ||
763 | |||
764 | iomp = NULL; | ||
765 | p_offset = 0; | ||
766 | bh = head = page_buffers(page); | ||
756 | 767 | ||
757 | do { | 768 | do { |
758 | if (offset >= end_offset) | 769 | if (offset >= end_offset) |
@@ -804,7 +815,6 @@ xfs_page_state_convert( | |||
804 | */ | 815 | */ |
805 | } else if (buffer_delay(bh)) { | 816 | } else if (buffer_delay(bh)) { |
806 | if (!iomp) { | 817 | if (!iomp) { |
807 | delalloc = 1; | ||
808 | err = xfs_map_blocks(inode, offset, len, &iomap, | 818 | err = xfs_map_blocks(inode, offset, len, &iomap, |
809 | BMAPI_ALLOCATE | flags); | 819 | BMAPI_ALLOCATE | flags); |
810 | if (err) { | 820 | if (err) { |
@@ -875,14 +885,15 @@ xfs_page_state_convert( | |||
875 | if (uptodate && bh == head) | 885 | if (uptodate && bh == head) |
876 | SetPageUptodate(page); | 886 | SetPageUptodate(page); |
877 | 887 | ||
878 | if (startio) | 888 | if (startio) { |
879 | xfs_submit_page(page, wbc, bh_arr, cnt, 0, 1); | 889 | WARN_ON(page_dirty); |
890 | xfs_submit_page(page, wbc, bh_arr, cnt, 0, !page_dirty); | ||
891 | } | ||
880 | 892 | ||
881 | if (iomp) { | 893 | if (iomp) { |
882 | tlast = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> | 894 | offset = (iomp->iomap_offset + iomp->iomap_bsize - 1) >> |
883 | PAGE_CACHE_SHIFT; | 895 | PAGE_CACHE_SHIFT; |
884 | if (delalloc && (tlast > last_index)) | 896 | tlast = min_t(pgoff_t, offset, last_index); |
885 | tlast = last_index; | ||
886 | xfs_cluster_write(inode, page->index + 1, iomp, wbc, | 897 | xfs_cluster_write(inode, page->index + 1, iomp, wbc, |
887 | startio, unmapped, tlast); | 898 | startio, unmapped, tlast); |
888 | } | 899 | } |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 23e0eb67fc25..997963e53622 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1746,13 +1746,15 @@ STATIC DECLARE_COMPLETION(pagebuf_daemon_done); | |||
1746 | STATIC struct task_struct *pagebuf_daemon_task; | 1746 | STATIC struct task_struct *pagebuf_daemon_task; |
1747 | STATIC int pagebuf_daemon_active; | 1747 | STATIC int pagebuf_daemon_active; |
1748 | STATIC int force_flush; | 1748 | STATIC int force_flush; |
1749 | 1749 | STATIC int force_sleep; | |
1750 | 1750 | ||
1751 | STATIC int | 1751 | STATIC int |
1752 | pagebuf_daemon_wakeup( | 1752 | pagebuf_daemon_wakeup( |
1753 | int priority, | 1753 | int priority, |
1754 | unsigned int mask) | 1754 | unsigned int mask) |
1755 | { | 1755 | { |
1756 | if (force_sleep) | ||
1757 | return 0; | ||
1756 | force_flush = 1; | 1758 | force_flush = 1; |
1757 | barrier(); | 1759 | barrier(); |
1758 | wake_up_process(pagebuf_daemon_task); | 1760 | wake_up_process(pagebuf_daemon_task); |
@@ -1778,7 +1780,12 @@ pagebuf_daemon( | |||
1778 | 1780 | ||
1779 | INIT_LIST_HEAD(&tmp); | 1781 | INIT_LIST_HEAD(&tmp); |
1780 | do { | 1782 | do { |
1781 | try_to_freeze(PF_FREEZE); | 1783 | if (unlikely(current->flags & PF_FREEZE)) { |
1784 | force_sleep = 1; | ||
1785 | refrigerator(PF_FREEZE); | ||
1786 | } else { | ||
1787 | force_sleep = 0; | ||
1788 | } | ||
1782 | 1789 | ||
1783 | set_current_state(TASK_INTERRUPTIBLE); | 1790 | set_current_state(TASK_INTERRUPTIBLE); |
1784 | schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100); | 1791 | schedule_timeout((xfs_buf_timer_centisecs * HZ) / 100); |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index 9f057a4a5b06..d0d412afd261 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
@@ -515,10 +515,49 @@ open_exec_out: | |||
515 | } | 515 | } |
516 | #endif /* HAVE_FOP_OPEN_EXEC */ | 516 | #endif /* HAVE_FOP_OPEN_EXEC */ |
517 | 517 | ||
518 | /* | ||
519 | * Temporary workaround to the AIO direct IO write problem. | ||
520 | * This code can go and we can revert to do_sync_write once | ||
521 | * the writepage(s) rework is merged. | ||
522 | */ | ||
523 | STATIC ssize_t | ||
524 | linvfs_write( | ||
525 | struct file *filp, | ||
526 | const char __user *buf, | ||
527 | size_t len, | ||
528 | loff_t *ppos) | ||
529 | { | ||
530 | struct kiocb kiocb; | ||
531 | ssize_t ret; | ||
532 | |||
533 | init_sync_kiocb(&kiocb, filp); | ||
534 | kiocb.ki_pos = *ppos; | ||
535 | ret = __linvfs_write(&kiocb, buf, 0, len, kiocb.ki_pos); | ||
536 | *ppos = kiocb.ki_pos; | ||
537 | return ret; | ||
538 | } | ||
539 | STATIC ssize_t | ||
540 | linvfs_write_invis( | ||
541 | struct file *filp, | ||
542 | const char __user *buf, | ||
543 | size_t len, | ||
544 | loff_t *ppos) | ||
545 | { | ||
546 | struct kiocb kiocb; | ||
547 | ssize_t ret; | ||
548 | |||
549 | init_sync_kiocb(&kiocb, filp); | ||
550 | kiocb.ki_pos = *ppos; | ||
551 | ret = __linvfs_write(&kiocb, buf, IO_INVIS, len, kiocb.ki_pos); | ||
552 | *ppos = kiocb.ki_pos; | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | |||
518 | struct file_operations linvfs_file_operations = { | 557 | struct file_operations linvfs_file_operations = { |
519 | .llseek = generic_file_llseek, | 558 | .llseek = generic_file_llseek, |
520 | .read = do_sync_read, | 559 | .read = do_sync_read, |
521 | .write = do_sync_write, | 560 | .write = linvfs_write, |
522 | .readv = linvfs_readv, | 561 | .readv = linvfs_readv, |
523 | .writev = linvfs_writev, | 562 | .writev = linvfs_writev, |
524 | .aio_read = linvfs_aio_read, | 563 | .aio_read = linvfs_aio_read, |
@@ -540,7 +579,7 @@ struct file_operations linvfs_file_operations = { | |||
540 | struct file_operations linvfs_invis_file_operations = { | 579 | struct file_operations linvfs_invis_file_operations = { |
541 | .llseek = generic_file_llseek, | 580 | .llseek = generic_file_llseek, |
542 | .read = do_sync_read, | 581 | .read = do_sync_read, |
543 | .write = do_sync_write, | 582 | .write = linvfs_write_invis, |
544 | .readv = linvfs_readv_invis, | 583 | .readv = linvfs_readv_invis, |
545 | .writev = linvfs_writev_invis, | 584 | .writev = linvfs_writev_invis, |
546 | .aio_read = linvfs_aio_read_invis, | 585 | .aio_read = linvfs_aio_read_invis, |
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c index ff145fd0d1a4..aa9daaea6c34 100644 --- a/fs/xfs/linux-2.6/xfs_lrw.c +++ b/fs/xfs/linux-2.6/xfs_lrw.c | |||
@@ -683,6 +683,9 @@ xfs_write( | |||
683 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? | 683 | (xip->i_d.di_flags & XFS_DIFLAG_REALTIME) ? |
684 | mp->m_rtdev_targp : mp->m_ddev_targp; | 684 | mp->m_rtdev_targp : mp->m_ddev_targp; |
685 | 685 | ||
686 | if (ioflags & IO_ISAIO) | ||
687 | return XFS_ERROR(-ENOSYS); | ||
688 | |||
686 | if ((pos & target->pbr_smask) || (count & target->pbr_smask)) | 689 | if ((pos & target->pbr_smask) || (count & target->pbr_smask)) |
687 | return XFS_ERROR(-EINVAL); | 690 | return XFS_ERROR(-EINVAL); |
688 | 691 | ||
diff --git a/fs/xfs/linux-2.6/xfs_vnode.c b/fs/xfs/linux-2.6/xfs_vnode.c index 849c61c74f3c..a832d165f24f 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.c +++ b/fs/xfs/linux-2.6/xfs_vnode.c | |||
@@ -156,7 +156,6 @@ vn_initialize( | |||
156 | 156 | ||
157 | #ifdef XFS_VNODE_TRACE | 157 | #ifdef XFS_VNODE_TRACE |
158 | vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); | 158 | vp->v_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); |
159 | printk("Allocated VNODE_TRACE at 0x%p\n", vp->v_trace); | ||
160 | #endif /* XFS_VNODE_TRACE */ | 159 | #endif /* XFS_VNODE_TRACE */ |
161 | 160 | ||
162 | vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); | 161 | vn_trace_exit(vp, "vn_initialize", (inst_t *)__return_address); |
@@ -424,13 +423,13 @@ vn_remove( | |||
424 | * Vnode tracing code. | 423 | * Vnode tracing code. |
425 | */ | 424 | */ |
426 | void | 425 | void |
427 | vn_trace_entry(vnode_t *vp, char *func, inst_t *ra) | 426 | vn_trace_entry(vnode_t *vp, const char *func, inst_t *ra) |
428 | { | 427 | { |
429 | KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); | 428 | KTRACE_ENTER(vp, VNODE_KTRACE_ENTRY, func, 0, ra); |
430 | } | 429 | } |
431 | 430 | ||
432 | void | 431 | void |
433 | vn_trace_exit(vnode_t *vp, char *func, inst_t *ra) | 432 | vn_trace_exit(vnode_t *vp, const char *func, inst_t *ra) |
434 | { | 433 | { |
435 | KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); | 434 | KTRACE_ENTER(vp, VNODE_KTRACE_EXIT, func, 0, ra); |
436 | } | 435 | } |
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h index da76c1f1e11c..00466c3194ac 100644 --- a/fs/xfs/linux-2.6/xfs_vnode.h +++ b/fs/xfs/linux-2.6/xfs_vnode.h | |||
@@ -86,10 +86,11 @@ typedef struct vnode { | |||
86 | vnumber_t v_number; /* in-core vnode number */ | 86 | vnumber_t v_number; /* in-core vnode number */ |
87 | vn_bhv_head_t v_bh; /* behavior head */ | 87 | vn_bhv_head_t v_bh; /* behavior head */ |
88 | spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ | 88 | spinlock_t v_lock; /* VN_LOCK/VN_UNLOCK */ |
89 | struct inode v_inode; /* Linux inode */ | ||
90 | #ifdef XFS_VNODE_TRACE | 89 | #ifdef XFS_VNODE_TRACE |
91 | struct ktrace *v_trace; /* trace header structure */ | 90 | struct ktrace *v_trace; /* trace header structure */ |
92 | #endif | 91 | #endif |
92 | struct inode v_inode; /* Linux inode */ | ||
93 | /* inode MUST be last */ | ||
93 | } vnode_t; | 94 | } vnode_t; |
94 | 95 | ||
95 | #define v_fbhv v_bh.bh_first /* first behavior */ | 96 | #define v_fbhv v_bh.bh_first /* first behavior */ |
@@ -409,7 +410,7 @@ typedef struct vattr { | |||
409 | int va_mask; /* bit-mask of attributes present */ | 410 | int va_mask; /* bit-mask of attributes present */ |
410 | enum vtype va_type; /* vnode type (for create) */ | 411 | enum vtype va_type; /* vnode type (for create) */ |
411 | mode_t va_mode; /* file access mode and type */ | 412 | mode_t va_mode; /* file access mode and type */ |
412 | nlink_t va_nlink; /* number of references to file */ | 413 | xfs_nlink_t va_nlink; /* number of references to file */ |
413 | uid_t va_uid; /* owner user id */ | 414 | uid_t va_uid; /* owner user id */ |
414 | gid_t va_gid; /* owner group id */ | 415 | gid_t va_gid; /* owner group id */ |
415 | xfs_ino_t va_nodeid; /* file id */ | 416 | xfs_ino_t va_nodeid; /* file id */ |
@@ -625,6 +626,7 @@ static inline int VN_BAD(struct vnode *vp) | |||
625 | #define ATTR_DMI 0x08 /* invocation from a DMI function */ | 626 | #define ATTR_DMI 0x08 /* invocation from a DMI function */ |
626 | #define ATTR_LAZY 0x80 /* set/get attributes lazily */ | 627 | #define ATTR_LAZY 0x80 /* set/get attributes lazily */ |
627 | #define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */ | 628 | #define ATTR_NONBLOCK 0x100 /* return EAGAIN if operation would block */ |
629 | #define ATTR_NOLOCK 0x200 /* Don't grab any conflicting locks */ | ||
628 | 630 | ||
629 | /* | 631 | /* |
630 | * Flags to VOP_FSYNC and VOP_RECLAIM. | 632 | * Flags to VOP_FSYNC and VOP_RECLAIM. |
@@ -646,8 +648,8 @@ static inline int VN_BAD(struct vnode *vp) | |||
646 | #define VNODE_KTRACE_REF 4 | 648 | #define VNODE_KTRACE_REF 4 |
647 | #define VNODE_KTRACE_RELE 5 | 649 | #define VNODE_KTRACE_RELE 5 |
648 | 650 | ||
649 | extern void vn_trace_entry(struct vnode *, char *, inst_t *); | 651 | extern void vn_trace_entry(struct vnode *, const char *, inst_t *); |
650 | extern void vn_trace_exit(struct vnode *, char *, inst_t *); | 652 | extern void vn_trace_exit(struct vnode *, const char *, inst_t *); |
651 | extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); | 653 | extern void vn_trace_hold(struct vnode *, char *, int, inst_t *); |
652 | extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); | 654 | extern void vn_trace_ref(struct vnode *, char *, int, inst_t *); |
653 | extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); | 655 | extern void vn_trace_rele(struct vnode *, char *, int, inst_t *); |
diff --git a/fs/xfs/xfs_dfrag.c b/fs/xfs/xfs_dfrag.c index 08d551a17347..63abdc2ac7f4 100644 --- a/fs/xfs/xfs_dfrag.c +++ b/fs/xfs/xfs_dfrag.c | |||
@@ -182,7 +182,7 @@ xfs_swapext( | |||
182 | 182 | ||
183 | if (VN_CACHED(tvp) != 0) | 183 | if (VN_CACHED(tvp) != 0) |
184 | xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), | 184 | xfs_inval_cached_pages(XFS_ITOV(tip), &(tip->i_iocore), |
185 | (loff_t)0, 0, 0); | 185 | (xfs_off_t)0, 0, 0); |
186 | 186 | ||
187 | /* Verify O_DIRECT for ftmp */ | 187 | /* Verify O_DIRECT for ftmp */ |
188 | if (VN_CACHED(tvp) != 0) { | 188 | if (VN_CACHED(tvp) != 0) { |
diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 3a0ba1dfd0e8..d3da00045f26 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c | |||
@@ -136,6 +136,40 @@ xfs_chash_free(xfs_mount_t *mp) | |||
136 | } | 136 | } |
137 | 137 | ||
138 | /* | 138 | /* |
139 | * Try to move an inode to the front of its hash list if possible | ||
140 | * (and if its not there already). Called right after obtaining | ||
141 | * the list version number and then dropping the read_lock on the | ||
142 | * hash list in question (which is done right after looking up the | ||
143 | * inode in question...). | ||
144 | */ | ||
145 | STATIC void | ||
146 | xfs_ihash_promote( | ||
147 | xfs_ihash_t *ih, | ||
148 | xfs_inode_t *ip, | ||
149 | ulong version) | ||
150 | { | ||
151 | xfs_inode_t *iq; | ||
152 | |||
153 | if ((ip->i_prevp != &ih->ih_next) && write_trylock(&ih->ih_lock)) { | ||
154 | if (likely(version == ih->ih_version)) { | ||
155 | /* remove from list */ | ||
156 | if ((iq = ip->i_next)) { | ||
157 | iq->i_prevp = ip->i_prevp; | ||
158 | } | ||
159 | *ip->i_prevp = iq; | ||
160 | |||
161 | /* insert at list head */ | ||
162 | iq = ih->ih_next; | ||
163 | iq->i_prevp = &ip->i_next; | ||
164 | ip->i_next = iq; | ||
165 | ip->i_prevp = &ih->ih_next; | ||
166 | ih->ih_next = ip; | ||
167 | } | ||
168 | write_unlock(&ih->ih_lock); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | /* | ||
139 | * Look up an inode by number in the given file system. | 173 | * Look up an inode by number in the given file system. |
140 | * The inode is looked up in the hash table for the file system | 174 | * The inode is looked up in the hash table for the file system |
141 | * represented by the mount point parameter mp. Each bucket of | 175 | * represented by the mount point parameter mp. Each bucket of |
@@ -229,7 +263,9 @@ again: | |||
229 | XFS_STATS_INC(xs_ig_found); | 263 | XFS_STATS_INC(xs_ig_found); |
230 | 264 | ||
231 | ip->i_flags &= ~XFS_IRECLAIMABLE; | 265 | ip->i_flags &= ~XFS_IRECLAIMABLE; |
266 | version = ih->ih_version; | ||
232 | read_unlock(&ih->ih_lock); | 267 | read_unlock(&ih->ih_lock); |
268 | xfs_ihash_promote(ih, ip, version); | ||
233 | 269 | ||
234 | XFS_MOUNT_ILOCK(mp); | 270 | XFS_MOUNT_ILOCK(mp); |
235 | list_del_init(&ip->i_reclaim); | 271 | list_del_init(&ip->i_reclaim); |
@@ -259,8 +295,15 @@ again: | |||
259 | inode_vp, vp); | 295 | inode_vp, vp); |
260 | } | 296 | } |
261 | 297 | ||
298 | /* | ||
299 | * Inode cache hit: if ip is not at the front of | ||
300 | * its hash chain, move it there now. | ||
301 | * Do this with the lock held for update, but | ||
302 | * do statistics after releasing the lock. | ||
303 | */ | ||
304 | version = ih->ih_version; | ||
262 | read_unlock(&ih->ih_lock); | 305 | read_unlock(&ih->ih_lock); |
263 | 306 | xfs_ihash_promote(ih, ip, version); | |
264 | XFS_STATS_INC(xs_ig_found); | 307 | XFS_STATS_INC(xs_ig_found); |
265 | 308 | ||
266 | finish_inode: | 309 | finish_inode: |
@@ -547,6 +590,7 @@ xfs_inode_incore(xfs_mount_t *mp, | |||
547 | { | 590 | { |
548 | xfs_ihash_t *ih; | 591 | xfs_ihash_t *ih; |
549 | xfs_inode_t *ip; | 592 | xfs_inode_t *ip; |
593 | ulong version; | ||
550 | 594 | ||
551 | ih = XFS_IHASH(mp, ino); | 595 | ih = XFS_IHASH(mp, ino); |
552 | read_lock(&ih->ih_lock); | 596 | read_lock(&ih->ih_lock); |
@@ -554,11 +598,15 @@ xfs_inode_incore(xfs_mount_t *mp, | |||
554 | if (ip->i_ino == ino) { | 598 | if (ip->i_ino == ino) { |
555 | /* | 599 | /* |
556 | * If we find it and tp matches, return it. | 600 | * If we find it and tp matches, return it. |
601 | * Also move it to the front of the hash list | ||
602 | * if we find it and it is not already there. | ||
557 | * Otherwise break from the loop and return | 603 | * Otherwise break from the loop and return |
558 | * NULL. | 604 | * NULL. |
559 | */ | 605 | */ |
560 | if (ip->i_transp == tp) { | 606 | if (ip->i_transp == tp) { |
607 | version = ih->ih_version; | ||
561 | read_unlock(&ih->ih_lock); | 608 | read_unlock(&ih->ih_lock); |
609 | xfs_ihash_promote(ih, ip, version); | ||
562 | return (ip); | 610 | return (ip); |
563 | } | 611 | } |
564 | break; | 612 | break; |
@@ -685,6 +733,7 @@ xfs_iextract( | |||
685 | iq->i_prevp = ip->i_prevp; | 733 | iq->i_prevp = ip->i_prevp; |
686 | } | 734 | } |
687 | *ip->i_prevp = iq; | 735 | *ip->i_prevp = iq; |
736 | ih->ih_version++; | ||
688 | write_unlock(&ih->ih_lock); | 737 | write_unlock(&ih->ih_lock); |
689 | 738 | ||
690 | /* | 739 | /* |
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 43c632ab86ad..bc8c8c7f9039 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1130,7 +1130,7 @@ xfs_ialloc( | |||
1130 | xfs_trans_t *tp, | 1130 | xfs_trans_t *tp, |
1131 | xfs_inode_t *pip, | 1131 | xfs_inode_t *pip, |
1132 | mode_t mode, | 1132 | mode_t mode, |
1133 | nlink_t nlink, | 1133 | xfs_nlink_t nlink, |
1134 | xfs_dev_t rdev, | 1134 | xfs_dev_t rdev, |
1135 | cred_t *cr, | 1135 | cred_t *cr, |
1136 | xfs_prid_t prid, | 1136 | xfs_prid_t prid, |
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index a53b1ccf6070..37e1c316f3b6 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h | |||
@@ -495,9 +495,9 @@ int xfs_itobp(struct xfs_mount *, struct xfs_trans *, | |||
495 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, | 495 | int xfs_iread(struct xfs_mount *, struct xfs_trans *, xfs_ino_t, |
496 | xfs_inode_t **, xfs_daddr_t); | 496 | xfs_inode_t **, xfs_daddr_t); |
497 | int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); | 497 | int xfs_iread_extents(struct xfs_trans *, xfs_inode_t *, int); |
498 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, nlink_t, | 498 | int xfs_ialloc(struct xfs_trans *, xfs_inode_t *, mode_t, |
499 | xfs_dev_t, struct cred *, xfs_prid_t, int, | 499 | xfs_nlink_t, xfs_dev_t, struct cred *, xfs_prid_t, |
500 | struct xfs_buf **, boolean_t *, xfs_inode_t **); | 500 | int, struct xfs_buf **, boolean_t *, xfs_inode_t **); |
501 | void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, | 501 | void xfs_xlate_dinode_core(xfs_caddr_t, struct xfs_dinode_core *, |
502 | int); | 502 | int); |
503 | uint xfs_ip2xflags(struct xfs_inode *); | 503 | uint xfs_ip2xflags(struct xfs_inode *); |
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 3826e8f0e28a..991f8a61f7c4 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c | |||
@@ -308,7 +308,8 @@ phase2: | |||
308 | break; | 308 | break; |
309 | } | 309 | } |
310 | 310 | ||
311 | error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, &imap, &nimaps); | 311 | error = XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, |
312 | &imap, &nimaps); | ||
312 | break; | 313 | break; |
313 | case BMAPI_UNWRITTEN: | 314 | case BMAPI_UNWRITTEN: |
314 | lockmode = 0; | 315 | lockmode = 0; |
@@ -365,7 +366,7 @@ xfs_flush_space( | |||
365 | int | 366 | int |
366 | xfs_iomap_write_direct( | 367 | xfs_iomap_write_direct( |
367 | xfs_inode_t *ip, | 368 | xfs_inode_t *ip, |
368 | loff_t offset, | 369 | xfs_off_t offset, |
369 | size_t count, | 370 | size_t count, |
370 | int flags, | 371 | int flags, |
371 | xfs_bmbt_irec_t *ret_imap, | 372 | xfs_bmbt_irec_t *ret_imap, |
@@ -541,7 +542,7 @@ error_out: | |||
541 | int | 542 | int |
542 | xfs_iomap_write_delay( | 543 | xfs_iomap_write_delay( |
543 | xfs_inode_t *ip, | 544 | xfs_inode_t *ip, |
544 | loff_t offset, | 545 | xfs_off_t offset, |
545 | size_t count, | 546 | size_t count, |
546 | int ioflag, | 547 | int ioflag, |
547 | xfs_bmbt_irec_t *ret_imap, | 548 | xfs_bmbt_irec_t *ret_imap, |
@@ -746,6 +747,8 @@ write_map: | |||
746 | int | 747 | int |
747 | xfs_iomap_write_allocate( | 748 | xfs_iomap_write_allocate( |
748 | xfs_inode_t *ip, | 749 | xfs_inode_t *ip, |
750 | xfs_off_t offset, | ||
751 | size_t count, | ||
749 | xfs_bmbt_irec_t *map, | 752 | xfs_bmbt_irec_t *map, |
750 | int *retmap) | 753 | int *retmap) |
751 | { | 754 | { |
@@ -770,9 +773,9 @@ xfs_iomap_write_allocate( | |||
770 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) | 773 | if ((error = XFS_QM_DQATTACH(mp, ip, 0))) |
771 | return XFS_ERROR(error); | 774 | return XFS_ERROR(error); |
772 | 775 | ||
773 | offset_fsb = map->br_startoff; | 776 | offset_fsb = XFS_B_TO_FSBT(mp, offset); |
774 | count_fsb = map->br_blockcount; | 777 | count_fsb = map->br_blockcount; |
775 | map_start_fsb = offset_fsb; | 778 | map_start_fsb = map->br_startoff; |
776 | 779 | ||
777 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); | 780 | XFS_STATS_ADD(xs_xstrat_bytes, XFS_FSB_TO_B(mp, count_fsb)); |
778 | 781 | ||
@@ -868,9 +871,9 @@ xfs_iomap_write_allocate( | |||
868 | imap[i].br_startoff, | 871 | imap[i].br_startoff, |
869 | imap[i].br_blockcount,imap[i].br_state); | 872 | imap[i].br_blockcount,imap[i].br_state); |
870 | } | 873 | } |
871 | if ((map->br_startoff >= imap[i].br_startoff) && | 874 | if ((offset_fsb >= imap[i].br_startoff) && |
872 | (map->br_startoff < (imap[i].br_startoff + | 875 | (offset_fsb < (imap[i].br_startoff + |
873 | imap[i].br_blockcount))) { | 876 | imap[i].br_blockcount))) { |
874 | *map = imap[i]; | 877 | *map = imap[i]; |
875 | *retmap = 1; | 878 | *retmap = 1; |
876 | XFS_STATS_INC(xs_xstrat_quick); | 879 | XFS_STATS_INC(xs_xstrat_quick); |
@@ -883,9 +886,8 @@ xfs_iomap_write_allocate( | |||
883 | * file, just surrounding data, try again. | 886 | * file, just surrounding data, try again. |
884 | */ | 887 | */ |
885 | nimaps--; | 888 | nimaps--; |
886 | offset_fsb = imap[nimaps].br_startoff + | 889 | map_start_fsb = imap[nimaps].br_startoff + |
887 | imap[nimaps].br_blockcount; | 890 | imap[nimaps].br_blockcount; |
888 | map_start_fsb = offset_fsb; | ||
889 | } | 891 | } |
890 | 892 | ||
891 | trans_cancel: | 893 | trans_cancel: |
@@ -899,7 +901,7 @@ error0: | |||
899 | int | 901 | int |
900 | xfs_iomap_write_unwritten( | 902 | xfs_iomap_write_unwritten( |
901 | xfs_inode_t *ip, | 903 | xfs_inode_t *ip, |
902 | loff_t offset, | 904 | xfs_off_t offset, |
903 | size_t count) | 905 | size_t count) |
904 | { | 906 | { |
905 | xfs_mount_t *mp = ip->i_mount; | 907 | xfs_mount_t *mp = ip->i_mount; |
diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 31c91087cb33..4daaa5212102 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2003,2004 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2003-2005 Silicon Graphics, Inc. All Rights Reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms of version 2 of the GNU General Public License as | 5 | * under the terms of version 2 of the GNU General Public License as |
@@ -29,9 +29,6 @@ | |||
29 | * | 29 | * |
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ | 30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ |
31 | */ | 31 | */ |
32 | |||
33 | |||
34 | |||
35 | #ifndef __XFS_IOMAP_H__ | 32 | #ifndef __XFS_IOMAP_H__ |
36 | #define __XFS_IOMAP_H__ | 33 | #define __XFS_IOMAP_H__ |
37 | 34 | ||
@@ -56,7 +53,7 @@ typedef enum { | |||
56 | BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ | 53 | BMAPI_UNWRITTEN = (1 << 3), /* unwritten extents to real extents */ |
57 | /* modifiers */ | 54 | /* modifiers */ |
58 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ | 55 | BMAPI_IGNSTATE = (1 << 4), /* ignore unwritten state on read */ |
59 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ | 56 | BMAPI_DIRECT = (1 << 5), /* direct instead of buffered write */ |
60 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ | 57 | BMAPI_MMAP = (1 << 6), /* allocate for mmap write */ |
61 | BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ | 58 | BMAPI_SYNC = (1 << 7), /* sync write to flush delalloc space */ |
62 | BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ | 59 | BMAPI_TRYLOCK = (1 << 8), /* non-blocking request */ |
@@ -67,13 +64,13 @@ typedef enum { | |||
67 | /* | 64 | /* |
68 | * xfs_iomap_t: File system I/O map | 65 | * xfs_iomap_t: File system I/O map |
69 | * | 66 | * |
70 | * The iomap_bn field is expressed in 512-byte blocks, and is where the | 67 | * The iomap_bn field is expressed in 512-byte blocks, and is where the |
71 | * mapping starts on disk. | 68 | * mapping starts on disk. |
72 | * | 69 | * |
73 | * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes. | 70 | * The iomap_offset, iomap_bsize and iomap_delta fields are in bytes. |
74 | * iomap_offset is the offset of the mapping in the file itself. | 71 | * iomap_offset is the offset of the mapping in the file itself. |
75 | * iomap_bsize is the size of the mapping, iomap_delta is the | 72 | * iomap_bsize is the size of the mapping, iomap_delta is the |
76 | * desired data's offset into the mapping, given the offset supplied | 73 | * desired data's offset into the mapping, given the offset supplied |
77 | * to the file I/O map routine. | 74 | * to the file I/O map routine. |
78 | * | 75 | * |
79 | * When a request is made to read beyond the logical end of the object, | 76 | * When a request is made to read beyond the logical end of the object, |
@@ -84,8 +81,8 @@ typedef enum { | |||
84 | typedef struct xfs_iomap { | 81 | typedef struct xfs_iomap { |
85 | xfs_daddr_t iomap_bn; /* first 512b blk of mapping */ | 82 | xfs_daddr_t iomap_bn; /* first 512b blk of mapping */ |
86 | xfs_buftarg_t *iomap_target; | 83 | xfs_buftarg_t *iomap_target; |
87 | loff_t iomap_offset; /* offset of mapping, bytes */ | 84 | xfs_off_t iomap_offset; /* offset of mapping, bytes */ |
88 | loff_t iomap_bsize; /* size of mapping, bytes */ | 85 | xfs_off_t iomap_bsize; /* size of mapping, bytes */ |
89 | size_t iomap_delta; /* offset into mapping, bytes */ | 86 | size_t iomap_delta; /* offset into mapping, bytes */ |
90 | iomap_flags_t iomap_flags; | 87 | iomap_flags_t iomap_flags; |
91 | } xfs_iomap_t; | 88 | } xfs_iomap_t; |
@@ -96,12 +93,12 @@ struct xfs_bmbt_irec; | |||
96 | 93 | ||
97 | extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, | 94 | extern int xfs_iomap(struct xfs_iocore *, xfs_off_t, ssize_t, int, |
98 | struct xfs_iomap *, int *); | 95 | struct xfs_iomap *, int *); |
99 | extern int xfs_iomap_write_direct(struct xfs_inode *, loff_t, size_t, | 96 | extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, |
100 | int, struct xfs_bmbt_irec *, int *, int); | 97 | int, struct xfs_bmbt_irec *, int *, int); |
101 | extern int xfs_iomap_write_delay(struct xfs_inode *, loff_t, size_t, int, | 98 | extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int, |
102 | struct xfs_bmbt_irec *, int *); | 99 | struct xfs_bmbt_irec *, int *); |
103 | extern int xfs_iomap_write_allocate(struct xfs_inode *, | 100 | extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, |
104 | struct xfs_bmbt_irec *, int *); | 101 | struct xfs_bmbt_irec *, int *); |
105 | extern int xfs_iomap_write_unwritten(struct xfs_inode *, loff_t, size_t); | 102 | extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t); |
106 | 103 | ||
107 | #endif /* __XFS_IOMAP_H__*/ | 104 | #endif /* __XFS_IOMAP_H__*/ |
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index b57423caef9b..2ec967d93e5a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -301,6 +301,15 @@ xfs_mount_validate_sb( | |||
301 | } | 301 | } |
302 | 302 | ||
303 | /* | 303 | /* |
304 | * Version 1 directory format has never worked on Linux. | ||
305 | */ | ||
306 | if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { | ||
307 | cmn_err(CE_WARN, | ||
308 | "XFS: Attempted to mount file system using version 1 directory format"); | ||
309 | return XFS_ERROR(ENOSYS); | ||
310 | } | ||
311 | |||
312 | /* | ||
304 | * Until this is fixed only page-sized or smaller data blocks work. | 313 | * Until this is fixed only page-sized or smaller data blocks work. |
305 | */ | 314 | */ |
306 | if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { | 315 | if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { |
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5fc6201dd8e2..30dd08fb9f57 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h | |||
@@ -210,15 +210,16 @@ typedef int (*xfs_bmapi_t)(struct xfs_trans *, void *, | |||
210 | struct xfs_bmap_free *); | 210 | struct xfs_bmap_free *); |
211 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); | 211 | typedef int (*xfs_bmap_eof_t)(void *, xfs_fileoff_t, int, int *); |
212 | typedef int (*xfs_iomap_write_direct_t)( | 212 | typedef int (*xfs_iomap_write_direct_t)( |
213 | void *, loff_t, size_t, int, | 213 | void *, xfs_off_t, size_t, int, |
214 | struct xfs_bmbt_irec *, int *, int); | 214 | struct xfs_bmbt_irec *, int *, int); |
215 | typedef int (*xfs_iomap_write_delay_t)( | 215 | typedef int (*xfs_iomap_write_delay_t)( |
216 | void *, loff_t, size_t, int, | 216 | void *, xfs_off_t, size_t, int, |
217 | struct xfs_bmbt_irec *, int *); | 217 | struct xfs_bmbt_irec *, int *); |
218 | typedef int (*xfs_iomap_write_allocate_t)( | 218 | typedef int (*xfs_iomap_write_allocate_t)( |
219 | void *, struct xfs_bmbt_irec *, int *); | 219 | void *, xfs_off_t, size_t, |
220 | struct xfs_bmbt_irec *, int *); | ||
220 | typedef int (*xfs_iomap_write_unwritten_t)( | 221 | typedef int (*xfs_iomap_write_unwritten_t)( |
221 | void *, loff_t, size_t); | 222 | void *, xfs_off_t, size_t); |
222 | typedef uint (*xfs_lck_map_shared_t)(void *); | 223 | typedef uint (*xfs_lck_map_shared_t)(void *); |
223 | typedef void (*xfs_lock_t)(void *, uint); | 224 | typedef void (*xfs_lock_t)(void *, uint); |
224 | typedef void (*xfs_lock_demote_t)(void *, uint); | 225 | typedef void (*xfs_lock_demote_t)(void *, uint); |
@@ -258,9 +259,9 @@ typedef struct xfs_ioops { | |||
258 | #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ | 259 | #define XFS_IOMAP_WRITE_DELAY(mp, io, offset, count, flags, mval, nmap) \ |
259 | (*(mp)->m_io_ops.xfs_iomap_write_delay) \ | 260 | (*(mp)->m_io_ops.xfs_iomap_write_delay) \ |
260 | ((io)->io_obj, offset, count, flags, mval, nmap) | 261 | ((io)->io_obj, offset, count, flags, mval, nmap) |
261 | #define XFS_IOMAP_WRITE_ALLOCATE(mp, io, mval, nmap) \ | 262 | #define XFS_IOMAP_WRITE_ALLOCATE(mp, io, offset, count, mval, nmap) \ |
262 | (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ | 263 | (*(mp)->m_io_ops.xfs_iomap_write_allocate) \ |
263 | ((io)->io_obj, mval, nmap) | 264 | ((io)->io_obj, offset, count, mval, nmap) |
264 | #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ | 265 | #define XFS_IOMAP_WRITE_UNWRITTEN(mp, io, offset, count) \ |
265 | (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ | 266 | (*(mp)->m_io_ops.xfs_iomap_write_unwritten) \ |
266 | ((io)->io_obj, offset, count) | 267 | ((io)->io_obj, offset, count) |
@@ -428,10 +429,10 @@ typedef struct xfs_mount { | |||
428 | #define XFS_WRITEIO_LOG_LARGE 16 | 429 | #define XFS_WRITEIO_LOG_LARGE 16 |
429 | 430 | ||
430 | /* | 431 | /* |
431 | * Max and min values for UIO and mount-option defined I/O sizes; | 432 | * Max and min values for mount-option defined I/O |
432 | * min value can't be less than a page. Currently unused. | 433 | * preallocation sizes. |
433 | */ | 434 | */ |
434 | #define XFS_MAX_IO_LOG 16 /* 64K */ | 435 | #define XFS_MAX_IO_LOG 30 /* 1G */ |
435 | #define XFS_MIN_IO_LOG PAGE_SHIFT | 436 | #define XFS_MIN_IO_LOG PAGE_SHIFT |
436 | 437 | ||
437 | /* | 438 | /* |
diff --git a/fs/xfs/xfs_types.h b/fs/xfs/xfs_types.h index 04609d27ea51..e4bf711e48ff 100644 --- a/fs/xfs/xfs_types.h +++ b/fs/xfs/xfs_types.h | |||
@@ -63,6 +63,7 @@ typedef __u64 xfs_ino_t; /* <inode> type */ | |||
63 | typedef __s64 xfs_daddr_t; /* <disk address> type */ | 63 | typedef __s64 xfs_daddr_t; /* <disk address> type */ |
64 | typedef char * xfs_caddr_t; /* <core address> type */ | 64 | typedef char * xfs_caddr_t; /* <core address> type */ |
65 | typedef __u32 xfs_dev_t; | 65 | typedef __u32 xfs_dev_t; |
66 | typedef __u32 xfs_nlink_t; | ||
66 | 67 | ||
67 | /* __psint_t is the same size as a pointer */ | 68 | /* __psint_t is the same size as a pointer */ |
68 | #if (BITS_PER_LONG == 32) | 69 | #if (BITS_PER_LONG == 32) |
diff --git a/fs/xfs/xfs_utils.c b/fs/xfs/xfs_utils.c index 816b945fa0ea..d1f8146a06ea 100644 --- a/fs/xfs/xfs_utils.c +++ b/fs/xfs/xfs_utils.c | |||
@@ -147,7 +147,7 @@ xfs_dir_ialloc( | |||
147 | xfs_inode_t *dp, /* directory within whose allocate | 147 | xfs_inode_t *dp, /* directory within whose allocate |
148 | the inode. */ | 148 | the inode. */ |
149 | mode_t mode, | 149 | mode_t mode, |
150 | nlink_t nlink, | 150 | xfs_nlink_t nlink, |
151 | xfs_dev_t rdev, | 151 | xfs_dev_t rdev, |
152 | cred_t *credp, | 152 | cred_t *credp, |
153 | prid_t prid, /* project id */ | 153 | prid_t prid, /* project id */ |
diff --git a/fs/xfs/xfs_utils.h b/fs/xfs/xfs_utils.h index e1ed6a588000..01d98b4b7af7 100644 --- a/fs/xfs/xfs_utils.h +++ b/fs/xfs/xfs_utils.h | |||
@@ -42,7 +42,7 @@ extern int xfs_get_dir_entry (vname_t *, xfs_inode_t **); | |||
42 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, | 42 | extern int xfs_dir_lookup_int (bhv_desc_t *, uint, vname_t *, xfs_ino_t *, |
43 | xfs_inode_t **); | 43 | xfs_inode_t **); |
44 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); | 44 | extern int xfs_truncate_file (xfs_mount_t *, xfs_inode_t *); |
45 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, nlink_t, | 45 | extern int xfs_dir_ialloc (xfs_trans_t **, xfs_inode_t *, mode_t, xfs_nlink_t, |
46 | xfs_dev_t, cred_t *, prid_t, int, | 46 | xfs_dev_t, cred_t *, prid_t, int, |
47 | xfs_inode_t **, int *); | 47 | xfs_inode_t **, int *); |
48 | extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *); | 48 | extern int xfs_droplink (xfs_trans_t *, xfs_inode_t *); |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index 00aae9c6a904..b53736650100 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -1649,6 +1649,7 @@ xfs_vget( | |||
1649 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ | 1649 | #define MNTOPT_SWIDTH "swidth" /* data volume stripe width */ |
1650 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ | 1650 | #define MNTOPT_NOUUID "nouuid" /* ignore filesystem UUID */ |
1651 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ | 1651 | #define MNTOPT_MTPT "mtpt" /* filesystem mount point */ |
1652 | #define MNTOPT_ALLOCSIZE "allocsize" /* preferred allocation size */ | ||
1652 | #define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ | 1653 | #define MNTOPT_IHASHSIZE "ihashsize" /* size of inode hash table */ |
1653 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ | 1654 | #define MNTOPT_NORECOVERY "norecovery" /* don't run XFS recovery */ |
1654 | #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ | 1655 | #define MNTOPT_NOLOGFLUSH "nologflush" /* don't hard flush on log writes */ |
@@ -1657,6 +1658,28 @@ xfs_vget( | |||
1657 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ | 1658 | #define MNTOPT_IKEEP "ikeep" /* do not free empty inode clusters */ |
1658 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ | 1659 | #define MNTOPT_NOIKEEP "noikeep" /* free empty inode clusters */ |
1659 | 1660 | ||
1661 | STATIC unsigned long | ||
1662 | suffix_strtoul(const char *cp, char **endp, unsigned int base) | ||
1663 | { | ||
1664 | int last, shift_left_factor = 0; | ||
1665 | char *value = (char *)cp; | ||
1666 | |||
1667 | last = strlen(value) - 1; | ||
1668 | if (value[last] == 'K' || value[last] == 'k') { | ||
1669 | shift_left_factor = 10; | ||
1670 | value[last] = '\0'; | ||
1671 | } | ||
1672 | if (value[last] == 'M' || value[last] == 'm') { | ||
1673 | shift_left_factor = 20; | ||
1674 | value[last] = '\0'; | ||
1675 | } | ||
1676 | if (value[last] == 'G' || value[last] == 'g') { | ||
1677 | shift_left_factor = 30; | ||
1678 | value[last] = '\0'; | ||
1679 | } | ||
1680 | |||
1681 | return simple_strtoul(cp, endp, base) << shift_left_factor; | ||
1682 | } | ||
1660 | 1683 | ||
1661 | int | 1684 | int |
1662 | xfs_parseargs( | 1685 | xfs_parseargs( |
@@ -1688,60 +1711,60 @@ xfs_parseargs( | |||
1688 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { | 1711 | if (!strcmp(this_char, MNTOPT_LOGBUFS)) { |
1689 | if (!value || !*value) { | 1712 | if (!value || !*value) { |
1690 | printk("XFS: %s option requires an argument\n", | 1713 | printk("XFS: %s option requires an argument\n", |
1691 | MNTOPT_LOGBUFS); | 1714 | this_char); |
1692 | return EINVAL; | 1715 | return EINVAL; |
1693 | } | 1716 | } |
1694 | args->logbufs = simple_strtoul(value, &eov, 10); | 1717 | args->logbufs = simple_strtoul(value, &eov, 10); |
1695 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { | 1718 | } else if (!strcmp(this_char, MNTOPT_LOGBSIZE)) { |
1696 | int last, in_kilobytes = 0; | ||
1697 | |||
1698 | if (!value || !*value) { | 1719 | if (!value || !*value) { |
1699 | printk("XFS: %s option requires an argument\n", | 1720 | printk("XFS: %s option requires an argument\n", |
1700 | MNTOPT_LOGBSIZE); | 1721 | this_char); |
1701 | return EINVAL; | 1722 | return EINVAL; |
1702 | } | 1723 | } |
1703 | last = strlen(value) - 1; | 1724 | args->logbufsize = suffix_strtoul(value, &eov, 10); |
1704 | if (value[last] == 'K' || value[last] == 'k') { | ||
1705 | in_kilobytes = 1; | ||
1706 | value[last] = '\0'; | ||
1707 | } | ||
1708 | args->logbufsize = simple_strtoul(value, &eov, 10); | ||
1709 | if (in_kilobytes) | ||
1710 | args->logbufsize <<= 10; | ||
1711 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { | 1725 | } else if (!strcmp(this_char, MNTOPT_LOGDEV)) { |
1712 | if (!value || !*value) { | 1726 | if (!value || !*value) { |
1713 | printk("XFS: %s option requires an argument\n", | 1727 | printk("XFS: %s option requires an argument\n", |
1714 | MNTOPT_LOGDEV); | 1728 | this_char); |
1715 | return EINVAL; | 1729 | return EINVAL; |
1716 | } | 1730 | } |
1717 | strncpy(args->logname, value, MAXNAMELEN); | 1731 | strncpy(args->logname, value, MAXNAMELEN); |
1718 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { | 1732 | } else if (!strcmp(this_char, MNTOPT_MTPT)) { |
1719 | if (!value || !*value) { | 1733 | if (!value || !*value) { |
1720 | printk("XFS: %s option requires an argument\n", | 1734 | printk("XFS: %s option requires an argument\n", |
1721 | MNTOPT_MTPT); | 1735 | this_char); |
1722 | return EINVAL; | 1736 | return EINVAL; |
1723 | } | 1737 | } |
1724 | strncpy(args->mtpt, value, MAXNAMELEN); | 1738 | strncpy(args->mtpt, value, MAXNAMELEN); |
1725 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { | 1739 | } else if (!strcmp(this_char, MNTOPT_RTDEV)) { |
1726 | if (!value || !*value) { | 1740 | if (!value || !*value) { |
1727 | printk("XFS: %s option requires an argument\n", | 1741 | printk("XFS: %s option requires an argument\n", |
1728 | MNTOPT_RTDEV); | 1742 | this_char); |
1729 | return EINVAL; | 1743 | return EINVAL; |
1730 | } | 1744 | } |
1731 | strncpy(args->rtname, value, MAXNAMELEN); | 1745 | strncpy(args->rtname, value, MAXNAMELEN); |
1732 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { | 1746 | } else if (!strcmp(this_char, MNTOPT_BIOSIZE)) { |
1733 | if (!value || !*value) { | 1747 | if (!value || !*value) { |
1734 | printk("XFS: %s option requires an argument\n", | 1748 | printk("XFS: %s option requires an argument\n", |
1735 | MNTOPT_BIOSIZE); | 1749 | this_char); |
1736 | return EINVAL; | 1750 | return EINVAL; |
1737 | } | 1751 | } |
1738 | iosize = simple_strtoul(value, &eov, 10); | 1752 | iosize = simple_strtoul(value, &eov, 10); |
1739 | args->flags |= XFSMNT_IOSIZE; | 1753 | args->flags |= XFSMNT_IOSIZE; |
1740 | args->iosizelog = (uint8_t) iosize; | 1754 | args->iosizelog = (uint8_t) iosize; |
1755 | } else if (!strcmp(this_char, MNTOPT_ALLOCSIZE)) { | ||
1756 | if (!value || !*value) { | ||
1757 | printk("XFS: %s option requires an argument\n", | ||
1758 | this_char); | ||
1759 | return EINVAL; | ||
1760 | } | ||
1761 | iosize = suffix_strtoul(value, &eov, 10); | ||
1762 | args->flags |= XFSMNT_IOSIZE; | ||
1763 | args->iosizelog = ffs(iosize) - 1; | ||
1741 | } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { | 1764 | } else if (!strcmp(this_char, MNTOPT_IHASHSIZE)) { |
1742 | if (!value || !*value) { | 1765 | if (!value || !*value) { |
1743 | printk("XFS: %s option requires an argument\n", | 1766 | printk("XFS: %s option requires an argument\n", |
1744 | this_char); | 1767 | this_char); |
1745 | return EINVAL; | 1768 | return EINVAL; |
1746 | } | 1769 | } |
1747 | args->flags |= XFSMNT_IHASHSIZE; | 1770 | args->flags |= XFSMNT_IHASHSIZE; |
@@ -1756,7 +1779,7 @@ xfs_parseargs( | |||
1756 | args->flags |= XFSMNT_INO64; | 1779 | args->flags |= XFSMNT_INO64; |
1757 | #if !XFS_BIG_INUMS | 1780 | #if !XFS_BIG_INUMS |
1758 | printk("XFS: %s option not allowed on this system\n", | 1781 | printk("XFS: %s option not allowed on this system\n", |
1759 | MNTOPT_INO64); | 1782 | this_char); |
1760 | return EINVAL; | 1783 | return EINVAL; |
1761 | #endif | 1784 | #endif |
1762 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { | 1785 | } else if (!strcmp(this_char, MNTOPT_NOALIGN)) { |
@@ -1766,14 +1789,14 @@ xfs_parseargs( | |||
1766 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { | 1789 | } else if (!strcmp(this_char, MNTOPT_SUNIT)) { |
1767 | if (!value || !*value) { | 1790 | if (!value || !*value) { |
1768 | printk("XFS: %s option requires an argument\n", | 1791 | printk("XFS: %s option requires an argument\n", |
1769 | MNTOPT_SUNIT); | 1792 | this_char); |
1770 | return EINVAL; | 1793 | return EINVAL; |
1771 | } | 1794 | } |
1772 | dsunit = simple_strtoul(value, &eov, 10); | 1795 | dsunit = simple_strtoul(value, &eov, 10); |
1773 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { | 1796 | } else if (!strcmp(this_char, MNTOPT_SWIDTH)) { |
1774 | if (!value || !*value) { | 1797 | if (!value || !*value) { |
1775 | printk("XFS: %s option requires an argument\n", | 1798 | printk("XFS: %s option requires an argument\n", |
1776 | MNTOPT_SWIDTH); | 1799 | this_char); |
1777 | return EINVAL; | 1800 | return EINVAL; |
1778 | } | 1801 | } |
1779 | dswidth = simple_strtoul(value, &eov, 10); | 1802 | dswidth = simple_strtoul(value, &eov, 10); |
@@ -1781,7 +1804,7 @@ xfs_parseargs( | |||
1781 | args->flags &= ~XFSMNT_32BITINODES; | 1804 | args->flags &= ~XFSMNT_32BITINODES; |
1782 | #if !XFS_BIG_INUMS | 1805 | #if !XFS_BIG_INUMS |
1783 | printk("XFS: %s option not allowed on this system\n", | 1806 | printk("XFS: %s option not allowed on this system\n", |
1784 | MNTOPT_64BITINODE); | 1807 | this_char); |
1785 | return EINVAL; | 1808 | return EINVAL; |
1786 | #endif | 1809 | #endif |
1787 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { | 1810 | } else if (!strcmp(this_char, MNTOPT_NOUUID)) { |
@@ -1877,7 +1900,7 @@ xfs_showargs( | |||
1877 | seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); | 1900 | seq_printf(m, "," MNTOPT_IHASHSIZE "=%d", mp->m_ihsize); |
1878 | 1901 | ||
1879 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) | 1902 | if (mp->m_flags & XFS_MOUNT_DFLT_IOSIZE) |
1880 | seq_printf(m, "," MNTOPT_BIOSIZE "=%d", mp->m_writeio_log); | 1903 | seq_printf(m, "," MNTOPT_ALLOCSIZE "=%d", 1<<mp->m_writeio_log); |
1881 | 1904 | ||
1882 | if (mp->m_logbufs > 0) | 1905 | if (mp->m_logbufs > 0) |
1883 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); | 1906 | seq_printf(m, "," MNTOPT_LOGBUFS "=%d", mp->m_logbufs); |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 70092963ca9e..25a526629b12 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -305,7 +305,7 @@ xfs_setattr( | |||
305 | int mandlock_before, mandlock_after; | 305 | int mandlock_before, mandlock_after; |
306 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; | 306 | struct xfs_dquot *udqp, *gdqp, *olddquot1, *olddquot2; |
307 | int file_owner; | 307 | int file_owner; |
308 | int need_iolock = (flags & ATTR_DMI) == 0; | 308 | int need_iolock = 1; |
309 | 309 | ||
310 | vp = BHV_TO_VNODE(bdp); | 310 | vp = BHV_TO_VNODE(bdp); |
311 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); | 311 | vn_trace_entry(vp, __FUNCTION__, (inst_t *)__return_address); |
@@ -384,6 +384,9 @@ xfs_setattr( | |||
384 | */ | 384 | */ |
385 | tp = NULL; | 385 | tp = NULL; |
386 | lock_flags = XFS_ILOCK_EXCL; | 386 | lock_flags = XFS_ILOCK_EXCL; |
387 | ASSERT(flags & ATTR_NOLOCK ? flags & ATTR_DMI : 1); | ||
388 | if (flags & ATTR_NOLOCK) | ||
389 | need_iolock = 0; | ||
387 | if (!(mask & XFS_AT_SIZE)) { | 390 | if (!(mask & XFS_AT_SIZE)) { |
388 | if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || | 391 | if ((mask != (XFS_AT_CTIME|XFS_AT_ATIME|XFS_AT_MTIME)) || |
389 | (mp->m_flags & XFS_MOUNT_WSYNC)) { | 392 | (mp->m_flags & XFS_MOUNT_WSYNC)) { |
@@ -4320,7 +4323,7 @@ xfs_free_file_space( | |||
4320 | int rt; | 4323 | int rt; |
4321 | xfs_fileoff_t startoffset_fsb; | 4324 | xfs_fileoff_t startoffset_fsb; |
4322 | xfs_trans_t *tp; | 4325 | xfs_trans_t *tp; |
4323 | int need_iolock = (attr_flags & ATTR_DMI) == 0; | 4326 | int need_iolock = 1; |
4324 | 4327 | ||
4325 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); | 4328 | vn_trace_entry(XFS_ITOV(ip), __FUNCTION__, (inst_t *)__return_address); |
4326 | mp = ip->i_mount; | 4329 | mp = ip->i_mount; |
@@ -4348,8 +4351,12 @@ xfs_free_file_space( | |||
4348 | return(error); | 4351 | return(error); |
4349 | } | 4352 | } |
4350 | 4353 | ||
4354 | ASSERT(attr_flags & ATTR_NOLOCK ? attr_flags & ATTR_DMI : 1); | ||
4355 | if (attr_flags & ATTR_NOLOCK) | ||
4356 | need_iolock = 0; | ||
4351 | if (need_iolock) | 4357 | if (need_iolock) |
4352 | xfs_ilock(ip, XFS_IOLOCK_EXCL); | 4358 | xfs_ilock(ip, XFS_IOLOCK_EXCL); |
4359 | |||
4353 | rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), | 4360 | rounding = MAX((__uint8_t)(1 << mp->m_sb.sb_blocklog), |
4354 | (__uint8_t)NBPP); | 4361 | (__uint8_t)NBPP); |
4355 | ilen = len + (offset & (rounding - 1)); | 4362 | ilen = len + (offset & (rounding - 1)); |
diff --git a/include/asm-arm/arch-imx/imx-regs.h b/include/asm-arm/arch-imx/imx-regs.h index f32c203952cf..93b840e8fa60 100644 --- a/include/asm-arm/arch-imx/imx-regs.h +++ b/include/asm-arm/arch-imx/imx-regs.h | |||
@@ -228,6 +228,30 @@ | |||
228 | #define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 ) | 228 | #define PD31_BIN_SPI2_TXD ( GPIO_PORTD | GPIO_BIN | 31 ) |
229 | 229 | ||
230 | /* | 230 | /* |
231 | * PWM controller | ||
232 | */ | ||
233 | #define PWMC __REG(IMX_PWM_BASE + 0x00) /* PWM Control Register */ | ||
234 | #define PWMS __REG(IMX_PWM_BASE + 0x04) /* PWM Sample Register */ | ||
235 | #define PWMP __REG(IMX_PWM_BASE + 0x08) /* PWM Period Register */ | ||
236 | #define PWMCNT __REG(IMX_PWM_BASE + 0x0C) /* PWM Counter Register */ | ||
237 | |||
238 | #define PWMC_HCTR (0x01<<18) /* Halfword FIFO Data Swapping */ | ||
239 | #define PWMC_BCTR (0x01<<17) /* Byte FIFO Data Swapping */ | ||
240 | #define PWMC_SWR (0x01<<16) /* Software Reset */ | ||
241 | #define PWMC_CLKSRC (0x01<<15) /* Clock Source */ | ||
242 | #define PWMC_PRESCALER(x) (((x-1) & 0x7F) << 8) /* PRESCALER */ | ||
243 | #define PWMC_IRQ (0x01<< 7) /* Interrupt Request */ | ||
244 | #define PWMC_IRQEN (0x01<< 6) /* Interrupt Request Enable */ | ||
245 | #define PWMC_FIFOAV (0x01<< 5) /* FIFO Available */ | ||
246 | #define PWMC_EN (0x01<< 4) /* Enables/Disables the PWM */ | ||
247 | #define PWMC_REPEAT(x) (((x) & 0x03) << 2) /* Sample Repeats */ | ||
248 | #define PWMC_CLKSEL(x) (((x) & 0x03) << 0) /* Clock Selection */ | ||
249 | |||
250 | #define PWMS_SAMPLE(x) ((x) & 0xFFFF) /* Contains a two-sample word */ | ||
251 | #define PWMP_PERIOD(x) ((x) & 0xFFFF) /* Represents the PWM's period */ | ||
252 | #define PWMC_COUNTER(x) ((x) & 0xFFFF) /* Represents the current count value */ | ||
253 | |||
254 | /* | ||
231 | * DMA Controller | 255 | * DMA Controller |
232 | */ | 256 | */ |
233 | #define DCR __REG(IMX_DMAC_BASE +0x00) /* DMA Control Register */ | 257 | #define DCR __REG(IMX_DMAC_BASE +0x00) /* DMA Control Register */ |
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h new file mode 100644 index 000000000000..2346d454ab9c --- /dev/null +++ b/include/asm-arm/arch-imx/imxfb.h | |||
@@ -0,0 +1,35 @@ | |||
1 | /* | ||
2 | * This structure describes the machine which we are running on. | ||
3 | */ | ||
4 | struct imxfb_mach_info { | ||
5 | u_long pixclock; | ||
6 | |||
7 | u_short xres; | ||
8 | u_short yres; | ||
9 | |||
10 | u_char bpp; | ||
11 | u_char hsync_len; | ||
12 | u_char left_margin; | ||
13 | u_char right_margin; | ||
14 | |||
15 | u_char vsync_len; | ||
16 | u_char upper_margin; | ||
17 | u_char lower_margin; | ||
18 | u_char sync; | ||
19 | |||
20 | u_int cmap_greyscale:1, | ||
21 | cmap_inverse:1, | ||
22 | cmap_static:1, | ||
23 | unused:29; | ||
24 | |||
25 | u_int pcr; | ||
26 | u_int pwmr; | ||
27 | u_int lscr1; | ||
28 | |||
29 | u_char * fixed_screen_cpu; | ||
30 | dma_addr_t fixed_screen_dma; | ||
31 | |||
32 | void (*lcd_power)(int); | ||
33 | void (*backlight_power)(int); | ||
34 | }; | ||
35 | void set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info); | ||
diff --git a/include/asm-arm/arch-s3c2410/regs-nand.h b/include/asm-arm/arch-s3c2410/regs-nand.h index c443ac834698..7cff235e667a 100644 --- a/include/asm-arm/arch-s3c2410/regs-nand.h +++ b/include/asm-arm/arch-s3c2410/regs-nand.h | |||
@@ -1,16 +1,17 @@ | |||
1 | /* linux/include/asm-arm/arch-s3c2410/regs-nand.h | 1 | /* linux/include/asm-arm/arch-s3c2410/regs-nand.h |
2 | * | 2 | * |
3 | * Copyright (c) 2004 Simtec Electronics <linux@simtec.co.uk> | 3 | * Copyright (c) 2004,2005 Simtec Electronics <linux@simtec.co.uk> |
4 | * http://www.simtec.co.uk/products/SWLINUX/ | 4 | * http://www.simtec.co.uk/products/SWLINUX/ |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * S3C2410 clock register definitions | 10 | * S3C2410 NAND register definitions |
11 | * | 11 | * |
12 | * Changelog: | 12 | * Changelog: |
13 | * 18-Aug-2004 BJD Copied file from 2.4 and updated | 13 | * 18-Aug-2004 BJD Copied file from 2.4 and updated |
14 | * 01-May-2005 BJD Added definitions for s3c2440 controller | ||
14 | */ | 15 | */ |
15 | 16 | ||
16 | #ifndef __ASM_ARM_REGS_NAND | 17 | #ifndef __ASM_ARM_REGS_NAND |
@@ -26,6 +27,22 @@ | |||
26 | #define S3C2410_NFSTAT S3C2410_NFREG(0x10) | 27 | #define S3C2410_NFSTAT S3C2410_NFREG(0x10) |
27 | #define S3C2410_NFECC S3C2410_NFREG(0x14) | 28 | #define S3C2410_NFECC S3C2410_NFREG(0x14) |
28 | 29 | ||
30 | #define S3C2440_NFCONT S3C2410_NFREG(0x04) | ||
31 | #define S3C2440_NFCMD S3C2410_NFREG(0x08) | ||
32 | #define S3C2440_NFADDR S3C2410_NFREG(0x0C) | ||
33 | #define S3C2440_NFDATA S3C2410_NFREG(0x10) | ||
34 | #define S3C2440_NFECCD0 S3C2410_NFREG(0x14) | ||
35 | #define S3C2440_NFECCD1 S3C2410_NFREG(0x18) | ||
36 | #define S3C2440_NFECCD S3C2410_NFREG(0x1C) | ||
37 | #define S3C2440_NFSTAT S3C2410_NFREG(0x20) | ||
38 | #define S3C2440_NFESTAT0 S3C2410_NFREG(0x24) | ||
39 | #define S3C2440_NFESTAT1 S3C2410_NFREG(0x28) | ||
40 | #define S3C2440_NFMECC0 S3C2410_NFREG(0x2C) | ||
41 | #define S3C2440_NFMECC1 S3C2410_NFREG(0x30) | ||
42 | #define S3C2440_NFSECC S3C2410_NFREG(0x34) | ||
43 | #define S3C2440_NFSBLK S3C2410_NFREG(0x38) | ||
44 | #define S3C2440_NFEBLK S3C2410_NFREG(0x3C) | ||
45 | |||
29 | #define S3C2410_NFCONF_EN (1<<15) | 46 | #define S3C2410_NFCONF_EN (1<<15) |
30 | #define S3C2410_NFCONF_512BYTE (1<<14) | 47 | #define S3C2410_NFCONF_512BYTE (1<<14) |
31 | #define S3C2410_NFCONF_4STEP (1<<13) | 48 | #define S3C2410_NFCONF_4STEP (1<<13) |
@@ -37,7 +54,28 @@ | |||
37 | 54 | ||
38 | #define S3C2410_NFSTAT_BUSY (1<<0) | 55 | #define S3C2410_NFSTAT_BUSY (1<<0) |
39 | 56 | ||
40 | /* think ECC can only be 8bit read? */ | 57 | #define S3C2440_NFCONF_BUSWIDTH_8 (0<<0) |
58 | #define S3C2440_NFCONF_BUSWIDTH_16 (1<<0) | ||
59 | #define S3C2440_NFCONF_ADVFLASH (1<<3) | ||
60 | #define S3C2440_NFCONF_TACLS(x) ((x)<<12) | ||
61 | #define S3C2440_NFCONF_TWRPH0(x) ((x)<<8) | ||
62 | #define S3C2440_NFCONF_TWRPH1(x) ((x)<<4) | ||
63 | |||
64 | #define S3C2440_NFCONT_LOCKTIGHT (1<<13) | ||
65 | #define S3C2440_NFCONT_SOFTLOCK (1<<12) | ||
66 | #define S3C2440_NFCONT_ILLEGALACC_EN (1<<10) | ||
67 | #define S3C2440_NFCONT_RNBINT_EN (1<<9) | ||
68 | #define S3C2440_NFCONT_RN_FALLING (1<<8) | ||
69 | #define S3C2440_NFCONT_SPARE_ECCLOCK (1<<6) | ||
70 | #define S3C2440_NFCONT_MAIN_ECCLOCK (1<<5) | ||
71 | #define S3C2440_NFCONT_INITECC (1<<4) | ||
72 | #define S3C2440_NFCONT_nFCE (1<<1) | ||
73 | #define S3C2440_NFCONT_ENABLE (1<<0) | ||
74 | |||
75 | #define S3C2440_NFSTAT_READY (1<<0) | ||
76 | #define S3C2440_NFSTAT_nCE (1<<1) | ||
77 | #define S3C2440_NFSTAT_RnB_CHANGE (1<<2) | ||
78 | #define S3C2440_NFSTAT_ILLEGAL_ACCESS (1<<3) | ||
41 | 79 | ||
42 | #endif /* __ASM_ARM_REGS_NAND */ | 80 | #endif /* __ASM_ARM_REGS_NAND */ |
43 | 81 | ||
diff --git a/include/asm-arm/page.h b/include/asm-arm/page.h index 4ca3a8e9348f..019c45d75730 100644 --- a/include/asm-arm/page.h +++ b/include/asm-arm/page.h | |||
@@ -114,19 +114,8 @@ extern void __cpu_copy_user_page(void *to, const void *from, | |||
114 | unsigned long user); | 114 | unsigned long user); |
115 | #endif | 115 | #endif |
116 | 116 | ||
117 | #define clear_user_page(addr,vaddr,pg) \ | 117 | #define clear_user_page(addr,vaddr,pg) __cpu_clear_user_page(addr, vaddr) |
118 | do { \ | 118 | #define copy_user_page(to,from,vaddr,pg) __cpu_copy_user_page(to, from, vaddr) |
119 | preempt_disable(); \ | ||
120 | __cpu_clear_user_page(addr, vaddr); \ | ||
121 | preempt_enable(); \ | ||
122 | } while (0) | ||
123 | |||
124 | #define copy_user_page(to,from,vaddr,pg) \ | ||
125 | do { \ | ||
126 | preempt_disable(); \ | ||
127 | __cpu_copy_user_page(to, from, vaddr); \ | ||
128 | preempt_enable(); \ | ||
129 | } while (0) | ||
130 | 119 | ||
131 | #define clear_page(page) memzero((void *)(page), PAGE_SIZE) | 120 | #define clear_page(page) memzero((void *)(page), PAGE_SIZE) |
132 | extern void copy_page(void *to, const void *from); | 121 | extern void copy_page(void *to, const void *from); |
@@ -171,6 +160,9 @@ typedef unsigned long pgprot_t; | |||
171 | 160 | ||
172 | #endif /* STRICT_MM_TYPECHECKS */ | 161 | #endif /* STRICT_MM_TYPECHECKS */ |
173 | 162 | ||
163 | /* the upper-most page table pointer */ | ||
164 | extern pmd_t *top_pmd; | ||
165 | |||
174 | /* Pure 2^n version of get_order */ | 166 | /* Pure 2^n version of get_order */ |
175 | static inline int get_order(unsigned long size) | 167 | static inline int get_order(unsigned long size) |
176 | { | 168 | { |
diff --git a/include/asm-arm/processor.h b/include/asm-arm/processor.h index 4a9845997a75..7d4118e09054 100644 --- a/include/asm-arm/processor.h +++ b/include/asm-arm/processor.h | |||
@@ -23,8 +23,6 @@ | |||
23 | #include <asm/procinfo.h> | 23 | #include <asm/procinfo.h> |
24 | #include <asm/types.h> | 24 | #include <asm/types.h> |
25 | 25 | ||
26 | #define KERNEL_STACK_SIZE PAGE_SIZE | ||
27 | |||
28 | union debug_insn { | 26 | union debug_insn { |
29 | u32 arm; | 27 | u32 arm; |
30 | u16 thumb; | 28 | u16 thumb; |
@@ -87,8 +85,9 @@ unsigned long get_wchan(struct task_struct *p); | |||
87 | */ | 85 | */ |
88 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); | 86 | extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); |
89 | 87 | ||
90 | #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1019]) | 88 | #define KSTK_REGS(tsk) (((struct pt_regs *)(THREAD_START_SP + (unsigned long)(tsk)->thread_info)) - 1) |
91 | #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)->thread_info))[1017]) | 89 | #define KSTK_EIP(tsk) KSTK_REGS(tsk)->ARM_pc |
90 | #define KSTK_ESP(tsk) KSTK_REGS(tsk)->ARM_sp | ||
92 | 91 | ||
93 | /* | 92 | /* |
94 | * Prefetching support - only ARMv5. | 93 | * Prefetching support - only ARMv5. |
diff --git a/include/asm-arm/thread_info.h b/include/asm-arm/thread_info.h index a61618fb433c..66c585c50cf9 100644 --- a/include/asm-arm/thread_info.h +++ b/include/asm-arm/thread_info.h | |||
@@ -14,6 +14,10 @@ | |||
14 | 14 | ||
15 | #include <asm/fpstate.h> | 15 | #include <asm/fpstate.h> |
16 | 16 | ||
17 | #define THREAD_SIZE_ORDER 1 | ||
18 | #define THREAD_SIZE 8192 | ||
19 | #define THREAD_START_SP (THREAD_SIZE - 8) | ||
20 | |||
17 | #ifndef __ASSEMBLY__ | 21 | #ifndef __ASSEMBLY__ |
18 | 22 | ||
19 | struct task_struct; | 23 | struct task_struct; |
@@ -77,8 +81,6 @@ struct thread_info { | |||
77 | #define init_thread_info (init_thread_union.thread_info) | 81 | #define init_thread_info (init_thread_union.thread_info) |
78 | #define init_stack (init_thread_union.stack) | 82 | #define init_stack (init_thread_union.stack) |
79 | 83 | ||
80 | #define THREAD_SIZE 8192 | ||
81 | |||
82 | /* | 84 | /* |
83 | * how to get the thread information struct from C | 85 | * how to get the thread information struct from C |
84 | */ | 86 | */ |
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 976ac29598b7..195ccdc069e6 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h | |||
@@ -8,6 +8,8 @@ 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)); | ||
11 | extern char _end[]; | 13 | extern char _end[]; |
12 | 14 | ||
13 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ | 15 | #endif /* _ASM_GENERIC_SECTIONS_H_ */ |
diff --git a/include/asm-i386/floppy.h b/include/asm-i386/floppy.h index f4782284807a..79727afb94c9 100644 --- a/include/asm-i386/floppy.h +++ b/include/asm-i386/floppy.h | |||
@@ -257,7 +257,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) | |||
257 | return 0; | 257 | return 0; |
258 | } | 258 | } |
259 | 259 | ||
260 | struct fd_routine_l { | 260 | static struct fd_routine_l { |
261 | int (*_request_dma)(unsigned int dmanr, const char * device_id); | 261 | int (*_request_dma)(unsigned int dmanr, const char * device_id); |
262 | void (*_free_dma)(unsigned int dmanr); | 262 | void (*_free_dma)(unsigned int dmanr); |
263 | int (*_get_dma_residue)(unsigned int dummy); | 263 | int (*_get_dma_residue)(unsigned int dummy); |
diff --git a/include/asm-i386/module.h b/include/asm-i386/module.h index 508865e26308..eb7f2b4234aa 100644 --- a/include/asm-i386/module.h +++ b/include/asm-i386/module.h | |||
@@ -52,8 +52,8 @@ struct mod_arch_specific | |||
52 | #define MODULE_PROC_FAMILY "CYRIXIII " | 52 | #define MODULE_PROC_FAMILY "CYRIXIII " |
53 | #elif defined CONFIG_MVIAC3_2 | 53 | #elif defined CONFIG_MVIAC3_2 |
54 | #define MODULE_PROC_FAMILY "VIAC3-2 " | 54 | #define MODULE_PROC_FAMILY "VIAC3-2 " |
55 | #elif CONFIG_MGEODE | 55 | #elif CONFIG_MGEODEGX1 |
56 | #define MODULE_PROC_FAMILY "GEODE " | 56 | #define MODULE_PROC_FAMILY "GEODEGX1 " |
57 | #else | 57 | #else |
58 | #error unknown processor family | 58 | #error unknown processor family |
59 | #endif | 59 | #endif |
diff --git a/include/asm-ia64/ioctl32.h b/include/asm-ia64/ioctl32.h deleted file mode 100644 index d0d227f45e05..000000000000 --- a/include/asm-ia64/ioctl32.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <linux/ioctl32.h> | ||
diff --git a/include/asm-parisc/floppy.h b/include/asm-parisc/floppy.h index 47f53df2cef5..ca3aed768cdc 100644 --- a/include/asm-parisc/floppy.h +++ b/include/asm-parisc/floppy.h | |||
@@ -235,7 +235,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) | |||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
238 | struct fd_routine_l { | 238 | static struct fd_routine_l { |
239 | int (*_request_dma)(unsigned int dmanr, const char * device_id); | 239 | int (*_request_dma)(unsigned int dmanr, const char * device_id); |
240 | void (*_free_dma)(unsigned int dmanr); | 240 | void (*_free_dma)(unsigned int dmanr); |
241 | int (*_get_dma_residue)(unsigned int dummy); | 241 | int (*_get_dma_residue)(unsigned int dummy); |
diff --git a/include/asm-ppc64/imalloc.h b/include/asm-ppc64/imalloc.h new file mode 100644 index 000000000000..3a45e918bf16 --- /dev/null +++ b/include/asm-ppc64/imalloc.h | |||
@@ -0,0 +1,24 @@ | |||
1 | #ifndef _PPC64_IMALLOC_H | ||
2 | #define _PPC64_IMALLOC_H | ||
3 | |||
4 | /* | ||
5 | * Define the address range of the imalloc VM area. | ||
6 | */ | ||
7 | #define PHBS_IO_BASE IOREGIONBASE | ||
8 | #define IMALLOC_BASE (IOREGIONBASE + 0x80000000ul) /* Reserve 2 gigs for PHBs */ | ||
9 | #define IMALLOC_END (IOREGIONBASE + EADDR_MASK) | ||
10 | |||
11 | |||
12 | /* imalloc region types */ | ||
13 | #define IM_REGION_UNUSED 0x1 | ||
14 | #define IM_REGION_SUBSET 0x2 | ||
15 | #define IM_REGION_EXISTS 0x4 | ||
16 | #define IM_REGION_OVERLAP 0x8 | ||
17 | #define IM_REGION_SUPERSET 0x10 | ||
18 | |||
19 | extern struct vm_struct * im_get_free_area(unsigned long size); | ||
20 | extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size, | ||
21 | int region_type); | ||
22 | unsigned long im_free(void *addr); | ||
23 | |||
24 | #endif /* _PPC64_IMALLOC_H */ | ||
diff --git a/include/asm-ppc64/mmu.h b/include/asm-ppc64/mmu.h index 188987e9d9d4..c78282a67d8e 100644 --- a/include/asm-ppc64/mmu.h +++ b/include/asm-ppc64/mmu.h | |||
@@ -15,19 +15,10 @@ | |||
15 | 15 | ||
16 | #include <linux/config.h> | 16 | #include <linux/config.h> |
17 | #include <asm/page.h> | 17 | #include <asm/page.h> |
18 | #include <linux/stringify.h> | ||
19 | 18 | ||
20 | #ifndef __ASSEMBLY__ | 19 | /* |
21 | 20 | * Segment table | |
22 | /* Time to allow for more things here */ | 21 | */ |
23 | typedef unsigned long mm_context_id_t; | ||
24 | typedef struct { | ||
25 | mm_context_id_t id; | ||
26 | #ifdef CONFIG_HUGETLB_PAGE | ||
27 | pgd_t *huge_pgdir; | ||
28 | u16 htlb_segs; /* bitmask */ | ||
29 | #endif | ||
30 | } mm_context_t; | ||
31 | 22 | ||
32 | #define STE_ESID_V 0x80 | 23 | #define STE_ESID_V 0x80 |
33 | #define STE_ESID_KS 0x20 | 24 | #define STE_ESID_KS 0x20 |
@@ -36,15 +27,48 @@ typedef struct { | |||
36 | 27 | ||
37 | #define STE_VSID_SHIFT 12 | 28 | #define STE_VSID_SHIFT 12 |
38 | 29 | ||
39 | struct stab_entry { | 30 | /* Location of cpu0's segment table */ |
40 | unsigned long esid_data; | 31 | #define STAB0_PAGE 0x9 |
41 | unsigned long vsid_data; | 32 | #define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT) |
42 | }; | 33 | #define STAB0_VIRT_ADDR (KERNELBASE+STAB0_PHYS_ADDR) |
34 | |||
35 | /* | ||
36 | * SLB | ||
37 | */ | ||
43 | 38 | ||
44 | /* Hardware Page Table Entry */ | 39 | #define SLB_NUM_BOLTED 3 |
40 | #define SLB_CACHE_ENTRIES 8 | ||
41 | |||
42 | /* Bits in the SLB ESID word */ | ||
43 | #define SLB_ESID_V ASM_CONST(0x0000000008000000) /* valid */ | ||
44 | |||
45 | /* Bits in the SLB VSID word */ | ||
46 | #define SLB_VSID_SHIFT 12 | ||
47 | #define SLB_VSID_KS ASM_CONST(0x0000000000000800) | ||
48 | #define SLB_VSID_KP ASM_CONST(0x0000000000000400) | ||
49 | #define SLB_VSID_N ASM_CONST(0x0000000000000200) /* no-execute */ | ||
50 | #define SLB_VSID_L ASM_CONST(0x0000000000000100) /* largepage 16M */ | ||
51 | #define SLB_VSID_C ASM_CONST(0x0000000000000080) /* class */ | ||
52 | |||
53 | #define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C) | ||
54 | #define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS) | ||
55 | |||
56 | /* | ||
57 | * Hash table | ||
58 | */ | ||
45 | 59 | ||
46 | #define HPTES_PER_GROUP 8 | 60 | #define HPTES_PER_GROUP 8 |
47 | 61 | ||
62 | /* Values for PP (assumes Ks=0, Kp=1) */ | ||
63 | /* pp0 will always be 0 for linux */ | ||
64 | #define PP_RWXX 0 /* Supervisor read/write, User none */ | ||
65 | #define PP_RWRX 1 /* Supervisor read/write, User read */ | ||
66 | #define PP_RWRW 2 /* Supervisor read/write, User read/write */ | ||
67 | #define PP_RXRX 3 /* Supervisor read, User read */ | ||
68 | |||
69 | #ifndef __ASSEMBLY__ | ||
70 | |||
71 | /* Hardware Page Table Entry */ | ||
48 | typedef struct { | 72 | typedef struct { |
49 | unsigned long avpn:57; /* vsid | api == avpn */ | 73 | unsigned long avpn:57; /* vsid | api == avpn */ |
50 | unsigned long : 2; /* Software use */ | 74 | unsigned long : 2; /* Software use */ |
@@ -90,14 +114,6 @@ typedef struct { | |||
90 | } dw1; | 114 | } dw1; |
91 | } HPTE; | 115 | } HPTE; |
92 | 116 | ||
93 | /* Values for PP (assumes Ks=0, Kp=1) */ | ||
94 | /* pp0 will always be 0 for linux */ | ||
95 | #define PP_RWXX 0 /* Supervisor read/write, User none */ | ||
96 | #define PP_RWRX 1 /* Supervisor read/write, User read */ | ||
97 | #define PP_RWRW 2 /* Supervisor read/write, User read/write */ | ||
98 | #define PP_RXRX 3 /* Supervisor read, User read */ | ||
99 | |||
100 | |||
101 | extern HPTE * htab_address; | 117 | extern HPTE * htab_address; |
102 | extern unsigned long htab_hash_mask; | 118 | extern unsigned long htab_hash_mask; |
103 | 119 | ||
@@ -174,31 +190,70 @@ extern int __hash_page(unsigned long ea, unsigned long access, | |||
174 | 190 | ||
175 | extern void htab_finish_init(void); | 191 | extern void htab_finish_init(void); |
176 | 192 | ||
193 | extern void hpte_init_native(void); | ||
194 | extern void hpte_init_lpar(void); | ||
195 | extern void hpte_init_iSeries(void); | ||
196 | |||
197 | extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, | ||
198 | unsigned long va, unsigned long prpn, | ||
199 | int secondary, unsigned long hpteflags, | ||
200 | int bolted, int large); | ||
201 | extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, | ||
202 | unsigned long prpn, int secondary, | ||
203 | unsigned long hpteflags, int bolted, int large); | ||
204 | |||
177 | #endif /* __ASSEMBLY__ */ | 205 | #endif /* __ASSEMBLY__ */ |
178 | 206 | ||
179 | /* | 207 | /* |
180 | * Location of cpu0's segment table | 208 | * VSID allocation |
209 | * | ||
210 | * We first generate a 36-bit "proto-VSID". For kernel addresses this | ||
211 | * is equal to the ESID, for user addresses it is: | ||
212 | * (context << 15) | (esid & 0x7fff) | ||
213 | * | ||
214 | * The two forms are distinguishable because the top bit is 0 for user | ||
215 | * addresses, whereas the top two bits are 1 for kernel addresses. | ||
216 | * Proto-VSIDs with the top two bits equal to 0b10 are reserved for | ||
217 | * now. | ||
218 | * | ||
219 | * The proto-VSIDs are then scrambled into real VSIDs with the | ||
220 | * multiplicative hash: | ||
221 | * | ||
222 | * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS | ||
223 | * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7 | ||
224 | * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF | ||
225 | * | ||
226 | * This scramble is only well defined for proto-VSIDs below | ||
227 | * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are | ||
228 | * reserved. VSID_MULTIPLIER is prime, so in particular it is | ||
229 | * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. | ||
230 | * Because the modulus is 2^n-1 we can compute it efficiently without | ||
231 | * a divide or extra multiply (see below). | ||
232 | * | ||
233 | * This scheme has several advantages over older methods: | ||
234 | * | ||
235 | * - We have VSIDs allocated for every kernel address | ||
236 | * (i.e. everything above 0xC000000000000000), except the very top | ||
237 | * segment, which simplifies several things. | ||
238 | * | ||
239 | * - We allow for 15 significant bits of ESID and 20 bits of | ||
240 | * context for user addresses. i.e. 8T (43 bits) of address space for | ||
241 | * up to 1M contexts (although the page table structure and context | ||
242 | * allocation will need changes to take advantage of this). | ||
243 | * | ||
244 | * - The scramble function gives robust scattering in the hash | ||
245 | * table (at least based on some initial results). The previous | ||
246 | * method was more susceptible to pathological cases giving excessive | ||
247 | * hash collisions. | ||
248 | */ | ||
249 | /* | ||
250 | * WARNING - If you change these you must make sure the asm | ||
251 | * implementations in slb_allocate (slb_low.S), do_stab_bolted | ||
252 | * (head.S) and ASM_VSID_SCRAMBLE (below) are changed accordingly. | ||
253 | * | ||
254 | * You'll also need to change the precomputed VSID values in head.S | ||
255 | * which are used by the iSeries firmware. | ||
181 | */ | 256 | */ |
182 | #define STAB0_PAGE 0x9 | ||
183 | #define STAB0_PHYS_ADDR (STAB0_PAGE<<PAGE_SHIFT) | ||
184 | #define STAB0_VIRT_ADDR (KERNELBASE+STAB0_PHYS_ADDR) | ||
185 | |||
186 | #define SLB_NUM_BOLTED 3 | ||
187 | #define SLB_CACHE_ENTRIES 8 | ||
188 | |||
189 | /* Bits in the SLB ESID word */ | ||
190 | #define SLB_ESID_V 0x0000000008000000 /* entry is valid */ | ||
191 | |||
192 | /* Bits in the SLB VSID word */ | ||
193 | #define SLB_VSID_SHIFT 12 | ||
194 | #define SLB_VSID_KS 0x0000000000000800 | ||
195 | #define SLB_VSID_KP 0x0000000000000400 | ||
196 | #define SLB_VSID_N 0x0000000000000200 /* no-execute */ | ||
197 | #define SLB_VSID_L 0x0000000000000100 /* largepage (4M) */ | ||
198 | #define SLB_VSID_C 0x0000000000000080 /* class */ | ||
199 | |||
200 | #define SLB_VSID_KERNEL (SLB_VSID_KP|SLB_VSID_C) | ||
201 | #define SLB_VSID_USER (SLB_VSID_KP|SLB_VSID_KS) | ||
202 | 257 | ||
203 | #define VSID_MULTIPLIER ASM_CONST(200730139) /* 28-bit prime */ | 258 | #define VSID_MULTIPLIER ASM_CONST(200730139) /* 28-bit prime */ |
204 | #define VSID_BITS 36 | 259 | #define VSID_BITS 36 |
@@ -239,4 +294,50 @@ extern void htab_finish_init(void); | |||
239 | srdi rx,rx,VSID_BITS; /* extract 2^36 bit */ \ | 294 | srdi rx,rx,VSID_BITS; /* extract 2^36 bit */ \ |
240 | add rt,rt,rx | 295 | add rt,rt,rx |
241 | 296 | ||
297 | |||
298 | #ifndef __ASSEMBLY__ | ||
299 | |||
300 | typedef unsigned long mm_context_id_t; | ||
301 | |||
302 | typedef struct { | ||
303 | mm_context_id_t id; | ||
304 | #ifdef CONFIG_HUGETLB_PAGE | ||
305 | pgd_t *huge_pgdir; | ||
306 | u16 htlb_segs; /* bitmask */ | ||
307 | #endif | ||
308 | } mm_context_t; | ||
309 | |||
310 | |||
311 | static inline unsigned long vsid_scramble(unsigned long protovsid) | ||
312 | { | ||
313 | #if 0 | ||
314 | /* The code below is equivalent to this function for arguments | ||
315 | * < 2^VSID_BITS, which is all this should ever be called | ||
316 | * with. However gcc is not clever enough to compute the | ||
317 | * modulus (2^n-1) without a second multiply. */ | ||
318 | return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS); | ||
319 | #else /* 1 */ | ||
320 | unsigned long x; | ||
321 | |||
322 | x = protovsid * VSID_MULTIPLIER; | ||
323 | x = (x >> VSID_BITS) + (x & VSID_MODULUS); | ||
324 | return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS; | ||
325 | #endif /* 1 */ | ||
326 | } | ||
327 | |||
328 | /* This is only valid for addresses >= KERNELBASE */ | ||
329 | static inline unsigned long get_kernel_vsid(unsigned long ea) | ||
330 | { | ||
331 | return vsid_scramble(ea >> SID_SHIFT); | ||
332 | } | ||
333 | |||
334 | /* This is only valid for user addresses (which are below 2^41) */ | ||
335 | static inline unsigned long get_vsid(unsigned long context, unsigned long ea) | ||
336 | { | ||
337 | return vsid_scramble((context << USER_ESID_BITS) | ||
338 | | (ea >> SID_SHIFT)); | ||
339 | } | ||
340 | |||
341 | #endif /* __ASSEMBLY */ | ||
342 | |||
242 | #endif /* _PPC64_MMU_H_ */ | 343 | #endif /* _PPC64_MMU_H_ */ |
diff --git a/include/asm-ppc64/mmu_context.h b/include/asm-ppc64/mmu_context.h index c2e8e0466383..77a743402db4 100644 --- a/include/asm-ppc64/mmu_context.h +++ b/include/asm-ppc64/mmu_context.h | |||
@@ -84,86 +84,4 @@ static inline void activate_mm(struct mm_struct *prev, struct mm_struct *next) | |||
84 | local_irq_restore(flags); | 84 | local_irq_restore(flags); |
85 | } | 85 | } |
86 | 86 | ||
87 | /* VSID allocation | ||
88 | * =============== | ||
89 | * | ||
90 | * We first generate a 36-bit "proto-VSID". For kernel addresses this | ||
91 | * is equal to the ESID, for user addresses it is: | ||
92 | * (context << 15) | (esid & 0x7fff) | ||
93 | * | ||
94 | * The two forms are distinguishable because the top bit is 0 for user | ||
95 | * addresses, whereas the top two bits are 1 for kernel addresses. | ||
96 | * Proto-VSIDs with the top two bits equal to 0b10 are reserved for | ||
97 | * now. | ||
98 | * | ||
99 | * The proto-VSIDs are then scrambled into real VSIDs with the | ||
100 | * multiplicative hash: | ||
101 | * | ||
102 | * VSID = (proto-VSID * VSID_MULTIPLIER) % VSID_MODULUS | ||
103 | * where VSID_MULTIPLIER = 268435399 = 0xFFFFFC7 | ||
104 | * VSID_MODULUS = 2^36-1 = 0xFFFFFFFFF | ||
105 | * | ||
106 | * This scramble is only well defined for proto-VSIDs below | ||
107 | * 0xFFFFFFFFF, so both proto-VSID and actual VSID 0xFFFFFFFFF are | ||
108 | * reserved. VSID_MULTIPLIER is prime, so in particular it is | ||
109 | * co-prime to VSID_MODULUS, making this a 1:1 scrambling function. | ||
110 | * Because the modulus is 2^n-1 we can compute it efficiently without | ||
111 | * a divide or extra multiply (see below). | ||
112 | * | ||
113 | * This scheme has several advantages over older methods: | ||
114 | * | ||
115 | * - We have VSIDs allocated for every kernel address | ||
116 | * (i.e. everything above 0xC000000000000000), except the very top | ||
117 | * segment, which simplifies several things. | ||
118 | * | ||
119 | * - We allow for 15 significant bits of ESID and 20 bits of | ||
120 | * context for user addresses. i.e. 8T (43 bits) of address space for | ||
121 | * up to 1M contexts (although the page table structure and context | ||
122 | * allocation will need changes to take advantage of this). | ||
123 | * | ||
124 | * - The scramble function gives robust scattering in the hash | ||
125 | * table (at least based on some initial results). The previous | ||
126 | * method was more susceptible to pathological cases giving excessive | ||
127 | * hash collisions. | ||
128 | */ | ||
129 | |||
130 | /* | ||
131 | * WARNING - If you change these you must make sure the asm | ||
132 | * implementations in slb_allocate(), do_stab_bolted and mmu.h | ||
133 | * (ASM_VSID_SCRAMBLE macro) are changed accordingly. | ||
134 | * | ||
135 | * You'll also need to change the precomputed VSID values in head.S | ||
136 | * which are used by the iSeries firmware. | ||
137 | */ | ||
138 | |||
139 | static inline unsigned long vsid_scramble(unsigned long protovsid) | ||
140 | { | ||
141 | #if 0 | ||
142 | /* The code below is equivalent to this function for arguments | ||
143 | * < 2^VSID_BITS, which is all this should ever be called | ||
144 | * with. However gcc is not clever enough to compute the | ||
145 | * modulus (2^n-1) without a second multiply. */ | ||
146 | return ((protovsid * VSID_MULTIPLIER) % VSID_MODULUS); | ||
147 | #else /* 1 */ | ||
148 | unsigned long x; | ||
149 | |||
150 | x = protovsid * VSID_MULTIPLIER; | ||
151 | x = (x >> VSID_BITS) + (x & VSID_MODULUS); | ||
152 | return (x + ((x+1) >> VSID_BITS)) & VSID_MODULUS; | ||
153 | #endif /* 1 */ | ||
154 | } | ||
155 | |||
156 | /* This is only valid for addresses >= KERNELBASE */ | ||
157 | static inline unsigned long get_kernel_vsid(unsigned long ea) | ||
158 | { | ||
159 | return vsid_scramble(ea >> SID_SHIFT); | ||
160 | } | ||
161 | |||
162 | /* This is only valid for user addresses (which are below 2^41) */ | ||
163 | static inline unsigned long get_vsid(unsigned long context, unsigned long ea) | ||
164 | { | ||
165 | return vsid_scramble((context << USER_ESID_BITS) | ||
166 | | (ea >> SID_SHIFT)); | ||
167 | } | ||
168 | |||
169 | #endif /* __PPC64_MMU_CONTEXT_H */ | 87 | #endif /* __PPC64_MMU_CONTEXT_H */ |
diff --git a/include/asm-ppc64/page.h b/include/asm-ppc64/page.h index 86219574c1a5..bcd21789d3b7 100644 --- a/include/asm-ppc64/page.h +++ b/include/asm-ppc64/page.h | |||
@@ -23,7 +23,6 @@ | |||
23 | #define PAGE_SHIFT 12 | 23 | #define PAGE_SHIFT 12 |
24 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) | 24 | #define PAGE_SIZE (ASM_CONST(1) << PAGE_SHIFT) |
25 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 25 | #define PAGE_MASK (~(PAGE_SIZE-1)) |
26 | #define PAGE_OFFSET_MASK (PAGE_SIZE-1) | ||
27 | 26 | ||
28 | #define SID_SHIFT 28 | 27 | #define SID_SHIFT 28 |
29 | #define SID_MASK 0xfffffffffUL | 28 | #define SID_MASK 0xfffffffffUL |
@@ -85,9 +84,6 @@ | |||
85 | /* align addr on a size boundary - adjust address up if needed */ | 84 | /* align addr on a size boundary - adjust address up if needed */ |
86 | #define _ALIGN(addr,size) _ALIGN_UP(addr,size) | 85 | #define _ALIGN(addr,size) _ALIGN_UP(addr,size) |
87 | 86 | ||
88 | /* to align the pointer to the (next) double word boundary */ | ||
89 | #define DOUBLEWORD_ALIGN(addr) _ALIGN(addr,sizeof(unsigned long)) | ||
90 | |||
91 | /* to align the pointer to the (next) page boundary */ | 87 | /* to align the pointer to the (next) page boundary */ |
92 | #define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) | 88 | #define PAGE_ALIGN(addr) _ALIGN(addr, PAGE_SIZE) |
93 | 89 | ||
@@ -100,7 +96,6 @@ | |||
100 | #define REGION_SIZE 4UL | 96 | #define REGION_SIZE 4UL |
101 | #define REGION_SHIFT 60UL | 97 | #define REGION_SHIFT 60UL |
102 | #define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT) | 98 | #define REGION_MASK (((1UL<<REGION_SIZE)-1UL)<<REGION_SHIFT) |
103 | #define REGION_STRIDE (1UL << REGION_SHIFT) | ||
104 | 99 | ||
105 | static __inline__ void clear_page(void *addr) | 100 | static __inline__ void clear_page(void *addr) |
106 | { | 101 | { |
@@ -209,13 +204,13 @@ extern u64 ppc64_pft_size; /* Log 2 of page table size */ | |||
209 | #define VMALLOCBASE ASM_CONST(0xD000000000000000) | 204 | #define VMALLOCBASE ASM_CONST(0xD000000000000000) |
210 | #define IOREGIONBASE ASM_CONST(0xE000000000000000) | 205 | #define IOREGIONBASE ASM_CONST(0xE000000000000000) |
211 | 206 | ||
212 | #define IO_REGION_ID (IOREGIONBASE>>REGION_SHIFT) | 207 | #define IO_REGION_ID (IOREGIONBASE >> REGION_SHIFT) |
213 | #define VMALLOC_REGION_ID (VMALLOCBASE>>REGION_SHIFT) | 208 | #define VMALLOC_REGION_ID (VMALLOCBASE >> REGION_SHIFT) |
214 | #define KERNEL_REGION_ID (KERNELBASE>>REGION_SHIFT) | 209 | #define KERNEL_REGION_ID (KERNELBASE >> REGION_SHIFT) |
215 | #define USER_REGION_ID (0UL) | 210 | #define USER_REGION_ID (0UL) |
216 | #define REGION_ID(X) (((unsigned long)(X))>>REGION_SHIFT) | 211 | #define REGION_ID(ea) (((unsigned long)(ea)) >> REGION_SHIFT) |
217 | 212 | ||
218 | #define __bpn_to_ba(x) ((((unsigned long)(x))<<PAGE_SHIFT) + KERNELBASE) | 213 | #define __bpn_to_ba(x) ((((unsigned long)(x)) << PAGE_SHIFT) + KERNELBASE) |
219 | #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) | 214 | #define __ba_to_bpn(x) ((((unsigned long)(x)) & ~REGION_MASK) >> PAGE_SHIFT) |
220 | 215 | ||
221 | #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) | 216 | #define __va(x) ((void *)((unsigned long)(x) + KERNELBASE)) |
diff --git a/include/asm-ppc64/pgtable.h b/include/asm-ppc64/pgtable.h index b984e2747e0c..264c4f7993be 100644 --- a/include/asm-ppc64/pgtable.h +++ b/include/asm-ppc64/pgtable.h | |||
@@ -17,16 +17,6 @@ | |||
17 | 17 | ||
18 | #include <asm-generic/pgtable-nopud.h> | 18 | #include <asm-generic/pgtable-nopud.h> |
19 | 19 | ||
20 | /* PMD_SHIFT determines what a second-level page table entry can map */ | ||
21 | #define PMD_SHIFT (PAGE_SHIFT + PAGE_SHIFT - 3) | ||
22 | #define PMD_SIZE (1UL << PMD_SHIFT) | ||
23 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
24 | |||
25 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ | ||
26 | #define PGDIR_SHIFT (PAGE_SHIFT + (PAGE_SHIFT - 3) + (PAGE_SHIFT - 2)) | ||
27 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||
28 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
29 | |||
30 | /* | 20 | /* |
31 | * Entries per page directory level. The PTE level must use a 64b record | 21 | * Entries per page directory level. The PTE level must use a 64b record |
32 | * for each page table entry. The PMD and PGD level use a 32b record for | 22 | * for each page table entry. The PMD and PGD level use a 32b record for |
@@ -40,40 +30,30 @@ | |||
40 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) | 30 | #define PTRS_PER_PMD (1 << PMD_INDEX_SIZE) |
41 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) | 31 | #define PTRS_PER_PGD (1 << PGD_INDEX_SIZE) |
42 | 32 | ||
43 | #define USER_PTRS_PER_PGD (1024) | 33 | /* PMD_SHIFT determines what a second-level page table entry can map */ |
44 | #define FIRST_USER_ADDRESS 0 | 34 | #define PMD_SHIFT (PAGE_SHIFT + PTE_INDEX_SIZE) |
35 | #define PMD_SIZE (1UL << PMD_SHIFT) | ||
36 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
45 | 37 | ||
46 | #define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ | 38 | /* PGDIR_SHIFT determines what a third-level page table entry can map */ |
47 | PGD_INDEX_SIZE + PAGE_SHIFT) | 39 | #define PGDIR_SHIFT (PMD_SHIFT + PMD_INDEX_SIZE) |
40 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||
41 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
42 | |||
43 | #define FIRST_USER_ADDRESS 0 | ||
48 | 44 | ||
49 | /* | 45 | /* |
50 | * Size of EA range mapped by our pagetables. | 46 | * Size of EA range mapped by our pagetables. |
51 | */ | 47 | */ |
52 | #define PGTABLE_EA_BITS 41 | 48 | #define EADDR_SIZE (PTE_INDEX_SIZE + PMD_INDEX_SIZE + \ |
53 | #define PGTABLE_EA_MASK ((1UL<<PGTABLE_EA_BITS)-1) | 49 | PGD_INDEX_SIZE + PAGE_SHIFT) |
50 | #define EADDR_MASK ((1UL << EADDR_SIZE) - 1) | ||
54 | 51 | ||
55 | /* | 52 | /* |
56 | * Define the address range of the vmalloc VM area. | 53 | * Define the address range of the vmalloc VM area. |
57 | */ | 54 | */ |
58 | #define VMALLOC_START (0xD000000000000000ul) | 55 | #define VMALLOC_START (0xD000000000000000ul) |
59 | #define VMALLOC_END (VMALLOC_START + PGTABLE_EA_MASK) | 56 | #define VMALLOC_END (VMALLOC_START + EADDR_MASK) |
60 | |||
61 | /* | ||
62 | * Define the address range of the imalloc VM area. | ||
63 | * (used for ioremap) | ||
64 | */ | ||
65 | #define IMALLOC_START (ioremap_bot) | ||
66 | #define IMALLOC_VMADDR(x) ((unsigned long)(x)) | ||
67 | #define PHBS_IO_BASE (0xE000000000000000ul) /* Reserve 2 gigs for PHBs */ | ||
68 | #define IMALLOC_BASE (0xE000000080000000ul) | ||
69 | #define IMALLOC_END (IMALLOC_BASE + PGTABLE_EA_MASK) | ||
70 | |||
71 | /* | ||
72 | * Define the user address range | ||
73 | */ | ||
74 | #define USER_START (0UL) | ||
75 | #define USER_END (USER_START + PGTABLE_EA_MASK) | ||
76 | |||
77 | 57 | ||
78 | /* | 58 | /* |
79 | * Bits in a linux-style PTE. These match the bits in the | 59 | * Bits in a linux-style PTE. These match the bits in the |
@@ -168,10 +148,6 @@ extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)]; | |||
168 | /* shift to put page number into pte */ | 148 | /* shift to put page number into pte */ |
169 | #define PTE_SHIFT (17) | 149 | #define PTE_SHIFT (17) |
170 | 150 | ||
171 | /* We allow 2^41 bytes of real memory, so we need 29 bits in the PMD | ||
172 | * to give the PTE page number. The bottom two bits are for flags. */ | ||
173 | #define PMD_TO_PTEPAGE_SHIFT (2) | ||
174 | |||
175 | #ifdef CONFIG_HUGETLB_PAGE | 151 | #ifdef CONFIG_HUGETLB_PAGE |
176 | 152 | ||
177 | #ifndef __ASSEMBLY__ | 153 | #ifndef __ASSEMBLY__ |
@@ -200,13 +176,14 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm); | |||
200 | */ | 176 | */ |
201 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) | 177 | #define mk_pte(page, pgprot) pfn_pte(page_to_pfn(page), (pgprot)) |
202 | 178 | ||
203 | #define pfn_pte(pfn,pgprot) \ | 179 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) |
204 | ({ \ | 180 | { |
205 | pte_t pte; \ | 181 | pte_t pte; |
206 | pte_val(pte) = ((unsigned long)(pfn) << PTE_SHIFT) | \ | 182 | |
207 | pgprot_val(pgprot); \ | 183 | |
208 | pte; \ | 184 | pte_val(pte) = (pfn << PTE_SHIFT) | pgprot_val(pgprot); |
209 | }) | 185 | return pte; |
186 | } | ||
210 | 187 | ||
211 | #define pte_modify(_pte, newprot) \ | 188 | #define pte_modify(_pte, newprot) \ |
212 | (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))) | 189 | (__pte((pte_val(_pte) & _PAGE_CHG_MASK) | pgprot_val(newprot))) |
@@ -220,13 +197,12 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm); | |||
220 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | 197 | #define pte_page(x) pfn_to_page(pte_pfn(x)) |
221 | 198 | ||
222 | #define pmd_set(pmdp, ptep) \ | 199 | #define pmd_set(pmdp, ptep) \ |
223 | (pmd_val(*(pmdp)) = (__ba_to_bpn(ptep) << PMD_TO_PTEPAGE_SHIFT)) | 200 | (pmd_val(*(pmdp)) = __ba_to_bpn(ptep)) |
224 | #define pmd_none(pmd) (!pmd_val(pmd)) | 201 | #define pmd_none(pmd) (!pmd_val(pmd)) |
225 | #define pmd_bad(pmd) (pmd_val(pmd) == 0) | 202 | #define pmd_bad(pmd) (pmd_val(pmd) == 0) |
226 | #define pmd_present(pmd) (pmd_val(pmd) != 0) | 203 | #define pmd_present(pmd) (pmd_val(pmd) != 0) |
227 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) | 204 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0) |
228 | #define pmd_page_kernel(pmd) \ | 205 | #define pmd_page_kernel(pmd) (__bpn_to_ba(pmd_val(pmd))) |
229 | (__bpn_to_ba(pmd_val(pmd) >> PMD_TO_PTEPAGE_SHIFT)) | ||
230 | #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) | 206 | #define pmd_page(pmd) virt_to_page(pmd_page_kernel(pmd)) |
231 | 207 | ||
232 | #define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp))) | 208 | #define pud_set(pudp, pmdp) (pud_val(*(pudp)) = (__ba_to_bpn(pmdp))) |
@@ -266,8 +242,6 @@ void hugetlb_mm_free_pgd(struct mm_struct *mm); | |||
266 | /* to find an entry in the ioremap page-table-directory */ | 242 | /* to find an entry in the ioremap page-table-directory */ |
267 | #define pgd_offset_i(address) (ioremap_pgd + pgd_index(address)) | 243 | #define pgd_offset_i(address) (ioremap_pgd + pgd_index(address)) |
268 | 244 | ||
269 | #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) | ||
270 | |||
271 | /* | 245 | /* |
272 | * The following only work if pte_present() is true. | 246 | * The following only work if pte_present() is true. |
273 | * Undefined behaviour if not.. | 247 | * Undefined behaviour if not.. |
@@ -442,7 +416,7 @@ static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | |||
442 | pte_clear(mm, addr, ptep); | 416 | pte_clear(mm, addr, ptep); |
443 | flush_tlb_pending(); | 417 | flush_tlb_pending(); |
444 | } | 418 | } |
445 | *ptep = __pte(pte_val(pte)) & ~_PAGE_HPTEFLAGS; | 419 | *ptep = __pte(pte_val(pte) & ~_PAGE_HPTEFLAGS); |
446 | } | 420 | } |
447 | 421 | ||
448 | /* Set the dirty and/or accessed bits atomically in a linux PTE, this | 422 | /* Set the dirty and/or accessed bits atomically in a linux PTE, this |
@@ -487,18 +461,13 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long addr, | |||
487 | 461 | ||
488 | extern unsigned long ioremap_bot, ioremap_base; | 462 | extern unsigned long ioremap_bot, ioremap_base; |
489 | 463 | ||
490 | #define USER_PGD_PTRS (PAGE_OFFSET >> PGDIR_SHIFT) | ||
491 | #define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) | ||
492 | |||
493 | #define pte_ERROR(e) \ | ||
494 | printk("%s:%d: bad pte %016lx.\n", __FILE__, __LINE__, pte_val(e)) | ||
495 | #define pmd_ERROR(e) \ | 464 | #define pmd_ERROR(e) \ |
496 | printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) | 465 | printk("%s:%d: bad pmd %08x.\n", __FILE__, __LINE__, pmd_val(e)) |
497 | #define pgd_ERROR(e) \ | 466 | #define pgd_ERROR(e) \ |
498 | printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) | 467 | printk("%s:%d: bad pgd %08x.\n", __FILE__, __LINE__, pgd_val(e)) |
499 | 468 | ||
500 | extern pgd_t swapper_pg_dir[1024]; | 469 | extern pgd_t swapper_pg_dir[]; |
501 | extern pgd_t ioremap_dir[1024]; | 470 | extern pgd_t ioremap_dir[]; |
502 | 471 | ||
503 | extern void paging_init(void); | 472 | extern void paging_init(void); |
504 | 473 | ||
@@ -540,43 +509,11 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t); | |||
540 | */ | 509 | */ |
541 | #define kern_addr_valid(addr) (1) | 510 | #define kern_addr_valid(addr) (1) |
542 | 511 | ||
543 | #define io_remap_page_range(vma, vaddr, paddr, size, prot) \ | ||
544 | remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot) | ||
545 | |||
546 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | 512 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ |
547 | remap_pfn_range(vma, vaddr, pfn, size, prot) | 513 | remap_pfn_range(vma, vaddr, pfn, size, prot) |
548 | 514 | ||
549 | #define MK_IOSPACE_PFN(space, pfn) (pfn) | ||
550 | #define GET_IOSPACE(pfn) 0 | ||
551 | #define GET_PFN(pfn) (pfn) | ||
552 | |||
553 | void pgtable_cache_init(void); | 515 | void pgtable_cache_init(void); |
554 | 516 | ||
555 | extern void hpte_init_native(void); | ||
556 | extern void hpte_init_lpar(void); | ||
557 | extern void hpte_init_iSeries(void); | ||
558 | |||
559 | /* imalloc region types */ | ||
560 | #define IM_REGION_UNUSED 0x1 | ||
561 | #define IM_REGION_SUBSET 0x2 | ||
562 | #define IM_REGION_EXISTS 0x4 | ||
563 | #define IM_REGION_OVERLAP 0x8 | ||
564 | #define IM_REGION_SUPERSET 0x10 | ||
565 | |||
566 | extern struct vm_struct * im_get_free_area(unsigned long size); | ||
567 | extern struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size, | ||
568 | int region_type); | ||
569 | unsigned long im_free(void *addr); | ||
570 | |||
571 | extern long pSeries_lpar_hpte_insert(unsigned long hpte_group, | ||
572 | unsigned long va, unsigned long prpn, | ||
573 | int secondary, unsigned long hpteflags, | ||
574 | int bolted, int large); | ||
575 | |||
576 | extern long native_hpte_insert(unsigned long hpte_group, unsigned long va, | ||
577 | unsigned long prpn, int secondary, | ||
578 | unsigned long hpteflags, int bolted, int large); | ||
579 | |||
580 | /* | 517 | /* |
581 | * find_linux_pte returns the address of a linux pte for a given | 518 | * find_linux_pte returns the address of a linux pte for a given |
582 | * effective address and directory. If not found, it returns zero. | 519 | * effective address and directory. If not found, it returns zero. |
diff --git a/include/asm-ppc64/xics.h b/include/asm-ppc64/xics.h index 0027da4364ac..fdec5e7a7af6 100644 --- a/include/asm-ppc64/xics.h +++ b/include/asm-ppc64/xics.h | |||
@@ -30,7 +30,4 @@ struct xics_ipi_struct { | |||
30 | 30 | ||
31 | extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; | 31 | extern struct xics_ipi_struct xics_ipi_message[NR_CPUS] __cacheline_aligned; |
32 | 32 | ||
33 | extern unsigned int default_distrib_server; | ||
34 | extern unsigned int interrupt_server_size; | ||
35 | |||
36 | #endif /* _PPC64_KERNEL_XICS_H */ | 33 | #endif /* _PPC64_KERNEL_XICS_H */ |
diff --git a/include/asm-sh/floppy.h b/include/asm-sh/floppy.h index f030ca08052b..38d7a2942476 100644 --- a/include/asm-sh/floppy.h +++ b/include/asm-sh/floppy.h | |||
@@ -227,7 +227,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) | |||
227 | return 0; | 227 | return 0; |
228 | } | 228 | } |
229 | 229 | ||
230 | struct fd_routine_l { | 230 | static struct fd_routine_l { |
231 | int (*_request_dma)(unsigned int dmanr, const char * device_id); | 231 | int (*_request_dma)(unsigned int dmanr, const char * device_id); |
232 | void (*_free_dma)(unsigned int dmanr); | 232 | void (*_free_dma)(unsigned int dmanr); |
233 | int (*_get_dma_residue)(unsigned int dummy); | 233 | int (*_get_dma_residue)(unsigned int dummy); |
diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index 2c28e1f605b7..b9b1914aae63 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h | |||
@@ -122,17 +122,12 @@ static __inline__ void free_pmd_slow(pmd_t *pmd) | |||
122 | #define pmd_populate(MM,PMD,PTE_PAGE) \ | 122 | #define pmd_populate(MM,PMD,PTE_PAGE) \ |
123 | pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) | 123 | pmd_populate_kernel(MM,PMD,page_address(PTE_PAGE)) |
124 | 124 | ||
125 | extern pte_t *__pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address); | 125 | extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address); |
126 | |||
127 | static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) | ||
128 | { | ||
129 | return __pte_alloc_one_kernel(mm, address); | ||
130 | } | ||
131 | 126 | ||
132 | static inline struct page * | 127 | static inline struct page * |
133 | pte_alloc_one(struct mm_struct *mm, unsigned long addr) | 128 | pte_alloc_one(struct mm_struct *mm, unsigned long addr) |
134 | { | 129 | { |
135 | pte_t *pte = __pte_alloc_one_kernel(mm, addr); | 130 | pte_t *pte = pte_alloc_one_kernel(mm, addr); |
136 | 131 | ||
137 | if (pte) | 132 | if (pte) |
138 | return virt_to_page(pte); | 133 | return virt_to_page(pte); |
diff --git a/include/asm-um/arch-signal-i386.h b/include/asm-um/arch-signal-i386.h deleted file mode 100644 index 99a9de4728da..000000000000 --- a/include/asm-um/arch-signal-i386.h +++ /dev/null | |||
@@ -1,24 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | |||
6 | #ifndef __UM_ARCH_SIGNAL_I386_H | ||
7 | #define __UM_ARCH_SIGNAL_I386_H | ||
8 | |||
9 | struct arch_signal_context { | ||
10 | unsigned long extrasigs[_NSIG_WORDS]; | ||
11 | }; | ||
12 | |||
13 | #endif | ||
14 | |||
15 | /* | ||
16 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
17 | * Emacs will notice this stuff at the end of the file and automatically | ||
18 | * adjust the settings for this buffer only. This must remain at the end | ||
19 | * of the file. | ||
20 | * --------------------------------------------------------------------------- | ||
21 | * Local variables: | ||
22 | * c-file-style: "linux" | ||
23 | * End: | ||
24 | */ | ||
diff --git a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h index 6f78de5b621b..49e89b8d7e58 100644 --- a/include/asm-um/archparam-i386.h +++ b/include/asm-um/archparam-i386.h | |||
@@ -6,143 +6,6 @@ | |||
6 | #ifndef __UM_ARCHPARAM_I386_H | 6 | #ifndef __UM_ARCHPARAM_I386_H |
7 | #define __UM_ARCHPARAM_I386_H | 7 | #define __UM_ARCHPARAM_I386_H |
8 | 8 | ||
9 | /********* Bits for asm-um/elf.h ************/ | ||
10 | |||
11 | #include <asm/user.h> | ||
12 | |||
13 | extern char * elf_aux_platform; | ||
14 | #define ELF_PLATFORM (elf_aux_platform) | ||
15 | |||
16 | #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) | ||
17 | |||
18 | typedef struct user_i387_struct elf_fpregset_t; | ||
19 | typedef unsigned long elf_greg_t; | ||
20 | |||
21 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
22 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
23 | |||
24 | #define ELF_DATA ELFDATA2LSB | ||
25 | #define ELF_ARCH EM_386 | ||
26 | |||
27 | #define ELF_PLAT_INIT(regs, load_addr) do { \ | ||
28 | PT_REGS_EBX(regs) = 0; \ | ||
29 | PT_REGS_ECX(regs) = 0; \ | ||
30 | PT_REGS_EDX(regs) = 0; \ | ||
31 | PT_REGS_ESI(regs) = 0; \ | ||
32 | PT_REGS_EDI(regs) = 0; \ | ||
33 | PT_REGS_EBP(regs) = 0; \ | ||
34 | PT_REGS_EAX(regs) = 0; \ | ||
35 | } while(0) | ||
36 | |||
37 | /* Shamelessly stolen from include/asm-i386/elf.h */ | ||
38 | |||
39 | #define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ | ||
40 | pr_reg[0] = PT_REGS_EBX(regs); \ | ||
41 | pr_reg[1] = PT_REGS_ECX(regs); \ | ||
42 | pr_reg[2] = PT_REGS_EDX(regs); \ | ||
43 | pr_reg[3] = PT_REGS_ESI(regs); \ | ||
44 | pr_reg[4] = PT_REGS_EDI(regs); \ | ||
45 | pr_reg[5] = PT_REGS_EBP(regs); \ | ||
46 | pr_reg[6] = PT_REGS_EAX(regs); \ | ||
47 | pr_reg[7] = PT_REGS_DS(regs); \ | ||
48 | pr_reg[8] = PT_REGS_ES(regs); \ | ||
49 | /* fake once used fs and gs selectors? */ \ | ||
50 | pr_reg[9] = PT_REGS_DS(regs); \ | ||
51 | pr_reg[10] = PT_REGS_DS(regs); \ | ||
52 | pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ | ||
53 | pr_reg[12] = PT_REGS_IP(regs); \ | ||
54 | pr_reg[13] = PT_REGS_CS(regs); \ | ||
55 | pr_reg[14] = PT_REGS_EFLAGS(regs); \ | ||
56 | pr_reg[15] = PT_REGS_SP(regs); \ | ||
57 | pr_reg[16] = PT_REGS_SS(regs); \ | ||
58 | } while(0); | ||
59 | |||
60 | |||
61 | extern unsigned long vsyscall_ehdr; | ||
62 | extern unsigned long vsyscall_end; | ||
63 | extern unsigned long __kernel_vsyscall; | ||
64 | |||
65 | #define VSYSCALL_BASE vsyscall_ehdr | ||
66 | #define VSYSCALL_END vsyscall_end | ||
67 | |||
68 | /* | ||
69 | * This is the range that is readable by user mode, and things | ||
70 | * acting like user mode such as get_user_pages. | ||
71 | */ | ||
72 | #define FIXADDR_USER_START VSYSCALL_BASE | ||
73 | #define FIXADDR_USER_END VSYSCALL_END | ||
74 | |||
75 | /* | ||
76 | * Architecture-neutral AT_ values in 0-17, leave some room | ||
77 | * for more of them, start the x86-specific ones at 32. | ||
78 | */ | ||
79 | #define AT_SYSINFO 32 | ||
80 | #define AT_SYSINFO_EHDR 33 | ||
81 | |||
82 | #define ARCH_DLINFO \ | ||
83 | do { \ | ||
84 | if ( vsyscall_ehdr ) { \ | ||
85 | NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ | ||
86 | NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ | ||
87 | } \ | ||
88 | } while (0) | ||
89 | |||
90 | /* | ||
91 | * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out | ||
92 | * extra segments containing the vsyscall DSO contents. Dumping its | ||
93 | * contents makes post-mortem fully interpretable later without matching up | ||
94 | * the same kernel and hardware config to see what PC values meant. | ||
95 | * Dumping its extra ELF program headers includes all the other information | ||
96 | * a debugger needs to easily find how the vsyscall DSO was being used. | ||
97 | */ | ||
98 | #define ELF_CORE_EXTRA_PHDRS \ | ||
99 | (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 ) | ||
100 | |||
101 | #define ELF_CORE_WRITE_EXTRA_PHDRS \ | ||
102 | if ( vsyscall_ehdr ) { \ | ||
103 | const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ | ||
104 | const struct elf_phdr *const phdrp = \ | ||
105 | (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ | ||
106 | int i; \ | ||
107 | Elf32_Off ofs = 0; \ | ||
108 | for (i = 0; i < ehdrp->e_phnum; ++i) { \ | ||
109 | struct elf_phdr phdr = phdrp[i]; \ | ||
110 | if (phdr.p_type == PT_LOAD) { \ | ||
111 | ofs = phdr.p_offset = offset; \ | ||
112 | offset += phdr.p_filesz; \ | ||
113 | } \ | ||
114 | else \ | ||
115 | phdr.p_offset += ofs; \ | ||
116 | phdr.p_paddr = 0; /* match other core phdrs */ \ | ||
117 | DUMP_WRITE(&phdr, sizeof(phdr)); \ | ||
118 | } \ | ||
119 | } | ||
120 | #define ELF_CORE_WRITE_EXTRA_DATA \ | ||
121 | if ( vsyscall_ehdr ) { \ | ||
122 | const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ | ||
123 | const struct elf_phdr *const phdrp = \ | ||
124 | (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ | ||
125 | int i; \ | ||
126 | for (i = 0; i < ehdrp->e_phnum; ++i) { \ | ||
127 | if (phdrp[i].p_type == PT_LOAD) \ | ||
128 | DUMP_WRITE((void *) phdrp[i].p_vaddr, \ | ||
129 | phdrp[i].p_filesz); \ | ||
130 | } \ | ||
131 | } | ||
132 | |||
133 | #define R_386_NONE 0 | ||
134 | #define R_386_32 1 | ||
135 | #define R_386_PC32 2 | ||
136 | #define R_386_GOT32 3 | ||
137 | #define R_386_PLT32 4 | ||
138 | #define R_386_COPY 5 | ||
139 | #define R_386_GLOB_DAT 6 | ||
140 | #define R_386_JMP_SLOT 7 | ||
141 | #define R_386_RELATIVE 8 | ||
142 | #define R_386_GOTOFF 9 | ||
143 | #define R_386_GOTPC 10 | ||
144 | #define R_386_NUM 11 | ||
145 | |||
146 | /********* Nothing for asm-um/hardirq.h **********/ | 9 | /********* Nothing for asm-um/hardirq.h **********/ |
147 | 10 | ||
148 | /********* Nothing for asm-um/hw_irq.h **********/ | 11 | /********* Nothing for asm-um/hw_irq.h **********/ |
diff --git a/include/asm-um/archparam-ppc.h b/include/asm-um/archparam-ppc.h index 0ebced92a762..172cd6ffacc4 100644 --- a/include/asm-um/archparam-ppc.h +++ b/include/asm-um/archparam-ppc.h | |||
@@ -1,26 +1,6 @@ | |||
1 | #ifndef __UM_ARCHPARAM_PPC_H | 1 | #ifndef __UM_ARCHPARAM_PPC_H |
2 | #define __UM_ARCHPARAM_PPC_H | 2 | #define __UM_ARCHPARAM_PPC_H |
3 | 3 | ||
4 | /********* Bits for asm-um/elf.h ************/ | ||
5 | |||
6 | #define ELF_PLATFORM (0) | ||
7 | |||
8 | #define ELF_ET_DYN_BASE (0x08000000) | ||
9 | |||
10 | /* the following stolen from asm-ppc/elf.h */ | ||
11 | #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ | ||
12 | #define ELF_NFPREG 33 /* includes fpscr */ | ||
13 | /* General registers */ | ||
14 | typedef unsigned long elf_greg_t; | ||
15 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
16 | |||
17 | /* Floating point registers */ | ||
18 | typedef double elf_fpreg_t; | ||
19 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | ||
20 | |||
21 | #define ELF_DATA ELFDATA2MSB | ||
22 | #define ELF_ARCH EM_PPC | ||
23 | |||
24 | /********* Bits for asm-um/hw_irq.h **********/ | 4 | /********* Bits for asm-um/hw_irq.h **********/ |
25 | 5 | ||
26 | struct hw_interrupt_type; | 6 | struct hw_interrupt_type; |
diff --git a/include/asm-um/archparam-x86_64.h b/include/asm-um/archparam-x86_64.h index 96321c4892f1..270ed9586b68 100644 --- a/include/asm-um/archparam-x86_64.h +++ b/include/asm-um/archparam-x86_64.h | |||
@@ -7,42 +7,6 @@ | |||
7 | #ifndef __UM_ARCHPARAM_X86_64_H | 7 | #ifndef __UM_ARCHPARAM_X86_64_H |
8 | #define __UM_ARCHPARAM_X86_64_H | 8 | #define __UM_ARCHPARAM_X86_64_H |
9 | 9 | ||
10 | #include <asm/user.h> | ||
11 | |||
12 | #define ELF_PLATFORM "x86_64" | ||
13 | |||
14 | #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) | ||
15 | |||
16 | typedef unsigned long elf_greg_t; | ||
17 | typedef struct { } elf_fpregset_t; | ||
18 | |||
19 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
20 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
21 | |||
22 | #define ELF_DATA ELFDATA2LSB | ||
23 | #define ELF_ARCH EM_X86_64 | ||
24 | |||
25 | #define ELF_PLAT_INIT(regs, load_addr) do { \ | ||
26 | PT_REGS_RBX(regs) = 0; \ | ||
27 | PT_REGS_RCX(regs) = 0; \ | ||
28 | PT_REGS_RDX(regs) = 0; \ | ||
29 | PT_REGS_RSI(regs) = 0; \ | ||
30 | PT_REGS_RDI(regs) = 0; \ | ||
31 | PT_REGS_RBP(regs) = 0; \ | ||
32 | PT_REGS_RAX(regs) = 0; \ | ||
33 | PT_REGS_R8(regs) = 0; \ | ||
34 | PT_REGS_R9(regs) = 0; \ | ||
35 | PT_REGS_R10(regs) = 0; \ | ||
36 | PT_REGS_R11(regs) = 0; \ | ||
37 | PT_REGS_R12(regs) = 0; \ | ||
38 | PT_REGS_R13(regs) = 0; \ | ||
39 | PT_REGS_R14(regs) = 0; \ | ||
40 | PT_REGS_R15(regs) = 0; \ | ||
41 | } while (0) | ||
42 | |||
43 | #ifdef TIF_IA32 /* XXX */ | ||
44 | clear_thread_flag(TIF_IA32); | ||
45 | #endif | ||
46 | 10 | ||
47 | /* No user-accessible fixmap addresses, i.e. vsyscall */ | 11 | /* No user-accessible fixmap addresses, i.e. vsyscall */ |
48 | #define FIXADDR_USER_START 0 | 12 | #define FIXADDR_USER_START 0 |
diff --git a/include/asm-um/delay.h b/include/asm-um/delay.h index 40695576ca60..0985bda66750 100644 --- a/include/asm-um/delay.h +++ b/include/asm-um/delay.h | |||
@@ -4,4 +4,6 @@ | |||
4 | #include "asm/arch/delay.h" | 4 | #include "asm/arch/delay.h" |
5 | #include "asm/archparam.h" | 5 | #include "asm/archparam.h" |
6 | 6 | ||
7 | #define MILLION 1000000 | ||
8 | |||
7 | #endif | 9 | #endif |
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h new file mode 100644 index 000000000000..9bab712dc5c0 --- /dev/null +++ b/include/asm-um/elf-i386.h | |||
@@ -0,0 +1,169 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) | ||
3 | * Licensed under the GPL | ||
4 | */ | ||
5 | #ifndef __UM_ELF_I386_H | ||
6 | #define __UM_ELF_I386_H | ||
7 | |||
8 | #include <asm/user.h> | ||
9 | |||
10 | #define R_386_NONE 0 | ||
11 | #define R_386_32 1 | ||
12 | #define R_386_PC32 2 | ||
13 | #define R_386_GOT32 3 | ||
14 | #define R_386_PLT32 4 | ||
15 | #define R_386_COPY 5 | ||
16 | #define R_386_GLOB_DAT 6 | ||
17 | #define R_386_JMP_SLOT 7 | ||
18 | #define R_386_RELATIVE 8 | ||
19 | #define R_386_GOTOFF 9 | ||
20 | #define R_386_GOTPC 10 | ||
21 | #define R_386_NUM 11 | ||
22 | |||
23 | typedef unsigned long elf_greg_t; | ||
24 | |||
25 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
26 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
27 | |||
28 | typedef struct user_i387_struct elf_fpregset_t; | ||
29 | |||
30 | /* | ||
31 | * This is used to ensure we don't load something for the wrong architecture. | ||
32 | */ | ||
33 | #define elf_check_arch(x) \ | ||
34 | (((x)->e_machine == EM_386) || ((x)->e_machine == EM_486)) | ||
35 | |||
36 | #define ELF_CLASS ELFCLASS32 | ||
37 | #define ELF_DATA ELFDATA2LSB | ||
38 | #define ELF_ARCH EM_386 | ||
39 | |||
40 | #define ELF_PLAT_INIT(regs, load_addr) do { \ | ||
41 | PT_REGS_EBX(regs) = 0; \ | ||
42 | PT_REGS_ECX(regs) = 0; \ | ||
43 | PT_REGS_EDX(regs) = 0; \ | ||
44 | PT_REGS_ESI(regs) = 0; \ | ||
45 | PT_REGS_EDI(regs) = 0; \ | ||
46 | PT_REGS_EBP(regs) = 0; \ | ||
47 | PT_REGS_EAX(regs) = 0; \ | ||
48 | } while(0) | ||
49 | |||
50 | #define USE_ELF_CORE_DUMP | ||
51 | #define ELF_EXEC_PAGESIZE 4096 | ||
52 | |||
53 | #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) | ||
54 | |||
55 | /* Shamelessly stolen from include/asm-i386/elf.h */ | ||
56 | |||
57 | #define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ | ||
58 | pr_reg[0] = PT_REGS_EBX(regs); \ | ||
59 | pr_reg[1] = PT_REGS_ECX(regs); \ | ||
60 | pr_reg[2] = PT_REGS_EDX(regs); \ | ||
61 | pr_reg[3] = PT_REGS_ESI(regs); \ | ||
62 | pr_reg[4] = PT_REGS_EDI(regs); \ | ||
63 | pr_reg[5] = PT_REGS_EBP(regs); \ | ||
64 | pr_reg[6] = PT_REGS_EAX(regs); \ | ||
65 | pr_reg[7] = PT_REGS_DS(regs); \ | ||
66 | pr_reg[8] = PT_REGS_ES(regs); \ | ||
67 | /* fake once used fs and gs selectors? */ \ | ||
68 | pr_reg[9] = PT_REGS_DS(regs); \ | ||
69 | pr_reg[10] = PT_REGS_DS(regs); \ | ||
70 | pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ | ||
71 | pr_reg[12] = PT_REGS_IP(regs); \ | ||
72 | pr_reg[13] = PT_REGS_CS(regs); \ | ||
73 | pr_reg[14] = PT_REGS_EFLAGS(regs); \ | ||
74 | pr_reg[15] = PT_REGS_SP(regs); \ | ||
75 | pr_reg[16] = PT_REGS_SS(regs); \ | ||
76 | } while(0); | ||
77 | |||
78 | extern long elf_aux_hwcap; | ||
79 | #define ELF_HWCAP (elf_aux_hwcap) | ||
80 | |||
81 | extern char * elf_aux_platform; | ||
82 | #define ELF_PLATFORM (elf_aux_platform) | ||
83 | |||
84 | #define SET_PERSONALITY(ex, ibcs2) do ; while(0) | ||
85 | |||
86 | extern unsigned long vsyscall_ehdr; | ||
87 | extern unsigned long vsyscall_end; | ||
88 | extern unsigned long __kernel_vsyscall; | ||
89 | |||
90 | #define VSYSCALL_BASE vsyscall_ehdr | ||
91 | #define VSYSCALL_END vsyscall_end | ||
92 | |||
93 | /* | ||
94 | * This is the range that is readable by user mode, and things | ||
95 | * acting like user mode such as get_user_pages. | ||
96 | */ | ||
97 | #define FIXADDR_USER_START VSYSCALL_BASE | ||
98 | #define FIXADDR_USER_END VSYSCALL_END | ||
99 | |||
100 | /* | ||
101 | * Architecture-neutral AT_ values in 0-17, leave some room | ||
102 | * for more of them, start the x86-specific ones at 32. | ||
103 | */ | ||
104 | #define AT_SYSINFO 32 | ||
105 | #define AT_SYSINFO_EHDR 33 | ||
106 | |||
107 | #define ARCH_DLINFO \ | ||
108 | do { \ | ||
109 | if ( vsyscall_ehdr ) { \ | ||
110 | NEW_AUX_ENT(AT_SYSINFO, __kernel_vsyscall); \ | ||
111 | NEW_AUX_ENT(AT_SYSINFO_EHDR, vsyscall_ehdr); \ | ||
112 | } \ | ||
113 | } while (0) | ||
114 | |||
115 | /* | ||
116 | * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out | ||
117 | * extra segments containing the vsyscall DSO contents. Dumping its | ||
118 | * contents makes post-mortem fully interpretable later without matching up | ||
119 | * the same kernel and hardware config to see what PC values meant. | ||
120 | * Dumping its extra ELF program headers includes all the other information | ||
121 | * a debugger needs to easily find how the vsyscall DSO was being used. | ||
122 | */ | ||
123 | #define ELF_CORE_EXTRA_PHDRS \ | ||
124 | (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 ) | ||
125 | |||
126 | #define ELF_CORE_WRITE_EXTRA_PHDRS \ | ||
127 | if ( vsyscall_ehdr ) { \ | ||
128 | const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ | ||
129 | const struct elf_phdr *const phdrp = \ | ||
130 | (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ | ||
131 | int i; \ | ||
132 | Elf32_Off ofs = 0; \ | ||
133 | for (i = 0; i < ehdrp->e_phnum; ++i) { \ | ||
134 | struct elf_phdr phdr = phdrp[i]; \ | ||
135 | if (phdr.p_type == PT_LOAD) { \ | ||
136 | ofs = phdr.p_offset = offset; \ | ||
137 | offset += phdr.p_filesz; \ | ||
138 | } \ | ||
139 | else \ | ||
140 | phdr.p_offset += ofs; \ | ||
141 | phdr.p_paddr = 0; /* match other core phdrs */ \ | ||
142 | DUMP_WRITE(&phdr, sizeof(phdr)); \ | ||
143 | } \ | ||
144 | } | ||
145 | #define ELF_CORE_WRITE_EXTRA_DATA \ | ||
146 | if ( vsyscall_ehdr ) { \ | ||
147 | const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ | ||
148 | const struct elf_phdr *const phdrp = \ | ||
149 | (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ | ||
150 | int i; \ | ||
151 | for (i = 0; i < ehdrp->e_phnum; ++i) { \ | ||
152 | if (phdrp[i].p_type == PT_LOAD) \ | ||
153 | DUMP_WRITE((void *) phdrp[i].p_vaddr, \ | ||
154 | phdrp[i].p_filesz); \ | ||
155 | } \ | ||
156 | } | ||
157 | |||
158 | #endif | ||
159 | |||
160 | /* | ||
161 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
162 | * Emacs will notice this stuff at the end of the file and automatically | ||
163 | * adjust the settings for this buffer only. This must remain at the end | ||
164 | * of the file. | ||
165 | * --------------------------------------------------------------------------- | ||
166 | * Local variables: | ||
167 | * c-file-style: "linux" | ||
168 | * End: | ||
169 | */ | ||
diff --git a/include/asm-um/elf.h b/include/asm-um/elf-ppc.h index 7908f8fe8231..2998cf925042 100644 --- a/include/asm-um/elf.h +++ b/include/asm-um/elf-ppc.h | |||
@@ -1,8 +1,7 @@ | |||
1 | #ifndef __UM_ELF_H | 1 | #ifndef __UM_ELF_PPC_H |
2 | #define __UM_ELF_H | 2 | #define __UM_ELF_PPC_H |
3 | 3 | ||
4 | #include "linux/config.h" | 4 | #include "linux/config.h" |
5 | #include "asm/archparam.h" | ||
6 | 5 | ||
7 | extern long elf_aux_hwcap; | 6 | extern long elf_aux_hwcap; |
8 | #define ELF_HWCAP (elf_aux_hwcap) | 7 | #define ELF_HWCAP (elf_aux_hwcap) |
@@ -13,7 +12,7 @@ extern long elf_aux_hwcap; | |||
13 | 12 | ||
14 | #define elf_check_arch(x) (1) | 13 | #define elf_check_arch(x) (1) |
15 | 14 | ||
16 | #ifdef CONFIG_64BIT | 15 | #ifdef CONFIG_64_BIT |
17 | #define ELF_CLASS ELFCLASS64 | 16 | #define ELF_CLASS ELFCLASS64 |
18 | #else | 17 | #else |
19 | #define ELF_CLASS ELFCLASS32 | 18 | #define ELF_CLASS ELFCLASS32 |
@@ -34,4 +33,22 @@ extern long elf_aux_hwcap; | |||
34 | #define R_386_GOTPC 10 | 33 | #define R_386_GOTPC 10 |
35 | #define R_386_NUM 11 | 34 | #define R_386_NUM 11 |
36 | 35 | ||
36 | #define ELF_PLATFORM (0) | ||
37 | |||
38 | #define ELF_ET_DYN_BASE (0x08000000) | ||
39 | |||
40 | /* the following stolen from asm-ppc/elf.h */ | ||
41 | #define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ | ||
42 | #define ELF_NFPREG 33 /* includes fpscr */ | ||
43 | /* General registers */ | ||
44 | typedef unsigned long elf_greg_t; | ||
45 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
46 | |||
47 | /* Floating point registers */ | ||
48 | typedef double elf_fpreg_t; | ||
49 | typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | ||
50 | |||
51 | #define ELF_DATA ELFDATA2MSB | ||
52 | #define ELF_ARCH EM_PPC | ||
53 | |||
37 | #endif | 54 | #endif |
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h new file mode 100644 index 000000000000..8a8246d03936 --- /dev/null +++ b/include/asm-um/elf-x86_64.h | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | * Copyright 2003 PathScale, Inc. | ||
3 | * | ||
4 | * Licensed under the GPL | ||
5 | */ | ||
6 | #ifndef __UM_ELF_X86_64_H | ||
7 | #define __UM_ELF_X86_64_H | ||
8 | |||
9 | #include <asm/user.h> | ||
10 | |||
11 | /* x86-64 relocation types, taken from asm-x86_64/elf.h */ | ||
12 | #define R_X86_64_NONE 0 /* No reloc */ | ||
13 | #define R_X86_64_64 1 /* Direct 64 bit */ | ||
14 | #define R_X86_64_PC32 2 /* PC relative 32 bit signed */ | ||
15 | #define R_X86_64_GOT32 3 /* 32 bit GOT entry */ | ||
16 | #define R_X86_64_PLT32 4 /* 32 bit PLT address */ | ||
17 | #define R_X86_64_COPY 5 /* Copy symbol at runtime */ | ||
18 | #define R_X86_64_GLOB_DAT 6 /* Create GOT entry */ | ||
19 | #define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */ | ||
20 | #define R_X86_64_RELATIVE 8 /* Adjust by program base */ | ||
21 | #define R_X86_64_GOTPCREL 9 /* 32 bit signed pc relative | ||
22 | offset to GOT */ | ||
23 | #define R_X86_64_32 10 /* Direct 32 bit zero extended */ | ||
24 | #define R_X86_64_32S 11 /* Direct 32 bit sign extended */ | ||
25 | #define R_X86_64_16 12 /* Direct 16 bit zero extended */ | ||
26 | #define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */ | ||
27 | #define R_X86_64_8 14 /* Direct 8 bit sign extended */ | ||
28 | #define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */ | ||
29 | |||
30 | #define R_X86_64_NUM 16 | ||
31 | |||
32 | typedef unsigned long elf_greg_t; | ||
33 | |||
34 | #define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) | ||
35 | typedef elf_greg_t elf_gregset_t[ELF_NGREG]; | ||
36 | |||
37 | typedef struct { } elf_fpregset_t; | ||
38 | |||
39 | /* | ||
40 | * This is used to ensure we don't load something for the wrong architecture. | ||
41 | */ | ||
42 | #define elf_check_arch(x) \ | ||
43 | ((x)->e_machine == EM_X86_64) | ||
44 | |||
45 | #define ELF_CLASS ELFCLASS64 | ||
46 | #define ELF_DATA ELFDATA2LSB | ||
47 | #define ELF_ARCH EM_X86_64 | ||
48 | |||
49 | #define ELF_PLAT_INIT(regs, load_addr) do { \ | ||
50 | PT_REGS_RBX(regs) = 0; \ | ||
51 | PT_REGS_RCX(regs) = 0; \ | ||
52 | PT_REGS_RDX(regs) = 0; \ | ||
53 | PT_REGS_RSI(regs) = 0; \ | ||
54 | PT_REGS_RDI(regs) = 0; \ | ||
55 | PT_REGS_RBP(regs) = 0; \ | ||
56 | PT_REGS_RAX(regs) = 0; \ | ||
57 | PT_REGS_R8(regs) = 0; \ | ||
58 | PT_REGS_R9(regs) = 0; \ | ||
59 | PT_REGS_R10(regs) = 0; \ | ||
60 | PT_REGS_R11(regs) = 0; \ | ||
61 | PT_REGS_R12(regs) = 0; \ | ||
62 | PT_REGS_R13(regs) = 0; \ | ||
63 | PT_REGS_R14(regs) = 0; \ | ||
64 | PT_REGS_R15(regs) = 0; \ | ||
65 | } while (0) | ||
66 | |||
67 | #ifdef TIF_IA32 /* XXX */ | ||
68 | #error XXX, indeed | ||
69 | clear_thread_flag(TIF_IA32); | ||
70 | #endif | ||
71 | |||
72 | #define USE_ELF_CORE_DUMP | ||
73 | #define ELF_EXEC_PAGESIZE 4096 | ||
74 | |||
75 | #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) | ||
76 | |||
77 | extern long elf_aux_hwcap; | ||
78 | #define ELF_HWCAP (elf_aux_hwcap) | ||
79 | |||
80 | #define ELF_PLATFORM "x86_64" | ||
81 | |||
82 | #define SET_PERSONALITY(ex, ibcs2) do ; while(0) | ||
83 | |||
84 | #endif | ||
85 | |||
86 | /* | ||
87 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
88 | * Emacs will notice this stuff at the end of the file and automatically | ||
89 | * adjust the settings for this buffer only. This must remain at the end | ||
90 | * of the file. | ||
91 | * --------------------------------------------------------------------------- | ||
92 | * Local variables: | ||
93 | * c-file-style: "linux" | ||
94 | * End: | ||
95 | */ | ||
diff --git a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h index 900f3fbb9fab..ae0ca3932d50 100644 --- a/include/asm-um/fixmap.h +++ b/include/asm-um/fixmap.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/config.h> | 4 | #include <linux/config.h> |
5 | #include <asm/kmap_types.h> | 5 | #include <asm/kmap_types.h> |
6 | #include <asm/archparam.h> | 6 | #include <asm/archparam.h> |
7 | #include <asm/elf.h> | ||
7 | 8 | ||
8 | /* | 9 | /* |
9 | * Here we define all the compile-time 'special' virtual | 10 | * Here we define all the compile-time 'special' virtual |
diff --git a/include/asm-um/ipc.h b/include/asm-um/ipc.h index e2ddc47f3e52..a46e3d9c2a3f 100644 --- a/include/asm-um/ipc.h +++ b/include/asm-um/ipc.h | |||
@@ -1,6 +1 @@ | |||
1 | #ifndef __UM_IPC_H | #include <asm-generic/ipc.h> | |
2 | #define __UM_IPC_H | ||
3 | |||
4 | #include "asm/arch/ipc.h" | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-um/linkage.h b/include/asm-um/linkage.h index 27011652b015..7dfce37adc8b 100644 --- a/include/asm-um/linkage.h +++ b/include/asm-um/linkage.h | |||
@@ -1,7 +1,6 @@ | |||
1 | #ifndef __ASM_LINKAGE_H | 1 | #ifndef __ASM_UM_LINKAGE_H |
2 | #define __ASM_LINKAGE_H | 2 | #define __ASM_UM_LINKAGE_H |
3 | 3 | ||
4 | #define FASTCALL(x) x __attribute__((regparm(3))) | 4 | #include "asm/arch/linkage.h" |
5 | #define fastcall __attribute__((regparm(3))) | ||
6 | 5 | ||
7 | #endif | 6 | #endif |
diff --git a/include/asm-um/page.h b/include/asm-um/page.h index 102eb3df1aaf..504ea8e486b0 100644 --- a/include/asm-um/page.h +++ b/include/asm-um/page.h | |||
@@ -45,6 +45,9 @@ typedef struct { unsigned long pgd; } pgd_t; | |||
45 | ({ (pte).pte_high = (phys) >> 32; \ | 45 | ({ (pte).pte_high = (phys) >> 32; \ |
46 | (pte).pte_low = (phys) | pgprot_val(prot); }) | 46 | (pte).pte_low = (phys) | pgprot_val(prot); }) |
47 | 47 | ||
48 | #define pmd_val(x) ((x).pmd) | ||
49 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
50 | |||
48 | typedef unsigned long long pfn_t; | 51 | typedef unsigned long long pfn_t; |
49 | typedef unsigned long long phys_t; | 52 | typedef unsigned long long phys_t; |
50 | 53 | ||
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h index d309f3a9e6f6..65e8bfc55fc4 100644 --- a/include/asm-um/pgtable-3level.h +++ b/include/asm-um/pgtable-3level.h | |||
@@ -149,7 +149,7 @@ static inline pmd_t pfn_pmd(pfn_t page_nr, pgprot_t pgprot) | |||
149 | 149 | ||
150 | #define pte_to_pgoff(p) ((p).pte >> 32) | 150 | #define pte_to_pgoff(p) ((p).pte >> 32) |
151 | 151 | ||
152 | #define pgoff_to_pte(off) ((pte_t) { ((off) < 32) | _PAGE_FILE }) | 152 | #define pgoff_to_pte(off) ((pte_t) { ((off) << 32) | _PAGE_FILE }) |
153 | 153 | ||
154 | #else | 154 | #else |
155 | 155 | ||
diff --git a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h index 71f9c0c78c0c..510e513c7f88 100644 --- a/include/asm-um/pgtable.h +++ b/include/asm-um/pgtable.h | |||
@@ -106,7 +106,7 @@ extern unsigned long end_iomem; | |||
106 | /* | 106 | /* |
107 | * Define this if things work differently on an i386 and an i486: | 107 | * Define this if things work differently on an i386 and an i486: |
108 | * it will (on an i486) warn about kernel memory accesses that are | 108 | * it will (on an i486) warn about kernel memory accesses that are |
109 | * done without a 'verify_area(VERIFY_WRITE,..)' | 109 | * done without a 'access_ok(VERIFY_WRITE,..)' |
110 | */ | 110 | */ |
111 | #undef TEST_VERIFY_AREA | 111 | #undef TEST_VERIFY_AREA |
112 | 112 | ||
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h index b953b1ad3b02..b2fc94fbc2d9 100644 --- a/include/asm-um/processor-generic.h +++ b/include/asm-um/processor-generic.h | |||
@@ -24,9 +24,6 @@ struct thread_struct { | |||
24 | int forking; | 24 | int forking; |
25 | int nsyscalls; | 25 | int nsyscalls; |
26 | struct pt_regs regs; | 26 | struct pt_regs regs; |
27 | unsigned long cr2; | ||
28 | int err; | ||
29 | unsigned long trap_no; | ||
30 | int singlestep_syscall; | 27 | int singlestep_syscall; |
31 | void *fault_addr; | 28 | void *fault_addr; |
32 | void *fault_catcher; | 29 | void *fault_catcher; |
@@ -74,8 +71,6 @@ struct thread_struct { | |||
74 | .forking = 0, \ | 71 | .forking = 0, \ |
75 | .nsyscalls = 0, \ | 72 | .nsyscalls = 0, \ |
76 | .regs = EMPTY_REGS, \ | 73 | .regs = EMPTY_REGS, \ |
77 | .cr2 = 0, \ | ||
78 | .err = 0, \ | ||
79 | .fault_addr = NULL, \ | 74 | .fault_addr = NULL, \ |
80 | .prev_sched = NULL, \ | 75 | .prev_sched = NULL, \ |
81 | .temp_stack = 0, \ | 76 | .temp_stack = 0, \ |
diff --git a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h index 2deb8f1adbf1..431bad3ae9d7 100644 --- a/include/asm-um/processor-i386.h +++ b/include/asm-um/processor-i386.h | |||
@@ -9,13 +9,18 @@ | |||
9 | extern int host_has_xmm; | 9 | extern int host_has_xmm; |
10 | extern int host_has_cmov; | 10 | extern int host_has_cmov; |
11 | 11 | ||
12 | /* include faultinfo structure */ | ||
13 | #include "sysdep/faultinfo.h" | ||
14 | |||
12 | struct arch_thread { | 15 | struct arch_thread { |
13 | unsigned long debugregs[8]; | 16 | unsigned long debugregs[8]; |
14 | int debugregs_seq; | 17 | int debugregs_seq; |
18 | struct faultinfo faultinfo; | ||
15 | }; | 19 | }; |
16 | 20 | ||
17 | #define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ | 21 | #define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ |
18 | .debugregs_seq = 0 } | 22 | .debugregs_seq = 0, \ |
23 | .faultinfo = { 0, 0, 0 } } | ||
19 | 24 | ||
20 | #include "asm/arch/user.h" | 25 | #include "asm/arch/user.h" |
21 | 26 | ||
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h index a1ae3a4cd938..0beb9a42ae05 100644 --- a/include/asm-um/processor-x86_64.h +++ b/include/asm-um/processor-x86_64.h | |||
@@ -7,9 +7,13 @@ | |||
7 | #ifndef __UM_PROCESSOR_X86_64_H | 7 | #ifndef __UM_PROCESSOR_X86_64_H |
8 | #define __UM_PROCESSOR_X86_64_H | 8 | #define __UM_PROCESSOR_X86_64_H |
9 | 9 | ||
10 | #include "asm/arch/user.h" | 10 | /* include faultinfo structure */ |
11 | #include "sysdep/faultinfo.h" | ||
11 | 12 | ||
12 | struct arch_thread { | 13 | struct arch_thread { |
14 | unsigned long debugregs[8]; | ||
15 | int debugregs_seq; | ||
16 | struct faultinfo faultinfo; | ||
13 | }; | 17 | }; |
14 | 18 | ||
15 | /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ | 19 | /* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ |
@@ -20,7 +24,11 @@ extern inline void rep_nop(void) | |||
20 | 24 | ||
21 | #define cpu_relax() rep_nop() | 25 | #define cpu_relax() rep_nop() |
22 | 26 | ||
23 | #define INIT_ARCH_THREAD { } | 27 | #define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ |
28 | .debugregs_seq = 0, \ | ||
29 | .faultinfo = { 0, 0, 0 } } | ||
30 | |||
31 | #include "asm/arch/user.h" | ||
24 | 32 | ||
25 | #define current_text_addr() \ | 33 | #define current_text_addr() \ |
26 | ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) | 34 | ({ void *pc; __asm__("movq $1f,%0\n1:":"=g" (pc)); pc; }) |
diff --git a/include/asm-um/setup.h b/include/asm-um/setup.h index c85252e803c1..99f086301f4c 100644 --- a/include/asm-um/setup.h +++ b/include/asm-um/setup.h | |||
@@ -2,7 +2,8 @@ | |||
2 | #define SETUP_H_INCLUDED | 2 | #define SETUP_H_INCLUDED |
3 | 3 | ||
4 | /* POSIX mandated with _POSIX_ARG_MAX that we can rely on 4096 chars in the | 4 | /* POSIX mandated with _POSIX_ARG_MAX that we can rely on 4096 chars in the |
5 | * command line, so this choice is ok.*/ | 5 | * command line, so this choice is ok. |
6 | */ | ||
6 | 7 | ||
7 | #define COMMAND_LINE_SIZE 4096 | 8 | #define COMMAND_LINE_SIZE 4096 |
8 | 9 | ||
diff --git a/include/asm-x86_64/apicdef.h b/include/asm-x86_64/apicdef.h index 3d7627ffe67d..bfebdb690654 100644 --- a/include/asm-x86_64/apicdef.h +++ b/include/asm-x86_64/apicdef.h | |||
@@ -112,7 +112,7 @@ | |||
112 | 112 | ||
113 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) | 113 | #define APIC_BASE (fix_to_virt(FIX_APIC_BASE)) |
114 | 114 | ||
115 | #define MAX_IO_APICS 32 | 115 | #define MAX_IO_APICS 128 |
116 | 116 | ||
117 | /* | 117 | /* |
118 | * All x86-64 systems are xAPIC compatible. | 118 | * All x86-64 systems are xAPIC compatible. |
diff --git a/include/asm-x86_64/floppy.h b/include/asm-x86_64/floppy.h index bca9b28a1a0a..af7ded63b517 100644 --- a/include/asm-x86_64/floppy.h +++ b/include/asm-x86_64/floppy.h | |||
@@ -223,7 +223,7 @@ static int hard_dma_setup(char *addr, unsigned long size, int mode, int io) | |||
223 | return 0; | 223 | return 0; |
224 | } | 224 | } |
225 | 225 | ||
226 | struct fd_routine_l { | 226 | static struct fd_routine_l { |
227 | int (*_request_dma)(unsigned int dmanr, const char * device_id); | 227 | int (*_request_dma)(unsigned int dmanr, const char * device_id); |
228 | void (*_free_dma)(unsigned int dmanr); | 228 | void (*_free_dma)(unsigned int dmanr); |
229 | int (*_get_dma_residue)(unsigned int dummy); | 229 | int (*_get_dma_residue)(unsigned int dummy); |
diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 7efc932e8f0b..32573749004c 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h | |||
@@ -202,7 +202,6 @@ extern int skip_ioapic_setup; | |||
202 | #define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) | 202 | #define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) |
203 | 203 | ||
204 | #ifdef CONFIG_ACPI_BOOT | 204 | #ifdef CONFIG_ACPI_BOOT |
205 | extern int io_apic_get_unique_id (int ioapic, int apic_id); | ||
206 | extern int io_apic_get_version (int ioapic); | 205 | extern int io_apic_get_version (int ioapic); |
207 | extern int io_apic_get_redir_entries (int ioapic); | 206 | extern int io_apic_get_redir_entries (int ioapic); |
208 | extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); | 207 | extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int, int); |
diff --git a/include/asm-x86_64/ioctl32.h b/include/asm-x86_64/ioctl32.h deleted file mode 100644 index d0d227f45e05..000000000000 --- a/include/asm-x86_64/ioctl32.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <linux/ioctl32.h> | ||
diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h index 21d56b086b9d..d3abfc6a8fd5 100644 --- a/include/asm-x86_64/nmi.h +++ b/include/asm-x86_64/nmi.h | |||
@@ -53,5 +53,7 @@ extern void die_nmi(char *str, struct pt_regs *regs); | |||
53 | 53 | ||
54 | extern int panic_on_timeout; | 54 | extern int panic_on_timeout; |
55 | extern int unknown_nmi_panic; | 55 | extern int unknown_nmi_panic; |
56 | |||
57 | extern int check_nmi_watchdog(void); | ||
56 | 58 | ||
57 | #endif /* ASM_NMI_H */ | 59 | #endif /* ASM_NMI_H */ |
diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index f0581c35628e..d641b19f6da5 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h | |||
@@ -62,7 +62,6 @@ struct cpuinfo_x86 { | |||
62 | int x86_tlbsize; /* number of 4K pages in DTLB/ITLB combined(in pages)*/ | 62 | int x86_tlbsize; /* number of 4K pages in DTLB/ITLB combined(in pages)*/ |
63 | __u8 x86_virt_bits, x86_phys_bits; | 63 | __u8 x86_virt_bits, x86_phys_bits; |
64 | __u8 x86_num_cores; | 64 | __u8 x86_num_cores; |
65 | __u8 x86_apicid; | ||
66 | __u32 x86_power; | 65 | __u32 x86_power; |
67 | __u32 extended_cpuid_level; /* Max extended CPUID function supported */ | 66 | __u32 extended_cpuid_level; /* Max extended CPUID function supported */ |
68 | unsigned long loops_per_jiffy; | 67 | unsigned long loops_per_jiffy; |
@@ -159,9 +158,9 @@ static inline void clear_in_cr4 (unsigned long mask) | |||
159 | 158 | ||
160 | 159 | ||
161 | /* | 160 | /* |
162 | * User space process size. 47bits. | 161 | * User space process size. 47bits minus one guard page. |
163 | */ | 162 | */ |
164 | #define TASK_SIZE (0x800000000000UL) | 163 | #define TASK_SIZE (0x800000000000UL - 4096) |
165 | 164 | ||
166 | /* This decides where the kernel will search for a free chunk of vm | 165 | /* This decides where the kernel will search for a free chunk of vm |
167 | * space during mmap's. | 166 | * space during mmap's. |
diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index d0f8f8b4c394..f2f073642d62 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h | |||
@@ -30,6 +30,11 @@ extern void ia32_syscall(void); | |||
30 | extern void iommu_hole_init(void); | 30 | extern void iommu_hole_init(void); |
31 | 31 | ||
32 | extern void time_init_gtod(void); | 32 | extern void time_init_gtod(void); |
33 | extern int pmtimer_mark_offset(void); | ||
34 | extern unsigned int do_gettimeoffset_pm(void); | ||
35 | extern u32 pmtmr_ioport; | ||
36 | extern unsigned long long monotonic_base; | ||
37 | extern int sysctl_vsyscall; | ||
33 | 38 | ||
34 | extern void do_softirq_thunk(void); | 39 | extern void do_softirq_thunk(void); |
35 | 40 | ||
diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h index b0c8d4339906..2872da23fc7e 100644 --- a/include/asm-x86_64/vsyscall.h +++ b/include/asm-x86_64/vsyscall.h | |||
@@ -25,6 +25,7 @@ enum vsyscall_num { | |||
25 | 25 | ||
26 | #define VXTIME_TSC 1 | 26 | #define VXTIME_TSC 1 |
27 | #define VXTIME_HPET 2 | 27 | #define VXTIME_HPET 2 |
28 | #define VXTIME_PMTMR 3 | ||
28 | 29 | ||
29 | struct vxtime_data { | 30 | struct vxtime_data { |
30 | long hpet_address; /* HPET base address */ | 31 | long hpet_address; /* HPET base address */ |
@@ -54,6 +55,8 @@ extern struct timezone sys_tz; | |||
54 | extern int sysctl_vsyscall; | 55 | extern int sysctl_vsyscall; |
55 | extern seqlock_t xtime_lock; | 56 | extern seqlock_t xtime_lock; |
56 | 57 | ||
58 | extern int sysctl_vsyscall; | ||
59 | |||
57 | #define ARCH_HAVE_XTIME_LOCK 1 | 60 | #define ARCH_HAVE_XTIME_LOCK 1 |
58 | 61 | ||
59 | #endif /* __KERNEL__ */ | 62 | #endif /* __KERNEL__ */ |
diff --git a/include/linux/awe_voice.h b/include/linux/awe_voice.h index da0e27de752c..4bf9f33048e2 100644 --- a/include/linux/awe_voice.h +++ b/include/linux/awe_voice.h | |||
@@ -29,9 +29,9 @@ | |||
29 | #define SAMPLE_TYPE_AWE32 0x20 | 29 | #define SAMPLE_TYPE_AWE32 0x20 |
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | #ifndef _PATCHKEY | 32 | #define _LINUX_PATCHKEY_H_INDIRECT |
33 | #define _PATCHKEY(id) ((id<<8)|0xfd) | 33 | #include <linux/patchkey.h> |
34 | #endif | 34 | #undef _LINUX_PATCHKEY_H_INDIRECT |
35 | 35 | ||
36 | /*---------------------------------------------------------------- | 36 | /*---------------------------------------------------------------- |
37 | * patch information record | 37 | * patch information record |
diff --git a/include/linux/binfmts.h b/include/linux/binfmts.h index 54f820832c73..7e736e201c46 100644 --- a/include/linux/binfmts.h +++ b/include/linux/binfmts.h | |||
@@ -77,7 +77,6 @@ extern int flush_old_exec(struct linux_binprm * bprm); | |||
77 | extern int setup_arg_pages(struct linux_binprm * bprm, | 77 | extern int setup_arg_pages(struct linux_binprm * bprm, |
78 | unsigned long stack_top, | 78 | unsigned long stack_top, |
79 | int executable_stack); | 79 | int executable_stack); |
80 | extern int copy_strings(int argc,char __user * __user * argv,struct linux_binprm *bprm); | ||
81 | extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); | 80 | extern int copy_strings_kernel(int argc,char ** argv,struct linux_binprm *bprm); |
82 | extern void compute_creds(struct linux_binprm *binprm); | 81 | extern void compute_creds(struct linux_binprm *binprm); |
83 | extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); | 82 | extern int do_coredump(long signr, int exit_code, struct pt_regs * regs); |
diff --git a/include/linux/device.h b/include/linux/device.h index cf470459fa69..df94c0de53f2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -273,9 +273,6 @@ struct device { | |||
273 | BIOS data relevant to device) */ | 273 | BIOS data relevant to device) */ |
274 | struct dev_pm_info power; | 274 | struct dev_pm_info power; |
275 | 275 | ||
276 | u32 detach_state; /* State to enter when device is | ||
277 | detached from its driver. */ | ||
278 | |||
279 | u64 *dma_mask; /* dma mask (if dma'able device) */ | 276 | u64 *dma_mask; /* dma mask (if dma'able device) */ |
280 | u64 coherent_dma_mask;/* Like dma_mask, but for | 277 | u64 coherent_dma_mask;/* Like dma_mask, but for |
281 | alloc_coherent mappings as | 278 | alloc_coherent mappings as |
diff --git a/include/linux/err.h b/include/linux/err.h index 17c55df13615..ff71d2af5da3 100644 --- a/include/linux/err.h +++ b/include/linux/err.h | |||
@@ -13,6 +13,8 @@ | |||
13 | * This should be a per-architecture thing, to allow different | 13 | * This should be a per-architecture thing, to allow different |
14 | * error and pointer decisions. | 14 | * error and pointer decisions. |
15 | */ | 15 | */ |
16 | #define IS_ERR_VALUE(x) unlikely((x) > (unsigned long)-1000L) | ||
17 | |||
16 | static inline void *ERR_PTR(long error) | 18 | static inline void *ERR_PTR(long error) |
17 | { | 19 | { |
18 | return (void *) error; | 20 | return (void *) error; |
@@ -25,7 +27,7 @@ static inline long PTR_ERR(const void *ptr) | |||
25 | 27 | ||
26 | static inline long IS_ERR(const void *ptr) | 28 | static inline long IS_ERR(const void *ptr) |
27 | { | 29 | { |
28 | return unlikely((unsigned long)ptr > (unsigned long)-1000L); | 30 | return IS_ERR_VALUE((unsigned long)ptr); |
29 | } | 31 | } |
30 | 32 | ||
31 | #endif /* _LINUX_ERR_H */ | 33 | #endif /* _LINUX_ERR_H */ |
diff --git a/include/linux/etherdevice.h b/include/linux/etherdevice.h index 396c48cbaeb1..220748b7abea 100644 --- a/include/linux/etherdevice.h +++ b/include/linux/etherdevice.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)eth.h 1.0.4 05/13/93 | 8 | * Version: @(#)eth.h 1.0.4 05/13/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * Relocated to include/linux where it belongs by Alan Cox | 13 | * Relocated to include/linux where it belongs by Alan Cox |
diff --git a/include/linux/fddidevice.h b/include/linux/fddidevice.h index 2e5ee47f3e1e..002f6367697d 100644 --- a/include/linux/fddidevice.h +++ b/include/linux/fddidevice.h | |||
@@ -10,7 +10,7 @@ | |||
10 | * Author: Lawrence V. Stefani, <stefani@lkg.dec.com> | 10 | * Author: Lawrence V. Stefani, <stefani@lkg.dec.com> |
11 | * | 11 | * |
12 | * fddidevice.h is based on previous trdevice.h work by | 12 | * fddidevice.h is based on previous trdevice.h work by |
13 | * Ross Biro, <bir7@leland.Stanford.Edu> | 13 | * Ross Biro |
14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
15 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 15 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
16 | * | 16 | * |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 4edba067a717..0180102dace1 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1341,7 +1341,7 @@ extern int fs_may_remount_ro(struct super_block *); | |||
1341 | 1341 | ||
1342 | extern int check_disk_change(struct block_device *); | 1342 | extern int check_disk_change(struct block_device *); |
1343 | extern int invalidate_inodes(struct super_block *); | 1343 | extern int invalidate_inodes(struct super_block *); |
1344 | extern int __invalidate_device(struct block_device *, int); | 1344 | extern int __invalidate_device(struct block_device *); |
1345 | extern int invalidate_partition(struct gendisk *, int); | 1345 | extern int invalidate_partition(struct gendisk *, int); |
1346 | unsigned long invalidate_mapping_pages(struct address_space *mapping, | 1346 | unsigned long invalidate_mapping_pages(struct address_space *mapping, |
1347 | pgoff_t start, pgoff_t end); | 1347 | pgoff_t start, pgoff_t end); |
diff --git a/include/linux/hippidevice.h b/include/linux/hippidevice.h index 89b3a4a5b761..9debe6bbe5f0 100644 --- a/include/linux/hippidevice.h +++ b/include/linux/hippidevice.h | |||
@@ -10,7 +10,7 @@ | |||
10 | * Author: Jes Sorensen, <Jes.Sorensen@cern.ch> | 10 | * Author: Jes Sorensen, <Jes.Sorensen@cern.ch> |
11 | * | 11 | * |
12 | * hippidevice.h is based on previous fddidevice.h work by | 12 | * hippidevice.h is based on previous fddidevice.h work by |
13 | * Ross Biro, <bir7@leland.Stanford.Edu> | 13 | * Ross Biro |
14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
15 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 15 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
16 | * Lawrence V. Stefani, <stefani@lkg.dec.com> | 16 | * Lawrence V. Stefani, <stefani@lkg.dec.com> |
diff --git a/include/linux/if.h b/include/linux/if.h index 110282dbd3e0..d73a9d62f208 100644 --- a/include/linux/if.h +++ b/include/linux/if.h | |||
@@ -8,7 +8,7 @@ | |||
8 | * Version: @(#)if.h 1.0.2 04/18/93 | 8 | * Version: @(#)if.h 1.0.2 04/18/93 |
9 | * | 9 | * |
10 | * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988 | 10 | * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1982-1988 |
11 | * Ross Biro, <bir7@leland.Stanford.Edu> | 11 | * Ross Biro |
12 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 12 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
13 | * | 13 | * |
14 | * This program is free software; you can redistribute it and/or | 14 | * This program is free software; you can redistribute it and/or |
diff --git a/include/linux/if_arp.h b/include/linux/if_arp.h index bbf49bcd7705..0856548a2a08 100644 --- a/include/linux/if_arp.h +++ b/include/linux/if_arp.h | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988 | 10 | * Authors: Original taken from Berkeley UNIX 4.3, (c) UCB 1986-1988 |
11 | * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. | 11 | * Portions taken from the KA9Q/NOS (v2.00m PA0GRI) source. |
12 | * Ross Biro, <bir7@leland.Stanford.Edu> | 12 | * Ross Biro |
13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
14 | * Florian La Roche, | 14 | * Florian La Roche, |
15 | * Jonathan Layes <layes@loran.com> | 15 | * Jonathan Layes <layes@loran.com> |
diff --git a/include/linux/if_ltalk.h b/include/linux/if_ltalk.h index e75e832b7ff0..76525760ba48 100644 --- a/include/linux/if_ltalk.h +++ b/include/linux/if_ltalk.h | |||
@@ -6,7 +6,7 @@ | |||
6 | #define LTALK_ALEN 1 | 6 | #define LTALK_ALEN 1 |
7 | 7 | ||
8 | #ifdef __KERNEL__ | 8 | #ifdef __KERNEL__ |
9 | extern void ltalk_setup(struct net_device *); | 9 | extern struct net_device *alloc_ltalkdev(int sizeof_priv); |
10 | #endif | 10 | #endif |
11 | 11 | ||
12 | #endif | 12 | #endif |
diff --git a/include/linux/ixjuser.h b/include/linux/ixjuser.h index 88121166d715..fd1756d3a47e 100644 --- a/include/linux/ixjuser.h +++ b/include/linux/ixjuser.h | |||
@@ -42,8 +42,6 @@ | |||
42 | * | 42 | * |
43 | *****************************************************************************/ | 43 | *****************************************************************************/ |
44 | 44 | ||
45 | static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 4.1 2001/08/05 00:17:37 craigs Exp $"; | ||
46 | |||
47 | #include <linux/telephony.h> | 45 | #include <linux/telephony.h> |
48 | 46 | ||
49 | 47 | ||
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index f20c163de4f5..99ddba5a4e00 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h | |||
@@ -43,6 +43,9 @@ typedef int (*kprobe_fault_handler_t) (struct kprobe *, struct pt_regs *, | |||
43 | struct kprobe { | 43 | struct kprobe { |
44 | struct hlist_node hlist; | 44 | struct hlist_node hlist; |
45 | 45 | ||
46 | /* list of kprobes for multi-handler support */ | ||
47 | struct list_head list; | ||
48 | |||
46 | /* location of the probe point */ | 49 | /* location of the probe point */ |
47 | kprobe_opcode_t *addr; | 50 | kprobe_opcode_t *addr; |
48 | 51 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index 505160ab472b..1f7e2039a04e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -584,6 +584,13 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) | |||
584 | ap->ops->scr_write(ap, reg, val); | 584 | ap->ops->scr_write(ap, reg, val); |
585 | } | 585 | } |
586 | 586 | ||
587 | static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, | ||
588 | u32 val) | ||
589 | { | ||
590 | ap->ops->scr_write(ap, reg, val); | ||
591 | (void) ap->ops->scr_read(ap, reg); | ||
592 | } | ||
593 | |||
587 | static inline unsigned int sata_dev_present(struct ata_port *ap) | 594 | static inline unsigned int sata_dev_present(struct ata_port *ap) |
588 | { | 595 | { |
589 | return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; | 596 | return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; |
diff --git a/include/linux/mm.h b/include/linux/mm.h index 8b007ad2d450..17518fe0b311 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -637,9 +637,9 @@ extern unsigned long do_mremap(unsigned long addr, | |||
637 | * These functions are passed a count `nr_to_scan' and a gfpmask. They should | 637 | * These functions are passed a count `nr_to_scan' and a gfpmask. They should |
638 | * scan `nr_to_scan' objects, attempting to free them. | 638 | * scan `nr_to_scan' objects, attempting to free them. |
639 | * | 639 | * |
640 | * The callback must the number of objects which remain in the cache. | 640 | * The callback must return the number of objects which remain in the cache. |
641 | * | 641 | * |
642 | * The callback will be passes nr_to_scan == 0 when the VM is querying the | 642 | * The callback will be passed nr_to_scan == 0 when the VM is querying the |
643 | * cache size, so a fastpath for that case is appropriate. | 643 | * cache size, so a fastpath for that case is appropriate. |
644 | */ | 644 | */ |
645 | typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask); | 645 | typedef int (*shrinker_t)(int nr_to_scan, unsigned int gfp_mask); |
diff --git a/include/linux/mpage.h b/include/linux/mpage.h index dea1b0083661..3ca880463c47 100644 --- a/include/linux/mpage.h +++ b/include/linux/mpage.h | |||
@@ -20,9 +20,6 @@ int mpage_writepages(struct address_space *mapping, | |||
20 | struct writeback_control *wbc, get_block_t get_block); | 20 | struct writeback_control *wbc, get_block_t get_block); |
21 | int mpage_writepage(struct page *page, get_block_t *get_block, | 21 | int mpage_writepage(struct page *page, get_block_t *get_block, |
22 | struct writeback_control *wbc); | 22 | struct writeback_control *wbc); |
23 | int __mpage_writepages(struct address_space *mapping, | ||
24 | struct writeback_control *wbc, get_block_t get_block, | ||
25 | writepage_t writepage); | ||
26 | 23 | ||
27 | static inline int | 24 | static inline int |
28 | generic_writepages(struct address_space *mapping, struct writeback_control *wbc) | 25 | generic_writepages(struct address_space *mapping, struct writeback_control *wbc) |
diff --git a/include/linux/net.h b/include/linux/net.h index e5914c1f0c4d..6d997ff3f103 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * Version: @(#)net.h 1.0.3 05/25/93 | 7 | * Version: @(#)net.h 1.0.3 05/25/93 |
8 | * | 8 | * |
9 | * Authors: Orest Zborowski, <obz@Kodak.COM> | 9 | * Authors: Orest Zborowski, <obz@Kodak.COM> |
10 | * Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 8d775be67833..ac11d73be4ce 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)dev.h 1.0.10 08/12/93 | 8 | * Version: @(#)dev.h 1.0.10 08/12/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 12 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
13 | * Donald J. Becker, <becker@cesdis.gsfc.nasa.gov> | 13 | * Donald J. Becker, <becker@cesdis.gsfc.nasa.gov> |
diff --git a/include/linux/patchkey.h b/include/linux/patchkey.h new file mode 100644 index 000000000000..d974a6e92372 --- /dev/null +++ b/include/linux/patchkey.h | |||
@@ -0,0 +1,45 @@ | |||
1 | /* | ||
2 | * <linux/patchkey.h> -- definition of _PATCHKEY macro | ||
3 | * | ||
4 | * Copyright (C) 2005 Stuart Brady | ||
5 | * | ||
6 | * This exists because awe_voice.h defined its own _PATCHKEY and it wasn't | ||
7 | * clear whether removing this would break anything in userspace. | ||
8 | * | ||
9 | * Do not include this file directly. Please use <sys/soundcard.h> instead. | ||
10 | * For kernel code, use <linux/soundcard.h> | ||
11 | */ | ||
12 | |||
13 | #ifndef _LINUX_PATCHKEY_H_INDIRECT | ||
14 | #error "patchkey.h included directly" | ||
15 | #endif | ||
16 | |||
17 | #ifndef _LINUX_PATCHKEY_H | ||
18 | #define _LINUX_PATCHKEY_H | ||
19 | |||
20 | /* Endian macros. */ | ||
21 | #ifdef __KERNEL__ | ||
22 | # include <asm/byteorder.h> | ||
23 | #else | ||
24 | # include <endian.h> | ||
25 | #endif | ||
26 | |||
27 | #if defined(__KERNEL__) | ||
28 | # if defined(__BIG_ENDIAN) | ||
29 | # define _PATCHKEY(id) (0xfd00|id) | ||
30 | # elif defined(__LITTLE_ENDIAN) | ||
31 | # define _PATCHKEY(id) ((id<<8)|0x00fd) | ||
32 | # else | ||
33 | # error "could not determine byte order" | ||
34 | # endif | ||
35 | #elif defined(__BYTE_ORDER) | ||
36 | # if __BYTE_ORDER == __BIG_ENDIAN | ||
37 | # define _PATCHKEY(id) (0xfd00|id) | ||
38 | # elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
39 | # define _PATCHKEY(id) ((id<<8)|0x00fd) | ||
40 | # else | ||
41 | # error "could not determine byte order" | ||
42 | # endif | ||
43 | #endif | ||
44 | |||
45 | #endif /* _LINUX_PATCHKEY_H */ | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 5d5820a4cf10..ae27792b5aa4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -854,6 +854,7 @@ | |||
854 | #define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020 | 854 | #define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020 |
855 | #define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050 | 855 | #define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050 |
856 | #define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 | 856 | #define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 |
857 | #define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166 | ||
857 | 858 | ||
858 | #define PCI_VENDOR_ID_PICOP 0x1066 | 859 | #define PCI_VENDOR_ID_PICOP 0x1066 |
859 | #define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 | 860 | #define PCI_DEVICE_ID_PICOP_PT86C52X 0x0001 |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 5f868a588581..4dbb109022f3 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -578,7 +578,7 @@ struct task_struct { | |||
578 | unsigned long flags; /* per process flags, defined below */ | 578 | unsigned long flags; /* per process flags, defined below */ |
579 | unsigned long ptrace; | 579 | unsigned long ptrace; |
580 | 580 | ||
581 | int lock_depth; /* Lock depth */ | 581 | int lock_depth; /* BKL lock depth */ |
582 | 582 | ||
583 | int prio, static_prio; | 583 | int prio, static_prio; |
584 | struct list_head run_list; | 584 | struct list_head run_list; |
@@ -661,7 +661,10 @@ struct task_struct { | |||
661 | struct key *thread_keyring; /* keyring private to this thread */ | 661 | struct key *thread_keyring; /* keyring private to this thread */ |
662 | #endif | 662 | #endif |
663 | int oomkilladj; /* OOM kill score adjustment (bit shift). */ | 663 | int oomkilladj; /* OOM kill score adjustment (bit shift). */ |
664 | char comm[TASK_COMM_LEN]; | 664 | char comm[TASK_COMM_LEN]; /* executable name excluding path |
665 | - access with [gs]et_task_comm (which lock | ||
666 | it with task_lock()) | ||
667 | - initialized normally by flush_old_exec */ | ||
665 | /* file system info */ | 668 | /* file system info */ |
666 | int link_count, total_link_count; | 669 | int link_count, total_link_count; |
667 | /* ipc stuff */ | 670 | /* ipc stuff */ |
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index c3fb5984f250..d6025af7efac 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h | |||
@@ -479,6 +479,25 @@ uart_handle_cts_change(struct uart_port *port, unsigned int status) | |||
479 | } | 479 | } |
480 | } | 480 | } |
481 | 481 | ||
482 | #include <linux/tty_flip.h> | ||
483 | |||
484 | static inline void | ||
485 | uart_insert_char(struct uart_port *port, unsigned int status, | ||
486 | unsigned int overrun, unsigned int ch, unsigned int flag) | ||
487 | { | ||
488 | struct tty_struct *tty = port->info->tty; | ||
489 | |||
490 | if ((status & port->ignore_status_mask & ~overrun) == 0) | ||
491 | tty_insert_flip_char(tty, ch, flag); | ||
492 | |||
493 | /* | ||
494 | * Overrun is special. Since it's reported immediately, | ||
495 | * it doesn't affect the current character. | ||
496 | */ | ||
497 | if (status & ~port->ignore_status_mask & overrun) | ||
498 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | ||
499 | } | ||
500 | |||
482 | /* | 501 | /* |
483 | * UART_ENABLE_MS - determine if port should enable modem status irqs | 502 | * UART_ENABLE_MS - determine if port should enable modem status irqs |
484 | */ | 503 | */ |
diff --git a/include/linux/sockios.h b/include/linux/sockios.h index 5eb33205cc04..e6b9d1d36ea2 100644 --- a/include/linux/sockios.h +++ b/include/linux/sockios.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)sockios.h 1.0.2 03/09/93 | 8 | * Version: @(#)sockios.h 1.0.2 03/09/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
diff --git a/include/linux/soundcard.h b/include/linux/soundcard.h index 28d2d1881978..523d069c862c 100644 --- a/include/linux/soundcard.h +++ b/include/linux/soundcard.h | |||
@@ -39,6 +39,13 @@ | |||
39 | /* In Linux we need to be prepared for cross compiling */ | 39 | /* In Linux we need to be prepared for cross compiling */ |
40 | #include <linux/ioctl.h> | 40 | #include <linux/ioctl.h> |
41 | 41 | ||
42 | /* Endian macros. */ | ||
43 | #ifdef __KERNEL__ | ||
44 | # include <asm/byteorder.h> | ||
45 | #else | ||
46 | # include <endian.h> | ||
47 | #endif | ||
48 | |||
42 | /* | 49 | /* |
43 | * Supported card ID numbers (Should be somewhere else?) | 50 | * Supported card ID numbers (Should be somewhere else?) |
44 | */ | 51 | */ |
@@ -179,13 +186,26 @@ typedef struct seq_event_rec { | |||
179 | * Some big endian/little endian handling macros | 186 | * Some big endian/little endian handling macros |
180 | */ | 187 | */ |
181 | 188 | ||
182 | #if defined(_AIX) || defined(AIX) || defined(sparc) || defined(__sparc__) || defined(HPPA) || defined(PPC) || defined(__mc68000__) | 189 | #define _LINUX_PATCHKEY_H_INDIRECT |
183 | /* Big endian machines */ | 190 | #include <linux/patchkey.h> |
184 | # define _PATCHKEY(id) (0xfd00|id) | 191 | #undef _LINUX_PATCHKEY_H_INDIRECT |
185 | # define AFMT_S16_NE AFMT_S16_BE | 192 | |
186 | #else | 193 | #if defined(__KERNEL__) |
187 | # define _PATCHKEY(id) ((id<<8)|0xfd) | 194 | # if defined(__BIG_ENDIAN) |
188 | # define AFMT_S16_NE AFMT_S16_LE | 195 | # define AFMT_S16_NE AFMT_S16_BE |
196 | # elif defined(__LITTLE_ENDIAN) | ||
197 | # define AFMT_S16_NE AFMT_S16_LE | ||
198 | # else | ||
199 | # error "could not determine byte order" | ||
200 | # endif | ||
201 | #elif defined(__BYTE_ORDER) | ||
202 | # if __BYTE_ORDER == __BIG_ENDIAN | ||
203 | # define AFMT_S16_NE AFMT_S16_BE | ||
204 | # elif __BYTE_ORDER == __LITTLE_ENDIAN | ||
205 | # define AFMT_S16_NE AFMT_S16_LE | ||
206 | # else | ||
207 | # error "could not determine byte order" | ||
208 | # endif | ||
189 | #endif | 209 | #endif |
190 | 210 | ||
191 | /* | 211 | /* |
diff --git a/include/linux/trdevice.h b/include/linux/trdevice.h index aaa1f337edcb..99e02ef54c47 100644 --- a/include/linux/trdevice.h +++ b/include/linux/trdevice.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)eth.h 1.0.4 05/13/93 | 8 | * Version: @(#)eth.h 1.0.4 05/13/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * Relocated to include/linux where it belongs by Alan Cox | 13 | * Relocated to include/linux where it belongs by Alan Cox |
diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 3a358c895188..6409d9cf5965 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h | |||
@@ -41,6 +41,7 @@ extern struct vm_struct *get_vm_area(unsigned long size, unsigned long flags); | |||
41 | extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, | 41 | extern struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags, |
42 | unsigned long start, unsigned long end); | 42 | unsigned long start, unsigned long end); |
43 | extern struct vm_struct *remove_vm_area(void *addr); | 43 | extern struct vm_struct *remove_vm_area(void *addr); |
44 | extern struct vm_struct *__remove_vm_area(void *addr); | ||
44 | extern int map_vm_area(struct vm_struct *area, pgprot_t prot, | 45 | extern int map_vm_area(struct vm_struct *area, pgprot_t prot, |
45 | struct page ***pages); | 46 | struct page ***pages); |
46 | extern void unmap_vm_area(struct vm_struct *area); | 47 | extern void unmap_vm_area(struct vm_struct *area); |
diff --git a/include/media/video-buf-dvb.h b/include/media/video-buf-dvb.h index 94bd33619aa5..ad0a07a3a895 100644 --- a/include/media/video-buf-dvb.h +++ b/include/media/video-buf-dvb.h | |||
@@ -16,7 +16,7 @@ struct videobuf_dvb { | |||
16 | int nfeeds; | 16 | int nfeeds; |
17 | 17 | ||
18 | /* videobuf_dvb_(un)register manges this */ | 18 | /* videobuf_dvb_(un)register manges this */ |
19 | struct dvb_adapter *adapter; | 19 | struct dvb_adapter adapter; |
20 | struct dvb_demux demux; | 20 | struct dvb_demux demux; |
21 | struct dmxdev dmxdev; | 21 | struct dmxdev dmxdev; |
22 | struct dmx_frontend fe_hw; | 22 | struct dmx_frontend fe_hw; |
diff --git a/include/net/act_generic.h b/include/net/act_generic.h index 95b120781c14..c9daa7e52300 100644 --- a/include/net/act_generic.h +++ b/include/net/act_generic.h | |||
@@ -2,8 +2,8 @@ | |||
2 | * include/net/act_generic.h | 2 | * include/net/act_generic.h |
3 | * | 3 | * |
4 | */ | 4 | */ |
5 | #ifndef ACT_GENERIC_H | 5 | #ifndef _NET_ACT_GENERIC_H |
6 | #define ACT_GENERIC_H | 6 | #define _NET_ACT_GENERIC_H |
7 | static inline int tcf_defact_release(struct tcf_defact *p, int bind) | 7 | static inline int tcf_defact_release(struct tcf_defact *p, int bind) |
8 | { | 8 | { |
9 | int ret = 0; | 9 | int ret = 0; |
diff --git a/include/net/icmp.h b/include/net/icmp.h index 3fc192478aa2..e5ef0d15fb45 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)icmp.h 1.0.4 05/13/93 | 8 | * Version: @(#)icmp.h 1.0.4 05/13/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
diff --git a/include/net/ip.h b/include/net/ip.h index b4db1375da2c..3f63992eb712 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)ip.h 1.0.2 05/07/93 | 8 | * Version: @(#)ip.h 1.0.2 05/07/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
13 | * | 13 | * |
diff --git a/include/net/route.h b/include/net/route.h index 22da7579d5de..efe92b239ef1 100644 --- a/include/net/route.h +++ b/include/net/route.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)route.h 1.0.4 05/27/93 | 8 | * Version: @(#)route.h 1.0.4 05/27/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Fixes: | 12 | * Fixes: |
13 | * Alan Cox : Reformatted. Added ip_rt_local() | 13 | * Alan Cox : Reformatted. Added ip_rt_local() |
diff --git a/include/net/sock.h b/include/net/sock.h index cc4c9190b7fd..a9ef3a6a13f3 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)sock.h 1.0.4 05/13/93 | 8 | * Version: @(#)sock.h 1.0.4 05/13/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 12 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
13 | * Florian La Roche <flla@stud.uni-sb.de> | 13 | * Florian La Roche <flla@stud.uni-sb.de> |
@@ -141,6 +141,7 @@ struct sock_common { | |||
141 | * @sk_callback_lock: used with the callbacks in the end of this struct | 141 | * @sk_callback_lock: used with the callbacks in the end of this struct |
142 | * @sk_error_queue: rarely used | 142 | * @sk_error_queue: rarely used |
143 | * @sk_prot: protocol handlers inside a network family | 143 | * @sk_prot: protocol handlers inside a network family |
144 | * @sk_prot_creator: sk_prot of original sock creator (see ipv6_setsockopt, IPV6_ADDRFORM for instance) | ||
144 | * @sk_err: last error | 145 | * @sk_err: last error |
145 | * @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out' | 146 | * @sk_err_soft: errors that don't cause failure but are the cause of a persistent failure not just 'timed out' |
146 | * @sk_ack_backlog: current listen backlog | 147 | * @sk_ack_backlog: current listen backlog |
@@ -218,6 +219,7 @@ struct sock { | |||
218 | } sk_backlog; | 219 | } sk_backlog; |
219 | struct sk_buff_head sk_error_queue; | 220 | struct sk_buff_head sk_error_queue; |
220 | struct proto *sk_prot; | 221 | struct proto *sk_prot; |
222 | struct proto *sk_prot_creator; | ||
221 | rwlock_t sk_callback_lock; | 223 | rwlock_t sk_callback_lock; |
222 | int sk_err, | 224 | int sk_err, |
223 | sk_err_soft; | 225 | sk_err_soft; |
diff --git a/include/net/tcp.h b/include/net/tcp.h index 9355ae5b1d75..e71f8ba3e101 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)tcp.h 1.0.5 05/23/93 | 8 | * Version: @(#)tcp.h 1.0.5 05/23/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * This program is free software; you can redistribute it and/or | 13 | * This program is free software; you can redistribute it and/or |
diff --git a/include/net/udp.h b/include/net/udp.h index c496d10101db..ac229b761dbc 100644 --- a/include/net/udp.h +++ b/include/net/udp.h | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)udp.h 1.0.2 05/07/93 | 8 | * Version: @(#)udp.h 1.0.2 05/07/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * Fixes: | 13 | * Fixes: |
diff --git a/include/scsi/scsi_transport_spi.h b/include/scsi/scsi_transport_spi.h index 6dcf497bf46d..a30d6cd4c0e8 100644 --- a/include/scsi/scsi_transport_spi.h +++ b/include/scsi/scsi_transport_spi.h | |||
@@ -27,8 +27,11 @@ struct scsi_transport_template; | |||
27 | 27 | ||
28 | struct spi_transport_attrs { | 28 | struct spi_transport_attrs { |
29 | int period; /* value in the PPR/SDTR command */ | 29 | int period; /* value in the PPR/SDTR command */ |
30 | int min_period; | ||
30 | int offset; | 31 | int offset; |
32 | int max_offset; | ||
31 | unsigned int width:1; /* 0 - narrow, 1 - wide */ | 33 | unsigned int width:1; /* 0 - narrow, 1 - wide */ |
34 | unsigned int max_width:1; | ||
32 | unsigned int iu:1; /* Information Units enabled */ | 35 | unsigned int iu:1; /* Information Units enabled */ |
33 | unsigned int dt:1; /* DT clocking enabled */ | 36 | unsigned int dt:1; /* DT clocking enabled */ |
34 | unsigned int qas:1; /* Quick Arbitration and Selection enabled */ | 37 | unsigned int qas:1; /* Quick Arbitration and Selection enabled */ |
@@ -63,8 +66,11 @@ struct spi_host_attrs { | |||
63 | 66 | ||
64 | /* accessor functions */ | 67 | /* accessor functions */ |
65 | #define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) | 68 | #define spi_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->period) |
69 | #define spi_min_period(x) (((struct spi_transport_attrs *)&(x)->starget_data)->min_period) | ||
66 | #define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) | 70 | #define spi_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->offset) |
71 | #define spi_max_offset(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_offset) | ||
67 | #define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) | 72 | #define spi_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->width) |
73 | #define spi_max_width(x) (((struct spi_transport_attrs *)&(x)->starget_data)->max_width) | ||
68 | #define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) | 74 | #define spi_iu(x) (((struct spi_transport_attrs *)&(x)->starget_data)->iu) |
69 | #define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) | 75 | #define spi_dt(x) (((struct spi_transport_attrs *)&(x)->starget_data)->dt) |
70 | #define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) | 76 | #define spi_qas(x) (((struct spi_transport_attrs *)&(x)->starget_data)->qas) |
diff --git a/kernel/Makefile b/kernel/Makefile index eb88b446c2cc..b01d26fe8db7 100644 --- a/kernel/Makefile +++ b/kernel/Makefile | |||
@@ -29,7 +29,7 @@ obj-$(CONFIG_SYSFS) += ksysfs.o | |||
29 | obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ | 29 | obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ |
30 | obj-$(CONFIG_SECCOMP) += seccomp.o | 30 | obj-$(CONFIG_SECCOMP) += seccomp.o |
31 | 31 | ||
32 | ifneq ($(CONFIG_IA64),y) | 32 | ifneq ($(CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER),y) |
33 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is | 33 | # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is |
34 | # needed for x86 only. Why this used to be enabled for all architectures is beyond | 34 | # needed for x86 only. Why this used to be enabled for all architectures is beyond |
35 | # me. I suspect most platforms don't need this, but until we know that for sure | 35 | # me. I suspect most platforms don't need this, but until we know that for sure |
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c index 2fb0e46e11f3..06b5a6323998 100644 --- a/kernel/irq/handle.c +++ b/kernel/irq/handle.c | |||
@@ -30,6 +30,7 @@ | |||
30 | */ | 30 | */ |
31 | irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { | 31 | irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = { |
32 | [0 ... NR_IRQS-1] = { | 32 | [0 ... NR_IRQS-1] = { |
33 | .status = IRQ_DISABLED, | ||
33 | .handler = &no_irq_type, | 34 | .handler = &no_irq_type, |
34 | .lock = SPIN_LOCK_UNLOCKED | 35 | .lock = SPIN_LOCK_UNLOCKED |
35 | } | 36 | } |
diff --git a/kernel/itimer.c b/kernel/itimer.c index e9a40e947e07..1dc988e0d2c7 100644 --- a/kernel/itimer.c +++ b/kernel/itimer.c | |||
@@ -123,7 +123,11 @@ static inline void it_real_arm(struct task_struct *p, unsigned long interval) | |||
123 | return; | 123 | return; |
124 | if (interval > (unsigned long) LONG_MAX) | 124 | if (interval > (unsigned long) LONG_MAX) |
125 | interval = LONG_MAX; | 125 | interval = LONG_MAX; |
126 | p->signal->real_timer.expires = jiffies + interval; | 126 | /* the "+ 1" below makes sure that the timer doesn't go off before |
127 | * the interval requested. This could happen if | ||
128 | * time requested % (usecs per jiffy) is more than the usecs left | ||
129 | * in the current jiffy */ | ||
130 | p->signal->real_timer.expires = jiffies + interval + 1; | ||
127 | add_timer(&p->signal->real_timer); | 131 | add_timer(&p->signal->real_timer); |
128 | } | 132 | } |
129 | 133 | ||
diff --git a/kernel/kallsyms.c b/kernel/kallsyms.c index 1627f8d6e0cd..13bcec151b57 100644 --- a/kernel/kallsyms.c +++ b/kernel/kallsyms.c | |||
@@ -46,6 +46,14 @@ static inline int is_kernel_inittext(unsigned long addr) | |||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | 48 | ||
49 | static inline int is_kernel_extratext(unsigned long addr) | ||
50 | { | ||
51 | if (addr >= (unsigned long)_sextratext | ||
52 | && addr <= (unsigned long)_eextratext) | ||
53 | return 1; | ||
54 | return 0; | ||
55 | } | ||
56 | |||
49 | static inline int is_kernel_text(unsigned long addr) | 57 | static inline int is_kernel_text(unsigned long addr) |
50 | { | 58 | { |
51 | if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) | 59 | if (addr >= (unsigned long)_stext && addr <= (unsigned long)_etext) |
@@ -169,8 +177,9 @@ const char *kallsyms_lookup(unsigned long addr, | |||
169 | namebuf[0] = 0; | 177 | namebuf[0] = 0; |
170 | 178 | ||
171 | if ((all_var && is_kernel(addr)) || | 179 | if ((all_var && is_kernel(addr)) || |
172 | (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr)))) { | 180 | (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) || |
173 | unsigned long symbol_end=0; | 181 | is_kernel_extratext(addr)))) { |
182 | unsigned long symbol_end = 0; | ||
174 | 183 | ||
175 | /* do a binary search on the sorted kallsyms_addresses array */ | 184 | /* do a binary search on the sorted kallsyms_addresses array */ |
176 | low = 0; | 185 | low = 0; |
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 1d5dd1337bd1..037142b72a49 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -44,6 +44,7 @@ static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; | |||
44 | 44 | ||
45 | unsigned int kprobe_cpu = NR_CPUS; | 45 | unsigned int kprobe_cpu = NR_CPUS; |
46 | static DEFINE_SPINLOCK(kprobe_lock); | 46 | static DEFINE_SPINLOCK(kprobe_lock); |
47 | static struct kprobe *curr_kprobe; | ||
47 | 48 | ||
48 | /* Locks kprobe: irqs must be disabled */ | 49 | /* Locks kprobe: irqs must be disabled */ |
49 | void lock_kprobes(void) | 50 | void lock_kprobes(void) |
@@ -73,22 +74,139 @@ struct kprobe *get_kprobe(void *addr) | |||
73 | return NULL; | 74 | return NULL; |
74 | } | 75 | } |
75 | 76 | ||
77 | /* | ||
78 | * Aggregate handlers for multiple kprobes support - these handlers | ||
79 | * take care of invoking the individual kprobe handlers on p->list | ||
80 | */ | ||
81 | int aggr_pre_handler(struct kprobe *p, struct pt_regs *regs) | ||
82 | { | ||
83 | struct kprobe *kp; | ||
84 | |||
85 | list_for_each_entry(kp, &p->list, list) { | ||
86 | if (kp->pre_handler) { | ||
87 | curr_kprobe = kp; | ||
88 | kp->pre_handler(kp, regs); | ||
89 | curr_kprobe = NULL; | ||
90 | } | ||
91 | } | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | void aggr_post_handler(struct kprobe *p, struct pt_regs *regs, | ||
96 | unsigned long flags) | ||
97 | { | ||
98 | struct kprobe *kp; | ||
99 | |||
100 | list_for_each_entry(kp, &p->list, list) { | ||
101 | if (kp->post_handler) { | ||
102 | curr_kprobe = kp; | ||
103 | kp->post_handler(kp, regs, flags); | ||
104 | curr_kprobe = NULL; | ||
105 | } | ||
106 | } | ||
107 | return; | ||
108 | } | ||
109 | |||
110 | int aggr_fault_handler(struct kprobe *p, struct pt_regs *regs, int trapnr) | ||
111 | { | ||
112 | /* | ||
113 | * if we faulted "during" the execution of a user specified | ||
114 | * probe handler, invoke just that probe's fault handler | ||
115 | */ | ||
116 | if (curr_kprobe && curr_kprobe->fault_handler) { | ||
117 | if (curr_kprobe->fault_handler(curr_kprobe, regs, trapnr)) | ||
118 | return 1; | ||
119 | } | ||
120 | return 0; | ||
121 | } | ||
122 | |||
123 | /* | ||
124 | * Fill in the required fields of the "manager kprobe". Replace the | ||
125 | * earlier kprobe in the hlist with the manager kprobe | ||
126 | */ | ||
127 | static inline void add_aggr_kprobe(struct kprobe *ap, struct kprobe *p) | ||
128 | { | ||
129 | ap->addr = p->addr; | ||
130 | ap->opcode = p->opcode; | ||
131 | memcpy(&ap->ainsn, &p->ainsn, sizeof(struct arch_specific_insn)); | ||
132 | |||
133 | ap->pre_handler = aggr_pre_handler; | ||
134 | ap->post_handler = aggr_post_handler; | ||
135 | ap->fault_handler = aggr_fault_handler; | ||
136 | |||
137 | INIT_LIST_HEAD(&ap->list); | ||
138 | list_add(&p->list, &ap->list); | ||
139 | |||
140 | INIT_HLIST_NODE(&ap->hlist); | ||
141 | hlist_del(&p->hlist); | ||
142 | hlist_add_head(&ap->hlist, | ||
143 | &kprobe_table[hash_ptr(ap->addr, KPROBE_HASH_BITS)]); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * This is the second or subsequent kprobe at the address - handle | ||
148 | * the intricacies | ||
149 | * TODO: Move kcalloc outside the spinlock | ||
150 | */ | ||
151 | static int register_aggr_kprobe(struct kprobe *old_p, struct kprobe *p) | ||
152 | { | ||
153 | int ret = 0; | ||
154 | struct kprobe *ap; | ||
155 | |||
156 | if (old_p->break_handler || p->break_handler) { | ||
157 | ret = -EEXIST; /* kprobe and jprobe can't (yet) coexist */ | ||
158 | } else if (old_p->pre_handler == aggr_pre_handler) { | ||
159 | list_add(&p->list, &old_p->list); | ||
160 | } else { | ||
161 | ap = kcalloc(1, sizeof(struct kprobe), GFP_ATOMIC); | ||
162 | if (!ap) | ||
163 | return -ENOMEM; | ||
164 | add_aggr_kprobe(ap, old_p); | ||
165 | list_add(&p->list, &ap->list); | ||
166 | } | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | /* kprobe removal house-keeping routines */ | ||
171 | static inline void cleanup_kprobe(struct kprobe *p, unsigned long flags) | ||
172 | { | ||
173 | *p->addr = p->opcode; | ||
174 | hlist_del(&p->hlist); | ||
175 | flush_icache_range((unsigned long) p->addr, | ||
176 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | ||
177 | spin_unlock_irqrestore(&kprobe_lock, flags); | ||
178 | arch_remove_kprobe(p); | ||
179 | } | ||
180 | |||
181 | static inline void cleanup_aggr_kprobe(struct kprobe *old_p, | ||
182 | struct kprobe *p, unsigned long flags) | ||
183 | { | ||
184 | list_del(&p->list); | ||
185 | if (list_empty(&old_p->list)) { | ||
186 | cleanup_kprobe(old_p, flags); | ||
187 | kfree(old_p); | ||
188 | } else | ||
189 | spin_unlock_irqrestore(&kprobe_lock, flags); | ||
190 | } | ||
191 | |||
76 | int register_kprobe(struct kprobe *p) | 192 | int register_kprobe(struct kprobe *p) |
77 | { | 193 | { |
78 | int ret = 0; | 194 | int ret = 0; |
79 | unsigned long flags = 0; | 195 | unsigned long flags = 0; |
196 | struct kprobe *old_p; | ||
80 | 197 | ||
81 | if ((ret = arch_prepare_kprobe(p)) != 0) { | 198 | if ((ret = arch_prepare_kprobe(p)) != 0) { |
82 | goto rm_kprobe; | 199 | goto rm_kprobe; |
83 | } | 200 | } |
84 | spin_lock_irqsave(&kprobe_lock, flags); | 201 | spin_lock_irqsave(&kprobe_lock, flags); |
85 | INIT_HLIST_NODE(&p->hlist); | 202 | old_p = get_kprobe(p->addr); |
86 | if (get_kprobe(p->addr)) { | 203 | if (old_p) { |
87 | ret = -EEXIST; | 204 | ret = register_aggr_kprobe(old_p, p); |
88 | goto out; | 205 | goto out; |
89 | } | 206 | } |
90 | arch_copy_kprobe(p); | ||
91 | 207 | ||
208 | arch_copy_kprobe(p); | ||
209 | INIT_HLIST_NODE(&p->hlist); | ||
92 | hlist_add_head(&p->hlist, | 210 | hlist_add_head(&p->hlist, |
93 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); | 211 | &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); |
94 | 212 | ||
@@ -107,13 +225,17 @@ rm_kprobe: | |||
107 | void unregister_kprobe(struct kprobe *p) | 225 | void unregister_kprobe(struct kprobe *p) |
108 | { | 226 | { |
109 | unsigned long flags; | 227 | unsigned long flags; |
110 | arch_remove_kprobe(p); | 228 | struct kprobe *old_p; |
229 | |||
111 | spin_lock_irqsave(&kprobe_lock, flags); | 230 | spin_lock_irqsave(&kprobe_lock, flags); |
112 | *p->addr = p->opcode; | 231 | old_p = get_kprobe(p->addr); |
113 | hlist_del(&p->hlist); | 232 | if (old_p) { |
114 | flush_icache_range((unsigned long) p->addr, | 233 | if (old_p->pre_handler == aggr_pre_handler) |
115 | (unsigned long) p->addr + sizeof(kprobe_opcode_t)); | 234 | cleanup_aggr_kprobe(old_p, p, flags); |
116 | spin_unlock_irqrestore(&kprobe_lock, flags); | 235 | else |
236 | cleanup_kprobe(p, flags); | ||
237 | } else | ||
238 | spin_unlock_irqrestore(&kprobe_lock, flags); | ||
117 | } | 239 | } |
118 | 240 | ||
119 | static struct notifier_block kprobe_exceptions_nb = { | 241 | static struct notifier_block kprobe_exceptions_nb = { |
diff --git a/kernel/power/main.c b/kernel/power/main.c index 7960ddf04a57..4cdebc972ff2 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c | |||
@@ -156,14 +156,14 @@ static int enter_state(suspend_state_t state) | |||
156 | goto Unlock; | 156 | goto Unlock; |
157 | } | 157 | } |
158 | 158 | ||
159 | pr_debug("PM: Preparing system for suspend\n"); | 159 | pr_debug("PM: Preparing system for %s sleep\n", pm_states[state]); |
160 | if ((error = suspend_prepare(state))) | 160 | if ((error = suspend_prepare(state))) |
161 | goto Unlock; | 161 | goto Unlock; |
162 | 162 | ||
163 | pr_debug("PM: Entering state.\n"); | 163 | pr_debug("PM: Entering %s sleep\n", pm_states[state]); |
164 | error = suspend_enter(state); | 164 | error = suspend_enter(state); |
165 | 165 | ||
166 | pr_debug("PM: Finishing up.\n"); | 166 | pr_debug("PM: Finishing wakeup.\n"); |
167 | suspend_finish(state); | 167 | suspend_finish(state); |
168 | Unlock: | 168 | Unlock: |
169 | up(&pm_sem); | 169 | up(&pm_sem); |
diff --git a/kernel/printk.c b/kernel/printk.c index 290a07ce2c8a..01b58d7d17ff 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -160,42 +160,6 @@ static int __init console_setup(char *str) | |||
160 | 160 | ||
161 | __setup("console=", console_setup); | 161 | __setup("console=", console_setup); |
162 | 162 | ||
163 | /** | ||
164 | * add_preferred_console - add a device to the list of preferred consoles. | ||
165 | * | ||
166 | * The last preferred console added will be used for kernel messages | ||
167 | * and stdin/out/err for init. Normally this is used by console_setup | ||
168 | * above to handle user-supplied console arguments; however it can also | ||
169 | * be used by arch-specific code either to override the user or more | ||
170 | * commonly to provide a default console (ie from PROM variables) when | ||
171 | * the user has not supplied one. | ||
172 | */ | ||
173 | int __init add_preferred_console(char *name, int idx, char *options) | ||
174 | { | ||
175 | struct console_cmdline *c; | ||
176 | int i; | ||
177 | |||
178 | /* | ||
179 | * See if this tty is not yet registered, and | ||
180 | * if we have a slot free. | ||
181 | */ | ||
182 | for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) | ||
183 | if (strcmp(console_cmdline[i].name, name) == 0 && | ||
184 | console_cmdline[i].index == idx) { | ||
185 | selected_console = i; | ||
186 | return 0; | ||
187 | } | ||
188 | if (i == MAX_CMDLINECONSOLES) | ||
189 | return -E2BIG; | ||
190 | selected_console = i; | ||
191 | c = &console_cmdline[i]; | ||
192 | memcpy(c->name, name, sizeof(c->name)); | ||
193 | c->name[sizeof(c->name) - 1] = 0; | ||
194 | c->options = options; | ||
195 | c->index = idx; | ||
196 | return 0; | ||
197 | } | ||
198 | |||
199 | static int __init log_buf_len_setup(char *str) | 163 | static int __init log_buf_len_setup(char *str) |
200 | { | 164 | { |
201 | unsigned long size = memparse(str, &str); | 165 | unsigned long size = memparse(str, &str); |
@@ -671,6 +635,42 @@ static void call_console_drivers(unsigned long start, unsigned long end) {} | |||
671 | #endif | 635 | #endif |
672 | 636 | ||
673 | /** | 637 | /** |
638 | * add_preferred_console - add a device to the list of preferred consoles. | ||
639 | * | ||
640 | * The last preferred console added will be used for kernel messages | ||
641 | * and stdin/out/err for init. Normally this is used by console_setup | ||
642 | * above to handle user-supplied console arguments; however it can also | ||
643 | * be used by arch-specific code either to override the user or more | ||
644 | * commonly to provide a default console (ie from PROM variables) when | ||
645 | * the user has not supplied one. | ||
646 | */ | ||
647 | int __init add_preferred_console(char *name, int idx, char *options) | ||
648 | { | ||
649 | struct console_cmdline *c; | ||
650 | int i; | ||
651 | |||
652 | /* | ||
653 | * See if this tty is not yet registered, and | ||
654 | * if we have a slot free. | ||
655 | */ | ||
656 | for(i = 0; i < MAX_CMDLINECONSOLES && console_cmdline[i].name[0]; i++) | ||
657 | if (strcmp(console_cmdline[i].name, name) == 0 && | ||
658 | console_cmdline[i].index == idx) { | ||
659 | selected_console = i; | ||
660 | return 0; | ||
661 | } | ||
662 | if (i == MAX_CMDLINECONSOLES) | ||
663 | return -E2BIG; | ||
664 | selected_console = i; | ||
665 | c = &console_cmdline[i]; | ||
666 | memcpy(c->name, name, sizeof(c->name)); | ||
667 | c->name[sizeof(c->name) - 1] = 0; | ||
668 | c->options = options; | ||
669 | c->index = idx; | ||
670 | return 0; | ||
671 | } | ||
672 | |||
673 | /** | ||
674 | * acquire_console_sem - lock the console system for exclusive use. | 674 | * acquire_console_sem - lock the console system for exclusive use. |
675 | * | 675 | * |
676 | * Acquires a semaphore which guarantees that the caller has | 676 | * Acquires a semaphore which guarantees that the caller has |
diff --git a/kernel/profile.c b/kernel/profile.c index 0221a50ca867..ad8cbb75ffa2 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -49,15 +49,19 @@ static DECLARE_MUTEX(profile_flip_mutex); | |||
49 | 49 | ||
50 | static int __init profile_setup(char * str) | 50 | static int __init profile_setup(char * str) |
51 | { | 51 | { |
52 | static char __initdata schedstr[] = "schedule"; | ||
52 | int par; | 53 | int par; |
53 | 54 | ||
54 | if (!strncmp(str, "schedule", 8)) { | 55 | if (!strncmp(str, schedstr, strlen(schedstr))) { |
55 | prof_on = SCHED_PROFILING; | 56 | prof_on = SCHED_PROFILING; |
56 | printk(KERN_INFO "kernel schedule profiling enabled\n"); | 57 | if (str[strlen(schedstr)] == ',') |
57 | if (str[7] == ',') | 58 | str += strlen(schedstr) + 1; |
58 | str += 8; | 59 | if (get_option(&str, &par)) |
59 | } | 60 | prof_shift = par; |
60 | if (get_option(&str,&par)) { | 61 | printk(KERN_INFO |
62 | "kernel schedule profiling enabled (shift: %ld)\n", | ||
63 | prof_shift); | ||
64 | } else if (get_option(&str, &par)) { | ||
61 | prof_shift = par; | 65 | prof_shift = par; |
62 | prof_on = CPU_PROFILING; | 66 | prof_on = CPU_PROFILING; |
63 | printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n", | 67 | printk(KERN_INFO "kernel profiling enabled (shift: %ld)\n", |
diff --git a/kernel/sched.c b/kernel/sched.c index 0dc3158667a2..66b2ed784822 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4243,7 +4243,7 @@ static void move_task_off_dead_cpu(int dead_cpu, struct task_struct *tsk) | |||
4243 | 4243 | ||
4244 | /* No more Mr. Nice Guy. */ | 4244 | /* No more Mr. Nice Guy. */ |
4245 | if (dest_cpu == NR_CPUS) { | 4245 | if (dest_cpu == NR_CPUS) { |
4246 | tsk->cpus_allowed = cpuset_cpus_allowed(tsk); | 4246 | cpus_setall(tsk->cpus_allowed); |
4247 | dest_cpu = any_online_cpu(tsk->cpus_allowed); | 4247 | dest_cpu = any_online_cpu(tsk->cpus_allowed); |
4248 | 4248 | ||
4249 | /* | 4249 | /* |
diff --git a/kernel/sys.c b/kernel/sys.c index f64e97cabe25..f006632c2ba7 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1195,7 +1195,7 @@ static int groups_from_user(struct group_info *group_info, | |||
1195 | return 0; | 1195 | return 0; |
1196 | } | 1196 | } |
1197 | 1197 | ||
1198 | /* a simple shell-metzner sort */ | 1198 | /* a simple Shell sort */ |
1199 | static void groups_sort(struct group_info *group_info) | 1199 | static void groups_sort(struct group_info *group_info) |
1200 | { | 1200 | { |
1201 | int base, max, stride; | 1201 | int base, max, stride; |
diff --git a/lib/sort.c b/lib/sort.c index ea3caedeabdb..b73dbb0e7c83 100644 --- a/lib/sort.c +++ b/lib/sort.c | |||
@@ -90,7 +90,7 @@ int cmpint(const void *a, const void *b) | |||
90 | 90 | ||
91 | static int sort_test(void) | 91 | static int sort_test(void) |
92 | { | 92 | { |
93 | int *a, i, r = 0; | 93 | int *a, i, r = 1; |
94 | 94 | ||
95 | a = kmalloc(1000 * sizeof(int), GFP_KERNEL); | 95 | a = kmalloc(1000 * sizeof(int), GFP_KERNEL); |
96 | BUG_ON(!a); | 96 | BUG_ON(!a); |
diff --git a/lib/string.c b/lib/string.c index 4bb93ad23c60..d886ef157c12 100644 --- a/lib/string.c +++ b/lib/string.c | |||
@@ -65,6 +65,7 @@ EXPORT_SYMBOL(strnicmp); | |||
65 | * @dest: Where to copy the string to | 65 | * @dest: Where to copy the string to |
66 | * @src: Where to copy the string from | 66 | * @src: Where to copy the string from |
67 | */ | 67 | */ |
68 | #undef strcpy | ||
68 | char * strcpy(char * dest,const char *src) | 69 | char * strcpy(char * dest,const char *src) |
69 | { | 70 | { |
70 | char *tmp = dest; | 71 | char *tmp = dest; |
@@ -85,6 +86,10 @@ EXPORT_SYMBOL(strcpy); | |||
85 | * | 86 | * |
86 | * The result is not %NUL-terminated if the source exceeds | 87 | * The result is not %NUL-terminated if the source exceeds |
87 | * @count bytes. | 88 | * @count bytes. |
89 | * | ||
90 | * In the case where the length of @src is less than that of | ||
91 | * count, the remainder of @dest will be padded with %NUL. | ||
92 | * | ||
88 | */ | 93 | */ |
89 | char * strncpy(char * dest,const char *src,size_t count) | 94 | char * strncpy(char * dest,const char *src,size_t count) |
90 | { | 95 | { |
@@ -132,6 +137,7 @@ EXPORT_SYMBOL(strlcpy); | |||
132 | * @dest: The string to be appended to | 137 | * @dest: The string to be appended to |
133 | * @src: The string to append to it | 138 | * @src: The string to append to it |
134 | */ | 139 | */ |
140 | #undef strcat | ||
135 | char * strcat(char * dest, const char * src) | 141 | char * strcat(char * dest, const char * src) |
136 | { | 142 | { |
137 | char *tmp = dest; | 143 | char *tmp = dest; |
@@ -209,6 +215,7 @@ EXPORT_SYMBOL(strlcat); | |||
209 | * @cs: One string | 215 | * @cs: One string |
210 | * @ct: Another string | 216 | * @ct: Another string |
211 | */ | 217 | */ |
218 | #undef strcmp | ||
212 | int strcmp(const char * cs,const char * ct) | 219 | int strcmp(const char * cs,const char * ct) |
213 | { | 220 | { |
214 | register signed char __res; | 221 | register signed char __res; |
@@ -514,6 +521,7 @@ EXPORT_SYMBOL(memmove); | |||
514 | * @ct: Another area of memory | 521 | * @ct: Another area of memory |
515 | * @count: The size of the area. | 522 | * @count: The size of the area. |
516 | */ | 523 | */ |
524 | #undef memcmp | ||
517 | int memcmp(const void * cs,const void * ct,size_t count) | 525 | int memcmp(const void * cs,const void * ct,size_t count) |
518 | { | 526 | { |
519 | const unsigned char *su1, *su2; | 527 | const unsigned char *su1, *su2; |
diff --git a/mm/filemap.c b/mm/filemap.c index d5fdae2eb183..47263ac3e4ea 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -29,11 +29,6 @@ | |||
29 | #include <linux/security.h> | 29 | #include <linux/security.h> |
30 | #include <linux/syscalls.h> | 30 | #include <linux/syscalls.h> |
31 | /* | 31 | /* |
32 | * This is needed for the following functions: | ||
33 | * - try_to_release_page | ||
34 | * - block_invalidatepage | ||
35 | * - generic_osync_inode | ||
36 | * | ||
37 | * FIXME: remove all knowledge of the buffer layer from the core VM | 32 | * FIXME: remove all knowledge of the buffer layer from the core VM |
38 | */ | 33 | */ |
39 | #include <linux/buffer_head.h> /* for generic_osync_inode */ | 34 | #include <linux/buffer_head.h> /* for generic_osync_inode */ |
diff --git a/mm/memory.c b/mm/memory.c index 6bad4c4064e7..d209f745db7f 100644 --- a/mm/memory.c +++ b/mm/memory.c | |||
@@ -1701,12 +1701,13 @@ static int do_swap_page(struct mm_struct * mm, | |||
1701 | spin_lock(&mm->page_table_lock); | 1701 | spin_lock(&mm->page_table_lock); |
1702 | page_table = pte_offset_map(pmd, address); | 1702 | page_table = pte_offset_map(pmd, address); |
1703 | if (unlikely(!pte_same(*page_table, orig_pte))) { | 1703 | if (unlikely(!pte_same(*page_table, orig_pte))) { |
1704 | pte_unmap(page_table); | ||
1705 | spin_unlock(&mm->page_table_lock); | ||
1706 | unlock_page(page); | ||
1707 | page_cache_release(page); | ||
1708 | ret = VM_FAULT_MINOR; | 1704 | ret = VM_FAULT_MINOR; |
1709 | goto out; | 1705 | goto out_nomap; |
1706 | } | ||
1707 | |||
1708 | if (unlikely(!PageUptodate(page))) { | ||
1709 | ret = VM_FAULT_SIGBUS; | ||
1710 | goto out_nomap; | ||
1710 | } | 1711 | } |
1711 | 1712 | ||
1712 | /* The page isn't present yet, go ahead with the fault. */ | 1713 | /* The page isn't present yet, go ahead with the fault. */ |
@@ -1741,6 +1742,12 @@ static int do_swap_page(struct mm_struct * mm, | |||
1741 | spin_unlock(&mm->page_table_lock); | 1742 | spin_unlock(&mm->page_table_lock); |
1742 | out: | 1743 | out: |
1743 | return ret; | 1744 | return ret; |
1745 | out_nomap: | ||
1746 | pte_unmap(page_table); | ||
1747 | spin_unlock(&mm->page_table_lock); | ||
1748 | unlock_page(page); | ||
1749 | page_cache_release(page); | ||
1750 | goto out; | ||
1744 | } | 1751 | } |
1745 | 1752 | ||
1746 | /* | 1753 | /* |
@@ -1244,7 +1244,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
1244 | addr = mm->free_area_cache; | 1244 | addr = mm->free_area_cache; |
1245 | 1245 | ||
1246 | /* make sure it can fit in the remaining address space */ | 1246 | /* make sure it can fit in the remaining address space */ |
1247 | if (addr >= len) { | 1247 | if (addr > len) { |
1248 | vma = find_vma(mm, addr-len); | 1248 | vma = find_vma(mm, addr-len); |
1249 | if (!vma || addr <= vma->vm_start) | 1249 | if (!vma || addr <= vma->vm_start) |
1250 | /* remember the address as a hint for next time */ | 1250 | /* remember the address as a hint for next time */ |
@@ -1266,7 +1266,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, | |||
1266 | 1266 | ||
1267 | /* try just below the current vma->vm_start */ | 1267 | /* try just below the current vma->vm_start */ |
1268 | addr = vma->vm_start-len; | 1268 | addr = vma->vm_start-len; |
1269 | } while (len <= vma->vm_start); | 1269 | } while (len < vma->vm_start); |
1270 | 1270 | ||
1271 | /* | 1271 | /* |
1272 | * A failed mmap() very likely causes application failure, | 1272 | * A failed mmap() very likely causes application failure, |
@@ -1302,37 +1302,40 @@ unsigned long | |||
1302 | get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, | 1302 | get_unmapped_area(struct file *file, unsigned long addr, unsigned long len, |
1303 | unsigned long pgoff, unsigned long flags) | 1303 | unsigned long pgoff, unsigned long flags) |
1304 | { | 1304 | { |
1305 | if (flags & MAP_FIXED) { | 1305 | unsigned long ret; |
1306 | unsigned long ret; | ||
1307 | 1306 | ||
1308 | if (addr > TASK_SIZE - len) | 1307 | if (!(flags & MAP_FIXED)) { |
1309 | return -ENOMEM; | 1308 | unsigned long (*get_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); |
1310 | if (addr & ~PAGE_MASK) | ||
1311 | return -EINVAL; | ||
1312 | if (file && is_file_hugepages(file)) { | ||
1313 | /* | ||
1314 | * Check if the given range is hugepage aligned, and | ||
1315 | * can be made suitable for hugepages. | ||
1316 | */ | ||
1317 | ret = prepare_hugepage_range(addr, len); | ||
1318 | } else { | ||
1319 | /* | ||
1320 | * Ensure that a normal request is not falling in a | ||
1321 | * reserved hugepage range. For some archs like IA-64, | ||
1322 | * there is a separate region for hugepages. | ||
1323 | */ | ||
1324 | ret = is_hugepage_only_range(current->mm, addr, len); | ||
1325 | } | ||
1326 | if (ret) | ||
1327 | return -EINVAL; | ||
1328 | return addr; | ||
1329 | } | ||
1330 | 1309 | ||
1331 | if (file && file->f_op && file->f_op->get_unmapped_area) | 1310 | get_area = current->mm->get_unmapped_area; |
1332 | return file->f_op->get_unmapped_area(file, addr, len, | 1311 | if (file && file->f_op && file->f_op->get_unmapped_area) |
1333 | pgoff, flags); | 1312 | get_area = file->f_op->get_unmapped_area; |
1313 | addr = get_area(file, addr, len, pgoff, flags); | ||
1314 | if (IS_ERR_VALUE(addr)) | ||
1315 | return addr; | ||
1316 | } | ||
1334 | 1317 | ||
1335 | return current->mm->get_unmapped_area(file, addr, len, pgoff, flags); | 1318 | if (addr > TASK_SIZE - len) |
1319 | return -ENOMEM; | ||
1320 | if (addr & ~PAGE_MASK) | ||
1321 | return -EINVAL; | ||
1322 | if (file && is_file_hugepages(file)) { | ||
1323 | /* | ||
1324 | * Check if the given range is hugepage aligned, and | ||
1325 | * can be made suitable for hugepages. | ||
1326 | */ | ||
1327 | ret = prepare_hugepage_range(addr, len); | ||
1328 | } else { | ||
1329 | /* | ||
1330 | * Ensure that a normal request is not falling in a | ||
1331 | * reserved hugepage range. For some archs like IA-64, | ||
1332 | * there is a separate region for hugepages. | ||
1333 | */ | ||
1334 | ret = is_hugepage_only_range(current->mm, addr, len); | ||
1335 | } | ||
1336 | if (ret) | ||
1337 | return -EINVAL; | ||
1338 | return addr; | ||
1336 | } | 1339 | } |
1337 | 1340 | ||
1338 | EXPORT_SYMBOL(get_unmapped_area); | 1341 | EXPORT_SYMBOL(get_unmapped_area); |
diff --git a/mm/mremap.c b/mm/mremap.c index 0dd7ace94e51..ec7238a78f36 100644 --- a/mm/mremap.c +++ b/mm/mremap.c | |||
@@ -224,6 +224,12 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
224 | split = 1; | 224 | split = 1; |
225 | } | 225 | } |
226 | 226 | ||
227 | /* | ||
228 | * if we failed to move page tables we still do total_vm increment | ||
229 | * since do_munmap() will decrement it by old_len == new_len | ||
230 | */ | ||
231 | mm->total_vm += new_len >> PAGE_SHIFT; | ||
232 | |||
227 | if (do_munmap(mm, old_addr, old_len) < 0) { | 233 | if (do_munmap(mm, old_addr, old_len) < 0) { |
228 | /* OOM: unable to split vma, just get accounts right */ | 234 | /* OOM: unable to split vma, just get accounts right */ |
229 | vm_unacct_memory(excess >> PAGE_SHIFT); | 235 | vm_unacct_memory(excess >> PAGE_SHIFT); |
@@ -237,7 +243,6 @@ static unsigned long move_vma(struct vm_area_struct *vma, | |||
237 | vma->vm_next->vm_flags |= VM_ACCOUNT; | 243 | vma->vm_next->vm_flags |= VM_ACCOUNT; |
238 | } | 244 | } |
239 | 245 | ||
240 | mm->total_vm += new_len >> PAGE_SHIFT; | ||
241 | __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); | 246 | __vm_stat_account(mm, vma->vm_flags, vma->vm_file, new_len>>PAGE_SHIFT); |
242 | if (vm_flags & VM_LOCKED) { | 247 | if (vm_flags & VM_LOCKED) { |
243 | mm->locked_vm += new_len >> PAGE_SHIFT; | 248 | mm->locked_vm += new_len >> PAGE_SHIFT; |
diff --git a/mm/nommu.c b/mm/nommu.c index b293ec1cc4e6..c53e9c8f6b4a 100644 --- a/mm/nommu.c +++ b/mm/nommu.c | |||
@@ -150,7 +150,8 @@ void vfree(void *addr) | |||
150 | kfree(addr); | 150 | kfree(addr); |
151 | } | 151 | } |
152 | 152 | ||
153 | void *__vmalloc(unsigned long size, int gfp_mask, pgprot_t prot) | 153 | void *__vmalloc(unsigned long size, unsigned int __nocast gfp_mask, |
154 | pgprot_t prot) | ||
154 | { | 155 | { |
155 | /* | 156 | /* |
156 | * kmalloc doesn't like __GFP_HIGHMEM for some reason | 157 | * kmalloc doesn't like __GFP_HIGHMEM for some reason |
@@ -586,7 +586,7 @@ static int try_to_unmap_one(struct page *page, struct vm_area_struct *vma) | |||
586 | dec_mm_counter(mm, anon_rss); | 586 | dec_mm_counter(mm, anon_rss); |
587 | } | 587 | } |
588 | 588 | ||
589 | inc_mm_counter(mm, rss); | 589 | dec_mm_counter(mm, rss); |
590 | page_remove_rmap(page); | 590 | page_remove_rmap(page); |
591 | page_cache_release(page); | 591 | page_cache_release(page); |
592 | 592 | ||
diff --git a/mm/swapfile.c b/mm/swapfile.c index a60e0075d55b..da48405cd9a3 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -79,7 +79,7 @@ void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page) | |||
79 | WARN_ON(page_count(page) <= 1); | 79 | WARN_ON(page_count(page) <= 1); |
80 | 80 | ||
81 | bdi = bdev->bd_inode->i_mapping->backing_dev_info; | 81 | bdi = bdev->bd_inode->i_mapping->backing_dev_info; |
82 | bdi->unplug_io_fn(bdi, page); | 82 | blk_run_backing_dev(bdi, page); |
83 | } | 83 | } |
84 | up_read(&swap_unplug_sem); | 84 | up_read(&swap_unplug_sem); |
85 | } | 85 | } |
diff --git a/mm/vmalloc.c b/mm/vmalloc.c index 2bd83e5c2bbf..8ff16a1eee6a 100644 --- a/mm/vmalloc.c +++ b/mm/vmalloc.c | |||
@@ -248,31 +248,20 @@ struct vm_struct *get_vm_area(unsigned long size, unsigned long flags) | |||
248 | return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END); | 248 | return __get_vm_area(size, flags, VMALLOC_START, VMALLOC_END); |
249 | } | 249 | } |
250 | 250 | ||
251 | /** | 251 | /* Caller must hold vmlist_lock */ |
252 | * remove_vm_area - find and remove a contingous kernel virtual area | 252 | struct vm_struct *__remove_vm_area(void *addr) |
253 | * | ||
254 | * @addr: base address | ||
255 | * | ||
256 | * Search for the kernel VM area starting at @addr, and remove it. | ||
257 | * This function returns the found VM area, but using it is NOT safe | ||
258 | * on SMP machines. | ||
259 | */ | ||
260 | struct vm_struct *remove_vm_area(void *addr) | ||
261 | { | 253 | { |
262 | struct vm_struct **p, *tmp; | 254 | struct vm_struct **p, *tmp; |
263 | 255 | ||
264 | write_lock(&vmlist_lock); | ||
265 | for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next) { | 256 | for (p = &vmlist ; (tmp = *p) != NULL ;p = &tmp->next) { |
266 | if (tmp->addr == addr) | 257 | if (tmp->addr == addr) |
267 | goto found; | 258 | goto found; |
268 | } | 259 | } |
269 | write_unlock(&vmlist_lock); | ||
270 | return NULL; | 260 | return NULL; |
271 | 261 | ||
272 | found: | 262 | found: |
273 | unmap_vm_area(tmp); | 263 | unmap_vm_area(tmp); |
274 | *p = tmp->next; | 264 | *p = tmp->next; |
275 | write_unlock(&vmlist_lock); | ||
276 | 265 | ||
277 | /* | 266 | /* |
278 | * Remove the guard page. | 267 | * Remove the guard page. |
@@ -281,6 +270,24 @@ found: | |||
281 | return tmp; | 270 | return tmp; |
282 | } | 271 | } |
283 | 272 | ||
273 | /** | ||
274 | * remove_vm_area - find and remove a contingous kernel virtual area | ||
275 | * | ||
276 | * @addr: base address | ||
277 | * | ||
278 | * Search for the kernel VM area starting at @addr, and remove it. | ||
279 | * This function returns the found VM area, but using it is NOT safe | ||
280 | * on SMP machines, except for its size or flags. | ||
281 | */ | ||
282 | struct vm_struct *remove_vm_area(void *addr) | ||
283 | { | ||
284 | struct vm_struct *v; | ||
285 | write_lock(&vmlist_lock); | ||
286 | v = __remove_vm_area(addr); | ||
287 | write_unlock(&vmlist_lock); | ||
288 | return v; | ||
289 | } | ||
290 | |||
284 | void __vunmap(void *addr, int deallocate_pages) | 291 | void __vunmap(void *addr, int deallocate_pages) |
285 | { | 292 | { |
286 | struct vm_struct *area; | 293 | struct vm_struct *area; |
diff --git a/net/802/fddi.c b/net/802/fddi.c index f9a31a9f70f1..ebcf4830d6f1 100644 --- a/net/802/fddi.c +++ b/net/802/fddi.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Authors: Lawrence V. Stefani, <stefani@lkg.dec.com> | 10 | * Authors: Lawrence V. Stefani, <stefani@lkg.dec.com> |
11 | * | 11 | * |
12 | * fddi.c is based on previous eth.c and tr.c work by | 12 | * fddi.c is based on previous eth.c and tr.c work by |
13 | * Ross Biro, <bir7@leland.Stanford.Edu> | 13 | * Ross Biro |
14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 14 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
15 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 15 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
16 | * Florian La Roche, <rzsfl@rz.uni-sb.de> | 16 | * Florian La Roche, <rzsfl@rz.uni-sb.de> |
diff --git a/net/802/hippi.c b/net/802/hippi.c index 4eb135c0afbb..051e8af56a77 100644 --- a/net/802/hippi.c +++ b/net/802/hippi.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)hippi.c 1.0.0 05/29/97 | 8 | * Version: @(#)hippi.c 1.0.0 05/29/97 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Florian La Roche, <rzsfl@rz.uni-sb.de> | 13 | * Florian La Roche, <rzsfl@rz.uni-sb.de> |
diff --git a/net/appletalk/dev.c b/net/appletalk/dev.c index 76598445d84b..1237e208e246 100644 --- a/net/appletalk/dev.c +++ b/net/appletalk/dev.c | |||
@@ -19,7 +19,7 @@ static int ltalk_mac_addr(struct net_device *dev, void *addr) | |||
19 | return -EINVAL; | 19 | return -EINVAL; |
20 | } | 20 | } |
21 | 21 | ||
22 | void ltalk_setup(struct net_device *dev) | 22 | static void ltalk_setup(struct net_device *dev) |
23 | { | 23 | { |
24 | /* Fill in the fields of the device structure with localtalk-generic values. */ | 24 | /* Fill in the fields of the device structure with localtalk-generic values. */ |
25 | 25 | ||
@@ -40,4 +40,22 @@ void ltalk_setup(struct net_device *dev) | |||
40 | 40 | ||
41 | dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; | 41 | dev->flags = IFF_BROADCAST|IFF_MULTICAST|IFF_NOARP; |
42 | } | 42 | } |
43 | EXPORT_SYMBOL(ltalk_setup); | 43 | |
44 | /** | ||
45 | * alloc_ltalkdev - Allocates and sets up an localtalk device | ||
46 | * @sizeof_priv: Size of additional driver-private structure to be allocated | ||
47 | * for this localtalk device | ||
48 | * | ||
49 | * Fill in the fields of the device structure with localtalk-generic | ||
50 | * values. Basically does everything except registering the device. | ||
51 | * | ||
52 | * Constructs a new net device, complete with a private data area of | ||
53 | * size @sizeof_priv. A 32-byte (not bit) alignment is enforced for | ||
54 | * this private data area. | ||
55 | */ | ||
56 | |||
57 | struct net_device *alloc_ltalkdev(int sizeof_priv) | ||
58 | { | ||
59 | return alloc_netdev(sizeof_priv, "lt%d", ltalk_setup); | ||
60 | } | ||
61 | EXPORT_SYMBOL(alloc_ltalkdev); | ||
diff --git a/net/core/dev.c b/net/core/dev.c index f5f005846fe1..d4d9e2680adb 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * 2 of the License, or (at your option) any later version. | 7 | * 2 of the License, or (at your option) any later version. |
8 | * | 8 | * |
9 | * Derived from the non IP parts of dev.c 1.0.19 | 9 | * Derived from the non IP parts of dev.c 1.0.19 |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * | 13 | * |
diff --git a/net/core/sock.c b/net/core/sock.c index 98171ddd7e7d..96e00b08698f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $ | 10 | * Version: $Id: sock.c,v 1.117 2002/02/01 22:01:03 davem Exp $ |
11 | * | 11 | * |
12 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 12 | * Authors: Ross Biro |
13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
14 | * Florian La Roche, <flla@stud.uni-sb.de> | 14 | * Florian La Roche, <flla@stud.uni-sb.de> |
15 | * Alan Cox, <A.Cox@swansea.ac.uk> | 15 | * Alan Cox, <A.Cox@swansea.ac.uk> |
@@ -635,7 +635,11 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | |||
635 | if (zero_it) { | 635 | if (zero_it) { |
636 | memset(sk, 0, prot->obj_size); | 636 | memset(sk, 0, prot->obj_size); |
637 | sk->sk_family = family; | 637 | sk->sk_family = family; |
638 | sk->sk_prot = prot; | 638 | /* |
639 | * See comment in struct sock definition to understand | ||
640 | * why we need sk_prot_creator -acme | ||
641 | */ | ||
642 | sk->sk_prot = sk->sk_prot_creator = prot; | ||
639 | sock_lock_init(sk); | 643 | sock_lock_init(sk); |
640 | } | 644 | } |
641 | 645 | ||
@@ -654,7 +658,7 @@ struct sock *sk_alloc(int family, int priority, struct proto *prot, int zero_it) | |||
654 | void sk_free(struct sock *sk) | 658 | void sk_free(struct sock *sk) |
655 | { | 659 | { |
656 | struct sk_filter *filter; | 660 | struct sk_filter *filter; |
657 | struct module *owner = sk->sk_prot->owner; | 661 | struct module *owner = sk->sk_prot_creator->owner; |
658 | 662 | ||
659 | if (sk->sk_destruct) | 663 | if (sk->sk_destruct) |
660 | sk->sk_destruct(sk); | 664 | sk->sk_destruct(sk); |
@@ -672,8 +676,8 @@ void sk_free(struct sock *sk) | |||
672 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); | 676 | __FUNCTION__, atomic_read(&sk->sk_omem_alloc)); |
673 | 677 | ||
674 | security_sk_free(sk); | 678 | security_sk_free(sk); |
675 | if (sk->sk_prot->slab != NULL) | 679 | if (sk->sk_prot_creator->slab != NULL) |
676 | kmem_cache_free(sk->sk_prot->slab, sk); | 680 | kmem_cache_free(sk->sk_prot_creator->slab, sk); |
677 | else | 681 | else |
678 | kfree(sk); | 682 | kfree(sk); |
679 | module_put(owner); | 683 | module_put(owner); |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index e6e23eb14428..ee7bf46eb78a 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -1426,7 +1426,7 @@ static struct rtnetlink_link dnet_rtnetlink_table[RTM_NR_MSGTYPES] = | |||
1426 | [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, | 1426 | [RTM_GETRULE - RTM_BASE] = { .dumpit = dn_fib_dump_rules, }, |
1427 | #else | 1427 | #else |
1428 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, | 1428 | [RTM_GETROUTE - RTM_BASE] = { .doit = dn_cache_getroute, |
1429 | .dumpit = dn_cache_dump, | 1429 | .dumpit = dn_cache_dump, }, |
1430 | #endif | 1430 | #endif |
1431 | 1431 | ||
1432 | }; | 1432 | }; |
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c index 16c4234cbe12..6617ea47d365 100644 --- a/net/ethernet/eth.c +++ b/net/ethernet/eth.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: @(#)eth.c 1.0.7 05/25/93 | 8 | * Version: @(#)eth.c 1.0.7 05/25/93 |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Florian La Roche, <rzsfl@rz.uni-sb.de> | 13 | * Florian La Roche, <rzsfl@rz.uni-sb.de> |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index cdad47642ae7..b3cb49ce5fad 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $ | 8 | * Version: $Id: af_inet.c,v 1.137 2002/02/01 22:01:03 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Florian La Roche, <flla@stud.uni-sb.de> | 12 | * Florian La Roche, <flla@stud.uni-sb.de> |
13 | * Alan Cox, <A.Cox@swansea.ac.uk> | 13 | * Alan Cox, <A.Cox@swansea.ac.uk> |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index abbc6d5c183e..3cc96730c4ed 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * Derived from the IP parts of dev.c 1.0.19 | 11 | * Derived from the IP parts of dev.c 1.0.19 |
12 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 12 | * Authors: Ross Biro |
13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 13 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
14 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 14 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
15 | * | 15 | * |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index a0d0833034be..4e47a2658c7c 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $ | 8 | * Version: $Id: ip_input.c,v 1.55 2002/01/12 07:39:45 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Donald Becker, <becker@super.org> | 12 | * Donald Becker, <becker@super.org> |
13 | * Alan Cox, <Alan.Cox@linux.org> | 13 | * Alan Cox, <Alan.Cox@linux.org> |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 24fe3e00b42b..760dc8238d65 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $ | 8 | * Version: $Id: ip_output.c,v 1.100 2002/02/01 22:01:03 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Donald Becker, <becker@super.org> | 12 | * Donald Becker, <becker@super.org> |
13 | * Alan Cox, <Alan.Cox@linux.org> | 13 | * Alan Cox, <Alan.Cox@linux.org> |
@@ -490,6 +490,14 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*)) | |||
490 | /* Partially cloned skb? */ | 490 | /* Partially cloned skb? */ |
491 | if (skb_shared(frag)) | 491 | if (skb_shared(frag)) |
492 | goto slow_path; | 492 | goto slow_path; |
493 | |||
494 | BUG_ON(frag->sk); | ||
495 | if (skb->sk) { | ||
496 | sock_hold(skb->sk); | ||
497 | frag->sk = skb->sk; | ||
498 | frag->destructor = sock_wfree; | ||
499 | skb->truesize -= frag->truesize; | ||
500 | } | ||
493 | } | 501 | } |
494 | 502 | ||
495 | /* Everything is OK. Generate! */ | 503 | /* Everything is OK. Generate! */ |
diff --git a/net/ipv4/ipvs/ip_vs_xmit.c b/net/ipv4/ipvs/ip_vs_xmit.c index faa6176bbeb1..de21da00057f 100644 --- a/net/ipv4/ipvs/ip_vs_xmit.c +++ b/net/ipv4/ipvs/ip_vs_xmit.c | |||
@@ -508,7 +508,6 @@ ip_vs_icmp_xmit(struct sk_buff *skb, struct ip_vs_conn *cp, | |||
508 | rc = NF_ACCEPT; | 508 | rc = NF_ACCEPT; |
509 | /* do not touch skb anymore */ | 509 | /* do not touch skb anymore */ |
510 | atomic_inc(&cp->in_pkts); | 510 | atomic_inc(&cp->in_pkts); |
511 | __ip_vs_conn_put(cp); | ||
512 | goto out; | 511 | goto out; |
513 | } | 512 | } |
514 | 513 | ||
diff --git a/net/ipv4/multipath_wrandom.c b/net/ipv4/multipath_wrandom.c index 10b23e1bece6..c3d2ca1a6781 100644 --- a/net/ipv4/multipath_wrandom.c +++ b/net/ipv4/multipath_wrandom.c | |||
@@ -172,7 +172,7 @@ static void wrandom_select_route(const struct flowi *flp, | |||
172 | multipath_comparekeys(&rt->fl, flp)) { | 172 | multipath_comparekeys(&rt->fl, flp)) { |
173 | struct multipath_candidate* mpc = | 173 | struct multipath_candidate* mpc = |
174 | (struct multipath_candidate*) | 174 | (struct multipath_candidate*) |
175 | kmalloc(size_mpc, GFP_KERNEL); | 175 | kmalloc(size_mpc, GFP_ATOMIC); |
176 | 176 | ||
177 | if (!mpc) | 177 | if (!mpc) |
178 | return; | 178 | return; |
@@ -244,7 +244,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
244 | if (!target_route) { | 244 | if (!target_route) { |
245 | const size_t size_rt = sizeof(struct multipath_route); | 245 | const size_t size_rt = sizeof(struct multipath_route); |
246 | target_route = (struct multipath_route *) | 246 | target_route = (struct multipath_route *) |
247 | kmalloc(size_rt, GFP_KERNEL); | 247 | kmalloc(size_rt, GFP_ATOMIC); |
248 | 248 | ||
249 | target_route->gw = nh->nh_gw; | 249 | target_route->gw = nh->nh_gw; |
250 | target_route->oif = nh->nh_oif; | 250 | target_route->oif = nh->nh_oif; |
@@ -265,7 +265,7 @@ static void wrandom_set_nhinfo(__u32 network, | |||
265 | if (!target_dest) { | 265 | if (!target_dest) { |
266 | const size_t size_dst = sizeof(struct multipath_dest); | 266 | const size_t size_dst = sizeof(struct multipath_dest); |
267 | target_dest = (struct multipath_dest*) | 267 | target_dest = (struct multipath_dest*) |
268 | kmalloc(size_dst, GFP_KERNEL); | 268 | kmalloc(size_dst, GFP_ATOMIC); |
269 | 269 | ||
270 | target_dest->nh_info = nh; | 270 | target_dest->nh_info = nh; |
271 | target_dest->network = network; | 271 | target_dest->network = network; |
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index 28d9425d5c39..09e824622977 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c | |||
@@ -940,37 +940,25 @@ void ip_ct_refresh_acct(struct ip_conntrack *ct, | |||
940 | struct sk_buff * | 940 | struct sk_buff * |
941 | ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) | 941 | ip_ct_gather_frags(struct sk_buff *skb, u_int32_t user) |
942 | { | 942 | { |
943 | struct sock *sk = skb->sk; | ||
944 | #ifdef CONFIG_NETFILTER_DEBUG | 943 | #ifdef CONFIG_NETFILTER_DEBUG |
945 | unsigned int olddebug = skb->nf_debug; | 944 | unsigned int olddebug = skb->nf_debug; |
946 | #endif | 945 | #endif |
947 | 946 | ||
948 | if (sk) { | 947 | skb_orphan(skb); |
949 | sock_hold(sk); | ||
950 | skb_orphan(skb); | ||
951 | } | ||
952 | 948 | ||
953 | local_bh_disable(); | 949 | local_bh_disable(); |
954 | skb = ip_defrag(skb, user); | 950 | skb = ip_defrag(skb, user); |
955 | local_bh_enable(); | 951 | local_bh_enable(); |
956 | 952 | ||
957 | if (!skb) { | 953 | if (skb) { |
958 | if (sk) | 954 | ip_send_check(skb->nh.iph); |
959 | sock_put(sk); | 955 | skb->nfcache |= NFC_ALTERED; |
960 | return skb; | ||
961 | } | ||
962 | |||
963 | if (sk) { | ||
964 | skb_set_owner_w(skb, sk); | ||
965 | sock_put(sk); | ||
966 | } | ||
967 | |||
968 | ip_send_check(skb->nh.iph); | ||
969 | skb->nfcache |= NFC_ALTERED; | ||
970 | #ifdef CONFIG_NETFILTER_DEBUG | 956 | #ifdef CONFIG_NETFILTER_DEBUG |
971 | /* Packet path as if nothing had happened. */ | 957 | /* Packet path as if nothing had happened. */ |
972 | skb->nf_debug = olddebug; | 958 | skb->nf_debug = olddebug; |
973 | #endif | 959 | #endif |
960 | } | ||
961 | |||
974 | return skb; | 962 | return skb; |
975 | } | 963 | } |
976 | 964 | ||
diff --git a/net/ipv4/protocol.c b/net/ipv4/protocol.c index 90a587cacaa4..0db405a869f2 100644 --- a/net/ipv4/protocol.c +++ b/net/ipv4/protocol.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $ | 8 | * Version: $Id: protocol.c,v 1.14 2001/05/18 02:25:49 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * Fixes: | 13 | * Fixes: |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 93624a32eb9a..5b1ec586bae6 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: raw.c,v 1.64 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * | 12 | * |
13 | * Fixes: | 13 | * Fixes: |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 199311746932..a682d28e247b 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ | 8 | * Version: $Id: route.c,v 1.103 2002/01/12 07:44:09 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
13 | * Linus Torvalds, <Linus.Torvalds@helsinki.fi> | 13 | * Linus Torvalds, <Linus.Torvalds@helsinki.fi> |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 5cff56af7855..a037bafcba3c 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: tcp.c,v 1.216 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6984042c0927..79835a67a274 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: tcp_input.c,v 1.243 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index fd70509f0d53..eea1a17a9ac2 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: tcp_minisocks.c,v 1.15 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a12df6979ffd..fa24e7ae1f40 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: tcp_output.c,v 1.146 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 85b279f1e935..799ebe061e2c 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: tcp_timer.c,v 1.88 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> | 12 | * Mark Evans, <evansmp@uhura.aston.ac.uk> |
13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> | 13 | * Corey Minyard <wf-rch!minyard@relay.EU.net> |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8a213238f287..4a6952e3fee9 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $ | 8 | * Version: $Id: udp.c,v 1.102 2002/02/01 22:01:04 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> | 12 | * Arnt Gulbrandsen, <agulbra@nvg.unit.no> |
13 | * Alan Cox, <Alan.Cox@linux.org> | 13 | * Alan Cox, <Alan.Cox@linux.org> |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0f0711417c9d..b78a53586804 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -552,13 +552,17 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
552 | skb_headroom(frag) < hlen) | 552 | skb_headroom(frag) < hlen) |
553 | goto slow_path; | 553 | goto slow_path; |
554 | 554 | ||
555 | /* Correct socket ownership. */ | ||
556 | if (frag->sk == NULL) | ||
557 | goto slow_path; | ||
558 | |||
559 | /* Partially cloned skb? */ | 555 | /* Partially cloned skb? */ |
560 | if (skb_shared(frag)) | 556 | if (skb_shared(frag)) |
561 | goto slow_path; | 557 | goto slow_path; |
558 | |||
559 | BUG_ON(frag->sk); | ||
560 | if (skb->sk) { | ||
561 | sock_hold(skb->sk); | ||
562 | frag->sk = skb->sk; | ||
563 | frag->destructor = sock_wfree; | ||
564 | skb->truesize -= frag->truesize; | ||
565 | } | ||
562 | } | 566 | } |
563 | 567 | ||
564 | err = 0; | 568 | err = 0; |
@@ -1116,12 +1120,10 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1116 | tail_skb = &(tmp_skb->next); | 1120 | tail_skb = &(tmp_skb->next); |
1117 | skb->len += tmp_skb->len; | 1121 | skb->len += tmp_skb->len; |
1118 | skb->data_len += tmp_skb->len; | 1122 | skb->data_len += tmp_skb->len; |
1119 | #if 0 /* Logically correct, but useless work, ip_fragment() will have to undo */ | ||
1120 | skb->truesize += tmp_skb->truesize; | 1123 | skb->truesize += tmp_skb->truesize; |
1121 | __sock_put(tmp_skb->sk); | 1124 | __sock_put(tmp_skb->sk); |
1122 | tmp_skb->destructor = NULL; | 1125 | tmp_skb->destructor = NULL; |
1123 | tmp_skb->sk = NULL; | 1126 | tmp_skb->sk = NULL; |
1124 | #endif | ||
1125 | } | 1127 | } |
1126 | 1128 | ||
1127 | ipv6_addr_copy(final_dst, &fl->fl6_dst); | 1129 | ipv6_addr_copy(final_dst, &fl->fl6_dst); |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 733bf52cef3e..e41ce458c2a9 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -735,11 +735,15 @@ static inline int do_one_broadcast(struct sock *sk, | |||
735 | 735 | ||
736 | sock_hold(sk); | 736 | sock_hold(sk); |
737 | if (p->skb2 == NULL) { | 737 | if (p->skb2 == NULL) { |
738 | if (atomic_read(&p->skb->users) != 1) { | 738 | if (skb_shared(p->skb)) { |
739 | p->skb2 = skb_clone(p->skb, p->allocation); | 739 | p->skb2 = skb_clone(p->skb, p->allocation); |
740 | } else { | 740 | } else { |
741 | p->skb2 = p->skb; | 741 | p->skb2 = skb_get(p->skb); |
742 | atomic_inc(&p->skb->users); | 742 | /* |
743 | * skb ownership may have been set when | ||
744 | * delivered to a previous socket. | ||
745 | */ | ||
746 | skb_orphan(p->skb2); | ||
743 | } | 747 | } |
744 | } | 748 | } |
745 | if (p->skb2 == NULL) { | 749 | if (p->skb2 == NULL) { |
@@ -785,11 +789,12 @@ int netlink_broadcast(struct sock *ssk, struct sk_buff *skb, u32 pid, | |||
785 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) | 789 | sk_for_each_bound(sk, node, &nl_table[ssk->sk_protocol].mc_list) |
786 | do_one_broadcast(sk, &info); | 790 | do_one_broadcast(sk, &info); |
787 | 791 | ||
792 | kfree_skb(skb); | ||
793 | |||
788 | netlink_unlock_table(); | 794 | netlink_unlock_table(); |
789 | 795 | ||
790 | if (info.skb2) | 796 | if (info.skb2) |
791 | kfree_skb(info.skb2); | 797 | kfree_skb(info.skb2); |
792 | kfree_skb(skb); | ||
793 | 798 | ||
794 | if (info.delivered) { | 799 | if (info.delivered) { |
795 | if (info.congested && (allocation & __GFP_WAIT)) | 800 | if (info.congested && (allocation & __GFP_WAIT)) |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 64acea0adaae..0269616e75a1 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -7,7 +7,7 @@ | |||
7 | * | 7 | * |
8 | * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $ | 8 | * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $ |
9 | * | 9 | * |
10 | * Authors: Ross Biro, <bir7@leland.Stanford.Edu> | 10 | * Authors: Ross Biro |
11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 11 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> | 12 | * Alan Cox, <gw4pts@gw4pts.ampr.org> |
13 | * | 13 | * |
diff --git a/net/socket.c b/net/socket.c index 2cd44990d8d3..cec0cb38b9ce 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * Version: @(#)socket.c 1.1.93 18/02/95 | 4 | * Version: @(#)socket.c 1.1.93 18/02/95 |
5 | * | 5 | * |
6 | * Authors: Orest Zborowski, <obz@Kodak.COM> | 6 | * Authors: Orest Zborowski, <obz@Kodak.COM> |
7 | * Ross Biro, <bir7@leland.Stanford.Edu> | 7 | * Ross Biro |
8 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> | 8 | * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> |
9 | * | 9 | * |
10 | * Fixes: | 10 | * Fixes: |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c478fc8db776..c420eba4876b 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -770,33 +770,12 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
770 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); | 770 | err = path_lookup(sunaddr->sun_path, LOOKUP_PARENT, &nd); |
771 | if (err) | 771 | if (err) |
772 | goto out_mknod_parent; | 772 | goto out_mknod_parent; |
773 | /* | 773 | |
774 | * Yucky last component or no last component at all? | 774 | dentry = lookup_create(&nd, 0); |
775 | * (foo/., foo/.., /////) | ||
776 | */ | ||
777 | err = -EEXIST; | ||
778 | if (nd.last_type != LAST_NORM) | ||
779 | goto out_mknod; | ||
780 | /* | ||
781 | * Lock the directory. | ||
782 | */ | ||
783 | down(&nd.dentry->d_inode->i_sem); | ||
784 | /* | ||
785 | * Do the final lookup. | ||
786 | */ | ||
787 | dentry = lookup_hash(&nd.last, nd.dentry); | ||
788 | err = PTR_ERR(dentry); | 775 | err = PTR_ERR(dentry); |
789 | if (IS_ERR(dentry)) | 776 | if (IS_ERR(dentry)) |
790 | goto out_mknod_unlock; | 777 | goto out_mknod_unlock; |
791 | err = -ENOENT; | 778 | |
792 | /* | ||
793 | * Special case - lookup gave negative, but... we had foo/bar/ | ||
794 | * From the vfs_mknod() POV we just have a negative dentry - | ||
795 | * all is fine. Let's be bastards - you had / on the end, you've | ||
796 | * been asking for (non-existent) directory. -ENOENT for you. | ||
797 | */ | ||
798 | if (nd.last.name[nd.last.len] && !dentry->d_inode) | ||
799 | goto out_mknod_dput; | ||
800 | /* | 779 | /* |
801 | * All right, let's create it. | 780 | * All right, let's create it. |
802 | */ | 781 | */ |
@@ -845,7 +824,6 @@ out_mknod_dput: | |||
845 | dput(dentry); | 824 | dput(dentry); |
846 | out_mknod_unlock: | 825 | out_mknod_unlock: |
847 | up(&nd.dentry->d_inode->i_sem); | 826 | up(&nd.dentry->d_inode->i_sem); |
848 | out_mknod: | ||
849 | path_release(&nd); | 827 | path_release(&nd); |
850 | out_mknod_parent: | 828 | out_mknod_parent: |
851 | if (err==-EEXIST) | 829 | if (err==-EEXIST) |
diff --git a/net/xfrm/xfrm_algo.c b/net/xfrm/xfrm_algo.c index 080aae243ce0..2f4531fcaca2 100644 --- a/net/xfrm/xfrm_algo.c +++ b/net/xfrm/xfrm_algo.c | |||
@@ -698,7 +698,7 @@ int skb_cow_data(struct sk_buff *skb, int tailbits, struct sk_buff **trailer) | |||
698 | return -ENOMEM; | 698 | return -ENOMEM; |
699 | 699 | ||
700 | if (skb1->sk) | 700 | if (skb1->sk) |
701 | skb_set_owner_w(skb, skb1->sk); | 701 | skb_set_owner_w(skb2, skb1->sk); |
702 | 702 | ||
703 | /* Looking around. Are we still alive? | 703 | /* Looking around. Are we still alive? |
704 | * OK, link new skb, drop old one */ | 704 | * OK, link new skb, drop old one */ |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 5ddda2c98af9..97509011c274 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -34,14 +34,21 @@ static int verify_one_alg(struct rtattr **xfrma, enum xfrm_attr_type_t type) | |||
34 | { | 34 | { |
35 | struct rtattr *rt = xfrma[type - 1]; | 35 | struct rtattr *rt = xfrma[type - 1]; |
36 | struct xfrm_algo *algp; | 36 | struct xfrm_algo *algp; |
37 | int len; | ||
37 | 38 | ||
38 | if (!rt) | 39 | if (!rt) |
39 | return 0; | 40 | return 0; |
40 | 41 | ||
41 | if ((rt->rta_len - sizeof(*rt)) < sizeof(*algp)) | 42 | len = (rt->rta_len - sizeof(*rt)) - sizeof(*algp); |
43 | if (len < 0) | ||
42 | return -EINVAL; | 44 | return -EINVAL; |
43 | 45 | ||
44 | algp = RTA_DATA(rt); | 46 | algp = RTA_DATA(rt); |
47 | |||
48 | len -= (algp->alg_key_len + 7U) / 8; | ||
49 | if (len < 0) | ||
50 | return -EINVAL; | ||
51 | |||
45 | switch (type) { | 52 | switch (type) { |
46 | case XFRMA_ALG_AUTH: | 53 | case XFRMA_ALG_AUTH: |
47 | if (!algp->alg_key_len && | 54 | if (!algp->alg_key_len && |
@@ -162,6 +169,7 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, | |||
162 | struct rtattr *rta = u_arg; | 169 | struct rtattr *rta = u_arg; |
163 | struct xfrm_algo *p, *ualg; | 170 | struct xfrm_algo *p, *ualg; |
164 | struct xfrm_algo_desc *algo; | 171 | struct xfrm_algo_desc *algo; |
172 | int len; | ||
165 | 173 | ||
166 | if (!rta) | 174 | if (!rta) |
167 | return 0; | 175 | return 0; |
@@ -173,11 +181,12 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props, | |||
173 | return -ENOSYS; | 181 | return -ENOSYS; |
174 | *props = algo->desc.sadb_alg_id; | 182 | *props = algo->desc.sadb_alg_id; |
175 | 183 | ||
176 | p = kmalloc(sizeof(*ualg) + ualg->alg_key_len, GFP_KERNEL); | 184 | len = sizeof(*ualg) + (ualg->alg_key_len + 7U) / 8; |
185 | p = kmalloc(len, GFP_KERNEL); | ||
177 | if (!p) | 186 | if (!p) |
178 | return -ENOMEM; | 187 | return -ENOMEM; |
179 | 188 | ||
180 | memcpy(p, ualg, sizeof(*ualg) + ualg->alg_key_len); | 189 | memcpy(p, ualg, len); |
181 | *algpp = p; | 190 | *algpp = p; |
182 | return 0; | 191 | return 0; |
183 | } | 192 | } |
diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index fe11df83d1fc..d3d2e5341051 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c | |||
@@ -67,7 +67,7 @@ struct sym_entry { | |||
67 | 67 | ||
68 | static struct sym_entry *table; | 68 | static struct sym_entry *table; |
69 | static int size, cnt; | 69 | static int size, cnt; |
70 | static unsigned long long _stext, _etext, _sinittext, _einittext; | 70 | static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; |
71 | static int all_symbols = 0; | 71 | static int all_symbols = 0; |
72 | static char symbol_prefix_char = '\0'; | 72 | static char symbol_prefix_char = '\0'; |
73 | 73 | ||
@@ -139,6 +139,10 @@ read_symbol(FILE *in, struct sym_entry *s) | |||
139 | _sinittext = s->addr; | 139 | _sinittext = s->addr; |
140 | else if (strcmp(sym, "_einittext") == 0) | 140 | else if (strcmp(sym, "_einittext") == 0) |
141 | _einittext = s->addr; | 141 | _einittext = s->addr; |
142 | else if (strcmp(sym, "_sextratext") == 0) | ||
143 | _sextratext = s->addr; | ||
144 | else if (strcmp(sym, "_eextratext") == 0) | ||
145 | _eextratext = s->addr; | ||
142 | else if (toupper(s->type) == 'A') | 146 | else if (toupper(s->type) == 'A') |
143 | { | 147 | { |
144 | /* Keep these useful absolute symbols */ | 148 | /* Keep these useful absolute symbols */ |
@@ -194,16 +198,18 @@ symbol_valid(struct sym_entry *s) | |||
194 | * and inittext sections are discarded */ | 198 | * and inittext sections are discarded */ |
195 | if (!all_symbols) { | 199 | if (!all_symbols) { |
196 | if ((s->addr < _stext || s->addr > _etext) | 200 | if ((s->addr < _stext || s->addr > _etext) |
197 | && (s->addr < _sinittext || s->addr > _einittext)) | 201 | && (s->addr < _sinittext || s->addr > _einittext) |
202 | && (s->addr < _sextratext || s->addr > _eextratext)) | ||
198 | return 0; | 203 | return 0; |
199 | /* Corner case. Discard any symbols with the same value as | 204 | /* Corner case. Discard any symbols with the same value as |
200 | * _etext or _einittext, they can move between pass 1 and 2 | 205 | * _etext _einittext or _eextratext; they can move between pass |
201 | * when the kallsyms data is added. If these symbols move then | 206 | * 1 and 2 when the kallsyms data are added. If these symbols |
202 | * they may get dropped in pass 2, which breaks the kallsyms | 207 | * move then they may get dropped in pass 2, which breaks the |
203 | * rules. | 208 | * kallsyms rules. |
204 | */ | 209 | */ |
205 | if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) || | 210 | if ((s->addr == _etext && strcmp(s->sym + offset, "_etext")) || |
206 | (s->addr == _einittext && strcmp(s->sym + offset, "_einittext"))) | 211 | (s->addr == _einittext && strcmp(s->sym + offset, "_einittext")) || |
212 | (s->addr == _eextratext && strcmp(s->sym + offset, "_eextratext"))) | ||
207 | return 0; | 213 | return 0; |
208 | } | 214 | } |
209 | 215 | ||
diff --git a/scripts/kconfig/Makefile b/scripts/kconfig/Makefile index 5a5ddc40f36c..09abb891d11f 100644 --- a/scripts/kconfig/Makefile +++ b/scripts/kconfig/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Kernel configuration targets | 2 | # Kernel configuration targets |
3 | # These targets are used from top-level makefile | 3 | # These targets are used from top-level makefile |
4 | 4 | ||
5 | .PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig | 5 | .PHONY: oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config |
6 | 6 | ||
7 | xconfig: $(obj)/qconf | 7 | xconfig: $(obj)/qconf |
8 | $< arch/$(ARCH)/Kconfig | 8 | $< arch/$(ARCH)/Kconfig |
@@ -23,6 +23,13 @@ oldconfig: $(obj)/conf | |||
23 | silentoldconfig: $(obj)/conf | 23 | silentoldconfig: $(obj)/conf |
24 | $< -s arch/$(ARCH)/Kconfig | 24 | $< -s arch/$(ARCH)/Kconfig |
25 | 25 | ||
26 | update-po-config: $(obj)/kxgettext | ||
27 | xgettext --default-domain=linux \ | ||
28 | --add-comments --keyword=_ --keyword=N_ \ | ||
29 | --files-from=scripts/kconfig/POTFILES.in \ | ||
30 | -o scripts/kconfig/linux.pot | ||
31 | scripts/kconfig/kxgettext arch/$(ARCH)/Kconfig >> scripts/kconfig/linux.pot | ||
32 | |||
26 | .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig | 33 | .PHONY: randconfig allyesconfig allnoconfig allmodconfig defconfig |
27 | 34 | ||
28 | randconfig: $(obj)/conf | 35 | randconfig: $(obj)/conf |
@@ -72,9 +79,10 @@ help: | |||
72 | # Based on GTK which needs to be installed to compile it | 79 | # Based on GTK which needs to be installed to compile it |
73 | # object files used by all kconfig flavours | 80 | # object files used by all kconfig flavours |
74 | 81 | ||
75 | hostprogs-y := conf mconf qconf gconf | 82 | hostprogs-y := conf mconf qconf gconf kxgettext |
76 | conf-objs := conf.o zconf.tab.o | 83 | conf-objs := conf.o zconf.tab.o |
77 | mconf-objs := mconf.o zconf.tab.o | 84 | mconf-objs := mconf.o zconf.tab.o |
85 | kxgettext-objs := kxgettext.o zconf.tab.o | ||
78 | 86 | ||
79 | ifeq ($(MAKECMDGOALS),xconfig) | 87 | ifeq ($(MAKECMDGOALS),xconfig) |
80 | qconf-target := 1 | 88 | qconf-target := 1 |
@@ -107,7 +115,7 @@ HOSTLOADLIBES_gconf = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --libs` | |||
107 | HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ | 115 | HOSTCFLAGS_gconf.o = `pkg-config gtk+-2.0 gmodule-2.0 libglade-2.0 --cflags` \ |
108 | -D LKC_DIRECT_LINK | 116 | -D LKC_DIRECT_LINK |
109 | 117 | ||
110 | $(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o: $(obj)/zconf.tab.h | 118 | $(obj)/conf.o $(obj)/mconf.o $(obj)/qconf.o $(obj)/gconf.o $(obj)/kxgettext: $(obj)/zconf.tab.h |
111 | 119 | ||
112 | $(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped | 120 | $(obj)/zconf.tab.h: $(src)/zconf.tab.h_shipped |
113 | $(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped | 121 | $(obj)/zconf.tab.c: $(src)/zconf.tab.c_shipped |
diff --git a/scripts/kconfig/POTFILES.in b/scripts/kconfig/POTFILES.in new file mode 100644 index 000000000000..cc94e46a79e8 --- /dev/null +++ b/scripts/kconfig/POTFILES.in | |||
@@ -0,0 +1,5 @@ | |||
1 | scripts/kconfig/mconf.c | ||
2 | scripts/kconfig/conf.c | ||
3 | scripts/kconfig/confdata.c | ||
4 | scripts/kconfig/gconf.c | ||
5 | scripts/kconfig/qconf.cc | ||
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index a494d1aeb9f9..70e7264c6942 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -34,7 +34,7 @@ static int conf_cnt; | |||
34 | static signed char line[128]; | 34 | static signed char line[128]; |
35 | static struct menu *rootEntry; | 35 | static struct menu *rootEntry; |
36 | 36 | ||
37 | static char nohelp_text[] = "Sorry, no help available for this option yet.\n"; | 37 | static char nohelp_text[] = N_("Sorry, no help available for this option yet.\n"); |
38 | 38 | ||
39 | static void strip(signed char *str) | 39 | static void strip(signed char *str) |
40 | { | 40 | { |
@@ -56,9 +56,9 @@ static void strip(signed char *str) | |||
56 | static void check_stdin(void) | 56 | static void check_stdin(void) |
57 | { | 57 | { |
58 | if (!valid_stdin && input_mode == ask_silent) { | 58 | if (!valid_stdin && input_mode == ask_silent) { |
59 | printf("aborted!\n\n"); | 59 | printf(_("aborted!\n\n")); |
60 | printf("Console input/output is redirected. "); | 60 | printf(_("Console input/output is redirected. ")); |
61 | printf("Run 'make oldconfig' to update configuration.\n\n"); | 61 | printf(_("Run 'make oldconfig' to update configuration.\n\n")); |
62 | exit(1); | 62 | exit(1); |
63 | } | 63 | } |
64 | } | 64 | } |
@@ -470,7 +470,7 @@ static void check_conf(struct menu *menu) | |||
470 | if (sym) { | 470 | if (sym) { |
471 | if (sym_is_changable(sym) && !sym_has_value(sym)) { | 471 | if (sym_is_changable(sym) && !sym_has_value(sym)) { |
472 | if (!conf_cnt++) | 472 | if (!conf_cnt++) |
473 | printf("*\n* Restart config...\n*\n"); | 473 | printf(_("*\n* Restart config...\n*\n")); |
474 | rootEntry = menu_get_parent_menu(menu); | 474 | rootEntry = menu_get_parent_menu(menu); |
475 | conf(rootEntry); | 475 | conf(rootEntry); |
476 | } | 476 | } |
@@ -504,7 +504,7 @@ int main(int ac, char **av) | |||
504 | input_mode = set_default; | 504 | input_mode = set_default; |
505 | defconfig_file = av[i++]; | 505 | defconfig_file = av[i++]; |
506 | if (!defconfig_file) { | 506 | if (!defconfig_file) { |
507 | printf("%s: No default config file specified\n", | 507 | printf(_("%s: No default config file specified\n"), |
508 | av[0]); | 508 | av[0]); |
509 | exit(1); | 509 | exit(1); |
510 | } | 510 | } |
@@ -530,7 +530,7 @@ int main(int ac, char **av) | |||
530 | } | 530 | } |
531 | name = av[i]; | 531 | name = av[i]; |
532 | if (!name) { | 532 | if (!name) { |
533 | printf("%s: Kconfig file missing\n", av[0]); | 533 | printf(_("%s: Kconfig file missing\n"), av[0]); |
534 | } | 534 | } |
535 | conf_parse(name); | 535 | conf_parse(name); |
536 | //zconfdump(stdout); | 536 | //zconfdump(stdout); |
@@ -547,12 +547,12 @@ int main(int ac, char **av) | |||
547 | break; | 547 | break; |
548 | case ask_silent: | 548 | case ask_silent: |
549 | if (stat(".config", &tmpstat)) { | 549 | if (stat(".config", &tmpstat)) { |
550 | printf("***\n" | 550 | printf(_("***\n" |
551 | "*** You have not yet configured your kernel!\n" | 551 | "*** You have not yet configured your kernel!\n" |
552 | "***\n" | 552 | "***\n" |
553 | "*** Please run some configurator (e.g. \"make oldconfig\" or\n" | 553 | "*** Please run some configurator (e.g. \"make oldconfig\" or\n" |
554 | "*** \"make menuconfig\" or \"make xconfig\").\n" | 554 | "*** \"make menuconfig\" or \"make xconfig\").\n" |
555 | "***\n"); | 555 | "***\n")); |
556 | exit(1); | 556 | exit(1); |
557 | } | 557 | } |
558 | case ask_all: | 558 | case ask_all: |
@@ -576,7 +576,7 @@ int main(int ac, char **av) | |||
576 | check_conf(&rootmenu); | 576 | check_conf(&rootmenu); |
577 | } while (conf_cnt); | 577 | } while (conf_cnt); |
578 | if (conf_write(NULL)) { | 578 | if (conf_write(NULL)) { |
579 | fprintf(stderr, "\n*** Error during writing of the kernel configuration.\n\n"); | 579 | fprintf(stderr, _("\n*** Error during writing of the kernel configuration.\n\n")); |
580 | return 1; | 580 | return 1; |
581 | } | 581 | } |
582 | return 0; | 582 | return 0; |
diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 1e82ae390a69..2755c459d780 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c | |||
@@ -88,9 +88,9 @@ int conf_read(const char *name) | |||
88 | name = conf_expand_value(name); | 88 | name = conf_expand_value(name); |
89 | in = zconf_fopen(name); | 89 | in = zconf_fopen(name); |
90 | if (in) { | 90 | if (in) { |
91 | printf("#\n" | 91 | printf(_("#\n" |
92 | "# using defaults found in %s\n" | 92 | "# using defaults found in %s\n" |
93 | "#\n", name); | 93 | "#\n"), name); |
94 | break; | 94 | break; |
95 | } | 95 | } |
96 | } | 96 | } |
@@ -312,11 +312,11 @@ int conf_write(const char *name) | |||
312 | if (env && *env) | 312 | if (env && *env) |
313 | use_timestamp = 0; | 313 | use_timestamp = 0; |
314 | 314 | ||
315 | fprintf(out, "#\n" | 315 | fprintf(out, _("#\n" |
316 | "# Automatically generated make config: don't edit\n" | 316 | "# Automatically generated make config: don't edit\n" |
317 | "# Linux kernel version: %s\n" | 317 | "# Linux kernel version: %s\n" |
318 | "%s%s" | 318 | "%s%s" |
319 | "#\n", | 319 | "#\n"), |
320 | sym_get_string_value(sym), | 320 | sym_get_string_value(sym), |
321 | use_timestamp ? "# " : "", | 321 | use_timestamp ? "# " : "", |
322 | use_timestamp ? ctime(&now) : ""); | 322 | use_timestamp ? ctime(&now) : ""); |
diff --git a/scripts/kconfig/gconf.c b/scripts/kconfig/gconf.c index 6fdbe6e3ce0d..ad6b12043874 100644 --- a/scripts/kconfig/gconf.c +++ b/scripts/kconfig/gconf.c | |||
@@ -41,7 +41,7 @@ static gboolean resizeable = FALSE; | |||
41 | static gboolean config_changed = FALSE; | 41 | static gboolean config_changed = FALSE; |
42 | 42 | ||
43 | static char nohelp_text[] = | 43 | static char nohelp_text[] = |
44 | "Sorry, no help available for this option yet.\n"; | 44 | N_("Sorry, no help available for this option yet.\n"); |
45 | 45 | ||
46 | GtkWidget *main_wnd = NULL; | 46 | GtkWidget *main_wnd = NULL; |
47 | GtkWidget *tree1_w = NULL; // left frame | 47 | GtkWidget *tree1_w = NULL; // left frame |
@@ -193,7 +193,7 @@ void init_main_window(const gchar * glade_file) | |||
193 | 193 | ||
194 | xml = glade_xml_new(glade_file, "window1", NULL); | 194 | xml = glade_xml_new(glade_file, "window1", NULL); |
195 | if (!xml) | 195 | if (!xml) |
196 | g_error("GUI loading failed !\n"); | 196 | g_error(_("GUI loading failed !\n")); |
197 | glade_xml_signal_autoconnect(xml); | 197 | glade_xml_signal_autoconnect(xml); |
198 | 198 | ||
199 | main_wnd = glade_xml_get_widget(xml, "window1"); | 199 | main_wnd = glade_xml_get_widget(xml, "window1"); |
@@ -275,7 +275,7 @@ void init_main_window(const gchar * glade_file) | |||
275 | /*"style", PANGO_STYLE_OBLIQUE, */ | 275 | /*"style", PANGO_STYLE_OBLIQUE, */ |
276 | NULL); | 276 | NULL); |
277 | 277 | ||
278 | sprintf(title, "Linux Kernel v%s Configuration", | 278 | sprintf(title, _("Linux Kernel v%s Configuration"), |
279 | getenv("KERNELRELEASE")); | 279 | getenv("KERNELRELEASE")); |
280 | gtk_window_set_title(GTK_WINDOW(main_wnd), title); | 280 | gtk_window_set_title(GTK_WINDOW(main_wnd), title); |
281 | 281 | ||
@@ -325,7 +325,7 @@ void init_left_tree(void) | |||
325 | 325 | ||
326 | column = gtk_tree_view_column_new(); | 326 | column = gtk_tree_view_column_new(); |
327 | gtk_tree_view_append_column(view, column); | 327 | gtk_tree_view_append_column(view, column); |
328 | gtk_tree_view_column_set_title(column, "Options"); | 328 | gtk_tree_view_column_set_title(column, _("Options")); |
329 | 329 | ||
330 | renderer = gtk_cell_renderer_toggle_new(); | 330 | renderer = gtk_cell_renderer_toggle_new(); |
331 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | 331 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), |
@@ -370,7 +370,7 @@ void init_right_tree(void) | |||
370 | 370 | ||
371 | column = gtk_tree_view_column_new(); | 371 | column = gtk_tree_view_column_new(); |
372 | gtk_tree_view_append_column(view, column); | 372 | gtk_tree_view_append_column(view, column); |
373 | gtk_tree_view_column_set_title(column, "Options"); | 373 | gtk_tree_view_column_set_title(column, _("Options")); |
374 | 374 | ||
375 | renderer = gtk_cell_renderer_pixbuf_new(); | 375 | renderer = gtk_cell_renderer_pixbuf_new(); |
376 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), | 376 | gtk_tree_view_column_pack_start(GTK_TREE_VIEW_COLUMN(column), |
@@ -401,7 +401,7 @@ void init_right_tree(void) | |||
401 | 401 | ||
402 | renderer = gtk_cell_renderer_text_new(); | 402 | renderer = gtk_cell_renderer_text_new(); |
403 | gtk_tree_view_insert_column_with_attributes(view, -1, | 403 | gtk_tree_view_insert_column_with_attributes(view, -1, |
404 | "Name", renderer, | 404 | _("Name"), renderer, |
405 | "text", COL_NAME, | 405 | "text", COL_NAME, |
406 | "foreground-gdk", | 406 | "foreground-gdk", |
407 | COL_COLOR, NULL); | 407 | COL_COLOR, NULL); |
@@ -425,7 +425,7 @@ void init_right_tree(void) | |||
425 | COL_COLOR, NULL); | 425 | COL_COLOR, NULL); |
426 | renderer = gtk_cell_renderer_text_new(); | 426 | renderer = gtk_cell_renderer_text_new(); |
427 | gtk_tree_view_insert_column_with_attributes(view, -1, | 427 | gtk_tree_view_insert_column_with_attributes(view, -1, |
428 | "Value", renderer, | 428 | _("Value"), renderer, |
429 | "text", COL_VALUE, | 429 | "text", COL_VALUE, |
430 | "editable", | 430 | "editable", |
431 | COL_EDIT, | 431 | COL_EDIT, |
@@ -466,15 +466,15 @@ static void text_insert_help(struct menu *menu) | |||
466 | GtkTextIter start, end; | 466 | GtkTextIter start, end; |
467 | const char *prompt = menu_get_prompt(menu); | 467 | const char *prompt = menu_get_prompt(menu); |
468 | gchar *name; | 468 | gchar *name; |
469 | const char *help = nohelp_text; | 469 | const char *help = _(nohelp_text); |
470 | 470 | ||
471 | if (!menu->sym) | 471 | if (!menu->sym) |
472 | help = ""; | 472 | help = ""; |
473 | else if (menu->sym->help) | 473 | else if (menu->sym->help) |
474 | help = menu->sym->help; | 474 | help = _(menu->sym->help); |
475 | 475 | ||
476 | if (menu->sym && menu->sym->name) | 476 | if (menu->sym && menu->sym->name) |
477 | name = g_strdup_printf(menu->sym->name); | 477 | name = g_strdup_printf(_(menu->sym->name)); |
478 | else | 478 | else |
479 | name = g_strdup(""); | 479 | name = g_strdup(""); |
480 | 480 | ||
@@ -530,7 +530,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, | |||
530 | if (config_changed == FALSE) | 530 | if (config_changed == FALSE) |
531 | return FALSE; | 531 | return FALSE; |
532 | 532 | ||
533 | dialog = gtk_dialog_new_with_buttons("Warning !", | 533 | dialog = gtk_dialog_new_with_buttons(_("Warning !"), |
534 | GTK_WINDOW(main_wnd), | 534 | GTK_WINDOW(main_wnd), |
535 | (GtkDialogFlags) | 535 | (GtkDialogFlags) |
536 | (GTK_DIALOG_MODAL | | 536 | (GTK_DIALOG_MODAL | |
@@ -544,7 +544,7 @@ gboolean on_window1_delete_event(GtkWidget * widget, GdkEvent * event, | |||
544 | gtk_dialog_set_default_response(GTK_DIALOG(dialog), | 544 | gtk_dialog_set_default_response(GTK_DIALOG(dialog), |
545 | GTK_RESPONSE_CANCEL); | 545 | GTK_RESPONSE_CANCEL); |
546 | 546 | ||
547 | label = gtk_label_new("\nSave configuration ?\n"); | 547 | label = gtk_label_new(_("\nSave configuration ?\n")); |
548 | gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); | 548 | gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), label); |
549 | gtk_widget_show(label); | 549 | gtk_widget_show(label); |
550 | 550 | ||
@@ -604,7 +604,7 @@ load_filename(GtkFileSelection * file_selector, gpointer user_data) | |||
604 | (user_data)); | 604 | (user_data)); |
605 | 605 | ||
606 | if (conf_read(fn)) | 606 | if (conf_read(fn)) |
607 | text_insert_msg("Error", "Unable to load configuration !"); | 607 | text_insert_msg(_("Error"), _("Unable to load configuration !")); |
608 | else | 608 | else |
609 | display_tree(&rootmenu); | 609 | display_tree(&rootmenu); |
610 | } | 610 | } |
@@ -613,7 +613,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
613 | { | 613 | { |
614 | GtkWidget *fs; | 614 | GtkWidget *fs; |
615 | 615 | ||
616 | fs = gtk_file_selection_new("Load file..."); | 616 | fs = gtk_file_selection_new(_("Load file...")); |
617 | g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | 617 | g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), |
618 | "clicked", | 618 | "clicked", |
619 | G_CALLBACK(load_filename), (gpointer) fs); | 619 | G_CALLBACK(load_filename), (gpointer) fs); |
@@ -632,7 +632,7 @@ void on_load1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
632 | void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data) | 632 | void on_save1_activate(GtkMenuItem * menuitem, gpointer user_data) |
633 | { | 633 | { |
634 | if (conf_write(NULL)) | 634 | if (conf_write(NULL)) |
635 | text_insert_msg("Error", "Unable to save configuration !"); | 635 | text_insert_msg(_("Error"), _("Unable to save configuration !")); |
636 | 636 | ||
637 | config_changed = FALSE; | 637 | config_changed = FALSE; |
638 | } | 638 | } |
@@ -647,7 +647,7 @@ store_filename(GtkFileSelection * file_selector, gpointer user_data) | |||
647 | (user_data)); | 647 | (user_data)); |
648 | 648 | ||
649 | if (conf_write(fn)) | 649 | if (conf_write(fn)) |
650 | text_insert_msg("Error", "Unable to save configuration !"); | 650 | text_insert_msg(_("Error"), _("Unable to save configuration !")); |
651 | 651 | ||
652 | gtk_widget_destroy(GTK_WIDGET(user_data)); | 652 | gtk_widget_destroy(GTK_WIDGET(user_data)); |
653 | } | 653 | } |
@@ -656,7 +656,7 @@ void on_save_as1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
656 | { | 656 | { |
657 | GtkWidget *fs; | 657 | GtkWidget *fs; |
658 | 658 | ||
659 | fs = gtk_file_selection_new("Save file as..."); | 659 | fs = gtk_file_selection_new(_("Save file as...")); |
660 | g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), | 660 | g_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(fs)->ok_button), |
661 | "clicked", | 661 | "clicked", |
662 | G_CALLBACK(store_filename), (gpointer) fs); | 662 | G_CALLBACK(store_filename), (gpointer) fs); |
@@ -740,7 +740,7 @@ on_show_debug_info1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
740 | void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | 740 | void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) |
741 | { | 741 | { |
742 | GtkWidget *dialog; | 742 | GtkWidget *dialog; |
743 | const gchar *intro_text = | 743 | const gchar *intro_text = _( |
744 | "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" | 744 | "Welcome to gkc, the GTK+ graphical kernel configuration tool\n" |
745 | "for Linux.\n" | 745 | "for Linux.\n" |
746 | "For each option, a blank box indicates the feature is disabled, a\n" | 746 | "For each option, a blank box indicates the feature is disabled, a\n" |
@@ -756,7 +756,7 @@ void on_introduction1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
756 | "option.\n" | 756 | "option.\n" |
757 | "\n" | 757 | "\n" |
758 | "Toggling Show Debug Info under the Options menu will show \n" | 758 | "Toggling Show Debug Info under the Options menu will show \n" |
759 | "the dependencies, which you can then match by examining other options."; | 759 | "the dependencies, which you can then match by examining other options."); |
760 | 760 | ||
761 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 761 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
762 | GTK_DIALOG_DESTROY_WITH_PARENT, | 762 | GTK_DIALOG_DESTROY_WITH_PARENT, |
@@ -773,8 +773,8 @@ void on_about1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
773 | { | 773 | { |
774 | GtkWidget *dialog; | 774 | GtkWidget *dialog; |
775 | const gchar *about_text = | 775 | const gchar *about_text = |
776 | "gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" | 776 | _("gkc is copyright (c) 2002 Romain Lievin <roms@lpg.ticalc.org>.\n" |
777 | "Based on the source code from Roman Zippel.\n"; | 777 | "Based on the source code from Roman Zippel.\n"); |
778 | 778 | ||
779 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 779 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
780 | GTK_DIALOG_DESTROY_WITH_PARENT, | 780 | GTK_DIALOG_DESTROY_WITH_PARENT, |
@@ -791,9 +791,9 @@ void on_license1_activate(GtkMenuItem * menuitem, gpointer user_data) | |||
791 | { | 791 | { |
792 | GtkWidget *dialog; | 792 | GtkWidget *dialog; |
793 | const gchar *license_text = | 793 | const gchar *license_text = |
794 | "gkc is released under the terms of the GNU GPL v2.\n" | 794 | _("gkc is released under the terms of the GNU GPL v2.\n" |
795 | "For more information, please see the source code or\n" | 795 | "For more information, please see the source code or\n" |
796 | "visit http://www.fsf.org/licenses/licenses.html\n"; | 796 | "visit http://www.fsf.org/licenses/licenses.html\n"); |
797 | 797 | ||
798 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), | 798 | dialog = gtk_message_dialog_new(GTK_WINDOW(main_wnd), |
799 | GTK_DIALOG_DESTROY_WITH_PARENT, | 799 | GTK_DIALOG_DESTROY_WITH_PARENT, |
@@ -1579,6 +1579,10 @@ int main(int ac, char *av[]) | |||
1579 | kconfig_load(); | 1579 | kconfig_load(); |
1580 | #endif | 1580 | #endif |
1581 | 1581 | ||
1582 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
1583 | bind_textdomain_codeset(PACKAGE, "UTF-8"); | ||
1584 | textdomain(PACKAGE); | ||
1585 | |||
1582 | /* GTK stuffs */ | 1586 | /* GTK stuffs */ |
1583 | gtk_set_locale(); | 1587 | gtk_set_locale(); |
1584 | gtk_init(&ac, &av); | 1588 | gtk_init(&ac, &av); |
diff --git a/scripts/kconfig/kxgettext.c b/scripts/kconfig/kxgettext.c new file mode 100644 index 000000000000..1c88d7c6d5a7 --- /dev/null +++ b/scripts/kconfig/kxgettext.c | |||
@@ -0,0 +1,221 @@ | |||
1 | /* | ||
2 | * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2005 | ||
3 | * | ||
4 | * Released under the terms of the GNU GPL v2.0 | ||
5 | */ | ||
6 | |||
7 | #include <stdlib.h> | ||
8 | #include <string.h> | ||
9 | |||
10 | #define LKC_DIRECT_LINK | ||
11 | #include "lkc.h" | ||
12 | |||
13 | static char *escape(const char* text, char *bf, int len) | ||
14 | { | ||
15 | char *bfp = bf; | ||
16 | int multiline = strchr(text, '\n') != NULL; | ||
17 | |||
18 | *bfp++ = '"'; | ||
19 | --len; | ||
20 | |||
21 | if (multiline) { | ||
22 | *bfp++ = '"'; | ||
23 | *bfp++ = '\n'; | ||
24 | *bfp++ = '"'; | ||
25 | len -= 3; | ||
26 | } | ||
27 | |||
28 | while (*text != '\0' && len > 1) { | ||
29 | if (*text == '"') | ||
30 | *bfp++ = '\\'; | ||
31 | else if (*text == '\n') { | ||
32 | *bfp++ = '\\'; | ||
33 | *bfp++ = 'n'; | ||
34 | *bfp++ = '"'; | ||
35 | *bfp++ = '\n'; | ||
36 | *bfp++ = '"'; | ||
37 | len -= 5; | ||
38 | ++text; | ||
39 | goto next; | ||
40 | } | ||
41 | *bfp++ = *text++; | ||
42 | next: | ||
43 | --len; | ||
44 | } | ||
45 | |||
46 | if (multiline) | ||
47 | bfp -= 3; | ||
48 | |||
49 | *bfp++ = '"'; | ||
50 | *bfp = '\0'; | ||
51 | |||
52 | return bf; | ||
53 | } | ||
54 | |||
55 | struct file_line { | ||
56 | struct file_line *next; | ||
57 | char* file; | ||
58 | int lineno; | ||
59 | }; | ||
60 | |||
61 | static struct file_line *file_line__new(char *file, int lineno) | ||
62 | { | ||
63 | struct file_line *self = malloc(sizeof(*self)); | ||
64 | |||
65 | if (self == NULL) | ||
66 | goto out; | ||
67 | |||
68 | self->file = file; | ||
69 | self->lineno = lineno; | ||
70 | self->next = NULL; | ||
71 | out: | ||
72 | return self; | ||
73 | } | ||
74 | |||
75 | struct message { | ||
76 | const char *msg; | ||
77 | const char *option; | ||
78 | struct message *next; | ||
79 | struct file_line *files; | ||
80 | }; | ||
81 | |||
82 | static struct message *message__list; | ||
83 | |||
84 | static struct message *message__new(const char *msg, char *option, char *file, int lineno) | ||
85 | { | ||
86 | struct message *self = malloc(sizeof(*self)); | ||
87 | |||
88 | if (self == NULL) | ||
89 | goto out; | ||
90 | |||
91 | self->files = file_line__new(file, lineno); | ||
92 | if (self->files == NULL) | ||
93 | goto out_fail; | ||
94 | |||
95 | self->msg = strdup(msg); | ||
96 | if (self->msg == NULL) | ||
97 | goto out_fail_msg; | ||
98 | |||
99 | self->option = option; | ||
100 | self->next = NULL; | ||
101 | out: | ||
102 | return self; | ||
103 | out_fail_msg: | ||
104 | free(self->files); | ||
105 | out_fail: | ||
106 | free(self); | ||
107 | self = NULL; | ||
108 | goto out; | ||
109 | } | ||
110 | |||
111 | static struct message *mesage__find(const char *msg) | ||
112 | { | ||
113 | struct message *m = message__list; | ||
114 | |||
115 | while (m != NULL) { | ||
116 | if (strcmp(m->msg, msg) == 0) | ||
117 | break; | ||
118 | m = m->next; | ||
119 | } | ||
120 | |||
121 | return m; | ||
122 | } | ||
123 | |||
124 | static int message__add_file_line(struct message *self, char *file, int lineno) | ||
125 | { | ||
126 | int rc = -1; | ||
127 | struct file_line *fl = file_line__new(file, lineno); | ||
128 | |||
129 | if (fl == NULL) | ||
130 | goto out; | ||
131 | |||
132 | fl->next = self->files; | ||
133 | self->files = fl; | ||
134 | rc = 0; | ||
135 | out: | ||
136 | return rc; | ||
137 | } | ||
138 | |||
139 | static int message__add(const char *msg, char *option, char *file, int lineno) | ||
140 | { | ||
141 | int rc = 0; | ||
142 | char bf[16384]; | ||
143 | char *escaped = escape(msg, bf, sizeof(bf)); | ||
144 | struct message *m = mesage__find(escaped); | ||
145 | |||
146 | if (m != NULL) | ||
147 | rc = message__add_file_line(m, file, lineno); | ||
148 | else { | ||
149 | m = message__new(escaped, option, file, lineno); | ||
150 | |||
151 | if (m != NULL) { | ||
152 | m->next = message__list; | ||
153 | message__list = m; | ||
154 | } else | ||
155 | rc = -1; | ||
156 | } | ||
157 | return rc; | ||
158 | } | ||
159 | |||
160 | void menu_build_message_list(struct menu *menu) | ||
161 | { | ||
162 | struct menu *child; | ||
163 | |||
164 | message__add(menu_get_prompt(menu), NULL, | ||
165 | menu->file == NULL ? "Root Menu" : menu->file->name, | ||
166 | menu->lineno); | ||
167 | |||
168 | if (menu->sym != NULL && menu->sym->help != NULL) | ||
169 | message__add(menu->sym->help, menu->sym->name, | ||
170 | menu->file == NULL ? "Root Menu" : menu->file->name, | ||
171 | menu->lineno); | ||
172 | |||
173 | for (child = menu->list; child != NULL; child = child->next) | ||
174 | if (child->prompt != NULL) | ||
175 | menu_build_message_list(child); | ||
176 | } | ||
177 | |||
178 | static void message__print_file_lineno(struct message *self) | ||
179 | { | ||
180 | struct file_line *fl = self->files; | ||
181 | |||
182 | printf("\n#: %s:%d", fl->file, fl->lineno); | ||
183 | fl = fl->next; | ||
184 | |||
185 | while (fl != NULL) { | ||
186 | printf(", %s:%d", fl->file, fl->lineno); | ||
187 | fl = fl->next; | ||
188 | } | ||
189 | |||
190 | if (self->option != NULL) | ||
191 | printf(", %s:00000", self->option); | ||
192 | |||
193 | putchar('\n'); | ||
194 | } | ||
195 | |||
196 | static void message__print_gettext_msgid_msgstr(struct message *self) | ||
197 | { | ||
198 | message__print_file_lineno(self); | ||
199 | |||
200 | printf("msgid %s\n" | ||
201 | "msgstr \"\"\n", self->msg); | ||
202 | } | ||
203 | |||
204 | void menu__xgettext(void) | ||
205 | { | ||
206 | struct message *m = message__list; | ||
207 | |||
208 | while (m != NULL) { | ||
209 | message__print_gettext_msgid_msgstr(m); | ||
210 | m = m->next; | ||
211 | } | ||
212 | } | ||
213 | |||
214 | int main(int ac, char **av) | ||
215 | { | ||
216 | conf_parse(av[1]); | ||
217 | |||
218 | menu_build_message_list(menu_get_root_menu(NULL)); | ||
219 | menu__xgettext(); | ||
220 | return 0; | ||
221 | } | ||
diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index b8a67fc9d647..8b84c42b49b5 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h | |||
@@ -8,6 +8,8 @@ | |||
8 | 8 | ||
9 | #include "expr.h" | 9 | #include "expr.h" |
10 | 10 | ||
11 | #include <libintl.h> | ||
12 | |||
11 | #ifdef __cplusplus | 13 | #ifdef __cplusplus |
12 | extern "C" { | 14 | extern "C" { |
13 | #endif | 15 | #endif |
@@ -23,6 +25,12 @@ extern "C" { | |||
23 | 25 | ||
24 | #define SRCTREE "srctree" | 26 | #define SRCTREE "srctree" |
25 | 27 | ||
28 | #define PACKAGE "linux" | ||
29 | #define LOCALEDIR "/usr/share/locale" | ||
30 | |||
31 | #define _(text) gettext(text) | ||
32 | #define N_(text) (text) | ||
33 | |||
26 | int zconfparse(void); | 34 | int zconfparse(void); |
27 | void zconfdump(FILE *out); | 35 | void zconfdump(FILE *out); |
28 | 36 | ||
diff --git a/scripts/kconfig/mconf.c b/scripts/kconfig/mconf.c index 730d316fe7fe..e5db10ca9564 100644 --- a/scripts/kconfig/mconf.c +++ b/scripts/kconfig/mconf.c | |||
@@ -4,6 +4,8 @@ | |||
4 | * | 4 | * |
5 | * Introduced single menu mode (show all sub-menus in one large tree). | 5 | * Introduced single menu mode (show all sub-menus in one large tree). |
6 | * 2002-11-06 Petr Baudis <pasky@ucw.cz> | 6 | * 2002-11-06 Petr Baudis <pasky@ucw.cz> |
7 | * | ||
8 | * i18n, 2005, Arnaldo Carvalho de Melo <acme@conectiva.com.br> | ||
7 | */ | 9 | */ |
8 | 10 | ||
9 | #include <sys/ioctl.h> | 11 | #include <sys/ioctl.h> |
@@ -23,7 +25,7 @@ | |||
23 | #include "lkc.h" | 25 | #include "lkc.h" |
24 | 26 | ||
25 | static char menu_backtitle[128]; | 27 | static char menu_backtitle[128]; |
26 | static const char mconf_readme[] = | 28 | static const char mconf_readme[] = N_( |
27 | "Overview\n" | 29 | "Overview\n" |
28 | "--------\n" | 30 | "--------\n" |
29 | "Some kernel features may be built directly into the kernel.\n" | 31 | "Some kernel features may be built directly into the kernel.\n" |
@@ -156,39 +158,39 @@ static const char mconf_readme[] = | |||
156 | "\n" | 158 | "\n" |
157 | "Note that this mode can eventually be a little more CPU expensive\n" | 159 | "Note that this mode can eventually be a little more CPU expensive\n" |
158 | "(especially with a larger number of unrolled categories) than the\n" | 160 | "(especially with a larger number of unrolled categories) than the\n" |
159 | "default mode.\n", | 161 | "default mode.\n"), |
160 | menu_instructions[] = | 162 | menu_instructions[] = N_( |
161 | "Arrow keys navigate the menu. " | 163 | "Arrow keys navigate the menu. " |
162 | "<Enter> selects submenus --->. " | 164 | "<Enter> selects submenus --->. " |
163 | "Highlighted letters are hotkeys. " | 165 | "Highlighted letters are hotkeys. " |
164 | "Pressing <Y> includes, <N> excludes, <M> modularizes features. " | 166 | "Pressing <Y> includes, <N> excludes, <M> modularizes features. " |
165 | "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " | 167 | "Press <Esc><Esc> to exit, <?> for Help, </> for Search. " |
166 | "Legend: [*] built-in [ ] excluded <M> module < > module capable", | 168 | "Legend: [*] built-in [ ] excluded <M> module < > module capable"), |
167 | radiolist_instructions[] = | 169 | radiolist_instructions[] = N_( |
168 | "Use the arrow keys to navigate this window or " | 170 | "Use the arrow keys to navigate this window or " |
169 | "press the hotkey of the item you wish to select " | 171 | "press the hotkey of the item you wish to select " |
170 | "followed by the <SPACE BAR>. " | 172 | "followed by the <SPACE BAR>. " |
171 | "Press <?> for additional information about this option.", | 173 | "Press <?> for additional information about this option."), |
172 | inputbox_instructions_int[] = | 174 | inputbox_instructions_int[] = N_( |
173 | "Please enter a decimal value. " | 175 | "Please enter a decimal value. " |
174 | "Fractions will not be accepted. " | 176 | "Fractions will not be accepted. " |
175 | "Use the <TAB> key to move from the input field to the buttons below it.", | 177 | "Use the <TAB> key to move from the input field to the buttons below it."), |
176 | inputbox_instructions_hex[] = | 178 | inputbox_instructions_hex[] = N_( |
177 | "Please enter a hexadecimal value. " | 179 | "Please enter a hexadecimal value. " |
178 | "Use the <TAB> key to move from the input field to the buttons below it.", | 180 | "Use the <TAB> key to move from the input field to the buttons below it."), |
179 | inputbox_instructions_string[] = | 181 | inputbox_instructions_string[] = N_( |
180 | "Please enter a string value. " | 182 | "Please enter a string value. " |
181 | "Use the <TAB> key to move from the input field to the buttons below it.", | 183 | "Use the <TAB> key to move from the input field to the buttons below it."), |
182 | setmod_text[] = | 184 | setmod_text[] = N_( |
183 | "This feature depends on another which has been configured as a module.\n" | 185 | "This feature depends on another which has been configured as a module.\n" |
184 | "As a result, this feature will be built as a module.", | 186 | "As a result, this feature will be built as a module."), |
185 | nohelp_text[] = | 187 | nohelp_text[] = N_( |
186 | "There is no help available for this kernel option.\n", | 188 | "There is no help available for this kernel option.\n"), |
187 | load_config_text[] = | 189 | load_config_text[] = N_( |
188 | "Enter the name of the configuration file you wish to load. " | 190 | "Enter the name of the configuration file you wish to load. " |
189 | "Accept the name shown to restore the configuration you " | 191 | "Accept the name shown to restore the configuration you " |
190 | "last retrieved. Leave blank to abort.", | 192 | "last retrieved. Leave blank to abort."), |
191 | load_config_help[] = | 193 | load_config_help[] = N_( |
192 | "\n" | 194 | "\n" |
193 | "For various reasons, one may wish to keep several different kernel\n" | 195 | "For various reasons, one may wish to keep several different kernel\n" |
194 | "configurations available on a single machine.\n" | 196 | "configurations available on a single machine.\n" |
@@ -198,11 +200,11 @@ load_config_help[] = | |||
198 | "to modify that configuration.\n" | 200 | "to modify that configuration.\n" |
199 | "\n" | 201 | "\n" |
200 | "If you are uncertain, then you have probably never used alternate\n" | 202 | "If you are uncertain, then you have probably never used alternate\n" |
201 | "configuration files. You should therefor leave this blank to abort.\n", | 203 | "configuration files. You should therefor leave this blank to abort.\n"), |
202 | save_config_text[] = | 204 | save_config_text[] = N_( |
203 | "Enter a filename to which this configuration should be saved " | 205 | "Enter a filename to which this configuration should be saved " |
204 | "as an alternate. Leave blank to abort.", | 206 | "as an alternate. Leave blank to abort."), |
205 | save_config_help[] = | 207 | save_config_help[] = N_( |
206 | "\n" | 208 | "\n" |
207 | "For various reasons, one may wish to keep different kernel\n" | 209 | "For various reasons, one may wish to keep different kernel\n" |
208 | "configurations available on a single machine.\n" | 210 | "configurations available on a single machine.\n" |
@@ -212,8 +214,8 @@ save_config_help[] = | |||
212 | "configuration options you have selected at that time.\n" | 214 | "configuration options you have selected at that time.\n" |
213 | "\n" | 215 | "\n" |
214 | "If you are uncertain what all this means then you should probably\n" | 216 | "If you are uncertain what all this means then you should probably\n" |
215 | "leave this blank.\n", | 217 | "leave this blank.\n"), |
216 | search_help[] = | 218 | search_help[] = N_( |
217 | "\n" | 219 | "\n" |
218 | "Search for CONFIG_ symbols and display their relations.\n" | 220 | "Search for CONFIG_ symbols and display their relations.\n" |
219 | "Example: search for \"^FOO\"\n" | 221 | "Example: search for \"^FOO\"\n" |
@@ -250,7 +252,7 @@ search_help[] = | |||
250 | "Examples: USB => find all CONFIG_ symbols containing USB\n" | 252 | "Examples: USB => find all CONFIG_ symbols containing USB\n" |
251 | " ^USB => find all CONFIG_ symbols starting with USB\n" | 253 | " ^USB => find all CONFIG_ symbols starting with USB\n" |
252 | " USB$ => find all CONFIG_ symbols ending with USB\n" | 254 | " USB$ => find all CONFIG_ symbols ending with USB\n" |
253 | "\n"; | 255 | "\n"); |
254 | 256 | ||
255 | static signed char buf[4096], *bufptr = buf; | 257 | static signed char buf[4096], *bufptr = buf; |
256 | static signed char input_buf[4096]; | 258 | static signed char input_buf[4096]; |
@@ -305,8 +307,8 @@ static void init_wsize(void) | |||
305 | } | 307 | } |
306 | 308 | ||
307 | if (rows < 19 || cols < 80) { | 309 | if (rows < 19 || cols < 80) { |
308 | fprintf(stderr, "Your display is too small to run Menuconfig!\n"); | 310 | fprintf(stderr, N_("Your display is too small to run Menuconfig!\n")); |
309 | fprintf(stderr, "It must be at least 19 lines by 80 columns.\n"); | 311 | fprintf(stderr, N_("It must be at least 19 lines by 80 columns.\n")); |
310 | exit(1); | 312 | exit(1); |
311 | } | 313 | } |
312 | 314 | ||
@@ -526,9 +528,9 @@ static void search_conf(void) | |||
526 | again: | 528 | again: |
527 | cprint_init(); | 529 | cprint_init(); |
528 | cprint("--title"); | 530 | cprint("--title"); |
529 | cprint("Search Configuration Parameter"); | 531 | cprint(_("Search Configuration Parameter")); |
530 | cprint("--inputbox"); | 532 | cprint("--inputbox"); |
531 | cprint("Enter Keyword"); | 533 | cprint(_("Enter Keyword")); |
532 | cprint("10"); | 534 | cprint("10"); |
533 | cprint("75"); | 535 | cprint("75"); |
534 | cprint(""); | 536 | cprint(""); |
@@ -539,7 +541,7 @@ again: | |||
539 | case 0: | 541 | case 0: |
540 | break; | 542 | break; |
541 | case 1: | 543 | case 1: |
542 | show_helptext("Search Configuration", search_help); | 544 | show_helptext(_("Search Configuration"), search_help); |
543 | goto again; | 545 | goto again; |
544 | default: | 546 | default: |
545 | return; | 547 | return; |
@@ -548,7 +550,7 @@ again: | |||
548 | sym_arr = sym_re_search(input_buf); | 550 | sym_arr = sym_re_search(input_buf); |
549 | res = get_relations_str(sym_arr); | 551 | res = get_relations_str(sym_arr); |
550 | free(sym_arr); | 552 | free(sym_arr); |
551 | show_textbox("Search Results", str_get(&res), 0, 0); | 553 | show_textbox(_("Search Results"), str_get(&res), 0, 0); |
552 | str_free(&res); | 554 | str_free(&res); |
553 | } | 555 | } |
554 | 556 | ||
@@ -721,9 +723,9 @@ static void conf(struct menu *menu) | |||
721 | while (1) { | 723 | while (1) { |
722 | cprint_init(); | 724 | cprint_init(); |
723 | cprint("--title"); | 725 | cprint("--title"); |
724 | cprint("%s", prompt ? prompt : "Main Menu"); | 726 | cprint("%s", prompt ? prompt : _("Main Menu")); |
725 | cprint("--menu"); | 727 | cprint("--menu"); |
726 | cprint(menu_instructions); | 728 | cprint(_(menu_instructions)); |
727 | cprint("%d", rows); | 729 | cprint("%d", rows); |
728 | cprint("%d", cols); | 730 | cprint("%d", cols); |
729 | cprint("%d", rows - 10); | 731 | cprint("%d", rows - 10); |
@@ -736,9 +738,9 @@ static void conf(struct menu *menu) | |||
736 | cprint(":"); | 738 | cprint(":"); |
737 | cprint("--- "); | 739 | cprint("--- "); |
738 | cprint("L"); | 740 | cprint("L"); |
739 | cprint(" Load an Alternate Configuration File"); | 741 | cprint(_(" Load an Alternate Configuration File")); |
740 | cprint("S"); | 742 | cprint("S"); |
741 | cprint(" Save Configuration to an Alternate File"); | 743 | cprint(_(" Save Configuration to an Alternate File")); |
742 | } | 744 | } |
743 | stat = exec_conf(); | 745 | stat = exec_conf(); |
744 | if (stat < 0) | 746 | if (stat < 0) |
@@ -793,7 +795,7 @@ static void conf(struct menu *menu) | |||
793 | if (sym) | 795 | if (sym) |
794 | show_help(submenu); | 796 | show_help(submenu); |
795 | else | 797 | else |
796 | show_helptext("README", mconf_readme); | 798 | show_helptext("README", _(mconf_readme)); |
797 | break; | 799 | break; |
798 | case 3: | 800 | case 3: |
799 | if (type == 't') { | 801 | if (type == 't') { |
@@ -849,7 +851,7 @@ static void show_help(struct menu *menu) | |||
849 | { | 851 | { |
850 | if (sym->name) { | 852 | if (sym->name) { |
851 | str_printf(&help, "CONFIG_%s:\n\n", sym->name); | 853 | str_printf(&help, "CONFIG_%s:\n\n", sym->name); |
852 | str_append(&help, sym->help); | 854 | str_append(&help, _(sym->help)); |
853 | str_append(&help, "\n"); | 855 | str_append(&help, "\n"); |
854 | } | 856 | } |
855 | } else { | 857 | } else { |
@@ -886,9 +888,9 @@ static void conf_choice(struct menu *menu) | |||
886 | while (1) { | 888 | while (1) { |
887 | cprint_init(); | 889 | cprint_init(); |
888 | cprint("--title"); | 890 | cprint("--title"); |
889 | cprint("%s", prompt ? prompt : "Main Menu"); | 891 | cprint("%s", prompt ? prompt : _("Main Menu")); |
890 | cprint("--radiolist"); | 892 | cprint("--radiolist"); |
891 | cprint(radiolist_instructions); | 893 | cprint(_(radiolist_instructions)); |
892 | cprint("15"); | 894 | cprint("15"); |
893 | cprint("70"); | 895 | cprint("70"); |
894 | cprint("6"); | 896 | cprint("6"); |
@@ -935,17 +937,17 @@ static void conf_string(struct menu *menu) | |||
935 | while (1) { | 937 | while (1) { |
936 | cprint_init(); | 938 | cprint_init(); |
937 | cprint("--title"); | 939 | cprint("--title"); |
938 | cprint("%s", prompt ? prompt : "Main Menu"); | 940 | cprint("%s", prompt ? prompt : _("Main Menu")); |
939 | cprint("--inputbox"); | 941 | cprint("--inputbox"); |
940 | switch (sym_get_type(menu->sym)) { | 942 | switch (sym_get_type(menu->sym)) { |
941 | case S_INT: | 943 | case S_INT: |
942 | cprint(inputbox_instructions_int); | 944 | cprint(_(inputbox_instructions_int)); |
943 | break; | 945 | break; |
944 | case S_HEX: | 946 | case S_HEX: |
945 | cprint(inputbox_instructions_hex); | 947 | cprint(_(inputbox_instructions_hex)); |
946 | break; | 948 | break; |
947 | case S_STRING: | 949 | case S_STRING: |
948 | cprint(inputbox_instructions_string); | 950 | cprint(_(inputbox_instructions_string)); |
949 | break; | 951 | break; |
950 | default: | 952 | default: |
951 | /* panic? */; | 953 | /* panic? */; |
@@ -958,7 +960,7 @@ static void conf_string(struct menu *menu) | |||
958 | case 0: | 960 | case 0: |
959 | if (sym_set_string_value(menu->sym, input_buf)) | 961 | if (sym_set_string_value(menu->sym, input_buf)) |
960 | return; | 962 | return; |
961 | show_textbox(NULL, "You have made an invalid entry.", 5, 43); | 963 | show_textbox(NULL, _("You have made an invalid entry."), 5, 43); |
962 | break; | 964 | break; |
963 | case 1: | 965 | case 1: |
964 | show_help(menu); | 966 | show_help(menu); |
@@ -987,10 +989,10 @@ static void conf_load(void) | |||
987 | return; | 989 | return; |
988 | if (!conf_read(input_buf)) | 990 | if (!conf_read(input_buf)) |
989 | return; | 991 | return; |
990 | show_textbox(NULL, "File does not exist!", 5, 38); | 992 | show_textbox(NULL, _("File does not exist!"), 5, 38); |
991 | break; | 993 | break; |
992 | case 1: | 994 | case 1: |
993 | show_helptext("Load Alternate Configuration", load_config_help); | 995 | show_helptext(_("Load Alternate Configuration"), load_config_help); |
994 | break; | 996 | break; |
995 | case 255: | 997 | case 255: |
996 | return; | 998 | return; |
@@ -1016,10 +1018,10 @@ static void conf_save(void) | |||
1016 | return; | 1018 | return; |
1017 | if (!conf_write(input_buf)) | 1019 | if (!conf_write(input_buf)) |
1018 | return; | 1020 | return; |
1019 | show_textbox(NULL, "Can't create file! Probably a nonexistent directory.", 5, 60); | 1021 | show_textbox(NULL, _("Can't create file! Probably a nonexistent directory."), 5, 60); |
1020 | break; | 1022 | break; |
1021 | case 1: | 1023 | case 1: |
1022 | show_helptext("Save Alternate Configuration", save_config_help); | 1024 | show_helptext(_("Save Alternate Configuration"), save_config_help); |
1023 | break; | 1025 | break; |
1024 | case 255: | 1026 | case 255: |
1025 | return; | 1027 | return; |
@@ -1040,12 +1042,16 @@ int main(int ac, char **av) | |||
1040 | char *mode; | 1042 | char *mode; |
1041 | int stat; | 1043 | int stat; |
1042 | 1044 | ||
1045 | setlocale(LC_ALL, ""); | ||
1046 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
1047 | textdomain(PACKAGE); | ||
1048 | |||
1043 | conf_parse(av[1]); | 1049 | conf_parse(av[1]); |
1044 | conf_read(NULL); | 1050 | conf_read(NULL); |
1045 | 1051 | ||
1046 | sym = sym_lookup("KERNELRELEASE", 0); | 1052 | sym = sym_lookup("KERNELRELEASE", 0); |
1047 | sym_calc_value(sym); | 1053 | sym_calc_value(sym); |
1048 | sprintf(menu_backtitle, "Linux Kernel v%s Configuration", | 1054 | sprintf(menu_backtitle, _("Linux Kernel v%s Configuration"), |
1049 | sym_get_string_value(sym)); | 1055 | sym_get_string_value(sym)); |
1050 | 1056 | ||
1051 | mode = getenv("MENUCONFIG_MODE"); | 1057 | mode = getenv("MENUCONFIG_MODE"); |
@@ -1062,7 +1068,7 @@ int main(int ac, char **av) | |||
1062 | do { | 1068 | do { |
1063 | cprint_init(); | 1069 | cprint_init(); |
1064 | cprint("--yesno"); | 1070 | cprint("--yesno"); |
1065 | cprint("Do you wish to save your new kernel configuration?"); | 1071 | cprint(_("Do you wish to save your new kernel configuration?")); |
1066 | cprint("5"); | 1072 | cprint("5"); |
1067 | cprint("60"); | 1073 | cprint("60"); |
1068 | stat = exec_conf(); | 1074 | stat = exec_conf(); |
@@ -1070,20 +1076,20 @@ int main(int ac, char **av) | |||
1070 | 1076 | ||
1071 | if (stat == 0) { | 1077 | if (stat == 0) { |
1072 | if (conf_write(NULL)) { | 1078 | if (conf_write(NULL)) { |
1073 | fprintf(stderr, "\n\n" | 1079 | fprintf(stderr, _("\n\n" |
1074 | "Error during writing of the kernel configuration.\n" | 1080 | "Error during writing of the kernel configuration.\n" |
1075 | "Your kernel configuration changes were NOT saved." | 1081 | "Your kernel configuration changes were NOT saved." |
1076 | "\n\n"); | 1082 | "\n\n")); |
1077 | return 1; | 1083 | return 1; |
1078 | } | 1084 | } |
1079 | printf("\n\n" | 1085 | printf(_("\n\n" |
1080 | "*** End of Linux kernel configuration.\n" | 1086 | "*** End of Linux kernel configuration.\n" |
1081 | "*** Execute 'make' to build the kernel or try 'make help'." | 1087 | "*** Execute 'make' to build the kernel or try 'make help'." |
1082 | "\n\n"); | 1088 | "\n\n")); |
1083 | } else { | 1089 | } else { |
1084 | fprintf(stderr, "\n\n" | 1090 | fprintf(stderr, _("\n\n" |
1085 | "Your kernel configuration changes were NOT saved." | 1091 | "Your kernel configuration changes were NOT saved." |
1086 | "\n\n"); | 1092 | "\n\n")); |
1087 | } | 1093 | } |
1088 | 1094 | ||
1089 | return 0; | 1095 | return 0; |
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 0c13156f3344..8c59b212722d 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c | |||
@@ -365,9 +365,9 @@ bool menu_is_visible(struct menu *menu) | |||
365 | const char *menu_get_prompt(struct menu *menu) | 365 | const char *menu_get_prompt(struct menu *menu) |
366 | { | 366 | { |
367 | if (menu->prompt) | 367 | if (menu->prompt) |
368 | return menu->prompt->text; | 368 | return _(menu->prompt->text); |
369 | else if (menu->sym) | 369 | else if (menu->sym) |
370 | return menu->sym->name; | 370 | return _(menu->sym->name); |
371 | return NULL; | 371 | return NULL; |
372 | } | 372 | } |
373 | 373 | ||
diff --git a/scripts/kconfig/qconf.cc b/scripts/kconfig/qconf.cc index 0cdbf9dbbd51..4590cd31623f 100644 --- a/scripts/kconfig/qconf.cc +++ b/scripts/kconfig/qconf.cc | |||
@@ -26,8 +26,23 @@ | |||
26 | #include "qconf.moc" | 26 | #include "qconf.moc" |
27 | #include "images.c" | 27 | #include "images.c" |
28 | 28 | ||
29 | #ifdef _ | ||
30 | # undef _ | ||
31 | # define _ qgettext | ||
32 | #endif | ||
33 | |||
29 | static QApplication *configApp; | 34 | static QApplication *configApp; |
30 | 35 | ||
36 | static inline QString qgettext(const char* str) | ||
37 | { | ||
38 | return QString::fromLocal8Bit(gettext(str)); | ||
39 | } | ||
40 | |||
41 | static inline QString qgettext(const QString& str) | ||
42 | { | ||
43 | return QString::fromLocal8Bit(gettext(str.latin1())); | ||
44 | } | ||
45 | |||
31 | ConfigSettings::ConfigSettings() | 46 | ConfigSettings::ConfigSettings() |
32 | : showAll(false), showName(false), showRange(false), showData(false) | 47 | : showAll(false), showName(false), showRange(false), showData(false) |
33 | { | 48 | { |
@@ -177,7 +192,7 @@ void ConfigItem::updateMenu(void) | |||
177 | 192 | ||
178 | sym = menu->sym; | 193 | sym = menu->sym; |
179 | prop = menu->prompt; | 194 | prop = menu->prompt; |
180 | prompt = menu_get_prompt(menu); | 195 | prompt = QString::fromLocal8Bit(menu_get_prompt(menu)); |
181 | 196 | ||
182 | if (prop) switch (prop->type) { | 197 | if (prop) switch (prop->type) { |
183 | case P_MENU: | 198 | case P_MENU: |
@@ -203,7 +218,7 @@ void ConfigItem::updateMenu(void) | |||
203 | if (!sym) | 218 | if (!sym) |
204 | goto set_prompt; | 219 | goto set_prompt; |
205 | 220 | ||
206 | setText(nameColIdx, sym->name); | 221 | setText(nameColIdx, QString::fromLocal8Bit(sym->name)); |
207 | 222 | ||
208 | type = sym_get_type(sym); | 223 | type = sym_get_type(sym); |
209 | switch (type) { | 224 | switch (type) { |
@@ -213,9 +228,9 @@ void ConfigItem::updateMenu(void) | |||
213 | 228 | ||
214 | if (!sym_is_changable(sym) && !list->showAll) { | 229 | if (!sym_is_changable(sym) && !list->showAll) { |
215 | setPixmap(promptColIdx, 0); | 230 | setPixmap(promptColIdx, 0); |
216 | setText(noColIdx, 0); | 231 | setText(noColIdx, QString::null); |
217 | setText(modColIdx, 0); | 232 | setText(modColIdx, QString::null); |
218 | setText(yesColIdx, 0); | 233 | setText(yesColIdx, QString::null); |
219 | break; | 234 | break; |
220 | } | 235 | } |
221 | expr = sym_get_tristate_value(sym); | 236 | expr = sym_get_tristate_value(sym); |
@@ -257,6 +272,7 @@ void ConfigItem::updateMenu(void) | |||
257 | const char* data; | 272 | const char* data; |
258 | 273 | ||
259 | data = sym_get_string_value(sym); | 274 | data = sym_get_string_value(sym); |
275 | |||
260 | #if QT_VERSION >= 300 | 276 | #if QT_VERSION >= 300 |
261 | int i = list->mapIdx(dataColIdx); | 277 | int i = list->mapIdx(dataColIdx); |
262 | if (i >= 0) | 278 | if (i >= 0) |
@@ -264,9 +280,9 @@ void ConfigItem::updateMenu(void) | |||
264 | #endif | 280 | #endif |
265 | setText(dataColIdx, data); | 281 | setText(dataColIdx, data); |
266 | if (type == S_STRING) | 282 | if (type == S_STRING) |
267 | prompt.sprintf("%s: %s", prompt.latin1(), data); | 283 | prompt = QString("%1: %2").arg(prompt).arg(data); |
268 | else | 284 | else |
269 | prompt.sprintf("(%s) %s", data, prompt.latin1()); | 285 | prompt = QString("(%2) %1").arg(prompt).arg(data); |
270 | break; | 286 | break; |
271 | } | 287 | } |
272 | if (!sym_has_value(sym) && visible) | 288 | if (!sym_has_value(sym) && visible) |
@@ -343,9 +359,9 @@ void ConfigLineEdit::show(ConfigItem* i) | |||
343 | { | 359 | { |
344 | item = i; | 360 | item = i; |
345 | if (sym_get_string_value(item->menu->sym)) | 361 | if (sym_get_string_value(item->menu->sym)) |
346 | setText(sym_get_string_value(item->menu->sym)); | 362 | setText(QString::fromLocal8Bit(sym_get_string_value(item->menu->sym))); |
347 | else | 363 | else |
348 | setText(0); | 364 | setText(QString::null); |
349 | Parent::show(); | 365 | Parent::show(); |
350 | setFocus(); | 366 | setFocus(); |
351 | } | 367 | } |
@@ -961,7 +977,7 @@ ConfigMainWindow::ConfigMainWindow(void) | |||
961 | delete configSettings; | 977 | delete configSettings; |
962 | } | 978 | } |
963 | 979 | ||
964 | static QString print_filter(const char *str) | 980 | static QString print_filter(const QString &str) |
965 | { | 981 | { |
966 | QRegExp re("[<>&\"\\n]"); | 982 | QRegExp re("[<>&\"\\n]"); |
967 | QString res = str; | 983 | QString res = str; |
@@ -994,7 +1010,7 @@ static QString print_filter(const char *str) | |||
994 | 1010 | ||
995 | static void expr_print_help(void *data, const char *str) | 1011 | static void expr_print_help(void *data, const char *str) |
996 | { | 1012 | { |
997 | ((QString*)data)->append(print_filter(str)); | 1013 | reinterpret_cast<QString*>(data)->append(print_filter(str)); |
998 | } | 1014 | } |
999 | 1015 | ||
1000 | /* | 1016 | /* |
@@ -1009,7 +1025,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item) | |||
1009 | if (item) | 1025 | if (item) |
1010 | menu = ((ConfigItem*)item)->menu; | 1026 | menu = ((ConfigItem*)item)->menu; |
1011 | if (!menu) { | 1027 | if (!menu) { |
1012 | helpText->setText(NULL); | 1028 | helpText->setText(QString::null); |
1013 | return; | 1029 | return; |
1014 | } | 1030 | } |
1015 | 1031 | ||
@@ -1019,16 +1035,16 @@ void ConfigMainWindow::setHelp(QListViewItem* item) | |||
1019 | if (sym) { | 1035 | if (sym) { |
1020 | if (menu->prompt) { | 1036 | if (menu->prompt) { |
1021 | head += "<big><b>"; | 1037 | head += "<big><b>"; |
1022 | head += print_filter(menu->prompt->text); | 1038 | head += print_filter(_(menu->prompt->text)); |
1023 | head += "</b></big>"; | 1039 | head += "</b></big>"; |
1024 | if (sym->name) { | 1040 | if (sym->name) { |
1025 | head += " ("; | 1041 | head += " ("; |
1026 | head += print_filter(sym->name); | 1042 | head += print_filter(_(sym->name)); |
1027 | head += ")"; | 1043 | head += ")"; |
1028 | } | 1044 | } |
1029 | } else if (sym->name) { | 1045 | } else if (sym->name) { |
1030 | head += "<big><b>"; | 1046 | head += "<big><b>"; |
1031 | head += print_filter(sym->name); | 1047 | head += print_filter(_(sym->name)); |
1032 | head += "</b></big>"; | 1048 | head += "</b></big>"; |
1033 | } | 1049 | } |
1034 | head += "<br><br>"; | 1050 | head += "<br><br>"; |
@@ -1049,7 +1065,7 @@ void ConfigMainWindow::setHelp(QListViewItem* item) | |||
1049 | case P_PROMPT: | 1065 | case P_PROMPT: |
1050 | case P_MENU: | 1066 | case P_MENU: |
1051 | debug += "prompt: "; | 1067 | debug += "prompt: "; |
1052 | debug += print_filter(prop->text); | 1068 | debug += print_filter(_(prop->text)); |
1053 | debug += "<br>"; | 1069 | debug += "<br>"; |
1054 | break; | 1070 | break; |
1055 | case P_DEFAULT: | 1071 | case P_DEFAULT: |
@@ -1088,10 +1104,10 @@ void ConfigMainWindow::setHelp(QListViewItem* item) | |||
1088 | debug += "<br>"; | 1104 | debug += "<br>"; |
1089 | } | 1105 | } |
1090 | 1106 | ||
1091 | help = print_filter(sym->help); | 1107 | help = print_filter(_(sym->help)); |
1092 | } else if (menu->prompt) { | 1108 | } else if (menu->prompt) { |
1093 | head += "<big><b>"; | 1109 | head += "<big><b>"; |
1094 | head += print_filter(menu->prompt->text); | 1110 | head += print_filter(_(menu->prompt->text)); |
1095 | head += "</b></big><br><br>"; | 1111 | head += "</b></big><br><br>"; |
1096 | if (showDebug) { | 1112 | if (showDebug) { |
1097 | if (menu->prompt->visible.expr) { | 1113 | if (menu->prompt->visible.expr) { |
@@ -1111,7 +1127,7 @@ void ConfigMainWindow::loadConfig(void) | |||
1111 | QString s = QFileDialog::getOpenFileName(".config", NULL, this); | 1127 | QString s = QFileDialog::getOpenFileName(".config", NULL, this); |
1112 | if (s.isNull()) | 1128 | if (s.isNull()) |
1113 | return; | 1129 | return; |
1114 | if (conf_read(s.latin1())) | 1130 | if (conf_read(QFile::encodeName(s))) |
1115 | QMessageBox::information(this, "qconf", "Unable to load configuration!"); | 1131 | QMessageBox::information(this, "qconf", "Unable to load configuration!"); |
1116 | ConfigView::updateListAll(); | 1132 | ConfigView::updateListAll(); |
1117 | } | 1133 | } |
@@ -1127,7 +1143,7 @@ void ConfigMainWindow::saveConfigAs(void) | |||
1127 | QString s = QFileDialog::getSaveFileName(".config", NULL, this); | 1143 | QString s = QFileDialog::getSaveFileName(".config", NULL, this); |
1128 | if (s.isNull()) | 1144 | if (s.isNull()) |
1129 | return; | 1145 | return; |
1130 | if (conf_write(s.latin1())) | 1146 | if (conf_write(QFile::encodeName(s))) |
1131 | QMessageBox::information(this, "qconf", "Unable to save configuration!"); | 1147 | QMessageBox::information(this, "qconf", "Unable to save configuration!"); |
1132 | } | 1148 | } |
1133 | 1149 | ||
@@ -1372,6 +1388,9 @@ int main(int ac, char** av) | |||
1372 | ConfigMainWindow* v; | 1388 | ConfigMainWindow* v; |
1373 | const char *name; | 1389 | const char *name; |
1374 | 1390 | ||
1391 | bindtextdomain(PACKAGE, LOCALEDIR); | ||
1392 | textdomain(PACKAGE); | ||
1393 | |||
1375 | #ifndef LKC_DIRECT_LINK | 1394 | #ifndef LKC_DIRECT_LINK |
1376 | kconfig_load(); | 1395 | kconfig_load(); |
1377 | #endif | 1396 | #endif |
diff --git a/scripts/patch-kernel b/scripts/patch-kernel index 43af01075612..f2d47ca9c8fa 100755 --- a/scripts/patch-kernel +++ b/scripts/patch-kernel | |||
@@ -46,6 +46,19 @@ | |||
46 | # fix some whitespace damage; | 46 | # fix some whitespace damage; |
47 | # be smarter about stopping when current version is larger than requested; | 47 | # be smarter about stopping when current version is larger than requested; |
48 | # Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18. | 48 | # Randy Dunlap <rddunlap@osdl.org>, 2004-AUG-18. |
49 | # | ||
50 | # Add better support for (non-incremental) 2.6.x.y patches; | ||
51 | # If an ending version number if not specified, the script automatically | ||
52 | # increments the SUBLEVEL (x in 2.6.x.y) until no more patch files are found; | ||
53 | # however, EXTRAVERSION (y in 2.6.x.y) is never automatically incremented | ||
54 | # but must be specified fully. | ||
55 | # | ||
56 | # patch-kernel does not normally support reverse patching, but does so when | ||
57 | # applying EXTRAVERSION (x.y) patches, so that moving from 2.6.11.y to 2.6.11.z | ||
58 | # is easy and handled by the script (reverse 2.6.11.y and apply 2.6.11.z). | ||
59 | # Randy Dunlap <rddunlap@osdl.org>, 2005-APR-08. | ||
60 | |||
61 | PNAME=patch-kernel | ||
49 | 62 | ||
50 | # Set directories from arguments, or use defaults. | 63 | # Set directories from arguments, or use defaults. |
51 | sourcedir=${1-/usr/src/linux} | 64 | sourcedir=${1-/usr/src/linux} |
@@ -54,7 +67,7 @@ stopvers=${3-default} | |||
54 | 67 | ||
55 | if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then | 68 | if [ "$1" == -h -o "$1" == --help -o ! -r "$sourcedir/Makefile" ]; then |
56 | cat << USAGE | 69 | cat << USAGE |
57 | usage: patch-kernel [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] | 70 | usage: $PNAME [-h] [ sourcedir [ patchdir [ stopversion ] [ -acxx ] ] ] |
58 | source directory defaults to /usr/src/linux, | 71 | source directory defaults to /usr/src/linux, |
59 | patch directory defaults to the current directory, | 72 | patch directory defaults to the current directory, |
60 | stopversion defaults to <all in patchdir>. | 73 | stopversion defaults to <all in patchdir>. |
@@ -73,6 +86,19 @@ do | |||
73 | done | 86 | done |
74 | 87 | ||
75 | # --------------------------------------------------------------------------- | 88 | # --------------------------------------------------------------------------- |
89 | # arg1 is filename | ||
90 | noFile () { | ||
91 | echo "cannot find patch file: ${patch}" | ||
92 | exit 1 | ||
93 | } | ||
94 | |||
95 | # --------------------------------------------------------------------------- | ||
96 | backwards () { | ||
97 | echo "$PNAME does not support reverse patching" | ||
98 | exit 1 | ||
99 | } | ||
100 | |||
101 | # --------------------------------------------------------------------------- | ||
76 | # Find a file, first parameter is basename of file | 102 | # Find a file, first parameter is basename of file |
77 | # it tries many compression mechanisms and sets variables to say how to get it | 103 | # it tries many compression mechanisms and sets variables to say how to get it |
78 | findFile () { | 104 | findFile () { |
@@ -133,6 +159,28 @@ applyPatch () { | |||
133 | return 0; | 159 | return 0; |
134 | } | 160 | } |
135 | 161 | ||
162 | # --------------------------------------------------------------------------- | ||
163 | # arg1 is patch filename | ||
164 | reversePatch () { | ||
165 | echo -n "Reversing $1 (${name}) ... " | ||
166 | if $uncomp ${patchdir}/"$1"${ext} | patch -p1 -Rs -N -E -d $sourcedir | ||
167 | then | ||
168 | echo "done." | ||
169 | else | ||
170 | echo "failed. Clean it up." | ||
171 | exit 1 | ||
172 | fi | ||
173 | if [ "`find $sourcedir/ '(' -name '*.rej' -o -name '.*.rej' ')' -print`" ] | ||
174 | then | ||
175 | echo "Aborting. Reject files found." | ||
176 | return 1 | ||
177 | fi | ||
178 | # Remove backup files | ||
179 | find $sourcedir/ '(' -name '*.orig' -o -name '.*.orig' ')' -exec rm -f {} \; | ||
180 | |||
181 | return 0 | ||
182 | } | ||
183 | |||
136 | # set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION | 184 | # set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION |
137 | TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; } | 185 | TMPFILE=`mktemp .tmpver.XXXXXX` || { echo "cannot make temp file" ; exit 1; } |
138 | grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE | 186 | grep -E "^(VERSION|PATCHLEVEL|SUBLEVEL|EXTRAVERSION)" $sourcedir/Makefile > $TMPFILE |
@@ -160,53 +208,57 @@ then | |||
160 | EXTRAVER=$EXTRAVERSION | 208 | EXTRAVER=$EXTRAVERSION |
161 | fi | 209 | fi |
162 | EXTRAVER=${EXTRAVER%%[[:punct:]]*} | 210 | EXTRAVER=${EXTRAVER%%[[:punct:]]*} |
163 | #echo "patch-kernel: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER" | 211 | #echo "$PNAME: changing EXTRAVERSION from $EXTRAVERSION to $EXTRAVER" |
164 | fi | 212 | fi |
165 | 213 | ||
166 | #echo "stopvers=$stopvers" | 214 | #echo "stopvers=$stopvers" |
167 | if [ $stopvers != "default" ]; then | 215 | if [ $stopvers != "default" ]; then |
168 | STOPSUBLEVEL=`echo $stopvers | cut -d. -f3` | 216 | STOPSUBLEVEL=`echo $stopvers | cut -d. -f3` |
169 | STOPEXTRA=`echo $stopvers | cut -d. -f4` | 217 | STOPEXTRA=`echo $stopvers | cut -d. -f4` |
170 | #echo "STOPSUBLEVEL=$STOPSUBLEVEL, STOPEXTRA=$STOPEXTRA" | 218 | #echo "#___STOPSUBLEVEL=/$STOPSUBLEVEL/, STOPEXTRA=/$STOPEXTRA/" |
171 | else | 219 | else |
172 | STOPSUBLEVEL=9999 | 220 | STOPSUBLEVEL=9999 |
173 | STOPEXTRA=9999 | 221 | STOPEXTRA=9999 |
174 | fi | 222 | fi |
175 | 223 | ||
176 | while : # incrementing SUBLEVEL (s in v.p.s) | 224 | # This all assumes a 2.6.x[.y] kernel tree. |
177 | do | 225 | # Don't allow backwards/reverse patching. |
178 | if [ x$EXTRAVER != "x" ]; then | 226 | if [ $STOPSUBLEVEL -lt $SUBLEVEL ]; then |
227 | backwards | ||
228 | fi | ||
229 | |||
230 | if [ x$EXTRAVER != "x" ]; then | ||
179 | CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER" | 231 | CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER" |
180 | else | 232 | else |
181 | CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" | 233 | CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" |
182 | fi | 234 | fi |
235 | |||
236 | if [ x$EXTRAVER != "x" ]; then | ||
237 | echo "backing up to: $VERSION.$PATCHLEVEL.$SUBLEVEL" | ||
238 | patch="patch-${CURRENTFULLVERSION}" | ||
239 | findFile $patchdir/${patch} || noFile ${patch} | ||
240 | reversePatch ${patch} || exit 1 | ||
241 | fi | ||
183 | 242 | ||
243 | # now current is 2.6.x, with no EXTRA applied, | ||
244 | # so update to target SUBLEVEL (2.6.SUBLEVEL) | ||
245 | # and then to target EXTRAVER (2.6.SUB.EXTRAVER) if requested. | ||
246 | # If not ending sublevel is specified, it is incremented until | ||
247 | # no further sublevels are found. | ||
248 | |||
249 | if [ $STOPSUBLEVEL -gt $SUBLEVEL ]; then | ||
250 | while : # incrementing SUBLEVEL (s in v.p.s) | ||
251 | do | ||
252 | CURRENTFULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" | ||
253 | EXTRAVER= | ||
184 | if [ $stopvers == $CURRENTFULLVERSION ]; then | 254 | if [ $stopvers == $CURRENTFULLVERSION ]; then |
185 | echo "Stopping at $CURRENTFULLVERSION base as requested." | 255 | echo "Stopping at $CURRENTFULLVERSION base as requested." |
186 | break | 256 | break |
187 | fi | 257 | fi |
188 | 258 | ||
189 | while : # incrementing EXTRAVER (x in v.p.s.x) | ||
190 | do | ||
191 | EXTRAVER=$((EXTRAVER + 1)) | ||
192 | FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$EXTRAVER" | ||
193 | #echo "... trying $FULLVERSION ..." | ||
194 | |||
195 | patch=patch-$FULLVERSION | ||
196 | |||
197 | # See if the file exists and find extension | ||
198 | findFile $patchdir/${patch} || break | ||
199 | |||
200 | # Apply the patch and check all is OK | ||
201 | applyPatch $patch || break | ||
202 | |||
203 | continue 2 | ||
204 | done | ||
205 | |||
206 | EXTRAVER= | ||
207 | SUBLEVEL=$((SUBLEVEL + 1)) | 259 | SUBLEVEL=$((SUBLEVEL + 1)) |
208 | FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" | 260 | FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL" |
209 | #echo "___ trying $FULLVERSION ___" | 261 | #echo "#___ trying $FULLVERSION ___" |
210 | 262 | ||
211 | if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then | 263 | if [ $((SUBLEVEL)) -gt $((STOPSUBLEVEL)) ]; then |
212 | echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)" | 264 | echo "Stopping since sublevel ($SUBLEVEL) is beyond stop-sublevel ($STOPSUBLEVEL)" |
@@ -214,14 +266,33 @@ do | |||
214 | fi | 266 | fi |
215 | 267 | ||
216 | patch=patch-$FULLVERSION | 268 | patch=patch-$FULLVERSION |
217 | |||
218 | # See if the file exists and find extension | 269 | # See if the file exists and find extension |
219 | findFile $patchdir/${patch} || break | 270 | findFile $patchdir/${patch} || noFile ${patch} |
220 | 271 | ||
221 | # Apply the patch and check all is OK | 272 | # Apply the patch and check all is OK |
222 | applyPatch $patch || break | 273 | applyPatch $patch || break |
223 | done | 274 | done |
224 | #echo "base all done" | 275 | #echo "#___sublevel all done" |
276 | fi | ||
277 | |||
278 | # There is no incremental searching for extraversion... | ||
279 | if [ "$STOPEXTRA" != "" ]; then | ||
280 | while : # just to allow break | ||
281 | do | ||
282 | # apply STOPEXTRA directly (not incrementally) (x in v.p.s.x) | ||
283 | FULLVERSION="$VERSION.$PATCHLEVEL.$SUBLEVEL.$STOPEXTRA" | ||
284 | #echo "#... trying $FULLVERSION ..." | ||
285 | patch=patch-$FULLVERSION | ||
286 | |||
287 | # See if the file exists and find extension | ||
288 | findFile $patchdir/${patch} || noFile ${patch} | ||
289 | |||
290 | # Apply the patch and check all is OK | ||
291 | applyPatch $patch || break | ||
292 | #echo "#___extraver all done" | ||
293 | break | ||
294 | done | ||
295 | fi | ||
225 | 296 | ||
226 | if [ x$gotac != x ]; then | 297 | if [ x$gotac != x ]; then |
227 | # Out great user wants the -ac patches | 298 | # Out great user wants the -ac patches |
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index 5a820cf88c9c..8449d667b062 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -476,8 +476,8 @@ int security_compute_av(u32 ssid, | |||
476 | int rc = 0; | 476 | int rc = 0; |
477 | 477 | ||
478 | if (!ss_initialized) { | 478 | if (!ss_initialized) { |
479 | avd->allowed = requested; | 479 | avd->allowed = 0xffffffff; |
480 | avd->decided = requested; | 480 | avd->decided = 0xffffffff; |
481 | avd->auditallow = 0; | 481 | avd->auditallow = 0; |
482 | avd->auditdeny = 0xffffffff; | 482 | avd->auditdeny = 0xffffffff; |
483 | avd->seqno = latest_granting; | 483 | avd->seqno = latest_granting; |
@@ -1196,9 +1196,11 @@ int security_load_policy(void *data, size_t len) | |||
1196 | } | 1196 | } |
1197 | policydb_loaded_version = policydb.policyvers; | 1197 | policydb_loaded_version = policydb.policyvers; |
1198 | ss_initialized = 1; | 1198 | ss_initialized = 1; |
1199 | 1199 | seqno = ++latest_granting; | |
1200 | LOAD_UNLOCK; | 1200 | LOAD_UNLOCK; |
1201 | selinux_complete_init(); | 1201 | selinux_complete_init(); |
1202 | avc_ss_reset(seqno); | ||
1203 | selnl_notify_policyload(seqno); | ||
1202 | return 0; | 1204 | return 0; |
1203 | } | 1205 | } |
1204 | 1206 | ||
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 4a6be966bd9f..3a3228b18726 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -164,6 +164,7 @@ config SND_INTERWAVE | |||
164 | select SND_RAWMIDI | 164 | select SND_RAWMIDI |
165 | select SND_CS4231_LIB | 165 | select SND_CS4231_LIB |
166 | select SND_GUS_SYNTH | 166 | select SND_GUS_SYNTH |
167 | select ISAPNP | ||
167 | help | 168 | help |
168 | Say Y here to include support for AMD InterWave based | 169 | Say Y here to include support for AMD InterWave based |
169 | soundcards (Gravis UltraSound Plug & Play, STB SoundRage32, | 170 | soundcards (Gravis UltraSound Plug & Play, STB SoundRage32, |
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c index 124b1e10a13d..3ecef4689f1b 100644 --- a/sound/oss/ac97_codec.c +++ b/sound/oss/ac97_codec.c | |||
@@ -155,6 +155,7 @@ static const struct { | |||
155 | {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops}, | 155 | {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops}, |
156 | {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops}, | 156 | {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops}, |
157 | {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops}, | 157 | {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops}, |
158 | {0x43585430, "CXT48", &default_ops, AC97_DELUDED_MODEM }, | ||
158 | {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM }, | 159 | {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM }, |
159 | {0x44543031, "Diamond Technology DT0893", &default_ops}, | 160 | {0x44543031, "Diamond Technology DT0893", &default_ops}, |
160 | {0x45838308, "ESS Allegro ES1988", &null_ops}, | 161 | {0x45838308, "ESS Allegro ES1988", &null_ops}, |
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index d143d2c78988..8b33b12fa5dc 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -125,8 +125,8 @@ MODULE_PARM_DESC(xbox, "Set to 1 for Xbox, if you have problems with the AC'97 c | |||
125 | #ifndef PCI_DEVICE_ID_INTEL_ICH7_20 | 125 | #ifndef PCI_DEVICE_ID_INTEL_ICH7_20 |
126 | #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de | 126 | #define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de |
127 | #endif | 127 | #endif |
128 | #ifndef PCI_DEVICE_ID_INTEL_ESB2_13 | 128 | #ifndef PCI_DEVICE_ID_INTEL_ESB2_14 |
129 | #define PCI_DEVICE_ID_INTEL_ESB2_13 0x2698 | 129 | #define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 |
130 | #endif | 130 | #endif |
131 | #ifndef PCI_DEVICE_ID_SI_7012 | 131 | #ifndef PCI_DEVICE_ID_SI_7012 |
132 | #define PCI_DEVICE_ID_SI_7012 0x7012 | 132 | #define PCI_DEVICE_ID_SI_7012 0x7012 |
@@ -2741,7 +2741,7 @@ static struct shortname_table { | |||
2741 | { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" }, | 2741 | { PCI_DEVICE_ID_INTEL_ESB_5, "Intel 6300ESB" }, |
2742 | { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" }, | 2742 | { PCI_DEVICE_ID_INTEL_ICH6_18, "Intel ICH6" }, |
2743 | { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" }, | 2743 | { PCI_DEVICE_ID_INTEL_ICH7_20, "Intel ICH7" }, |
2744 | { PCI_DEVICE_ID_INTEL_ESB2_13, "Intel ESB2" }, | 2744 | { PCI_DEVICE_ID_INTEL_ESB2_14, "Intel ESB2" }, |
2745 | { PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, | 2745 | { PCI_DEVICE_ID_SI_7012, "SiS SI7012" }, |
2746 | { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" }, | 2746 | { PCI_DEVICE_ID_NVIDIA_MCP_AUDIO, "NVidia nForce" }, |
2747 | { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" }, | 2747 | { PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO, "NVidia nForce2" }, |
diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index f1ce808501da..9b4d74d49f98 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c | |||
@@ -1836,7 +1836,7 @@ static void __devinit snd_via82xx_proc_init(via82xx_t *chip) | |||
1836 | * | 1836 | * |
1837 | */ | 1837 | */ |
1838 | 1838 | ||
1839 | static int __devinit snd_via82xx_chip_init(via82xx_t *chip) | 1839 | static int snd_via82xx_chip_init(via82xx_t *chip) |
1840 | { | 1840 | { |
1841 | unsigned int val; | 1841 | unsigned int val; |
1842 | int max_count; | 1842 | int max_count; |