Merge branch 'master' of /home/davem/src/GIT/linux-2.6/
Conflicts: drivers/net/pcmcia/fmvj18x_cs.c drivers/net/pcmcia/nmclan_cs.c drivers/net/pcmcia/xirc2ps_cs.c drivers/net/wireless/ray_cs.c
This commit is contained in:
commit
28b4d5cc17
325 changed files with 9119 additions and 9761 deletions
|
@ -1,185 +1,10 @@
|
|||
CONFIG_RCU_TRACE debugfs Files and Formats
|
||||
|
||||
|
||||
The rcupreempt and rcutree implementations of RCU provide debugfs trace
|
||||
output that summarizes counters and state. This information is useful for
|
||||
debugging RCU itself, and can sometimes also help to debug abuses of RCU.
|
||||
Note that the rcuclassic implementation of RCU does not provide debugfs
|
||||
trace output.
|
||||
|
||||
The following sections describe the debugfs files and formats for
|
||||
preemptable RCU (rcupreempt) and hierarchical RCU (rcutree).
|
||||
|
||||
|
||||
Preemptable RCU debugfs Files and Formats
|
||||
|
||||
This implementation of RCU provides three debugfs files under the
|
||||
top-level directory RCU: rcu/rcuctrs (which displays the per-CPU
|
||||
counters used by preemptable RCU) rcu/rcugp (which displays grace-period
|
||||
counters), and rcu/rcustats (which internal counters for debugging RCU).
|
||||
|
||||
The output of "cat rcu/rcuctrs" looks as follows:
|
||||
|
||||
CPU last cur F M
|
||||
0 5 -5 0 0
|
||||
1 -1 0 0 0
|
||||
2 0 1 0 0
|
||||
3 0 1 0 0
|
||||
4 0 1 0 0
|
||||
5 0 1 0 0
|
||||
6 0 2 0 0
|
||||
7 0 -1 0 0
|
||||
8 0 1 0 0
|
||||
ggp = 26226, state = waitzero
|
||||
|
||||
The per-CPU fields are as follows:
|
||||
|
||||
o "CPU" gives the CPU number. Offline CPUs are not displayed.
|
||||
|
||||
o "last" gives the value of the counter that is being decremented
|
||||
for the current grace period phase. In the example above,
|
||||
the counters sum to 4, indicating that there are still four
|
||||
RCU read-side critical sections still running that started
|
||||
before the last counter flip.
|
||||
|
||||
o "cur" gives the value of the counter that is currently being
|
||||
both incremented (by rcu_read_lock()) and decremented (by
|
||||
rcu_read_unlock()). In the example above, the counters sum to
|
||||
1, indicating that there is only one RCU read-side critical section
|
||||
still running that started after the last counter flip.
|
||||
|
||||
o "F" indicates whether RCU is waiting for this CPU to acknowledge
|
||||
a counter flip. In the above example, RCU is not waiting on any,
|
||||
which is consistent with the state being "waitzero" rather than
|
||||
"waitack".
|
||||
|
||||
o "M" indicates whether RCU is waiting for this CPU to execute a
|
||||
memory barrier. In the above example, RCU is not waiting on any,
|
||||
which is consistent with the state being "waitzero" rather than
|
||||
"waitmb".
|
||||
|
||||
o "ggp" is the global grace-period counter.
|
||||
|
||||
o "state" is the RCU state, which can be one of the following:
|
||||
|
||||
o "idle": there is no grace period in progress.
|
||||
|
||||
o "waitack": RCU just incremented the global grace-period
|
||||
counter, which has the effect of reversing the roles of
|
||||
the "last" and "cur" counters above, and is waiting for
|
||||
all the CPUs to acknowledge the flip. Once the flip has
|
||||
been acknowledged, CPUs will no longer be incrementing
|
||||
what are now the "last" counters, so that their sum will
|
||||
decrease monotonically down to zero.
|
||||
|
||||
o "waitzero": RCU is waiting for the sum of the "last" counters
|
||||
to decrease to zero.
|
||||
|
||||
o "waitmb": RCU is waiting for each CPU to execute a memory
|
||||
barrier, which ensures that instructions from a given CPU's
|
||||
last RCU read-side critical section cannot be reordered
|
||||
with instructions following the memory-barrier instruction.
|
||||
|
||||
The output of "cat rcu/rcugp" looks as follows:
|
||||
|
||||
oldggp=48870 newggp=48873
|
||||
|
||||
Note that reading from this file provokes a synchronize_rcu(). The
|
||||
"oldggp" value is that of "ggp" from rcu/rcuctrs above, taken before
|
||||
executing the synchronize_rcu(), and the "newggp" value is also the
|
||||
"ggp" value, but taken after the synchronize_rcu() command returns.
|
||||
|
||||
|
||||
The output of "cat rcu/rcugp" looks as follows:
|
||||
|
||||
na=1337955 nl=40 wa=1337915 wl=44 da=1337871 dl=0 dr=1337871 di=1337871
|
||||
1=50989 e1=6138 i1=49722 ie1=82 g1=49640 a1=315203 ae1=265563 a2=49640
|
||||
z1=1401244 ze1=1351605 z2=49639 m1=5661253 me1=5611614 m2=49639
|
||||
|
||||
These are counters tracking internal preemptable-RCU events, however,
|
||||
some of them may be useful for debugging algorithms using RCU. In
|
||||
particular, the "nl", "wl", and "dl" values track the number of RCU
|
||||
callbacks in various states. The fields are as follows:
|
||||
|
||||
o "na" is the total number of RCU callbacks that have been enqueued
|
||||
since boot.
|
||||
|
||||
o "nl" is the number of RCU callbacks waiting for the previous
|
||||
grace period to end so that they can start waiting on the next
|
||||
grace period.
|
||||
|
||||
o "wa" is the total number of RCU callbacks that have started waiting
|
||||
for a grace period since boot. "na" should be roughly equal to
|
||||
"nl" plus "wa".
|
||||
|
||||
o "wl" is the number of RCU callbacks currently waiting for their
|
||||
grace period to end.
|
||||
|
||||
o "da" is the total number of RCU callbacks whose grace periods
|
||||
have completed since boot. "wa" should be roughly equal to
|
||||
"wl" plus "da".
|
||||
|
||||
o "dr" is the total number of RCU callbacks that have been removed
|
||||
from the list of callbacks ready to invoke. "dr" should be roughly
|
||||
equal to "da".
|
||||
|
||||
o "di" is the total number of RCU callbacks that have been invoked
|
||||
since boot. "di" should be roughly equal to "da", though some
|
||||
early versions of preemptable RCU had a bug so that only the
|
||||
last CPU's count of invocations was displayed, rather than the
|
||||
sum of all CPU's counts.
|
||||
|
||||
o "1" is the number of calls to rcu_try_flip(). This should be
|
||||
roughly equal to the sum of "e1", "i1", "a1", "z1", and "m1"
|
||||
described below. In other words, the number of times that
|
||||
the state machine is visited should be equal to the sum of the
|
||||
number of times that each state is visited plus the number of
|
||||
times that the state-machine lock acquisition failed.
|
||||
|
||||
o "e1" is the number of times that rcu_try_flip() was unable to
|
||||
acquire the fliplock.
|
||||
|
||||
o "i1" is the number of calls to rcu_try_flip_idle().
|
||||
|
||||
o "ie1" is the number of times rcu_try_flip_idle() exited early
|
||||
due to the calling CPU having no work for RCU.
|
||||
|
||||
o "g1" is the number of times that rcu_try_flip_idle() decided
|
||||
to start a new grace period. "i1" should be roughly equal to
|
||||
"ie1" plus "g1".
|
||||
|
||||
o "a1" is the number of calls to rcu_try_flip_waitack().
|
||||
|
||||
o "ae1" is the number of times that rcu_try_flip_waitack() found
|
||||
that at least one CPU had not yet acknowledge the new grace period
|
||||
(AKA "counter flip").
|
||||
|
||||
o "a2" is the number of time rcu_try_flip_waitack() found that
|
||||
all CPUs had acknowledged. "a1" should be roughly equal to
|
||||
"ae1" plus "a2". (This particular output was collected on
|
||||
a 128-CPU machine, hence the smaller-than-usual fraction of
|
||||
calls to rcu_try_flip_waitack() finding all CPUs having already
|
||||
acknowledged.)
|
||||
|
||||
o "z1" is the number of calls to rcu_try_flip_waitzero().
|
||||
|
||||
o "ze1" is the number of times that rcu_try_flip_waitzero() found
|
||||
that not all of the old RCU read-side critical sections had
|
||||
completed.
|
||||
|
||||
o "z2" is the number of times that rcu_try_flip_waitzero() finds
|
||||
the sum of the counters equal to zero, in other words, that
|
||||
all of the old RCU read-side critical sections had completed.
|
||||
The value of "z1" should be roughly equal to "ze1" plus
|
||||
"z2".
|
||||
|
||||
o "m1" is the number of calls to rcu_try_flip_waitmb().
|
||||
|
||||
o "me1" is the number of times that rcu_try_flip_waitmb() finds
|
||||
that at least one CPU has not yet executed a memory barrier.
|
||||
|
||||
o "m2" is the number of times that rcu_try_flip_waitmb() finds that
|
||||
all CPUs have executed a memory barrier.
|
||||
The rcutree implementation of RCU provides debugfs trace output that
|
||||
summarizes counters and state. This information is useful for debugging
|
||||
RCU itself, and can sometimes also help to debug abuses of RCU.
|
||||
The following sections describe the debugfs files and formats.
|
||||
|
||||
|
||||
Hierarchical RCU debugfs Files and Formats
|
||||
|
@ -210,9 +35,10 @@ rcu_bh:
|
|||
6 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=859/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||
7 c=-275 g=-275 pq=1 pqc=-275 qp=0 dt=3761/1 dn=0 df=15 of=0 ri=0 ql=0 b=10
|
||||
|
||||
The first section lists the rcu_data structures for rcu, the second for
|
||||
rcu_bh. Each section has one line per CPU, or eight for this 8-CPU system.
|
||||
The fields are as follows:
|
||||
The first section lists the rcu_data structures for rcu_sched, the second
|
||||
for rcu_bh. Note that CONFIG_TREE_PREEMPT_RCU kernels will have an
|
||||
additional section for rcu_preempt. Each section has one line per CPU,
|
||||
or eight for this 8-CPU system. The fields are as follows:
|
||||
|
||||
o The number at the beginning of each line is the CPU number.
|
||||
CPUs numbers followed by an exclamation mark are offline,
|
||||
|
@ -223,9 +49,9 @@ o The number at the beginning of each line is the CPU number.
|
|||
|
||||
o "c" is the count of grace periods that this CPU believes have
|
||||
completed. CPUs in dynticks idle mode may lag quite a ways
|
||||
behind, for example, CPU 4 under "rcu" above, which has slept
|
||||
through the past 25 RCU grace periods. It is not unusual to
|
||||
see CPUs lagging by thousands of grace periods.
|
||||
behind, for example, CPU 4 under "rcu_sched" above, which has
|
||||
slept through the past 25 RCU grace periods. It is not unusual
|
||||
to see CPUs lagging by thousands of grace periods.
|
||||
|
||||
o "g" is the count of grace periods that this CPU believes have
|
||||
started. Again, CPUs in dynticks idle mode may lag behind.
|
||||
|
@ -308,8 +134,10 @@ The output of "cat rcu/rcugp" looks as follows:
|
|||
rcu_sched: completed=33062 gpnum=33063
|
||||
rcu_bh: completed=464 gpnum=464
|
||||
|
||||
Again, this output is for both "rcu" and "rcu_bh". The fields are
|
||||
taken from the rcu_state structure, and are as follows:
|
||||
Again, this output is for both "rcu_sched" and "rcu_bh". Note that
|
||||
kernels built with CONFIG_TREE_PREEMPT_RCU will have an additional
|
||||
"rcu_preempt" line. The fields are taken from the rcu_state structure,
|
||||
and are as follows:
|
||||
|
||||
o "completed" is the number of grace periods that have completed.
|
||||
It is comparable to the "c" field from rcu/rcudata in that a
|
||||
|
@ -324,23 +152,24 @@ o "gpnum" is the number of grace periods that have started. It is
|
|||
If these two fields are equal (as they are for "rcu_bh" above),
|
||||
then there is no grace period in progress, in other words, RCU
|
||||
is idle. On the other hand, if the two fields differ (as they
|
||||
do for "rcu" above), then an RCU grace period is in progress.
|
||||
do for "rcu_sched" above), then an RCU grace period is in progress.
|
||||
|
||||
|
||||
The output of "cat rcu/rcuhier" looks as follows, with very long lines:
|
||||
|
||||
c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6
|
||||
1/1 0:127 ^0
|
||||
3/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
|
||||
3/3f 0:5 ^0 2/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
|
||||
c=6902 g=6903 s=2 jfq=3 j=72c7 nfqs=13142/nfqsng=0(13142) fqlh=6 oqlen=0
|
||||
1/1 .>. 0:127 ^0
|
||||
3/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
|
||||
3/3f .>. 0:5 ^0 2/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
|
||||
rcu_bh:
|
||||
c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0
|
||||
0/1 0:127 ^0
|
||||
0/3 0:35 ^0 0/0 36:71 ^1 0/0 72:107 ^2 0/0 108:127 ^3
|
||||
0/3f 0:5 ^0 0/3 6:11 ^1 0/0 12:17 ^2 0/0 18:23 ^3 0/0 24:29 ^4 0/0 30:35 ^5 0/0 36:41 ^0 0/0 42:47 ^1 0/0 48:53 ^2 0/0 54:59 ^3 0/0 60:65 ^4 0/0 66:71 ^5 0/0 72:77 ^0 0/0 78:83 ^1 0/0 84:89 ^2 0/0 90:95 ^3 0/0 96:101 ^4 0/0 102:107 ^5 0/0 108:113 ^0 0/0 114:119 ^1 0/0 120:125 ^2 0/0 126:127 ^3
|
||||
c=-226 g=-226 s=1 jfq=-5701 j=72c7 nfqs=88/nfqsng=0(88) fqlh=0 oqlen=0
|
||||
0/1 .>. 0:127 ^0
|
||||
0/3 .>. 0:35 ^0 0/0 .>. 36:71 ^1 0/0 .>. 72:107 ^2 0/0 .>. 108:127 ^3
|
||||
0/3f .>. 0:5 ^0 0/3 .>. 6:11 ^1 0/0 .>. 12:17 ^2 0/0 .>. 18:23 ^3 0/0 .>. 24:29 ^4 0/0 .>. 30:35 ^5 0/0 .>. 36:41 ^0 0/0 .>. 42:47 ^1 0/0 .>. 48:53 ^2 0/0 .>. 54:59 ^3 0/0 .>. 60:65 ^4 0/0 .>. 66:71 ^5 0/0 .>. 72:77 ^0 0/0 .>. 78:83 ^1 0/0 .>. 84:89 ^2 0/0 .>. 90:95 ^3 0/0 .>. 96:101 ^4 0/0 .>. 102:107 ^5 0/0 .>. 108:113 ^0 0/0 .>. 114:119 ^1 0/0 .>. 120:125 ^2 0/0 .>. 126:127 ^3
|
||||
|
||||
This is once again split into "rcu" and "rcu_bh" portions. The fields are
|
||||
as follows:
|
||||
This is once again split into "rcu_sched" and "rcu_bh" portions,
|
||||
and CONFIG_TREE_PREEMPT_RCU kernels will again have an additional
|
||||
"rcu_preempt" section. The fields are as follows:
|
||||
|
||||
o "c" is exactly the same as "completed" under rcu/rcugp.
|
||||
|
||||
|
@ -372,6 +201,11 @@ o "fqlh" is the number of calls to force_quiescent_state() that
|
|||
exited immediately (without even being counted in nfqs above)
|
||||
due to contention on ->fqslock.
|
||||
|
||||
o "oqlen" is the number of callbacks on the "orphan" callback
|
||||
list. RCU callbacks are placed on this list by CPUs going
|
||||
offline, and are "adopted" either by the CPU helping the outgoing
|
||||
CPU or by the next rcu_barrier*() call, whichever comes first.
|
||||
|
||||
o Each element of the form "1/1 0:127 ^0" represents one struct
|
||||
rcu_node. Each line represents one level of the hierarchy, from
|
||||
root to leaves. It is best to think of the rcu_data structures
|
||||
|
@ -379,7 +213,7 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
|||
might be either one, two, or three levels of rcu_node structures,
|
||||
depending on the relationship between CONFIG_RCU_FANOUT and
|
||||
CONFIG_NR_CPUS.
|
||||
|
||||
|
||||
o The numbers separated by the "/" are the qsmask followed
|
||||
by the qsmaskinit. The qsmask will have one bit
|
||||
set for each entity in the next lower level that
|
||||
|
@ -389,10 +223,19 @@ o Each element of the form "1/1 0:127 ^0" represents one struct
|
|||
The value of qsmaskinit is assigned to that of qsmask
|
||||
at the beginning of each grace period.
|
||||
|
||||
For example, for "rcu", the qsmask of the first entry
|
||||
of the lowest level is 0x14, meaning that we are still
|
||||
waiting for CPUs 2 and 4 to check in for the current
|
||||
grace period.
|
||||
For example, for "rcu_sched", the qsmask of the first
|
||||
entry of the lowest level is 0x14, meaning that we
|
||||
are still waiting for CPUs 2 and 4 to check in for the
|
||||
current grace period.
|
||||
|
||||
o The characters separated by the ">" indicate the state
|
||||
of the blocked-tasks lists. A "T" preceding the ">"
|
||||
indicates that at least one task blocked in an RCU
|
||||
read-side critical section blocks the current grace
|
||||
period, while a "." preceding the ">" indicates otherwise.
|
||||
The character following the ">" indicates similarly for
|
||||
the next grace period. A "T" should appear in this
|
||||
field only for rcu-preempt.
|
||||
|
||||
o The numbers separated by the ":" are the range of CPUs
|
||||
served by this struct rcu_node. This can be helpful
|
||||
|
@ -431,8 +274,9 @@ rcu_bh:
|
|||
6 np=120834 qsp=9902 cbr=0 cng=0 gpc=6 gps=3 nf=2 nn=110921
|
||||
7 np=144888 qsp=26336 cbr=0 cng=0 gpc=8 gps=2 nf=0 nn=118542
|
||||
|
||||
As always, this is once again split into "rcu" and "rcu_bh" portions.
|
||||
The fields are as follows:
|
||||
As always, this is once again split into "rcu_sched" and "rcu_bh"
|
||||
portions, with CONFIG_TREE_PREEMPT_RCU kernels having an additional
|
||||
"rcu_preempt" section. The fields are as follows:
|
||||
|
||||
o "np" is the number of times that __rcu_pending() has been invoked
|
||||
for the corresponding flavor of RCU.
|
||||
|
|
|
@ -830,7 +830,7 @@ sched: Critical sections Grace period Barrier
|
|||
SRCU: Critical sections Grace period Barrier
|
||||
|
||||
srcu_read_lock synchronize_srcu N/A
|
||||
srcu_read_unlock
|
||||
srcu_read_unlock synchronize_srcu_expedited
|
||||
|
||||
SRCU: Initialization/cleanup
|
||||
init_srcu_struct
|
||||
|
|
|
@ -65,6 +65,7 @@ aicdb.h*
|
|||
asm-offsets.h
|
||||
asm_offsets.h
|
||||
autoconf.h*
|
||||
av_permissions.h
|
||||
bbootsect
|
||||
bin2c
|
||||
binkernel.spec
|
||||
|
@ -95,12 +96,14 @@ docproc
|
|||
elf2ecoff
|
||||
elfconfig.h*
|
||||
fixdep
|
||||
flask.h
|
||||
fore200e_mkfirm
|
||||
fore200e_pca_fw.c*
|
||||
gconf
|
||||
gen-devlist
|
||||
gen_crc32table
|
||||
gen_init_cpio
|
||||
genheaders
|
||||
genksyms
|
||||
*_gray256.c
|
||||
ihex2fw
|
||||
|
|
|
@ -85,7 +85,6 @@ parameter is applicable:
|
|||
PPT Parallel port support is enabled.
|
||||
PS2 Appropriate PS/2 support is enabled.
|
||||
RAM RAM disk support is enabled.
|
||||
ROOTPLUG The example Root Plug LSM is enabled.
|
||||
S390 S390 architecture is enabled.
|
||||
SCSI Appropriate SCSI support is enabled.
|
||||
A lot of drivers has their options described inside of
|
||||
|
@ -779,6 +778,13 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
by the set_ftrace_notrace file in the debugfs
|
||||
tracing directory.
|
||||
|
||||
ftrace_graph_filter=[function-list]
|
||||
[FTRACE] Limit the top level callers functions traced
|
||||
by the function graph tracer at boot up.
|
||||
function-list is a comma separated list of functions
|
||||
that can be changed at run time by the
|
||||
set_graph_function file in the debugfs tracing directory.
|
||||
|
||||
gamecon.map[2|3]=
|
||||
[HW,JOY] Multisystem joystick and NES/SNES/PSX pad
|
||||
support via parallel port (up to 5 devices per port)
|
||||
|
@ -2032,8 +2038,15 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
|
||||
print-fatal-signals=
|
||||
[KNL] debug: print fatal signals
|
||||
print-fatal-signals=1: print segfault info to
|
||||
the kernel console.
|
||||
|
||||
If enabled, warn about various signal handling
|
||||
related application anomalies: too many signals,
|
||||
too many POSIX.1 timers, fatal signals causing a
|
||||
coredump - etc.
|
||||
|
||||
If you hit the warning due to signal overflow,
|
||||
you might want to try "ulimit -i unlimited".
|
||||
|
||||
default: off.
|
||||
|
||||
printk.time= Show timing data prefixed to each printk message line
|
||||
|
@ -2164,15 +2177,6 @@ and is between 256 and 4096 characters. It is defined in the file
|
|||
Useful for devices that are detected asynchronously
|
||||
(e.g. USB and MMC devices).
|
||||
|
||||
root_plug.vendor_id=
|
||||
[ROOTPLUG] Override the default vendor ID
|
||||
|
||||
root_plug.product_id=
|
||||
[ROOTPLUG] Override the default product ID
|
||||
|
||||
root_plug.debug=
|
||||
[ROOTPLUG] Enable debugging output
|
||||
|
||||
rw [KNL] Mount root device read-write on boot
|
||||
|
||||
S [KNL] Run init in single mode
|
||||
|
|
|
@ -1,5 +1,17 @@
|
|||
This file details changes in 2.6 which affect PCMCIA card driver authors:
|
||||
|
||||
* no cs_error / CS_CHECK / CONFIG_PCMCIA_DEBUG (as of 2.6.33)
|
||||
Instead of the cs_error() callback or the CS_CHECK() macro, please use
|
||||
Linux-style checking of return values, and -- if necessary -- debug
|
||||
messages using "dev_dbg()" or "pr_debug()".
|
||||
|
||||
* New CIS tuple access (as of 2.6.33)
|
||||
Instead of pcmcia_get_{first,next}_tuple(), pcmcia_get_tuple_data() and
|
||||
pcmcia_parse_tuple(), a driver shall use "pcmcia_get_tuple()" if it is
|
||||
only interested in one (raw) tuple, or "pcmcia_loop_tuple()" if it is
|
||||
interested in all tuples of one type. To decode the MAC from CISTPL_FUNCE,
|
||||
a new helper "pcmcia_get_mac_from_cis()" was added.
|
||||
|
||||
* New configuration loop helper (as of 2.6.28)
|
||||
By calling pcmcia_loop_config(), a driver can iterate over all available
|
||||
configuration options. During a driver's probe() phase, one doesn't need
|
||||
|
|
|
@ -213,10 +213,19 @@ If you can't trace NMI functions, then skip this option.
|
|||
<details to be filled>
|
||||
|
||||
|
||||
HAVE_FTRACE_SYSCALLS
|
||||
HAVE_SYSCALL_TRACEPOINTS
|
||||
---------------------
|
||||
|
||||
<details to be filled>
|
||||
You need very few things to get the syscalls tracing in an arch.
|
||||
|
||||
- Have a NR_syscalls variable in <asm/unistd.h> that provides the number
|
||||
of syscalls supported by the arch.
|
||||
- Implement arch_syscall_addr() that resolves a syscall address from a
|
||||
syscall number.
|
||||
- Support the TIF_SYSCALL_TRACEPOINT thread flags
|
||||
- Put the trace_sys_enter() and trace_sys_exit() tracepoints calls from ptrace
|
||||
in the ptrace syscalls tracing path.
|
||||
- Tag this arch as HAVE_SYSCALL_TRACEPOINTS.
|
||||
|
||||
|
||||
HAVE_FTRACE_MCOUNT_RECORD
|
||||
|
|
|
@ -3023,11 +3023,8 @@ S: Maintained
|
|||
F: fs/autofs4/
|
||||
|
||||
KERNEL BUILD
|
||||
M: Sam Ravnborg <sam@ravnborg.org>
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-next.git
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild-fixes.git
|
||||
L: linux-kbuild@vger.kernel.org
|
||||
S: Maintained
|
||||
S: Orphan
|
||||
F: Documentation/kbuild/
|
||||
F: Makefile
|
||||
F: scripts/Makefile.*
|
||||
|
|
3
Makefile
3
Makefile
|
@ -1,7 +1,7 @@
|
|||
VERSION = 2
|
||||
PATCHLEVEL = 6
|
||||
SUBLEVEL = 32
|
||||
EXTRAVERSION = -rc8
|
||||
EXTRAVERSION =
|
||||
NAME = Man-Eating Seals of Antiquity
|
||||
|
||||
# *DOCUMENTATION*
|
||||
|
@ -379,6 +379,7 @@ export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exc
|
|||
PHONY += scripts_basic
|
||||
scripts_basic:
|
||||
$(Q)$(MAKE) $(build)=scripts/basic
|
||||
$(Q)rm -f .tmp_quiet_recordmcount
|
||||
|
||||
# To avoid any implicit rule to kick in, define an empty command.
|
||||
scripts/basic/%: scripts_basic ;
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
#define BUG() \
|
||||
do { \
|
||||
_BUG_OR_WARN(0); \
|
||||
for (;;); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(condition) \
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
#include <linux/dma-mapping.h>
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
extern int swiotlb_force;
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
extern int swiotlb;
|
||||
extern void pci_swiotlb_init(void);
|
||||
|
|
|
@ -41,7 +41,7 @@ struct dma_map_ops swiotlb_dma_ops = {
|
|||
void __init swiotlb_dma_init(void)
|
||||
{
|
||||
dma_ops = &swiotlb_dma_ops;
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
}
|
||||
|
||||
void __init pci_swiotlb_init(void)
|
||||
|
@ -51,7 +51,7 @@ void __init pci_swiotlb_init(void)
|
|||
swiotlb = 1;
|
||||
printk(KERN_INFO "PCI-DMA: Re-initialize machine vector.\n");
|
||||
machvec_init("dig");
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
dma_ops = &swiotlb_dma_ops;
|
||||
#else
|
||||
panic("Unable to find Intel IOMMU");
|
||||
|
|
|
@ -11,9 +11,7 @@
|
|||
static inline void __noreturn BUG(void)
|
||||
{
|
||||
__asm__ __volatile__("break %0" : : "i" (BRK_BUG));
|
||||
/* Fool GCC into thinking the function doesn't return. */
|
||||
while (1)
|
||||
;
|
||||
unreachable();
|
||||
}
|
||||
|
||||
#define HAVE_ARCH_BUG
|
||||
|
|
|
@ -306,6 +306,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
|||
|
||||
if (cpu_has_llsc && R10000_LLSC_WAR) {
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" li %[err], 0 \n"
|
||||
"1: ll %[old], (%[addr]) \n"
|
||||
" move %[tmp], %[new] \n"
|
||||
|
@ -320,6 +321,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
|||
" "STR(PTR)" 1b, 4b \n"
|
||||
" "STR(PTR)" 2b, 4b \n"
|
||||
" .previous \n"
|
||||
" .set mips0 \n"
|
||||
: [old] "=&r" (old),
|
||||
[err] "=&r" (err),
|
||||
[tmp] "=&r" (tmp)
|
||||
|
@ -329,6 +331,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
|||
: "memory");
|
||||
} else if (cpu_has_llsc) {
|
||||
__asm__ __volatile__ (
|
||||
" .set mips3 \n"
|
||||
" li %[err], 0 \n"
|
||||
"1: ll %[old], (%[addr]) \n"
|
||||
" move %[tmp], %[new] \n"
|
||||
|
@ -347,6 +350,7 @@ static inline int mips_atomic_set(struct pt_regs *regs,
|
|||
" "STR(PTR)" 1b, 5b \n"
|
||||
" "STR(PTR)" 2b, 5b \n"
|
||||
" .previous \n"
|
||||
" .set mips0 \n"
|
||||
: [old] "=&r" (old),
|
||||
[err] "=&r" (err),
|
||||
[tmp] "=&r" (tmp)
|
||||
|
|
|
@ -110,7 +110,6 @@ static struct korina_device korina_dev0_data = {
|
|||
static struct platform_device korina_dev0 = {
|
||||
.id = -1,
|
||||
.name = "korina",
|
||||
.dev.driver_data = &korina_dev0_data,
|
||||
.resource = korina_dev0_res,
|
||||
.num_resources = ARRAY_SIZE(korina_dev0_res),
|
||||
};
|
||||
|
@ -332,6 +331,8 @@ static int __init plat_setup_devices(void)
|
|||
/* set the uart clock to the current cpu frequency */
|
||||
rb532_uart_res[0].uartclk = idt_cpu_freq;
|
||||
|
||||
dev_set_drvdata(&korina_dev0.dev, &korina_dev0_data);
|
||||
|
||||
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
|
||||
}
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (ppc_swiotlb_enable)
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
|
|
@ -550,7 +550,7 @@ void __init setup_arch(char **cmdline_p)
|
|||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
if (ppc_swiotlb_enable)
|
||||
swiotlb_init();
|
||||
swiotlb_init(1);
|
||||
#endif
|
||||
|
||||
paging_init();
|
||||
|
|
|
@ -95,6 +95,34 @@ config S390
|
|||
select HAVE_ARCH_TRACEHOOK
|
||||
select INIT_ALL_POSSIBLE
|
||||
select HAVE_PERF_EVENTS
|
||||
select ARCH_INLINE_SPIN_TRYLOCK
|
||||
select ARCH_INLINE_SPIN_TRYLOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK
|
||||
select ARCH_INLINE_SPIN_LOCK_BH
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_SPIN_UNLOCK
|
||||
select ARCH_INLINE_SPIN_UNLOCK_BH
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQ
|
||||
select ARCH_INLINE_SPIN_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_READ_TRYLOCK
|
||||
select ARCH_INLINE_READ_LOCK
|
||||
select ARCH_INLINE_READ_LOCK_BH
|
||||
select ARCH_INLINE_READ_LOCK_IRQ
|
||||
select ARCH_INLINE_READ_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_READ_UNLOCK
|
||||
select ARCH_INLINE_READ_UNLOCK_BH
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQ
|
||||
select ARCH_INLINE_READ_UNLOCK_IRQRESTORE
|
||||
select ARCH_INLINE_WRITE_TRYLOCK
|
||||
select ARCH_INLINE_WRITE_LOCK
|
||||
select ARCH_INLINE_WRITE_LOCK_BH
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_LOCK_IRQSAVE
|
||||
select ARCH_INLINE_WRITE_UNLOCK
|
||||
select ARCH_INLINE_WRITE_UNLOCK_BH
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQ
|
||||
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
|
||||
|
||||
config SCHED_OMIT_FRAME_POINTER
|
||||
bool
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
|
||||
#define BUG() do { \
|
||||
__EMIT_BUG(0); \
|
||||
for (;;); \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#define WARN_ON(x) ({ \
|
||||
|
|
|
@ -191,33 +191,4 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
|
|||
#define _raw_read_relax(lock) cpu_relax()
|
||||
#define _raw_write_relax(lock) cpu_relax()
|
||||
|
||||
#define __always_inline__spin_lock
|
||||
#define __always_inline__read_lock
|
||||
#define __always_inline__write_lock
|
||||
#define __always_inline__spin_lock_bh
|
||||
#define __always_inline__read_lock_bh
|
||||
#define __always_inline__write_lock_bh
|
||||
#define __always_inline__spin_lock_irq
|
||||
#define __always_inline__read_lock_irq
|
||||
#define __always_inline__write_lock_irq
|
||||
#define __always_inline__spin_lock_irqsave
|
||||
#define __always_inline__read_lock_irqsave
|
||||
#define __always_inline__write_lock_irqsave
|
||||
#define __always_inline__spin_trylock
|
||||
#define __always_inline__read_trylock
|
||||
#define __always_inline__write_trylock
|
||||
#define __always_inline__spin_trylock_bh
|
||||
#define __always_inline__spin_unlock
|
||||
#define __always_inline__read_unlock
|
||||
#define __always_inline__write_unlock
|
||||
#define __always_inline__spin_unlock_bh
|
||||
#define __always_inline__read_unlock_bh
|
||||
#define __always_inline__write_unlock_bh
|
||||
#define __always_inline__spin_unlock_irq
|
||||
#define __always_inline__read_unlock_irq
|
||||
#define __always_inline__write_unlock_irq
|
||||
#define __always_inline__spin_unlock_irqrestore
|
||||
#define __always_inline__read_unlock_irqrestore
|
||||
#define __always_inline__write_unlock_irqrestore
|
||||
|
||||
#endif /* __ASM_SPINLOCK_H */
|
||||
|
|
|
@ -203,73 +203,10 @@ out:
|
|||
|
||||
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||
|
||||
extern unsigned long __start_syscalls_metadata[];
|
||||
extern unsigned long __stop_syscalls_metadata[];
|
||||
extern unsigned int sys_call_table[];
|
||||
|
||||
static struct syscall_metadata **syscalls_metadata;
|
||||
|
||||
struct syscall_metadata *syscall_nr_to_meta(int nr)
|
||||
unsigned long __init arch_syscall_addr(int nr)
|
||||
{
|
||||
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
|
||||
return NULL;
|
||||
|
||||
return syscalls_metadata[nr];
|
||||
return (unsigned long)sys_call_table[nr];
|
||||
}
|
||||
|
||||
int syscall_name_to_nr(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!syscalls_metadata)
|
||||
return -1;
|
||||
for (i = 0; i < NR_syscalls; i++)
|
||||
if (syscalls_metadata[i])
|
||||
if (!strcmp(syscalls_metadata[i]->name, name))
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_syscall_enter_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->enter_id = id;
|
||||
}
|
||||
|
||||
void set_syscall_exit_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->exit_id = id;
|
||||
}
|
||||
|
||||
static struct syscall_metadata *find_syscall_meta(unsigned long syscall)
|
||||
{
|
||||
struct syscall_metadata *start;
|
||||
struct syscall_metadata *stop;
|
||||
char str[KSYM_SYMBOL_LEN];
|
||||
|
||||
start = (struct syscall_metadata *)__start_syscalls_metadata;
|
||||
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
|
||||
kallsyms_lookup(syscall, NULL, NULL, NULL, str);
|
||||
|
||||
for ( ; start < stop; start++) {
|
||||
if (start->name && !strcmp(start->name + 3, str + 3))
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int __init arch_init_ftrace_syscalls(void)
|
||||
{
|
||||
struct syscall_metadata *meta;
|
||||
int i;
|
||||
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) * NR_syscalls,
|
||||
GFP_KERNEL);
|
||||
if (!syscalls_metadata)
|
||||
return -ENOMEM;
|
||||
for (i = 0; i < NR_syscalls; i++) {
|
||||
meta = find_syscall_meta((unsigned long)sys_call_table[i]);
|
||||
syscalls_metadata[i] = meta;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(arch_init_ftrace_syscalls);
|
||||
#endif
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
|
||||
* Author: Joerg Roedel <joerg.roedel@amd.com>
|
||||
* Leo Duran <leo.duran@amd.com>
|
||||
*
|
||||
|
@ -23,19 +23,13 @@
|
|||
#include <linux/irqreturn.h>
|
||||
|
||||
#ifdef CONFIG_AMD_IOMMU
|
||||
extern int amd_iommu_init(void);
|
||||
extern int amd_iommu_init_dma_ops(void);
|
||||
extern int amd_iommu_init_passthrough(void);
|
||||
|
||||
extern void amd_iommu_detect(void);
|
||||
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
||||
extern void amd_iommu_flush_all_domains(void);
|
||||
extern void amd_iommu_flush_all_devices(void);
|
||||
extern void amd_iommu_shutdown(void);
|
||||
extern void amd_iommu_apply_erratum_63(u16 devid);
|
||||
|
||||
#else
|
||||
static inline int amd_iommu_init(void) { return -ENODEV; }
|
||||
|
||||
static inline void amd_iommu_detect(void) { }
|
||||
static inline void amd_iommu_shutdown(void) { }
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_X86_AMD_IOMMU_H */
|
||||
|
|
38
arch/x86/include/asm/amd_iommu_proto.h
Normal file
38
arch/x86/include/asm/amd_iommu_proto.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (C) 2009 Advanced Micro Devices, Inc.
|
||||
* Author: Joerg Roedel <joerg.roedel@amd.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published
|
||||
* by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef _ASM_X86_AMD_IOMMU_PROTO_H
|
||||
#define _ASM_X86_AMD_IOMMU_PROTO_H
|
||||
|
||||
struct amd_iommu;
|
||||
|
||||
extern int amd_iommu_init_dma_ops(void);
|
||||
extern int amd_iommu_init_passthrough(void);
|
||||
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
|
||||
extern void amd_iommu_flush_all_domains(void);
|
||||
extern void amd_iommu_flush_all_devices(void);
|
||||
extern void amd_iommu_apply_erratum_63(u16 devid);
|
||||
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
|
||||
|
||||
#ifndef CONFIG_AMD_IOMMU_STATS
|
||||
|
||||
static inline void amd_iommu_stats_init(void) { }
|
||||
|
||||
#endif /* !CONFIG_AMD_IOMMU_STATS */
|
||||
|
||||
#endif /* _ASM_X86_AMD_IOMMU_PROTO_H */
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
|
||||
* Author: Joerg Roedel <joerg.roedel@amd.com>
|
||||
* Leo Duran <leo.duran@amd.com>
|
||||
*
|
||||
|
@ -24,6 +24,11 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
/*
|
||||
* Maximum number of IOMMUs supported
|
||||
*/
|
||||
#define MAX_IOMMUS 32
|
||||
|
||||
/*
|
||||
* some size calculation constants
|
||||
*/
|
||||
|
@ -206,6 +211,9 @@ extern bool amd_iommu_dump;
|
|||
printk(KERN_INFO "AMD-Vi: " format, ## arg); \
|
||||
} while(0);
|
||||
|
||||
/* global flag if IOMMUs cache non-present entries */
|
||||
extern bool amd_iommu_np_cache;
|
||||
|
||||
/*
|
||||
* Make iterating over all IOMMUs easier
|
||||
*/
|
||||
|
@ -226,6 +234,8 @@ extern bool amd_iommu_dump;
|
|||
* independent of their use.
|
||||
*/
|
||||
struct protection_domain {
|
||||
struct list_head list; /* for list of all protection domains */
|
||||
struct list_head dev_list; /* List of all devices in this domain */
|
||||
spinlock_t lock; /* mostly used to lock the page table*/
|
||||
u16 id; /* the domain id written to the device table */
|
||||
int mode; /* paging mode (0-6 levels) */
|
||||
|
@ -233,7 +243,20 @@ struct protection_domain {
|
|||
unsigned long flags; /* flags to find out type of domain */
|
||||
bool updated; /* complete domain flush required */
|
||||
unsigned dev_cnt; /* devices assigned to this domain */
|
||||
unsigned dev_iommu[MAX_IOMMUS]; /* per-IOMMU reference count */
|
||||
void *priv; /* private data */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* This struct contains device specific data for the IOMMU
|
||||
*/
|
||||
struct iommu_dev_data {
|
||||
struct list_head list; /* For domain->dev_list */
|
||||
struct device *dev; /* Device this data belong to */
|
||||
struct device *alias; /* The Alias Device */
|
||||
struct protection_domain *domain; /* Domain the device is bound to */
|
||||
atomic_t bind; /* Domain attach reverent count */
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -291,6 +314,9 @@ struct dma_ops_domain {
|
|||
struct amd_iommu {
|
||||
struct list_head list;
|
||||
|
||||
/* Index within the IOMMU array */
|
||||
int index;
|
||||
|
||||
/* locks the accesses to the hardware */
|
||||
spinlock_t lock;
|
||||
|
||||
|
@ -356,6 +382,21 @@ struct amd_iommu {
|
|||
*/
|
||||
extern struct list_head amd_iommu_list;
|
||||
|
||||
/*
|
||||
* Array with pointers to each IOMMU struct
|
||||
* The indices are referenced in the protection domains
|
||||
*/
|
||||
extern struct amd_iommu *amd_iommus[MAX_IOMMUS];
|
||||
|
||||
/* Number of IOMMUs present in the system */
|
||||
extern int amd_iommus_present;
|
||||
|
||||
/*
|
||||
* Declarations for the global list of all protection domains
|
||||
*/
|
||||
extern spinlock_t amd_iommu_pd_lock;
|
||||
extern struct list_head amd_iommu_pd_list;
|
||||
|
||||
/*
|
||||
* Structure defining one entry in the device table
|
||||
*/
|
||||
|
@ -416,15 +457,9 @@ extern unsigned amd_iommu_aperture_order;
|
|||
/* largest PCI device id we expect translation requests for */
|
||||
extern u16 amd_iommu_last_bdf;
|
||||
|
||||
/* data structures for protection domain handling */
|
||||
extern struct protection_domain **amd_iommu_pd_table;
|
||||
|
||||
/* allocation bitmap for domain ids */
|
||||
extern unsigned long *amd_iommu_pd_alloc_bitmap;
|
||||
|
||||
/* will be 1 if device isolation is enabled */
|
||||
extern bool amd_iommu_isolate;
|
||||
|
||||
/*
|
||||
* If true, the addresses will be flushed on unmap time, not when
|
||||
* they are reused
|
||||
|
@ -462,11 +497,6 @@ struct __iommu_counter {
|
|||
#define ADD_STATS_COUNTER(name, x)
|
||||
#define SUB_STATS_COUNTER(name, x)
|
||||
|
||||
static inline void amd_iommu_stats_init(void) { }
|
||||
|
||||
#endif /* CONFIG_AMD_IOMMU_STATS */
|
||||
|
||||
/* some function prototypes */
|
||||
extern void amd_iommu_reset_cmd_buffer(struct amd_iommu *iommu);
|
||||
|
||||
#endif /* _ASM_X86_AMD_IOMMU_TYPES_H */
|
||||
|
|
|
@ -22,14 +22,14 @@ do { \
|
|||
".popsection" \
|
||||
: : "i" (__FILE__), "i" (__LINE__), \
|
||||
"i" (sizeof(struct bug_entry))); \
|
||||
for (;;) ; \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define BUG() \
|
||||
do { \
|
||||
asm volatile("ud2"); \
|
||||
for (;;) ; \
|
||||
unreachable(); \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
|
|
|
@ -62,10 +62,8 @@ struct cal_chipset_ops {
|
|||
extern int use_calgary;
|
||||
|
||||
#ifdef CONFIG_CALGARY_IOMMU
|
||||
extern int calgary_iommu_init(void);
|
||||
extern void detect_calgary(void);
|
||||
#else
|
||||
static inline int calgary_iommu_init(void) { return 1; }
|
||||
static inline void detect_calgary(void) { return; }
|
||||
#endif
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@ struct dev_archdata {
|
|||
#ifdef CONFIG_X86_64
|
||||
struct dma_map_ops *dma_ops;
|
||||
#endif
|
||||
#ifdef CONFIG_DMAR
|
||||
#if defined(CONFIG_DMAR) || defined(CONFIG_AMD_IOMMU)
|
||||
void *iommu; /* hook for IOMMU specific extension */
|
||||
#endif
|
||||
};
|
||||
|
|
|
@ -20,7 +20,8 @@
|
|||
# define ISA_DMA_BIT_MASK DMA_BIT_MASK(32)
|
||||
#endif
|
||||
|
||||
extern dma_addr_t bad_dma_address;
|
||||
#define DMA_ERROR_CODE 0
|
||||
|
||||
extern int iommu_merge;
|
||||
extern struct device x86_dma_fallback_dev;
|
||||
extern int panic_on_overflow;
|
||||
|
@ -48,7 +49,7 @@ static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
|||
if (ops->mapping_error)
|
||||
return ops->mapping_error(dev, dma_addr);
|
||||
|
||||
return (dma_addr == bad_dma_address);
|
||||
return (dma_addr == DMA_ERROR_CODE);
|
||||
}
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
|
|
|
@ -35,8 +35,7 @@ extern int gart_iommu_aperture_allowed;
|
|||
extern int gart_iommu_aperture_disabled;
|
||||
|
||||
extern void early_gart_iommu_check(void);
|
||||
extern void gart_iommu_init(void);
|
||||
extern void gart_iommu_shutdown(void);
|
||||
extern int gart_iommu_init(void);
|
||||
extern void __init gart_parse_options(char *);
|
||||
extern void gart_iommu_hole_init(void);
|
||||
|
||||
|
@ -48,12 +47,6 @@ extern void gart_iommu_hole_init(void);
|
|||
static inline void early_gart_iommu_check(void)
|
||||
{
|
||||
}
|
||||
static inline void gart_iommu_init(void)
|
||||
{
|
||||
}
|
||||
static inline void gart_iommu_shutdown(void)
|
||||
{
|
||||
}
|
||||
static inline void gart_parse_options(char *options)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#ifndef _ASM_X86_IOMMU_H
|
||||
#define _ASM_X86_IOMMU_H
|
||||
|
||||
extern void pci_iommu_shutdown(void);
|
||||
extern void no_iommu_init(void);
|
||||
extern struct dma_map_ops nommu_dma_ops;
|
||||
extern int force_iommu, no_iommu;
|
||||
extern int iommu_detected;
|
||||
|
|
|
@ -3,17 +3,14 @@
|
|||
|
||||
#include <linux/swiotlb.h>
|
||||
|
||||
/* SWIOTLB interface */
|
||||
|
||||
extern int swiotlb_force;
|
||||
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
extern int swiotlb;
|
||||
extern void pci_swiotlb_init(void);
|
||||
extern int pci_swiotlb_init(void);
|
||||
#else
|
||||
#define swiotlb 0
|
||||
static inline void pci_swiotlb_init(void)
|
||||
static inline int pci_swiotlb_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -90,6 +90,14 @@ struct x86_init_timers {
|
|||
void (*timer_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_iommu - platform specific iommu setup
|
||||
* @iommu_init: platform specific iommu setup
|
||||
*/
|
||||
struct x86_init_iommu {
|
||||
int (*iommu_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct x86_init_ops - functions for platform specific setup
|
||||
*
|
||||
|
@ -101,6 +109,7 @@ struct x86_init_ops {
|
|||
struct x86_init_oem oem;
|
||||
struct x86_init_paging paging;
|
||||
struct x86_init_timers timers;
|
||||
struct x86_init_iommu iommu;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -121,6 +130,7 @@ struct x86_platform_ops {
|
|||
unsigned long (*calibrate_tsc)(void);
|
||||
unsigned long (*get_wallclock)(void);
|
||||
int (*set_wallclock)(unsigned long nowtime);
|
||||
void (*iommu_shutdown)(void);
|
||||
};
|
||||
|
||||
extern struct x86_init_ops x86_init;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
|
||||
* Copyright (C) 2007-2009 Advanced Micro Devices, Inc.
|
||||
* Author: Joerg Roedel <joerg.roedel@amd.com>
|
||||
* Leo Duran <leo.duran@amd.com>
|
||||
*
|
||||
|
@ -25,10 +25,12 @@
|
|||
#include <linux/interrupt.h>
|
||||
#include <linux/msi.h>
|
||||
#include <asm/pci-direct.h>
|
||||
#include <asm/amd_iommu_proto.h>
|
||||
#include <asm/amd_iommu_types.h>
|
||||
#include <asm/amd_iommu.h>
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/gart.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
/*
|
||||
* definitions for the ACPI scanning code
|
||||
|
@ -123,18 +125,24 @@ u16 amd_iommu_last_bdf; /* largest PCI device id we have
|
|||
to handle */
|
||||
LIST_HEAD(amd_iommu_unity_map); /* a list of required unity mappings
|
||||
we find in ACPI */
|
||||
#ifdef CONFIG_IOMMU_STRESS
|
||||
bool amd_iommu_isolate = false;
|
||||
#else
|
||||
bool amd_iommu_isolate = true; /* if true, device isolation is
|
||||
enabled */
|
||||
#endif
|
||||
|
||||
bool amd_iommu_unmap_flush; /* if true, flush on every unmap */
|
||||
|
||||
LIST_HEAD(amd_iommu_list); /* list of all AMD IOMMUs in the
|
||||
system */
|
||||
|
||||
/* Array to assign indices to IOMMUs*/
|
||||
struct amd_iommu *amd_iommus[MAX_IOMMUS];
|
||||
int amd_iommus_present;
|
||||
|
||||
/* IOMMUs have a non-present cache? */
|
||||
bool amd_iommu_np_cache __read_mostly;
|
||||
|
||||
/*
|
||||
* List of protection domains - used during resume
|
||||
*/
|
||||
LIST_HEAD(amd_iommu_pd_list);
|
||||
spinlock_t amd_iommu_pd_lock;
|
||||
|
||||
/*
|
||||
* Pointer to the device table which is shared by all AMD IOMMUs
|
||||
* it is indexed by the PCI device id or the HT unit id and contains
|
||||
|
@ -156,12 +164,6 @@ u16 *amd_iommu_alias_table;
|
|||
*/
|
||||
struct amd_iommu **amd_iommu_rlookup_table;
|
||||
|
||||
/*
|
||||
* The pd table (protection domain table) is used to find the protection domain
|
||||
* data structure a device belongs to. Indexed with the PCI device id too.
|
||||
*/
|
||||
struct protection_domain **amd_iommu_pd_table;
|
||||
|
||||
/*
|
||||
* AMD IOMMU allows up to 2^16 differend protection domains. This is a bitmap
|
||||
* to know which ones are already in use.
|
||||
|
@ -838,7 +840,18 @@ static void __init free_iommu_all(void)
|
|||
static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
|
||||
{
|
||||
spin_lock_init(&iommu->lock);
|
||||
|
||||
/* Add IOMMU to internal data structures */
|
||||
list_add_tail(&iommu->list, &amd_iommu_list);
|
||||
iommu->index = amd_iommus_present++;
|
||||
|
||||
if (unlikely(iommu->index >= MAX_IOMMUS)) {
|
||||
WARN(1, "AMD-Vi: System has more IOMMUs than supported by this driver\n");
|
||||
return -ENOSYS;
|
||||
}
|
||||
|
||||
/* Index is fine - add IOMMU to the array */
|
||||
amd_iommus[iommu->index] = iommu;
|
||||
|
||||
/*
|
||||
* Copy data from ACPI table entry to the iommu struct
|
||||
|
@ -868,6 +881,9 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
|
|||
init_iommu_from_acpi(iommu, h);
|
||||
init_iommu_devices(iommu);
|
||||
|
||||
if (iommu->cap & (1UL << IOMMU_CAP_NPCACHE))
|
||||
amd_iommu_np_cache = true;
|
||||
|
||||
return pci_enable_device(iommu->dev);
|
||||
}
|
||||
|
||||
|
@ -925,7 +941,7 @@ static int __init init_iommu_all(struct acpi_table_header *table)
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
static int __init iommu_setup_msi(struct amd_iommu *iommu)
|
||||
static int iommu_setup_msi(struct amd_iommu *iommu)
|
||||
{
|
||||
int r;
|
||||
|
||||
|
@ -1176,19 +1192,10 @@ static struct sys_device device_amd_iommu = {
|
|||
* functions. Finally it prints some information about AMD IOMMUs and
|
||||
* the driver state and enables the hardware.
|
||||
*/
|
||||
int __init amd_iommu_init(void)
|
||||
static int __init amd_iommu_init(void)
|
||||
{
|
||||
int i, ret = 0;
|
||||
|
||||
|
||||
if (no_iommu) {
|
||||
printk(KERN_INFO "AMD-Vi disabled by kernel command line\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!amd_iommu_detected)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* First parse ACPI tables to find the largest Bus/Dev/Func
|
||||
* we need to handle. Upon this information the shared data
|
||||
|
@ -1225,15 +1232,6 @@ int __init amd_iommu_init(void)
|
|||
if (amd_iommu_rlookup_table == NULL)
|
||||
goto free;
|
||||
|
||||
/*
|
||||
* Protection Domain table - maps devices to protection domains
|
||||
* This table has the same size as the rlookup_table
|
||||
*/
|
||||
amd_iommu_pd_table = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
|
||||
get_order(rlookup_table_size));
|
||||
if (amd_iommu_pd_table == NULL)
|
||||
goto free;
|
||||
|
||||
amd_iommu_pd_alloc_bitmap = (void *)__get_free_pages(
|
||||
GFP_KERNEL | __GFP_ZERO,
|
||||
get_order(MAX_DOMAIN_ID/8));
|
||||
|
@ -1255,6 +1253,8 @@ int __init amd_iommu_init(void)
|
|||
*/
|
||||
amd_iommu_pd_alloc_bitmap[0] = 1;
|
||||
|
||||
spin_lock_init(&amd_iommu_pd_lock);
|
||||
|
||||
/*
|
||||
* now the data structures are allocated and basically initialized
|
||||
* start the real acpi table scan
|
||||
|
@ -1286,17 +1286,12 @@ int __init amd_iommu_init(void)
|
|||
if (iommu_pass_through)
|
||||
goto out;
|
||||
|
||||
printk(KERN_INFO "AMD-Vi: device isolation ");
|
||||
if (amd_iommu_isolate)
|
||||
printk("enabled\n");
|
||||
else
|
||||
printk("disabled\n");
|
||||
|
||||
if (amd_iommu_unmap_flush)
|
||||
printk(KERN_INFO "AMD-Vi: IO/TLB flush on unmap enabled\n");
|
||||
else
|
||||
printk(KERN_INFO "AMD-Vi: Lazy IO/TLB flushing enabled\n");
|
||||
|
||||
x86_platform.iommu_shutdown = disable_iommus;
|
||||
out:
|
||||
return ret;
|
||||
|
||||
|
@ -1304,9 +1299,6 @@ free:
|
|||
free_pages((unsigned long)amd_iommu_pd_alloc_bitmap,
|
||||
get_order(MAX_DOMAIN_ID/8));
|
||||
|
||||
free_pages((unsigned long)amd_iommu_pd_table,
|
||||
get_order(rlookup_table_size));
|
||||
|
||||
free_pages((unsigned long)amd_iommu_rlookup_table,
|
||||
get_order(rlookup_table_size));
|
||||
|
||||
|
@ -1323,11 +1315,6 @@ free:
|
|||
goto out;
|
||||
}
|
||||
|
||||
void amd_iommu_shutdown(void)
|
||||
{
|
||||
disable_iommus();
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
*
|
||||
* Early detect code. This code runs at IOMMU detection time in the DMA
|
||||
|
@ -1342,16 +1329,13 @@ static int __init early_amd_iommu_detect(struct acpi_table_header *table)
|
|||
|
||||
void __init amd_iommu_detect(void)
|
||||
{
|
||||
if (swiotlb || no_iommu || (iommu_detected && !gart_iommu_aperture))
|
||||
if (no_iommu || (iommu_detected && !gart_iommu_aperture))
|
||||
return;
|
||||
|
||||
if (acpi_table_parse("IVRS", early_amd_iommu_detect) == 0) {
|
||||
iommu_detected = 1;
|
||||
amd_iommu_detected = 1;
|
||||
#ifdef CONFIG_GART_IOMMU
|
||||
gart_iommu_aperture_disabled = 1;
|
||||
gart_iommu_aperture = 0;
|
||||
#endif
|
||||
x86_init.iommu.iommu_init = amd_iommu_init;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1372,10 +1356,6 @@ static int __init parse_amd_iommu_dump(char *str)
|
|||
static int __init parse_amd_iommu_options(char *str)
|
||||
{
|
||||
for (; *str; ++str) {
|
||||
if (strncmp(str, "isolate", 7) == 0)
|
||||
amd_iommu_isolate = true;
|
||||
if (strncmp(str, "share", 5) == 0)
|
||||
amd_iommu_isolate = false;
|
||||
if (strncmp(str, "fullflush", 9) == 0)
|
||||
amd_iommu_unmap_flush = true;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <asm/pci-direct.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/k8.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
int gart_iommu_aperture;
|
||||
int gart_iommu_aperture_disabled __initdata;
|
||||
|
@ -400,6 +401,7 @@ void __init gart_iommu_hole_init(void)
|
|||
|
||||
iommu_detected = 1;
|
||||
gart_iommu_aperture = 1;
|
||||
x86_init.iommu.iommu_init = gart_iommu_init;
|
||||
|
||||
aper_order = (read_pci_config(bus, slot, 3, AMD64_GARTAPERTURECTL) >> 1) & 7;
|
||||
aper_size = (32 * 1024 * 1024) << aper_order;
|
||||
|
@ -456,7 +458,7 @@ out:
|
|||
|
||||
if (aper_alloc) {
|
||||
/* Got the aperture from the AGP bridge */
|
||||
} else if (swiotlb && !valid_agp) {
|
||||
} else if (!valid_agp) {
|
||||
/* Do nothing */
|
||||
} else if ((!no_iommu && max_pfn > MAX_DMA32_PFN) ||
|
||||
force_iommu ||
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
#include <asm/cpu.h>
|
||||
#include <asm/reboot.h>
|
||||
#include <asm/virtext.h>
|
||||
#include <asm/iommu.h>
|
||||
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#if defined(CONFIG_SMP) && defined(CONFIG_X86_LOCAL_APIC)
|
||||
|
||||
|
@ -106,7 +105,7 @@ void native_machine_crash_shutdown(struct pt_regs *regs)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
pci_iommu_shutdown();
|
||||
x86_platform.iommu_shutdown();
|
||||
#endif
|
||||
|
||||
crash_save_cpu(regs, safe_smp_processor_id());
|
||||
|
|
|
@ -1185,17 +1185,14 @@ END(ftrace_graph_caller)
|
|||
|
||||
.globl return_to_handler
|
||||
return_to_handler:
|
||||
pushl $0
|
||||
pushl %eax
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
movl %ebp, %eax
|
||||
call ftrace_return_to_handler
|
||||
movl %eax, 0xc(%esp)
|
||||
movl %eax, %ecx
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %eax
|
||||
ret
|
||||
jmp *%ecx
|
||||
#endif
|
||||
|
||||
.section .rodata,"a"
|
||||
|
|
|
@ -155,11 +155,11 @@ GLOBAL(return_to_handler)
|
|||
|
||||
call ftrace_return_to_handler
|
||||
|
||||
movq %rax, 16(%rsp)
|
||||
movq %rax, %rdi
|
||||
movq 8(%rsp), %rdx
|
||||
movq (%rsp), %rax
|
||||
addq $16, %rsp
|
||||
retq
|
||||
addq $24, %rsp
|
||||
jmp *%rdi
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
* the dangers of modifying code on the run.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -336,15 +338,15 @@ int __init ftrace_dyn_arch_init(void *data)
|
|||
|
||||
switch (faulted) {
|
||||
case 0:
|
||||
pr_info("ftrace: converting mcount calls to 0f 1f 44 00 00\n");
|
||||
pr_info("converting mcount calls to 0f 1f 44 00 00\n");
|
||||
memcpy(ftrace_nop, ftrace_test_p6nop, MCOUNT_INSN_SIZE);
|
||||
break;
|
||||
case 1:
|
||||
pr_info("ftrace: converting mcount calls to 66 66 66 66 90\n");
|
||||
pr_info("converting mcount calls to 66 66 66 66 90\n");
|
||||
memcpy(ftrace_nop, ftrace_test_nop5, MCOUNT_INSN_SIZE);
|
||||
break;
|
||||
case 2:
|
||||
pr_info("ftrace: converting mcount calls to jmp . + 5\n");
|
||||
pr_info("converting mcount calls to jmp . + 5\n");
|
||||
memcpy(ftrace_nop, ftrace_test_jmp, MCOUNT_INSN_SIZE);
|
||||
break;
|
||||
}
|
||||
|
@ -468,82 +470,10 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
|
|||
|
||||
#ifdef CONFIG_FTRACE_SYSCALLS
|
||||
|
||||
extern unsigned long __start_syscalls_metadata[];
|
||||
extern unsigned long __stop_syscalls_metadata[];
|
||||
extern unsigned long *sys_call_table;
|
||||
|
||||
static struct syscall_metadata **syscalls_metadata;
|
||||
|
||||
static struct syscall_metadata *find_syscall_meta(unsigned long *syscall)
|
||||
unsigned long __init arch_syscall_addr(int nr)
|
||||
{
|
||||
struct syscall_metadata *start;
|
||||
struct syscall_metadata *stop;
|
||||
char str[KSYM_SYMBOL_LEN];
|
||||
|
||||
|
||||
start = (struct syscall_metadata *)__start_syscalls_metadata;
|
||||
stop = (struct syscall_metadata *)__stop_syscalls_metadata;
|
||||
kallsyms_lookup((unsigned long) syscall, NULL, NULL, NULL, str);
|
||||
|
||||
for ( ; start < stop; start++) {
|
||||
if (start->name && !strcmp(start->name, str))
|
||||
return start;
|
||||
}
|
||||
return NULL;
|
||||
return (unsigned long)(&sys_call_table)[nr];
|
||||
}
|
||||
|
||||
struct syscall_metadata *syscall_nr_to_meta(int nr)
|
||||
{
|
||||
if (!syscalls_metadata || nr >= NR_syscalls || nr < 0)
|
||||
return NULL;
|
||||
|
||||
return syscalls_metadata[nr];
|
||||
}
|
||||
|
||||
int syscall_name_to_nr(char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!syscalls_metadata)
|
||||
return -1;
|
||||
|
||||
for (i = 0; i < NR_syscalls; i++) {
|
||||
if (syscalls_metadata[i]) {
|
||||
if (!strcmp(syscalls_metadata[i]->name, name))
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void set_syscall_enter_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->enter_id = id;
|
||||
}
|
||||
|
||||
void set_syscall_exit_id(int num, int id)
|
||||
{
|
||||
syscalls_metadata[num]->exit_id = id;
|
||||
}
|
||||
|
||||
static int __init arch_init_ftrace_syscalls(void)
|
||||
{
|
||||
int i;
|
||||
struct syscall_metadata *meta;
|
||||
unsigned long **psys_syscall_table = &sys_call_table;
|
||||
|
||||
syscalls_metadata = kzalloc(sizeof(*syscalls_metadata) *
|
||||
NR_syscalls, GFP_KERNEL);
|
||||
if (!syscalls_metadata) {
|
||||
WARN_ON(1);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_syscalls; i++) {
|
||||
meta = find_syscall_meta(psys_syscall_table[i]);
|
||||
syscalls_metadata[i] = meta;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(arch_init_ftrace_syscalls);
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <asm/dma.h>
|
||||
#include <asm/rio.h>
|
||||
#include <asm/bios_ebda.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT
|
||||
int use_calgary __read_mostly = 1;
|
||||
|
@ -244,7 +245,7 @@ static unsigned long iommu_range_alloc(struct device *dev,
|
|||
if (panic_on_overflow)
|
||||
panic("Calgary: fix the allocator.\n");
|
||||
else
|
||||
return bad_dma_address;
|
||||
return DMA_ERROR_CODE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,12 +261,15 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
|
|||
void *vaddr, unsigned int npages, int direction)
|
||||
{
|
||||
unsigned long entry;
|
||||
dma_addr_t ret = bad_dma_address;
|
||||
dma_addr_t ret;
|
||||
|
||||
entry = iommu_range_alloc(dev, tbl, npages);
|
||||
|
||||
if (unlikely(entry == bad_dma_address))
|
||||
goto error;
|
||||
if (unlikely(entry == DMA_ERROR_CODE)) {
|
||||
printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
|
||||
"iommu %p\n", npages, tbl);
|
||||
return DMA_ERROR_CODE;
|
||||
}
|
||||
|
||||
/* set the return dma address */
|
||||
ret = (entry << PAGE_SHIFT) | ((unsigned long)vaddr & ~PAGE_MASK);
|
||||
|
@ -273,13 +277,7 @@ static dma_addr_t iommu_alloc(struct device *dev, struct iommu_table *tbl,
|
|||
/* put the TCEs in the HW table */
|
||||
tce_build(tbl, entry, npages, (unsigned long)vaddr & PAGE_MASK,
|
||||
direction);
|
||||
|
||||
return ret;
|
||||
|
||||
error:
|
||||
printk(KERN_WARNING "Calgary: failed to allocate %u pages in "
|
||||
"iommu %p\n", npages, tbl);
|
||||
return bad_dma_address;
|
||||
}
|
||||
|
||||
static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
||||
|
@ -290,8 +288,8 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
|
|||
unsigned long flags;
|
||||
|
||||
/* were we called with bad_dma_address? */
|
||||
badend = bad_dma_address + (EMERGENCY_PAGES * PAGE_SIZE);
|
||||
if (unlikely((dma_addr >= bad_dma_address) && (dma_addr < badend))) {
|
||||
badend = DMA_ERROR_CODE + (EMERGENCY_PAGES * PAGE_SIZE);
|
||||
if (unlikely((dma_addr >= DMA_ERROR_CODE) && (dma_addr < badend))) {
|
||||
WARN(1, KERN_ERR "Calgary: driver tried unmapping bad DMA "
|
||||
"address 0x%Lx\n", dma_addr);
|
||||
return;
|
||||
|
@ -318,13 +316,15 @@ static inline struct iommu_table *find_iommu_table(struct device *dev)
|
|||
|
||||
pdev = to_pci_dev(dev);
|
||||
|
||||
/* search up the device tree for an iommu */
|
||||
pbus = pdev->bus;
|
||||
|
||||
/* is the device behind a bridge? Look for the root bus */
|
||||
while (pbus->parent)
|
||||
do {
|
||||
tbl = pci_iommu(pbus);
|
||||
if (tbl && tbl->it_busno == pbus->number)
|
||||
break;
|
||||
tbl = NULL;
|
||||
pbus = pbus->parent;
|
||||
|
||||
tbl = pci_iommu(pbus);
|
||||
} while (pbus);
|
||||
|
||||
BUG_ON(tbl && (tbl->it_busno != pbus->number));
|
||||
|
||||
|
@ -373,7 +373,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
|
|||
npages = iommu_num_pages(vaddr, s->length, PAGE_SIZE);
|
||||
|
||||
entry = iommu_range_alloc(dev, tbl, npages);
|
||||
if (entry == bad_dma_address) {
|
||||
if (entry == DMA_ERROR_CODE) {
|
||||
/* makes sure unmap knows to stop */
|
||||
s->dma_length = 0;
|
||||
goto error;
|
||||
|
@ -391,7 +391,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
|
|||
error:
|
||||
calgary_unmap_sg(dev, sg, nelems, dir, NULL);
|
||||
for_each_sg(sg, s, nelems, i) {
|
||||
sg->dma_address = bad_dma_address;
|
||||
sg->dma_address = DMA_ERROR_CODE;
|
||||
sg->dma_length = 0;
|
||||
}
|
||||
return 0;
|
||||
|
@ -446,7 +446,7 @@ static void* calgary_alloc_coherent(struct device *dev, size_t size,
|
|||
|
||||
/* set up tces to cover the allocated range */
|
||||
mapping = iommu_alloc(dev, tbl, ret, npages, DMA_BIDIRECTIONAL);
|
||||
if (mapping == bad_dma_address)
|
||||
if (mapping == DMA_ERROR_CODE)
|
||||
goto free;
|
||||
*dma_handle = mapping;
|
||||
return ret;
|
||||
|
@ -727,7 +727,7 @@ static void __init calgary_reserve_regions(struct pci_dev *dev)
|
|||
struct iommu_table *tbl = pci_iommu(dev->bus);
|
||||
|
||||
/* reserve EMERGENCY_PAGES from bad_dma_address and up */
|
||||
iommu_range_reserve(tbl, bad_dma_address, EMERGENCY_PAGES);
|
||||
iommu_range_reserve(tbl, DMA_ERROR_CODE, EMERGENCY_PAGES);
|
||||
|
||||
/* avoid the BIOS/VGA first 640KB-1MB region */
|
||||
/* for CalIOC2 - avoid the entire first MB */
|
||||
|
@ -1344,6 +1344,23 @@ static void __init get_tce_space_from_tar(void)
|
|||
return;
|
||||
}
|
||||
|
||||
static int __init calgary_iommu_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* ok, we're trying to use Calgary - let's roll */
|
||||
printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
|
||||
|
||||
ret = calgary_init();
|
||||
if (ret) {
|
||||
printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
|
||||
"falling back to no_iommu\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init detect_calgary(void)
|
||||
{
|
||||
int bus;
|
||||
|
@ -1357,7 +1374,7 @@ void __init detect_calgary(void)
|
|||
* if the user specified iommu=off or iommu=soft or we found
|
||||
* another HW IOMMU already, bail out.
|
||||
*/
|
||||
if (swiotlb || no_iommu || iommu_detected)
|
||||
if (no_iommu || iommu_detected)
|
||||
return;
|
||||
|
||||
if (!use_calgary)
|
||||
|
@ -1442,9 +1459,7 @@ void __init detect_calgary(void)
|
|||
printk(KERN_INFO "PCI-DMA: Calgary TCE table spec is %d\n",
|
||||
specified_table_size);
|
||||
|
||||
/* swiotlb for devices that aren't behind the Calgary. */
|
||||
if (max_pfn > MAX_DMA32_PFN)
|
||||
swiotlb = 1;
|
||||
x86_init.iommu.iommu_init = calgary_iommu_init;
|
||||
}
|
||||
return;
|
||||
|
||||
|
@ -1457,35 +1472,6 @@ cleanup:
|
|||
}
|
||||
}
|
||||
|
||||
int __init calgary_iommu_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (no_iommu || (swiotlb && !calgary_detected))
|
||||
return -ENODEV;
|
||||
|
||||
if (!calgary_detected)
|
||||
return -ENODEV;
|
||||
|
||||
/* ok, we're trying to use Calgary - let's roll */
|
||||
printk(KERN_INFO "PCI-DMA: Using Calgary IOMMU\n");
|
||||
|
||||
ret = calgary_init();
|
||||
if (ret) {
|
||||
printk(KERN_ERR "PCI-DMA: Calgary init failed %d, "
|
||||
"falling back to no_iommu\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
force_iommu = 1;
|
||||
bad_dma_address = 0x0;
|
||||
/* dma_ops is set to swiotlb or nommu */
|
||||
if (!dma_ops)
|
||||
dma_ops = &nommu_dma_ops;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __init calgary_parse_options(char *p)
|
||||
{
|
||||
unsigned int bridge;
|
||||
|
|
|
@ -11,10 +11,11 @@
|
|||
#include <asm/gart.h>
|
||||
#include <asm/calgary.h>
|
||||
#include <asm/amd_iommu.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
static int forbid_dac __read_mostly;
|
||||
|
||||
struct dma_map_ops *dma_ops;
|
||||
struct dma_map_ops *dma_ops = &nommu_dma_ops;
|
||||
EXPORT_SYMBOL(dma_ops);
|
||||
|
||||
static int iommu_sac_force __read_mostly;
|
||||
|
@ -42,9 +43,6 @@ int iommu_detected __read_mostly = 0;
|
|||
*/
|
||||
int iommu_pass_through __read_mostly;
|
||||
|
||||
dma_addr_t bad_dma_address __read_mostly = 0;
|
||||
EXPORT_SYMBOL(bad_dma_address);
|
||||
|
||||
/* Dummy device used for NULL arguments (normally ISA). */
|
||||
struct device x86_dma_fallback_dev = {
|
||||
.init_name = "fallback device",
|
||||
|
@ -126,20 +124,17 @@ void __init pci_iommu_alloc(void)
|
|||
/* free the range so iommu could get some range less than 4G */
|
||||
dma32_free_bootmem();
|
||||
#endif
|
||||
if (pci_swiotlb_init())
|
||||
return;
|
||||
|
||||
/*
|
||||
* The order of these functions is important for
|
||||
* fall-back/fail-over reasons
|
||||
*/
|
||||
gart_iommu_hole_init();
|
||||
|
||||
detect_calgary();
|
||||
|
||||
detect_intel_iommu();
|
||||
|
||||
/* needs to be called after gart_iommu_hole_init */
|
||||
amd_iommu_detect();
|
||||
|
||||
pci_swiotlb_init();
|
||||
}
|
||||
|
||||
void *dma_generic_alloc_coherent(struct device *dev, size_t size,
|
||||
|
@ -214,7 +209,7 @@ static __init int iommu_setup(char *p)
|
|||
if (!strncmp(p, "allowdac", 8))
|
||||
forbid_dac = 0;
|
||||
if (!strncmp(p, "nodac", 5))
|
||||
forbid_dac = -1;
|
||||
forbid_dac = 1;
|
||||
if (!strncmp(p, "usedac", 6)) {
|
||||
forbid_dac = -1;
|
||||
return 1;
|
||||
|
@ -289,25 +284,17 @@ static int __init pci_iommu_init(void)
|
|||
#ifdef CONFIG_PCI
|
||||
dma_debug_add_bus(&pci_bus_type);
|
||||
#endif
|
||||
x86_init.iommu.iommu_init();
|
||||
|
||||
calgary_iommu_init();
|
||||
if (swiotlb) {
|
||||
printk(KERN_INFO "PCI-DMA: "
|
||||
"Using software bounce buffering for IO (SWIOTLB)\n");
|
||||
swiotlb_print_info();
|
||||
} else
|
||||
swiotlb_free();
|
||||
|
||||
intel_iommu_init();
|
||||
|
||||
amd_iommu_init();
|
||||
|
||||
gart_iommu_init();
|
||||
|
||||
no_iommu_init();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pci_iommu_shutdown(void)
|
||||
{
|
||||
gart_iommu_shutdown();
|
||||
|
||||
amd_iommu_shutdown();
|
||||
}
|
||||
/* Must execute after PCI subsystem */
|
||||
rootfs_initcall(pci_iommu_init);
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include <asm/swiotlb.h>
|
||||
#include <asm/dma.h>
|
||||
#include <asm/k8.h>
|
||||
#include <asm/x86_init.h>
|
||||
|
||||
static unsigned long iommu_bus_base; /* GART remapping area (physical) */
|
||||
static unsigned long iommu_size; /* size of remapping area bytes */
|
||||
|
@ -46,6 +47,8 @@ static unsigned long iommu_pages; /* .. and in pages */
|
|||
|
||||
static u32 *iommu_gatt_base; /* Remapping table */
|
||||
|
||||
static dma_addr_t bad_dma_addr;
|
||||
|
||||
/*
|
||||
* If this is disabled the IOMMU will use an optimized flushing strategy
|
||||
* of only flushing when an mapping is reused. With it true the GART is
|
||||
|
@ -92,7 +95,7 @@ static unsigned long alloc_iommu(struct device *dev, int size,
|
|||
|
||||
base_index = ALIGN(iommu_bus_base & dma_get_seg_boundary(dev),
|
||||
PAGE_SIZE) >> PAGE_SHIFT;
|
||||
boundary_size = ALIGN((unsigned long long)dma_get_seg_boundary(dev) + 1,
|
||||
boundary_size = ALIGN((u64)dma_get_seg_boundary(dev) + 1,
|
||||
PAGE_SIZE) >> PAGE_SHIFT;
|
||||
|
||||
spin_lock_irqsave(&iommu_bitmap_lock, flags);
|
||||
|
@ -216,7 +219,7 @@ static dma_addr_t dma_map_area(struct device *dev, dma_addr_t phys_mem,
|
|||
if (panic_on_overflow)
|
||||
panic("dma_map_area overflow %lu bytes\n", size);
|
||||
iommu_full(dev, size, dir);
|
||||
return bad_dma_address;
|
||||
return bad_dma_addr;
|
||||
}
|
||||
|
||||
for (i = 0; i < npages; i++) {
|
||||
|
@ -294,7 +297,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
|
|||
int i;
|
||||
|
||||
#ifdef CONFIG_IOMMU_DEBUG
|
||||
printk(KERN_DEBUG "dma_map_sg overflow\n");
|
||||
pr_debug("dma_map_sg overflow\n");
|
||||
#endif
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
|
@ -302,7 +305,7 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
|
|||
|
||||
if (nonforced_iommu(dev, addr, s->length)) {
|
||||
addr = dma_map_area(dev, addr, s->length, dir, 0);
|
||||
if (addr == bad_dma_address) {
|
||||
if (addr == bad_dma_addr) {
|
||||
if (i > 0)
|
||||
gart_unmap_sg(dev, sg, i, dir, NULL);
|
||||
nents = 0;
|
||||
|
@ -389,12 +392,14 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
|||
if (!dev)
|
||||
dev = &x86_dma_fallback_dev;
|
||||
|
||||
out = 0;
|
||||
start = 0;
|
||||
start_sg = sgmap = sg;
|
||||
seg_size = 0;
|
||||
max_seg_size = dma_get_max_seg_size(dev);
|
||||
ps = NULL; /* shut up gcc */
|
||||
out = 0;
|
||||
start = 0;
|
||||
start_sg = sg;
|
||||
sgmap = sg;
|
||||
seg_size = 0;
|
||||
max_seg_size = dma_get_max_seg_size(dev);
|
||||
ps = NULL; /* shut up gcc */
|
||||
|
||||
for_each_sg(sg, s, nents, i) {
|
||||
dma_addr_t addr = sg_phys(s);
|
||||
|
||||
|
@ -417,11 +422,12 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
|||
sgmap, pages, need) < 0)
|
||||
goto error;
|
||||
out++;
|
||||
seg_size = 0;
|
||||
sgmap = sg_next(sgmap);
|
||||
pages = 0;
|
||||
start = i;
|
||||
start_sg = s;
|
||||
|
||||
seg_size = 0;
|
||||
sgmap = sg_next(sgmap);
|
||||
pages = 0;
|
||||
start = i;
|
||||
start_sg = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -455,7 +461,7 @@ error:
|
|||
|
||||
iommu_full(dev, pages << PAGE_SHIFT, dir);
|
||||
for_each_sg(sg, s, nents, i)
|
||||
s->dma_address = bad_dma_address;
|
||||
s->dma_address = bad_dma_addr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -479,7 +485,7 @@ gart_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_addr,
|
|||
DMA_BIDIRECTIONAL, align_mask);
|
||||
|
||||
flush_gart();
|
||||
if (paddr != bad_dma_address) {
|
||||
if (paddr != bad_dma_addr) {
|
||||
*dma_addr = paddr;
|
||||
return page_address(page);
|
||||
}
|
||||
|
@ -499,6 +505,11 @@ gart_free_coherent(struct device *dev, size_t size, void *vaddr,
|
|||
free_pages((unsigned long)vaddr, get_order(size));
|
||||
}
|
||||
|
||||
static int gart_mapping_error(struct device *dev, dma_addr_t dma_addr)
|
||||
{
|
||||
return (dma_addr == bad_dma_addr);
|
||||
}
|
||||
|
||||
static int no_agp;
|
||||
|
||||
static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
|
||||
|
@ -515,7 +526,7 @@ static __init unsigned long check_iommu_size(unsigned long aper, u64 aper_size)
|
|||
iommu_size -= round_up(a, PMD_PAGE_SIZE) - a;
|
||||
|
||||
if (iommu_size < 64*1024*1024) {
|
||||
printk(KERN_WARNING
|
||||
pr_warning(
|
||||
"PCI-DMA: Warning: Small IOMMU %luMB."
|
||||
" Consider increasing the AGP aperture in BIOS\n",
|
||||
iommu_size >> 20);
|
||||
|
@ -570,28 +581,32 @@ void set_up_gart_resume(u32 aper_order, u32 aper_alloc)
|
|||
aperture_alloc = aper_alloc;
|
||||
}
|
||||
|
||||
static void gart_fixup_northbridges(struct sys_device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!fix_up_north_bridges)
|
||||
return;
|
||||
|
||||
pr_info("PCI-DMA: Restoring GART aperture settings\n");
|
||||
|
||||
for (i = 0; i < num_k8_northbridges; i++) {
|
||||
struct pci_dev *dev = k8_northbridges[i];
|
||||
|
||||
/*
|
||||
* Don't enable translations just yet. That is the next
|
||||
* step. Restore the pre-suspend aperture settings.
|
||||
*/
|
||||
pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, aperture_order << 1);
|
||||
pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE, aperture_alloc >> 25);
|
||||
}
|
||||
}
|
||||
|
||||
static int gart_resume(struct sys_device *dev)
|
||||
{
|
||||
printk(KERN_INFO "PCI-DMA: Resuming GART IOMMU\n");
|
||||
pr_info("PCI-DMA: Resuming GART IOMMU\n");
|
||||
|
||||
if (fix_up_north_bridges) {
|
||||
int i;
|
||||
|
||||
printk(KERN_INFO "PCI-DMA: Restoring GART aperture settings\n");
|
||||
|
||||
for (i = 0; i < num_k8_northbridges; i++) {
|
||||
struct pci_dev *dev = k8_northbridges[i];
|
||||
|
||||
/*
|
||||
* Don't enable translations just yet. That is the next
|
||||
* step. Restore the pre-suspend aperture settings.
|
||||
*/
|
||||
pci_write_config_dword(dev, AMD64_GARTAPERTURECTL,
|
||||
aperture_order << 1);
|
||||
pci_write_config_dword(dev, AMD64_GARTAPERTUREBASE,
|
||||
aperture_alloc >> 25);
|
||||
}
|
||||
}
|
||||
gart_fixup_northbridges(dev);
|
||||
|
||||
enable_gart_translations();
|
||||
|
||||
|
@ -604,15 +619,14 @@ static int gart_suspend(struct sys_device *dev, pm_message_t state)
|
|||
}
|
||||
|
||||
static struct sysdev_class gart_sysdev_class = {
|
||||
.name = "gart",
|
||||
.suspend = gart_suspend,
|
||||
.resume = gart_resume,
|
||||
.name = "gart",
|
||||
.suspend = gart_suspend,
|
||||
.resume = gart_resume,
|
||||
|
||||
};
|
||||
|
||||
static struct sys_device device_gart = {
|
||||
.id = 0,
|
||||
.cls = &gart_sysdev_class,
|
||||
.cls = &gart_sysdev_class,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -627,7 +641,8 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
|
|||
void *gatt;
|
||||
int i, error;
|
||||
|
||||
printk(KERN_INFO "PCI-DMA: Disabling AGP.\n");
|
||||
pr_info("PCI-DMA: Disabling AGP.\n");
|
||||
|
||||
aper_size = aper_base = info->aper_size = 0;
|
||||
dev = NULL;
|
||||
for (i = 0; i < num_k8_northbridges; i++) {
|
||||
|
@ -645,6 +660,7 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
|
|||
}
|
||||
if (!aper_base)
|
||||
goto nommu;
|
||||
|
||||
info->aper_base = aper_base;
|
||||
info->aper_size = aper_size >> 20;
|
||||
|
||||
|
@ -667,14 +683,14 @@ static __init int init_k8_gatt(struct agp_kern_info *info)
|
|||
|
||||
flush_gart();
|
||||
|
||||
printk(KERN_INFO "PCI-DMA: aperture base @ %x size %u KB\n",
|
||||
pr_info("PCI-DMA: aperture base @ %x size %u KB\n",
|
||||
aper_base, aper_size>>10);
|
||||
|
||||
return 0;
|
||||
|
||||
nommu:
|
||||
/* Should not happen anymore */
|
||||
printk(KERN_WARNING "PCI-DMA: More than 4GB of RAM and no IOMMU\n"
|
||||
pr_warning("PCI-DMA: More than 4GB of RAM and no IOMMU\n"
|
||||
"falling back to iommu=soft.\n");
|
||||
return -1;
|
||||
}
|
||||
|
@ -686,14 +702,15 @@ static struct dma_map_ops gart_dma_ops = {
|
|||
.unmap_page = gart_unmap_page,
|
||||
.alloc_coherent = gart_alloc_coherent,
|
||||
.free_coherent = gart_free_coherent,
|
||||
.mapping_error = gart_mapping_error,
|
||||
};
|
||||
|
||||
void gart_iommu_shutdown(void)
|
||||
static void gart_iommu_shutdown(void)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
int i;
|
||||
|
||||
if (no_agp && (dma_ops != &gart_dma_ops))
|
||||
if (no_agp)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_k8_northbridges; i++) {
|
||||
|
@ -708,7 +725,7 @@ void gart_iommu_shutdown(void)
|
|||
}
|
||||
}
|
||||
|
||||
void __init gart_iommu_init(void)
|
||||
int __init gart_iommu_init(void)
|
||||
{
|
||||
struct agp_kern_info info;
|
||||
unsigned long iommu_start;
|
||||
|
@ -718,7 +735,7 @@ void __init gart_iommu_init(void)
|
|||
long i;
|
||||
|
||||
if (cache_k8_northbridges() < 0 || num_k8_northbridges == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
#ifndef CONFIG_AGP_AMD64
|
||||
no_agp = 1;
|
||||
|
@ -730,35 +747,28 @@ void __init gart_iommu_init(void)
|
|||
(agp_copy_info(agp_bridge, &info) < 0);
|
||||
#endif
|
||||
|
||||
if (swiotlb)
|
||||
return;
|
||||
|
||||
/* Did we detect a different HW IOMMU? */
|
||||
if (iommu_detected && !gart_iommu_aperture)
|
||||
return;
|
||||
|
||||
if (no_iommu ||
|
||||
(!force_iommu && max_pfn <= MAX_DMA32_PFN) ||
|
||||
!gart_iommu_aperture ||
|
||||
(no_agp && init_k8_gatt(&info) < 0)) {
|
||||
if (max_pfn > MAX_DMA32_PFN) {
|
||||
printk(KERN_WARNING "More than 4GB of memory "
|
||||
"but GART IOMMU not available.\n");
|
||||
printk(KERN_WARNING "falling back to iommu=soft.\n");
|
||||
pr_warning("More than 4GB of memory but GART IOMMU not available.\n");
|
||||
pr_warning("falling back to iommu=soft.\n");
|
||||
}
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* need to map that range */
|
||||
aper_size = info.aper_size << 20;
|
||||
aper_base = info.aper_base;
|
||||
end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
|
||||
aper_size = info.aper_size << 20;
|
||||
aper_base = info.aper_base;
|
||||
end_pfn = (aper_base>>PAGE_SHIFT) + (aper_size>>PAGE_SHIFT);
|
||||
|
||||
if (end_pfn > max_low_pfn_mapped) {
|
||||
start_pfn = (aper_base>>PAGE_SHIFT);
|
||||
init_memory_mapping(start_pfn<<PAGE_SHIFT, end_pfn<<PAGE_SHIFT);
|
||||
}
|
||||
|
||||
printk(KERN_INFO "PCI-DMA: using GART IOMMU.\n");
|
||||
pr_info("PCI-DMA: using GART IOMMU.\n");
|
||||
iommu_size = check_iommu_size(info.aper_base, aper_size);
|
||||
iommu_pages = iommu_size >> PAGE_SHIFT;
|
||||
|
||||
|
@ -773,8 +783,7 @@ void __init gart_iommu_init(void)
|
|||
|
||||
ret = dma_debug_resize_entries(iommu_pages);
|
||||
if (ret)
|
||||
printk(KERN_DEBUG
|
||||
"PCI-DMA: Cannot trace all the entries\n");
|
||||
pr_debug("PCI-DMA: Cannot trace all the entries\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -784,15 +793,14 @@ void __init gart_iommu_init(void)
|
|||
*/
|
||||
iommu_area_reserve(iommu_gart_bitmap, 0, EMERGENCY_PAGES);
|
||||
|
||||
agp_memory_reserved = iommu_size;
|
||||
printk(KERN_INFO
|
||||
"PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
|
||||
pr_info("PCI-DMA: Reserving %luMB of IOMMU area in the AGP aperture\n",
|
||||
iommu_size >> 20);
|
||||
|
||||
iommu_start = aper_size - iommu_size;
|
||||
iommu_bus_base = info.aper_base + iommu_start;
|
||||
bad_dma_address = iommu_bus_base;
|
||||
iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
|
||||
agp_memory_reserved = iommu_size;
|
||||
iommu_start = aper_size - iommu_size;
|
||||
iommu_bus_base = info.aper_base + iommu_start;
|
||||
bad_dma_addr = iommu_bus_base;
|
||||
iommu_gatt_base = agp_gatt_table + (iommu_start>>PAGE_SHIFT);
|
||||
|
||||
/*
|
||||
* Unmap the IOMMU part of the GART. The alias of the page is
|
||||
|
@ -814,7 +822,7 @@ void __init gart_iommu_init(void)
|
|||
* the pages as Not-Present:
|
||||
*/
|
||||
wbinvd();
|
||||
|
||||
|
||||
/*
|
||||
* Now all caches are flushed and we can safely enable
|
||||
* GART hardware. Doing it early leaves the possibility
|
||||
|
@ -838,6 +846,10 @@ void __init gart_iommu_init(void)
|
|||
|
||||
flush_gart();
|
||||
dma_ops = &gart_dma_ops;
|
||||
x86_platform.iommu_shutdown = gart_iommu_shutdown;
|
||||
swiotlb = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __init gart_parse_options(char *p)
|
||||
|
@ -856,7 +868,7 @@ void __init gart_parse_options(char *p)
|
|||
#endif
|
||||
if (isdigit(*p) && get_option(&p, &arg))
|
||||
iommu_size = arg;
|
||||
if (!strncmp(p, "fullflush", 8))
|
||||
if (!strncmp(p, "fullflush", 9))
|
||||
iommu_fullflush = 1;
|
||||
if (!strncmp(p, "nofullflush", 11))
|
||||
iommu_fullflush = 0;
|
||||
|
|
|
@ -33,7 +33,7 @@ static dma_addr_t nommu_map_page(struct device *dev, struct page *page,
|
|||
dma_addr_t bus = page_to_phys(page) + offset;
|
||||
WARN_ON(size == 0);
|
||||
if (!check_addr("map_single", dev, bus, size))
|
||||
return bad_dma_address;
|
||||
return DMA_ERROR_CODE;
|
||||
flush_write_buffers();
|
||||
return bus;
|
||||
}
|
||||
|
@ -103,12 +103,3 @@ struct dma_map_ops nommu_dma_ops = {
|
|||
.sync_sg_for_device = nommu_sync_sg_for_device,
|
||||
.is_phys = 1,
|
||||
};
|
||||
|
||||
void __init no_iommu_init(void)
|
||||
{
|
||||
if (dma_ops)
|
||||
return;
|
||||
|
||||
force_iommu = 0; /* no HW IOMMU */
|
||||
dma_ops = &nommu_dma_ops;
|
||||
}
|
||||
|
|
|
@ -42,18 +42,28 @@ static struct dma_map_ops swiotlb_dma_ops = {
|
|||
.dma_supported = NULL,
|
||||
};
|
||||
|
||||
void __init pci_swiotlb_init(void)
|
||||
/*
|
||||
* pci_swiotlb_init - initialize swiotlb if necessary
|
||||
*
|
||||
* This returns non-zero if we are forced to use swiotlb (by the boot
|
||||
* option).
|
||||
*/
|
||||
int __init pci_swiotlb_init(void)
|
||||
{
|
||||
int use_swiotlb = swiotlb | swiotlb_force;
|
||||
|
||||
/* don't initialize swiotlb if iommu=off (no_iommu=1) */
|
||||
#ifdef CONFIG_X86_64
|
||||
if ((!iommu_detected && !no_iommu && max_pfn > MAX_DMA32_PFN))
|
||||
if (!no_iommu && max_pfn > MAX_DMA32_PFN)
|
||||
swiotlb = 1;
|
||||
#endif
|
||||
if (swiotlb_force)
|
||||
swiotlb = 1;
|
||||
|
||||
if (swiotlb) {
|
||||
printk(KERN_INFO "PCI-DMA: Using software bounce buffering for IO (SWIOTLB)\n");
|
||||
swiotlb_init();
|
||||
swiotlb_init(0);
|
||||
dma_ops = &swiotlb_dma_ops;
|
||||
}
|
||||
|
||||
return use_swiotlb;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
# include <linux/ctype.h>
|
||||
# include <linux/mc146818rtc.h>
|
||||
#else
|
||||
# include <asm/iommu.h>
|
||||
# include <asm/x86_init.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -622,7 +622,7 @@ void native_machine_shutdown(void)
|
|||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
pci_iommu_shutdown();
|
||||
x86_platform.iommu_shutdown();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -14,10 +14,13 @@
|
|||
#include <asm/time.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/tsc.h>
|
||||
#include <asm/iommu.h>
|
||||
|
||||
void __cpuinit x86_init_noop(void) { }
|
||||
void __init x86_init_uint_noop(unsigned int unused) { }
|
||||
void __init x86_init_pgd_noop(pgd_t *unused) { }
|
||||
int __init iommu_init_noop(void) { return 0; }
|
||||
void iommu_shutdown_noop(void) { }
|
||||
|
||||
/*
|
||||
* The platform setup functions are preset with the default functions
|
||||
|
@ -62,6 +65,10 @@ struct x86_init_ops x86_init __initdata = {
|
|||
.tsc_pre_init = x86_init_noop,
|
||||
.timer_init = hpet_time_init,
|
||||
},
|
||||
|
||||
.iommu = {
|
||||
.iommu_init = iommu_init_noop,
|
||||
},
|
||||
};
|
||||
|
||||
struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
|
||||
|
@ -72,4 +79,5 @@ struct x86_platform_ops x86_platform = {
|
|||
.calibrate_tsc = native_calibrate_tsc,
|
||||
.get_wallclock = mach_get_cmos_time,
|
||||
.set_wallclock = mach_set_rtc_mmss,
|
||||
.iommu_shutdown = iommu_shutdown_noop,
|
||||
};
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/*
|
||||
* Written by Pekka Paalanen, 2008-2009 <pq@iki.fi>
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mmiotrace.h>
|
||||
|
||||
#define MODULE_NAME "testmmiotrace"
|
||||
|
||||
static unsigned long mmio_address;
|
||||
module_param(mmio_address, ulong, 0);
|
||||
MODULE_PARM_DESC(mmio_address, " Start address of the mapping of 16 kB "
|
||||
|
@ -30,7 +31,7 @@ static unsigned v32(unsigned i)
|
|||
static void do_write_test(void __iomem *p)
|
||||
{
|
||||
unsigned int i;
|
||||
pr_info(MODULE_NAME ": write test.\n");
|
||||
pr_info("write test.\n");
|
||||
mmiotrace_printk("Write test.\n");
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
|
@ -47,7 +48,7 @@ static void do_read_test(void __iomem *p)
|
|||
{
|
||||
unsigned int i;
|
||||
unsigned errs[3] = { 0 };
|
||||
pr_info(MODULE_NAME ": read test.\n");
|
||||
pr_info("read test.\n");
|
||||
mmiotrace_printk("Read test.\n");
|
||||
|
||||
for (i = 0; i < 256; i++)
|
||||
|
@ -68,7 +69,7 @@ static void do_read_test(void __iomem *p)
|
|||
|
||||
static void do_read_far_test(void __iomem *p)
|
||||
{
|
||||
pr_info(MODULE_NAME ": read far test.\n");
|
||||
pr_info("read far test.\n");
|
||||
mmiotrace_printk("Read far test.\n");
|
||||
|
||||
ioread32(p + read_far);
|
||||
|
@ -78,7 +79,7 @@ static void do_test(unsigned long size)
|
|||
{
|
||||
void __iomem *p = ioremap_nocache(mmio_address, size);
|
||||
if (!p) {
|
||||
pr_err(MODULE_NAME ": could not ioremap, aborting.\n");
|
||||
pr_err("could not ioremap, aborting.\n");
|
||||
return;
|
||||
}
|
||||
mmiotrace_printk("ioremap returned %p.\n", p);
|
||||
|
@ -94,24 +95,22 @@ static int __init init(void)
|
|||
unsigned long size = (read_far) ? (8 << 20) : (16 << 10);
|
||||
|
||||
if (mmio_address == 0) {
|
||||
pr_err(MODULE_NAME ": you have to use the module argument "
|
||||
"mmio_address.\n");
|
||||
pr_err(MODULE_NAME ": DO NOT LOAD THIS MODULE UNLESS"
|
||||
" YOU REALLY KNOW WHAT YOU ARE DOING!\n");
|
||||
pr_err("you have to use the module argument mmio_address.\n");
|
||||
pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
pr_warning(MODULE_NAME ": WARNING: mapping %lu kB @ 0x%08lx in PCI "
|
||||
"address space, and writing 16 kB of rubbish in there.\n",
|
||||
size >> 10, mmio_address);
|
||||
pr_warning("WARNING: mapping %lu kB @ 0x%08lx in PCI address space, "
|
||||
"and writing 16 kB of rubbish in there.\n",
|
||||
size >> 10, mmio_address);
|
||||
do_test(size);
|
||||
pr_info(MODULE_NAME ": All done.\n");
|
||||
pr_info("All done.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __exit cleanup(void)
|
||||
{
|
||||
pr_debug(MODULE_NAME ": unloaded.\n");
|
||||
pr_debug("unloaded.\n");
|
||||
}
|
||||
|
||||
module_init(init);
|
||||
|
|
|
@ -177,9 +177,6 @@ static struct ata_port_operations pcmcia_8bit_port_ops = {
|
|||
.drain_fifo = pcmcia_8bit_drain_fifo,
|
||||
};
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
|
||||
struct pcmcia_config_check {
|
||||
unsigned long ctl_base;
|
||||
|
@ -252,7 +249,7 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
struct ata_port *ap;
|
||||
struct ata_pcmcia_info *info;
|
||||
struct pcmcia_config_check *stk = NULL;
|
||||
int last_ret = 0, last_fn = 0, is_kme = 0, ret = -ENOMEM, p;
|
||||
int is_kme = 0, ret = -ENOMEM, p;
|
||||
unsigned long io_base, ctl_base;
|
||||
void __iomem *io_addr, *ctl_addr;
|
||||
int n_ports = 1;
|
||||
|
@ -271,7 +268,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
pdev->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
pdev->io.IOAddrLines = 3;
|
||||
pdev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
pdev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
pdev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
pdev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -296,8 +292,13 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
}
|
||||
io_base = pdev->io.BasePort1;
|
||||
ctl_base = stk->ctl_base;
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(pdev, &pdev->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(pdev, &pdev->conf));
|
||||
ret = pcmcia_request_irq(pdev, &pdev->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(pdev, &pdev->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* iomap */
|
||||
ret = -ENOMEM;
|
||||
|
@ -351,8 +352,6 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
|
|||
kfree(stk);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(pdev, last_fn, last_ret);
|
||||
failed:
|
||||
kfree(stk);
|
||||
info->ndev = 0;
|
||||
|
|
|
@ -735,6 +735,21 @@ diskstats(struct gendisk *disk, struct bio *bio, ulong duration, sector_t sector
|
|||
part_stat_unlock();
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure we don't create aliases in VI caches
|
||||
*/
|
||||
static inline void
|
||||
killalias(struct bio *bio)
|
||||
{
|
||||
struct bio_vec *bv;
|
||||
int i;
|
||||
|
||||
if (bio_data_dir(bio) == READ)
|
||||
__bio_for_each_segment(bv, bio, i, 0) {
|
||||
flush_dcache_page(bv->bv_page);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
aoecmd_ata_rsp(struct sk_buff *skb)
|
||||
{
|
||||
|
@ -853,8 +868,12 @@ aoecmd_ata_rsp(struct sk_buff *skb)
|
|||
|
||||
if (buf && --buf->nframesout == 0 && buf->resid == 0) {
|
||||
diskstats(d->gd, buf->bio, jiffies - buf->stime, buf->sector);
|
||||
n = (buf->flags & BUFFL_FAIL) ? -EIO : 0;
|
||||
bio_endio(buf->bio, n);
|
||||
if (buf->flags & BUFFL_FAIL)
|
||||
bio_endio(buf->bio, -EIO);
|
||||
else {
|
||||
killalias(buf->bio);
|
||||
bio_endio(buf->bio, 0);
|
||||
}
|
||||
mempool_free(buf, d->bufpool);
|
||||
}
|
||||
|
||||
|
|
|
@ -867,11 +867,9 @@ static int bluecard_probe(struct pcmcia_device *link)
|
|||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = bluecard_interrupt;
|
||||
link->irq.Instance = info;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -905,22 +903,16 @@ static int bluecard_config(struct pcmcia_device *link)
|
|||
break;
|
||||
}
|
||||
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIO, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (bluecard_open(info) != 0)
|
||||
goto failed;
|
||||
|
|
|
@ -659,11 +659,9 @@ static int bt3c_probe(struct pcmcia_device *link)
|
|||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = bt3c_interrupt;
|
||||
link->irq.Instance = info;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -740,21 +738,16 @@ static int bt3c_config(struct pcmcia_device *link)
|
|||
goto found_port;
|
||||
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, -ENODEV);
|
||||
goto failed;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (bt3c_open(info) != 0)
|
||||
goto failed;
|
||||
|
|
|
@ -588,11 +588,9 @@ static int btuart_probe(struct pcmcia_device *link)
|
|||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = btuart_interrupt;
|
||||
link->irq.Instance = info;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -669,21 +667,16 @@ static int btuart_config(struct pcmcia_device *link)
|
|||
goto found_port;
|
||||
|
||||
BT_ERR("No usable port range found");
|
||||
cs_error(link, RequestIO, -ENODEV);
|
||||
goto failed;
|
||||
|
||||
found_port:
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (btuart_open(info) != 0)
|
||||
goto failed;
|
||||
|
|
|
@ -573,11 +573,9 @@ static int dtl1_probe(struct pcmcia_device *link)
|
|||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
|
||||
link->irq.Handler = dtl1_interrupt;
|
||||
link->irq.Instance = info;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -622,16 +620,12 @@ static int dtl1_config(struct pcmcia_device *link)
|
|||
goto failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
if (i != 0)
|
||||
link->irq.AssignedIRQ = 0;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (dtl1_open(info) != 0)
|
||||
goto failed;
|
||||
|
|
|
@ -56,9 +56,8 @@ config AGP_AMD
|
|||
X on AMD Irongate, 761, and 762 chipsets.
|
||||
|
||||
config AGP_AMD64
|
||||
tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
|
||||
tristate "AMD Opteron/Athlon64 on-CPU GART support"
|
||||
depends on AGP && X86
|
||||
default y if GART_IOMMU
|
||||
help
|
||||
This option gives you AGP support for the GLX component of
|
||||
X using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
|
||||
|
|
|
@ -23,8 +23,6 @@
|
|||
* All rights reserved. Licensed under dual BSD/GPL license.
|
||||
*/
|
||||
|
||||
/* #define PCMCIA_DEBUG 6 */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -47,18 +45,17 @@
|
|||
|
||||
/* #define ATR_CSUM */
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0600);
|
||||
#define DEBUGP(n, rdr, x, args...) do { \
|
||||
if (pc_debug >= (n)) \
|
||||
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
|
||||
__func__ , ## args); \
|
||||
#define reader_to_dev(x) (&x->p_dev->dev)
|
||||
|
||||
/* n (debug level) is ignored */
|
||||
/* additional debug output may be enabled by re-compiling with
|
||||
* CM4000_DEBUG set */
|
||||
/* #define CM4000_DEBUG */
|
||||
#define DEBUGP(n, rdr, x, args...) do { \
|
||||
dev_dbg(reader_to_dev(rdr), "%s:" x, \
|
||||
__func__ , ## args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DEBUGP(n, rdr, x, args...)
|
||||
#endif
|
||||
|
||||
static char *version = "cm4000_cs.c v2.4.0gm6 - All bugs added by Harald Welte";
|
||||
|
||||
#define T_1SEC (HZ)
|
||||
|
@ -174,14 +171,13 @@ static unsigned char fi_di_table[10][14] = {
|
|||
/* 9 */ {0x09,0x19,0x29,0x39,0x49,0x59,0x69,0x11,0x11,0x99,0xA9,0xB9,0xC9,0xD9}
|
||||
};
|
||||
|
||||
#ifndef PCMCIA_DEBUG
|
||||
#ifndef CM4000_DEBUG
|
||||
#define xoutb outb
|
||||
#define xinb inb
|
||||
#else
|
||||
static inline void xoutb(unsigned char val, unsigned short port)
|
||||
{
|
||||
if (pc_debug >= 7)
|
||||
printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
|
||||
pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
|
||||
outb(val, port);
|
||||
}
|
||||
static inline unsigned char xinb(unsigned short port)
|
||||
|
@ -189,8 +185,7 @@ static inline unsigned char xinb(unsigned short port)
|
|||
unsigned char val;
|
||||
|
||||
val = inb(port);
|
||||
if (pc_debug >= 7)
|
||||
printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
|
||||
pr_debug("%.2x=inb(%.4x)\n", val, port);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
@ -514,12 +509,10 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
|
|||
for (i = 0; i < 4; i++) {
|
||||
xoutb(i, REG_BUF_ADDR(iobase));
|
||||
xoutb(dev->pts[i], REG_BUF_DATA(iobase)); /* buf data */
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug >= 5)
|
||||
printk("0x%.2x ", dev->pts[i]);
|
||||
#ifdef CM4000_DEBUG
|
||||
pr_debug("0x%.2x ", dev->pts[i]);
|
||||
}
|
||||
if (pc_debug >= 5)
|
||||
printk("\n");
|
||||
pr_debug("\n");
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
@ -579,14 +572,13 @@ static int set_protocol(struct cm4000_dev *dev, struct ptsreq *ptsreq)
|
|||
pts_reply[i] = inb(REG_BUF_DATA(iobase));
|
||||
}
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#ifdef CM4000_DEBUG
|
||||
DEBUGP(2, dev, "PTSreply: ");
|
||||
for (i = 0; i < num_bytes_read; i++) {
|
||||
if (pc_debug >= 5)
|
||||
printk("0x%.2x ", pts_reply[i]);
|
||||
pr_debug("0x%.2x ", pts_reply[i]);
|
||||
}
|
||||
printk("\n");
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
pr_debug("\n");
|
||||
#endif /* CM4000_DEBUG */
|
||||
|
||||
DEBUGP(5, dev, "Clear Tactive in Flags1\n");
|
||||
xoutb(0x20, REG_FLAGS1(iobase));
|
||||
|
@ -655,7 +647,7 @@ static void terminate_monitor(struct cm4000_dev *dev)
|
|||
|
||||
DEBUGP(5, dev, "Delete timer\n");
|
||||
del_timer_sync(&dev->timer);
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#ifdef CM4000_DEBUG
|
||||
dev->monitor_running = 0;
|
||||
#endif
|
||||
|
||||
|
@ -898,7 +890,7 @@ static void monitor_card(unsigned long p)
|
|||
DEBUGP(4, dev, "ATR checksum (0x%.2x, should "
|
||||
"be zero) failed\n", dev->atr_csum);
|
||||
}
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#ifdef CM4000_DEBUG
|
||||
else if (test_bit(IS_BAD_LENGTH, &dev->flags)) {
|
||||
DEBUGP(4, dev, "ATR length error\n");
|
||||
} else {
|
||||
|
@ -1415,7 +1407,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
int size;
|
||||
int rc;
|
||||
void __user *argp = (void __user *)arg;
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#ifdef CM4000_DEBUG
|
||||
char *ioctl_names[CM_IOC_MAXNR + 1] = {
|
||||
[_IOC_NR(CM_IOCGSTATUS)] "CM_IOCGSTATUS",
|
||||
[_IOC_NR(CM_IOCGATR)] "CM_IOCGATR",
|
||||
|
@ -1423,9 +1415,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
[_IOC_NR(CM_IOCSPTS)] "CM_IOCSPTS",
|
||||
[_IOC_NR(CM_IOSDBGLVL)] "CM4000_DBGLVL",
|
||||
};
|
||||
#endif
|
||||
DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
|
||||
iminor(inode), ioctl_names[_IOC_NR(cmd)]);
|
||||
#endif
|
||||
|
||||
lock_kernel();
|
||||
rc = -ENODEV;
|
||||
|
@ -1523,7 +1515,7 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
}
|
||||
case CM_IOCARDOFF:
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#ifdef CM4000_DEBUG
|
||||
DEBUGP(4, dev, "... in CM_IOCARDOFF\n");
|
||||
if (dev->flags0 & 0x01) {
|
||||
DEBUGP(4, dev, " Card inserted\n");
|
||||
|
@ -1625,18 +1617,9 @@ static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
|
||||
}
|
||||
break;
|
||||
#ifdef PCMCIA_DEBUG
|
||||
case CM_IOSDBGLVL: /* set debug log level */
|
||||
{
|
||||
int old_pc_debug = 0;
|
||||
|
||||
old_pc_debug = pc_debug;
|
||||
if (copy_from_user(&pc_debug, argp, sizeof(int)))
|
||||
rc = -EFAULT;
|
||||
else if (old_pc_debug != pc_debug)
|
||||
DEBUGP(0, dev, "Changed debug log level "
|
||||
"to %i\n", pc_debug);
|
||||
}
|
||||
#ifdef CM4000_DEBUG
|
||||
case CM_IOSDBGLVL:
|
||||
rc = -ENOTTY;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
* All rights reserved, Dual BSD/GPL Licensed.
|
||||
*/
|
||||
|
||||
/* #define PCMCIA_DEBUG 6 */
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -41,18 +39,16 @@
|
|||
#include "cm4040_cs.h"
|
||||
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#define reader_to_dev(x) (&handle_to_dev(x->p_dev))
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0600);
|
||||
#define DEBUGP(n, rdr, x, args...) do { \
|
||||
if (pc_debug >= (n)) \
|
||||
dev_printk(KERN_DEBUG, reader_to_dev(rdr), "%s:" x, \
|
||||
__func__ , ##args); \
|
||||
#define reader_to_dev(x) (&x->p_dev->dev)
|
||||
|
||||
/* n (debug level) is ignored */
|
||||
/* additional debug output may be enabled by re-compiling with
|
||||
* CM4040_DEBUG set */
|
||||
/* #define CM4040_DEBUG */
|
||||
#define DEBUGP(n, rdr, x, args...) do { \
|
||||
dev_dbg(reader_to_dev(rdr), "%s:" x, \
|
||||
__func__ , ## args); \
|
||||
} while (0)
|
||||
#else
|
||||
#define DEBUGP(n, rdr, x, args...)
|
||||
#endif
|
||||
|
||||
static char *version =
|
||||
"OMNIKEY CardMan 4040 v1.1.0gm5 - All bugs added by Harald Welte";
|
||||
|
@ -90,14 +86,13 @@ struct reader_dev {
|
|||
|
||||
static struct pcmcia_device *dev_table[CM_MAX_DEV];
|
||||
|
||||
#ifndef PCMCIA_DEBUG
|
||||
#ifndef CM4040_DEBUG
|
||||
#define xoutb outb
|
||||
#define xinb inb
|
||||
#else
|
||||
static inline void xoutb(unsigned char val, unsigned short port)
|
||||
{
|
||||
if (pc_debug >= 7)
|
||||
printk(KERN_DEBUG "outb(val=%.2x,port=%.4x)\n", val, port);
|
||||
pr_debug("outb(val=%.2x,port=%.4x)\n", val, port);
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
|
@ -106,8 +101,7 @@ static inline unsigned char xinb(unsigned short port)
|
|||
unsigned char val;
|
||||
|
||||
val = inb(port);
|
||||
if (pc_debug >= 7)
|
||||
printk(KERN_DEBUG "%.2x=inb(%.4x)\n", val, port);
|
||||
pr_debug("%.2x=inb(%.4x)\n", val, port);
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
@ -260,23 +254,22 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
|
|||
return -EIO;
|
||||
}
|
||||
dev->r_buf[i] = xinb(iobase + REG_OFFSET_BULK_IN);
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug >= 6)
|
||||
printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
|
||||
#ifdef CM4040_DEBUG
|
||||
pr_debug("%lu:%2x ", i, dev->r_buf[i]);
|
||||
}
|
||||
printk("\n");
|
||||
pr_debug("\n");
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
||||
bytes_to_read = 5 + le32_to_cpu(*(__le32 *)&dev->r_buf[1]);
|
||||
|
||||
DEBUGP(6, dev, "BytesToRead=%lu\n", bytes_to_read);
|
||||
DEBUGP(6, dev, "BytesToRead=%zu\n", bytes_to_read);
|
||||
|
||||
min_bytes_to_read = min(count, bytes_to_read + 5);
|
||||
min_bytes_to_read = min_t(size_t, min_bytes_to_read, READ_WRITE_BUFFER_SIZE);
|
||||
|
||||
DEBUGP(6, dev, "Min=%lu\n", min_bytes_to_read);
|
||||
DEBUGP(6, dev, "Min=%zu\n", min_bytes_to_read);
|
||||
|
||||
for (i = 0; i < (min_bytes_to_read-5); i++) {
|
||||
rc = wait_for_bulk_in_ready(dev);
|
||||
|
@ -288,11 +281,10 @@ static ssize_t cm4040_read(struct file *filp, char __user *buf,
|
|||
return -EIO;
|
||||
}
|
||||
dev->r_buf[i+5] = xinb(iobase + REG_OFFSET_BULK_IN);
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug >= 6)
|
||||
printk(KERN_DEBUG "%lu:%2x ", i, dev->r_buf[i]);
|
||||
#ifdef CM4040_DEBUG
|
||||
pr_debug("%lu:%2x ", i, dev->r_buf[i]);
|
||||
}
|
||||
printk("\n");
|
||||
pr_debug("\n");
|
||||
#else
|
||||
}
|
||||
#endif
|
||||
|
@ -547,7 +539,7 @@ static int cm4040_config_check(struct pcmcia_device *p_dev,
|
|||
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
||||
|
||||
rc = pcmcia_request_io(p_dev, &p_dev->io);
|
||||
dev_printk(KERN_INFO, &handle_to_dev(p_dev),
|
||||
dev_printk(KERN_INFO, &p_dev->dev,
|
||||
"pcmcia_request_io returned 0x%x\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
@ -569,7 +561,7 @@ static int reader_config(struct pcmcia_device *link, int devno)
|
|||
|
||||
fail_rc = pcmcia_request_configuration(link, &link->conf);
|
||||
if (fail_rc != 0) {
|
||||
dev_printk(KERN_INFO, &handle_to_dev(link),
|
||||
dev_printk(KERN_INFO, &link->dev,
|
||||
"pcmcia_request_configuration failed 0x%x\n",
|
||||
fail_rc);
|
||||
goto cs_release;
|
||||
|
|
|
@ -1213,12 +1213,12 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
|
|||
|
||||
irqreturn_t ipwireless_interrupt(int irq, void *dev_id)
|
||||
{
|
||||
struct ipw_hardware *hw = dev_id;
|
||||
struct ipw_dev *ipw = dev_id;
|
||||
|
||||
if (hw->hw_version == HW_VERSION_1)
|
||||
return ipwireless_handle_v1_interrupt(irq, hw);
|
||||
if (ipw->hardware->hw_version == HW_VERSION_1)
|
||||
return ipwireless_handle_v1_interrupt(irq, ipw->hardware);
|
||||
else
|
||||
return ipwireless_handle_v2_v3_interrupt(irq, hw);
|
||||
return ipwireless_handle_v2_v3_interrupt(irq, ipw->hardware);
|
||||
}
|
||||
|
||||
static void flush_packets_to_hw(struct ipw_hardware *hw)
|
||||
|
|
|
@ -65,10 +65,7 @@ static void signalled_reboot_work(struct work_struct *work_reboot)
|
|||
struct ipw_dev *ipw = container_of(work_reboot, struct ipw_dev,
|
||||
work_reboot);
|
||||
struct pcmcia_device *link = ipw->link;
|
||||
int ret = pcmcia_reset_card(link->socket);
|
||||
|
||||
if (ret != 0)
|
||||
cs_error(link, ResetCard, ret);
|
||||
pcmcia_reset_card(link->socket);
|
||||
}
|
||||
|
||||
static void signalled_reboot_callback(void *callback_data)
|
||||
|
@ -79,208 +76,127 @@ static void signalled_reboot_callback(void *callback_data)
|
|||
schedule_work(&ipw->work_reboot);
|
||||
}
|
||||
|
||||
static int config_ipwireless(struct ipw_dev *ipw)
|
||||
static int ipwireless_probe(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
struct pcmcia_device *link = ipw->link;
|
||||
int ret;
|
||||
tuple_t tuple;
|
||||
unsigned short buf[64];
|
||||
cisparse_t parse;
|
||||
unsigned short cor_value;
|
||||
struct ipw_dev *ipw = priv_data;
|
||||
struct resource *io_resource;
|
||||
memreq_t memreq_attr_memory;
|
||||
memreq_t memreq_common_memory;
|
||||
int ret;
|
||||
|
||||
ipw->is_v2_card = 0;
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *) buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
|
||||
|
||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
||||
|
||||
while (ret == 0) {
|
||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetTupleData, ret);
|
||||
goto exit0;
|
||||
}
|
||||
ret = pcmcia_get_next_tuple(link, &tuple);
|
||||
}
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetFirstTuple, ret);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetTupleData, ret);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, ParseTuple, ret);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.BasePort1 = parse.cftable_entry.io.win[0].base;
|
||||
link->io.NumPorts1 = parse.cftable_entry.io.win[0].len;
|
||||
link->io.IOAddrLines = 16;
|
||||
|
||||
link->irq.IRQInfo1 = parse.cftable_entry.irq.IRQInfo1;
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||
p_dev->io.IOAddrLines = 16;
|
||||
|
||||
/* 0x40 causes it to generate level mode interrupts. */
|
||||
/* 0x04 enables IREQ pin. */
|
||||
cor_value = parse.cftable_entry.index | 0x44;
|
||||
link->conf.ConfigIndex = cor_value;
|
||||
p_dev->conf.ConfigIndex = cfg->index | 0x44;
|
||||
ret = pcmcia_request_io(p_dev, &p_dev->io);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* IRQ and I/O settings */
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
io_resource = request_region(p_dev->io.BasePort1, p_dev->io.NumPorts1,
|
||||
IPWIRELESS_PCCARD_NAME);
|
||||
|
||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
||||
if (cfg->mem.nwin == 0)
|
||||
return 0;
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetFirstTuple, ret);
|
||||
goto exit0;
|
||||
}
|
||||
ipw->request_common_memory.Attributes =
|
||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
|
||||
ipw->request_common_memory.Base = cfg->mem.win[0].host_addr;
|
||||
ipw->request_common_memory.Size = cfg->mem.win[0].len;
|
||||
if (ipw->request_common_memory.Size < 0x1000)
|
||||
ipw->request_common_memory.Size = 0x1000;
|
||||
ipw->request_common_memory.AccessSpeed = 0;
|
||||
|
||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetTupleData, ret);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetTupleData, ret);
|
||||
goto exit0;
|
||||
}
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.ConfigBase = parse.config.base;
|
||||
link->conf.Present = parse.config.rmask[0];
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.Handler = ipwireless_interrupt;
|
||||
link->irq.Instance = ipw->hardware;
|
||||
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestIO, ret);
|
||||
goto exit0;
|
||||
}
|
||||
|
||||
request_region(link->io.BasePort1, link->io.NumPorts1,
|
||||
IPWIRELESS_PCCARD_NAME);
|
||||
|
||||
/* memory settings */
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
|
||||
ret = pcmcia_get_first_tuple(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetFirstTuple, ret);
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
ret = pcmcia_get_tuple_data(link, &tuple);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, GetTupleData, ret);
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
ret = pcmcia_parse_tuple(&tuple, &parse);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, ParseTuple, ret);
|
||||
goto exit1;
|
||||
}
|
||||
|
||||
if (parse.cftable_entry.mem.nwin > 0) {
|
||||
ipw->request_common_memory.Attributes =
|
||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_CM | WIN_ENABLE;
|
||||
ipw->request_common_memory.Base =
|
||||
parse.cftable_entry.mem.win[0].host_addr;
|
||||
ipw->request_common_memory.Size = parse.cftable_entry.mem.win[0].len;
|
||||
if (ipw->request_common_memory.Size < 0x1000)
|
||||
ipw->request_common_memory.Size = 0x1000;
|
||||
ipw->request_common_memory.AccessSpeed = 0;
|
||||
|
||||
ret = pcmcia_request_window(&link, &ipw->request_common_memory,
|
||||
ret = pcmcia_request_window(p_dev, &ipw->request_common_memory,
|
||||
&ipw->handle_common_memory);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestWindow, ret);
|
||||
goto exit1;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit1;
|
||||
|
||||
memreq_common_memory.CardOffset =
|
||||
parse.cftable_entry.mem.win[0].card_addr;
|
||||
memreq_common_memory.Page = 0;
|
||||
memreq_common_memory.CardOffset = cfg->mem.win[0].card_addr;
|
||||
memreq_common_memory.Page = 0;
|
||||
|
||||
ret = pcmcia_map_mem_page(ipw->handle_common_memory,
|
||||
ret = pcmcia_map_mem_page(p_dev, ipw->handle_common_memory,
|
||||
&memreq_common_memory);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, MapMemPage, ret);
|
||||
goto exit1;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit2;
|
||||
|
||||
ipw->is_v2_card =
|
||||
parse.cftable_entry.mem.win[0].len == 0x100;
|
||||
ipw->is_v2_card = cfg->mem.win[0].len == 0x100;
|
||||
|
||||
ipw->common_memory = ioremap(ipw->request_common_memory.Base,
|
||||
ipw->common_memory = ioremap(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size);
|
||||
request_mem_region(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size, IPWIRELESS_PCCARD_NAME);
|
||||
request_mem_region(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size,
|
||||
IPWIRELESS_PCCARD_NAME);
|
||||
|
||||
ipw->request_attr_memory.Attributes =
|
||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
|
||||
ipw->request_attr_memory.Base = 0;
|
||||
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
|
||||
ipw->request_attr_memory.AccessSpeed = 0;
|
||||
ipw->request_attr_memory.Attributes =
|
||||
WIN_DATA_WIDTH_16 | WIN_MEMORY_TYPE_AM | WIN_ENABLE;
|
||||
ipw->request_attr_memory.Base = 0;
|
||||
ipw->request_attr_memory.Size = 0; /* this used to be 0x1000 */
|
||||
ipw->request_attr_memory.AccessSpeed = 0;
|
||||
|
||||
ret = pcmcia_request_window(&link, &ipw->request_attr_memory,
|
||||
ret = pcmcia_request_window(p_dev, &ipw->request_attr_memory,
|
||||
&ipw->handle_attr_memory);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestWindow, ret);
|
||||
goto exit2;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit2;
|
||||
|
||||
memreq_attr_memory.CardOffset = 0;
|
||||
memreq_attr_memory.Page = 0;
|
||||
memreq_attr_memory.CardOffset = 0;
|
||||
memreq_attr_memory.Page = 0;
|
||||
|
||||
ret = pcmcia_map_mem_page(ipw->handle_attr_memory,
|
||||
ret = pcmcia_map_mem_page(p_dev, ipw->handle_attr_memory,
|
||||
&memreq_attr_memory);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, MapMemPage, ret);
|
||||
goto exit2;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit3;
|
||||
|
||||
ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
|
||||
ipw->attr_memory = ioremap(ipw->request_attr_memory.Base,
|
||||
ipw->request_attr_memory.Size);
|
||||
request_mem_region(ipw->request_attr_memory.Base, ipw->request_attr_memory.Size,
|
||||
IPWIRELESS_PCCARD_NAME);
|
||||
}
|
||||
request_mem_region(ipw->request_attr_memory.Base,
|
||||
ipw->request_attr_memory.Size, IPWIRELESS_PCCARD_NAME);
|
||||
|
||||
return 0;
|
||||
|
||||
exit3:
|
||||
pcmcia_release_window(p_dev, ipw->handle_attr_memory);
|
||||
exit2:
|
||||
if (ipw->common_memory) {
|
||||
release_mem_region(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size);
|
||||
iounmap(ipw->common_memory);
|
||||
pcmcia_release_window(p_dev, ipw->handle_common_memory);
|
||||
} else
|
||||
pcmcia_release_window(p_dev, ipw->handle_common_memory);
|
||||
exit1:
|
||||
release_resource(io_resource);
|
||||
pcmcia_disable_device(p_dev);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int config_ipwireless(struct ipw_dev *ipw)
|
||||
{
|
||||
struct pcmcia_device *link = ipw->link;
|
||||
int ret = 0;
|
||||
|
||||
ipw->is_v2_card = 0;
|
||||
|
||||
ret = pcmcia_loop_config(link, ipwireless_probe, ipw);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = ipwireless_interrupt;
|
||||
|
||||
INIT_WORK(&ipw->work_reboot, signalled_reboot_work);
|
||||
|
||||
|
@ -291,10 +207,8 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestIRQ, ret);
|
||||
goto exit3;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit;
|
||||
|
||||
printk(KERN_INFO IPWIRELESS_PCCARD_NAME ": Card type %s\n",
|
||||
ipw->is_v2_card ? "V2/V3" : "V1");
|
||||
|
@ -316,12 +230,12 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
|
||||
ipw->network = ipwireless_network_create(ipw->hardware);
|
||||
if (!ipw->network)
|
||||
goto exit3;
|
||||
goto exit;
|
||||
|
||||
ipw->tty = ipwireless_tty_create(ipw->hardware, ipw->network,
|
||||
ipw->nodes);
|
||||
if (!ipw->tty)
|
||||
goto exit3;
|
||||
goto exit;
|
||||
|
||||
ipwireless_init_hardware_v2_v3(ipw->hardware);
|
||||
|
||||
|
@ -331,35 +245,27 @@ static int config_ipwireless(struct ipw_dev *ipw)
|
|||
*/
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestConfiguration, ret);
|
||||
goto exit4;
|
||||
}
|
||||
if (ret != 0)
|
||||
goto exit;
|
||||
|
||||
link->dev_node = &ipw->nodes[0];
|
||||
|
||||
return 0;
|
||||
|
||||
exit4:
|
||||
pcmcia_disable_device(link);
|
||||
exit3:
|
||||
exit:
|
||||
if (ipw->attr_memory) {
|
||||
release_mem_region(ipw->request_attr_memory.Base,
|
||||
ipw->request_attr_memory.Size);
|
||||
iounmap(ipw->attr_memory);
|
||||
pcmcia_release_window(ipw->handle_attr_memory);
|
||||
pcmcia_disable_device(link);
|
||||
pcmcia_release_window(link, ipw->handle_attr_memory);
|
||||
}
|
||||
exit2:
|
||||
if (ipw->common_memory) {
|
||||
release_mem_region(ipw->request_common_memory.Base,
|
||||
ipw->request_common_memory.Size);
|
||||
iounmap(ipw->common_memory);
|
||||
pcmcia_release_window(ipw->handle_common_memory);
|
||||
pcmcia_release_window(link, ipw->handle_common_memory);
|
||||
}
|
||||
exit1:
|
||||
pcmcia_disable_device(link);
|
||||
exit0:
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -378,9 +284,9 @@ static void release_ipwireless(struct ipw_dev *ipw)
|
|||
iounmap(ipw->attr_memory);
|
||||
}
|
||||
if (ipw->common_memory)
|
||||
pcmcia_release_window(ipw->handle_common_memory);
|
||||
pcmcia_release_window(ipw->link, ipw->handle_common_memory);
|
||||
if (ipw->attr_memory)
|
||||
pcmcia_release_window(ipw->handle_attr_memory);
|
||||
pcmcia_release_window(ipw->link, ipw->handle_attr_memory);
|
||||
|
||||
/* Break the link with Card Services */
|
||||
pcmcia_disable_device(ipw->link);
|
||||
|
@ -406,7 +312,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
|
|||
|
||||
ipw->link = link;
|
||||
link->priv = ipw;
|
||||
link->irq.Instance = ipw;
|
||||
|
||||
/* Link this device into our device list. */
|
||||
link->dev_node = &ipw->nodes[0];
|
||||
|
@ -421,7 +326,6 @@ static int ipwireless_attach(struct pcmcia_device *link)
|
|||
ret = config_ipwireless(ipw);
|
||||
|
||||
if (ret != 0) {
|
||||
cs_error(link, RegisterClient, ret);
|
||||
ipwireless_detach(link);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -554,7 +554,6 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
|||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
link->conf.Attributes = 0;
|
||||
|
@ -572,69 +571,51 @@ static int mgslpc_probe(struct pcmcia_device *link)
|
|||
/* Card has been inserted.
|
||||
*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
static int mgslpc_ioprobe(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
if (cfg->io.nwin > 0) {
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(cfg->io.flags & CISTPL_IO_8BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(cfg->io.flags & CISTPL_IO_16BIT))
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
p_dev->io.IOAddrLines = cfg->io.flags & CISTPL_IO_LINES_MASK;
|
||||
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||
}
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int mgslpc_config(struct pcmcia_device *link)
|
||||
{
|
||||
MGSLPC_INFO *info = link->priv;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int last_fn, last_ret;
|
||||
u_char buf[64];
|
||||
cistpl_cftable_entry_t dflt = { 0 };
|
||||
cistpl_cftable_entry_t *cfg;
|
||||
int ret;
|
||||
|
||||
if (debug_level >= DEBUG_LEVEL_INFO)
|
||||
printk("mgslpc_config(0x%p)\n", link);
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
/* get CIS configuration entry */
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
|
||||
cfg = &(parse.cftable_entry);
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
|
||||
|
||||
if (cfg->flags & CISTPL_CFTABLE_DEFAULT) dflt = *cfg;
|
||||
if (cfg->index == 0)
|
||||
goto cs_failed;
|
||||
|
||||
link->conf.ConfigIndex = cfg->index;
|
||||
link->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
link->io.NumPorts1 = 0;
|
||||
if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
|
||||
cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
if (!(io->flags & CISTPL_IO_8BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
if (!(io->flags & CISTPL_IO_16BIT))
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
|
||||
link->io.BasePort1 = io->win[0].base;
|
||||
link->io.NumPorts1 = io->win[0].len;
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
}
|
||||
ret = pcmcia_loop_config(link, mgslpc_ioprobe, NULL);
|
||||
if (ret != 0)
|
||||
goto failed;
|
||||
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 8;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->irq.Attributes |= IRQ_HANDLE_PRESENT;
|
||||
link->irq.Handler = mgslpc_isr;
|
||||
link->irq.Instance = info;
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
info->io_base = link->io.BasePort1;
|
||||
info->irq_level = link->irq.AssignedIRQ;
|
||||
|
@ -654,8 +635,7 @@ static int mgslpc_config(struct pcmcia_device *link)
|
|||
printk("\n");
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
mgslpc_release((u_long)link);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
enum tpm_const {
|
||||
TPM_MINOR = 224, /* officially assigned */
|
||||
TPM_BUFSIZE = 2048,
|
||||
TPM_BUFSIZE = 4096,
|
||||
TPM_NUM_DEVICES = 256,
|
||||
};
|
||||
|
||||
|
|
|
@ -257,6 +257,10 @@ out:
|
|||
return size;
|
||||
}
|
||||
|
||||
static int itpm;
|
||||
module_param(itpm, bool, 0444);
|
||||
MODULE_PARM_DESC(itpm, "Force iTPM workarounds (found on some Lenovo laptops)");
|
||||
|
||||
/*
|
||||
* If interrupts are used (signaled by an irq set in the vendor structure)
|
||||
* tpm.c can skip polling for the data to be available as the interrupt is
|
||||
|
@ -293,7 +297,7 @@ static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
|
|||
wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
|
||||
&chip->vendor.int_queue);
|
||||
status = tpm_tis_status(chip);
|
||||
if ((status & TPM_STS_DATA_EXPECT) == 0) {
|
||||
if (!itpm && (status & TPM_STS_DATA_EXPECT) == 0) {
|
||||
rc = -EIO;
|
||||
goto out_err;
|
||||
}
|
||||
|
@ -467,6 +471,10 @@ static int tpm_tis_init(struct device *dev, resource_size_t start,
|
|||
"1.2 TPM (device-id 0x%X, rev-id %d)\n",
|
||||
vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
|
||||
|
||||
if (itpm)
|
||||
dev_info(dev, "Intel iTPM workaround enabled\n");
|
||||
|
||||
|
||||
/* Figure out the capabilities */
|
||||
intfcaps =
|
||||
ioread32(chip->vendor.iobase +
|
||||
|
@ -629,6 +637,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
|
|||
{"", 0}, /* User Specified */
|
||||
{"", 0} /* Terminator */
|
||||
};
|
||||
MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);
|
||||
|
||||
static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev)
|
||||
{
|
||||
|
|
|
@ -144,13 +144,6 @@ static int lnw_irq_type(unsigned irq, unsigned type)
|
|||
|
||||
static void lnw_irq_unmask(unsigned irq)
|
||||
{
|
||||
struct lnw_gpio *lnw = get_irq_chip_data(irq);
|
||||
u32 gpio = irq - lnw->irq_base;
|
||||
u8 reg = gpio / 32;
|
||||
void __iomem *gedr;
|
||||
|
||||
gedr = (void __iomem *)(&lnw->reg_base->GEDR[reg]);
|
||||
writel(BIT(gpio % 32), gedr);
|
||||
};
|
||||
|
||||
static void lnw_irq_mask(unsigned irq)
|
||||
|
@ -183,13 +176,11 @@ static void lnw_irq_handler(unsigned irq, struct irq_desc *desc)
|
|||
gedr_v = readl(gedr);
|
||||
if (!gedr_v)
|
||||
continue;
|
||||
for (gpio = reg*32; gpio < reg*32+32; gpio++) {
|
||||
gedr_v = readl(gedr);
|
||||
for (gpio = reg*32; gpio < reg*32+32; gpio++)
|
||||
if (gedr_v & BIT(gpio % 32)) {
|
||||
pr_debug("pin %d triggered\n", gpio);
|
||||
generic_handle_irq(lnw->irq_base + gpio);
|
||||
}
|
||||
}
|
||||
/* clear the edge detect status bit */
|
||||
writel(gedr_v, gedr);
|
||||
}
|
||||
|
|
|
@ -60,15 +60,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||
MODULE_DESCRIPTION("PCMCIA ATA/IDE card driver");
|
||||
MODULE_LICENSE("Dual MPL/GPL");
|
||||
|
||||
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
|
||||
|
||||
#ifdef CONFIG_PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
typedef struct ide_info_t {
|
||||
|
@ -98,7 +89,7 @@ static int ide_probe(struct pcmcia_device *link)
|
|||
{
|
||||
ide_info_t *info;
|
||||
|
||||
DEBUG(0, "ide_attach()\n");
|
||||
dev_dbg(&link->dev, "ide_attach()\n");
|
||||
|
||||
/* Create new ide device */
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
|
@ -112,7 +103,6 @@ static int ide_probe(struct pcmcia_device *link)
|
|||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.IOAddrLines = 3;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -134,7 +124,7 @@ static void ide_detach(struct pcmcia_device *link)
|
|||
ide_hwif_t *hwif = info->host->ports[0];
|
||||
unsigned long data_addr, ctl_addr;
|
||||
|
||||
DEBUG(0, "ide_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ide_detach(0x%p)\n", link);
|
||||
|
||||
data_addr = hwif->io_ports.data_addr;
|
||||
ctl_addr = hwif->io_ports.ctl_addr;
|
||||
|
@ -217,9 +207,6 @@ out_release:
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
struct pcmcia_config_check {
|
||||
unsigned long ctl_base;
|
||||
int skip_vcc;
|
||||
|
@ -282,11 +269,11 @@ static int ide_config(struct pcmcia_device *link)
|
|||
{
|
||||
ide_info_t *info = link->priv;
|
||||
struct pcmcia_config_check *stk = NULL;
|
||||
int last_ret = 0, last_fn = 0, is_kme = 0;
|
||||
int ret = 0, is_kme = 0;
|
||||
unsigned long io_base, ctl_base;
|
||||
struct ide_host *host;
|
||||
|
||||
DEBUG(0, "ide_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ide_config(0x%p)\n", link);
|
||||
|
||||
is_kme = ((link->manf_id == MANFID_KME) &&
|
||||
((link->card_id == PRODID_KME_KXLC005_A) ||
|
||||
|
@ -306,8 +293,12 @@ static int ide_config(struct pcmcia_device *link)
|
|||
io_base = link->io.BasePort1;
|
||||
ctl_base = stk->ctl_base;
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* disable drive interrupts during IDE probe */
|
||||
outb(0x02, ctl_base);
|
||||
|
@ -342,8 +333,6 @@ err_mem:
|
|||
printk(KERN_NOTICE "ide-cs: ide_config failed memory allocation\n");
|
||||
goto failed;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
kfree(stk);
|
||||
ide_release(link);
|
||||
|
@ -363,7 +352,7 @@ static void ide_release(struct pcmcia_device *link)
|
|||
ide_info_t *info = link->priv;
|
||||
struct ide_host *host = info->host;
|
||||
|
||||
DEBUG(0, "ide_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ide_release(0x%p)\n", link);
|
||||
|
||||
if (info->ndev)
|
||||
/* FIXME: if this fails we need to queue the cleanup somehow
|
||||
|
|
|
@ -447,6 +447,27 @@ static struct dmi_system_id __initdata i8042_dmi_reset_table[] = {
|
|||
DMI_MATCH(DMI_PRODUCT_NAME, "N10"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Dell Vostro 1320",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1320"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Dell Vostro 1520",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1520"),
|
||||
},
|
||||
},
|
||||
{
|
||||
.ident = "Dell Vostro 1720",
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
|
||||
DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 1720"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -111,8 +111,6 @@ static int avmcs_probe(struct pcmcia_device *p_dev)
|
|||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -198,7 +196,6 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
*/
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
/* undo */
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
|
@ -209,7 +206,6 @@ static int avmcs_config(struct pcmcia_device *link)
|
|||
*/
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -30,22 +30,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for AVM A1/Fritz!PCMCIA car
|
|||
MODULE_AUTHOR("Carsten Paeth");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
||||
static char *version =
|
||||
"avma1_cs.c 1.00 1998/01/23 10:00:00 (Carsten Paeth)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -119,7 +103,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "avma1cs_attach()\n");
|
||||
dev_dbg(&p_dev->dev, "avma1cs_attach()\n");
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
|
@ -139,8 +123,6 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
|
||||
/* General socket configuration */
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
@ -161,7 +143,7 @@ static int avma1cs_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
static void avma1cs_detach(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "avma1cs_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "avma1cs_detach(0x%p)\n", link);
|
||||
avma1cs_release(link);
|
||||
kfree(link->priv);
|
||||
} /* avma1cs_detach */
|
||||
|
@ -203,7 +185,7 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||
|
||||
dev = link->priv;
|
||||
|
||||
DEBUG(0, "avma1cs_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "avma1cs_config(0x%p)\n", link);
|
||||
|
||||
devname[0] = 0;
|
||||
if (link->prod_id[1])
|
||||
|
@ -218,7 +200,6 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||
*/
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIRQ, i);
|
||||
/* undo */
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
|
@ -229,7 +210,6 @@ static int avma1cs_config(struct pcmcia_device *link)
|
|||
*/
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestConfiguration, i);
|
||||
pcmcia_disable_device(link);
|
||||
break;
|
||||
}
|
||||
|
@ -281,7 +261,7 @@ static void avma1cs_release(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
DEBUG(0, "avma1cs_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "avma1cs_release(0x%p)\n", link);
|
||||
|
||||
/* now unregister function with hisax */
|
||||
HiSax_closecard(local->node.minor);
|
||||
|
|
|
@ -57,23 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Elsa PCM cards");
|
|||
MODULE_AUTHOR("Klaus Lichtenwalder");
|
||||
MODULE_LICENSE("Dual MPL/GPL");
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
||||
static char *version =
|
||||
"elsa_cs.c $Revision: 1.2.2.4 $ $Date: 2004/01/25 15:07:06 $ (K.Lichtenwalder)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -142,7 +125,7 @@ static int elsa_cs_probe(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "elsa_cs_attach()\n");
|
||||
dev_dbg(&link->dev, "elsa_cs_attach()\n");
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
|
@ -155,7 +138,6 @@ static int elsa_cs_probe(struct pcmcia_device *link)
|
|||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
|
@ -188,7 +170,7 @@ static void elsa_cs_detach(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "elsa_cs_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link);
|
||||
|
||||
info->busy = 1;
|
||||
elsa_cs_release(link);
|
||||
|
@ -231,30 +213,25 @@ static int elsa_cs_configcheck(struct pcmcia_device *p_dev,
|
|||
static int elsa_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev;
|
||||
int i, last_fn;
|
||||
int i;
|
||||
IsdnCard_t icard;
|
||||
|
||||
DEBUG(0, "elsa_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "elsa_config(0x%p)\n", link);
|
||||
dev = link->priv;
|
||||
|
||||
i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL);
|
||||
if (i != 0) {
|
||||
last_fn = RequestIO;
|
||||
goto cs_failed;
|
||||
}
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
link->irq.AssignedIRQ = 0;
|
||||
last_fn = RequestIRQ;
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
last_fn = RequestConfiguration;
|
||||
goto cs_failed;
|
||||
}
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
/* At this point, the dev_node_t structure(s) should be
|
||||
initialized and arranged in a linked list at link->dev. *//* */
|
||||
|
@ -290,8 +267,7 @@ static int elsa_cs_config(struct pcmcia_device *link)
|
|||
((local_info_t*)link->priv)->cardnr = i;
|
||||
|
||||
return 0;
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, i);
|
||||
failed:
|
||||
elsa_cs_release(link);
|
||||
return -ENODEV;
|
||||
} /* elsa_cs_config */
|
||||
|
@ -308,7 +284,7 @@ static void elsa_cs_release(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
DEBUG(0, "elsa_cs_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "elsa_cs_release(0x%p)\n", link);
|
||||
|
||||
if (local) {
|
||||
if (local->cardnr >= 0) {
|
||||
|
|
|
@ -57,24 +57,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Sedlbauer cards");
|
|||
MODULE_AUTHOR("Marcus Niemann");
|
||||
MODULE_LICENSE("Dual MPL/GPL");
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
||||
static char *version =
|
||||
"sedlbauer_cs.c 1.1a 2001/01/28 15:04:04 (M.Niemann)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -151,7 +133,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "sedlbauer_attach()\n");
|
||||
dev_dbg(&link->dev, "sedlbauer_attach()\n");
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
|
@ -163,7 +145,6 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
|
@ -198,7 +179,7 @@ static int sedlbauer_probe(struct pcmcia_device *link)
|
|||
|
||||
static void sedlbauer_detach(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "sedlbauer_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "sedlbauer_detach(0x%p)\n", link);
|
||||
|
||||
((local_info_t *)link->priv)->stop = 1;
|
||||
sedlbauer_release(link);
|
||||
|
@ -214,9 +195,6 @@ static void sedlbauer_detach(struct pcmcia_device *link)
|
|||
device available to the system.
|
||||
|
||||
======================================================================*/
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
|
@ -293,11 +271,11 @@ static int sedlbauer_config_check(struct pcmcia_device *p_dev,
|
|||
req->Base = mem->win[0].host_addr;
|
||||
req->Size = mem->win[0].len;
|
||||
req->AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
||||
if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
|
||||
return -ENODEV;
|
||||
map.Page = 0;
|
||||
map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
||||
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
return 0;
|
||||
|
@ -309,10 +287,10 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *dev = link->priv;
|
||||
win_req_t *req;
|
||||
int last_fn, last_ret;
|
||||
int ret;
|
||||
IsdnCard_t icard;
|
||||
|
||||
DEBUG(0, "sedlbauer_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "sedlbauer_config(0x%p)\n", link);
|
||||
|
||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||
if (!req)
|
||||
|
@ -330,8 +308,8 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
these things without consulting the CIS, and most client drivers
|
||||
will only use the CIS to fill in implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
|
||||
if (last_ret)
|
||||
ret = pcmcia_loop_config(link, sedlbauer_config_check, req);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
|
@ -339,15 +317,20 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
handler to the interrupt, unless the 'Handler' member of the
|
||||
irq structure is initialized.
|
||||
*/
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
the I/O windows and the interrupt mapping, and putting the
|
||||
card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
At this point, the dev_node_t structure(s) need to be
|
||||
|
@ -380,19 +363,18 @@ static int sedlbauer_config(struct pcmcia_device *link)
|
|||
icard.protocol = protocol;
|
||||
icard.typ = ISDN_CTYPE_SEDLBAUER_PCMCIA;
|
||||
|
||||
last_ret = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->stop), &icard);
|
||||
if (last_ret < 0) {
|
||||
printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
|
||||
last_ret, link->io.BasePort1);
|
||||
ret = hisax_init_pcmcia(link,
|
||||
&(((local_info_t *)link->priv)->stop), &icard);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR "sedlbauer_cs: failed to initialize SEDLBAUER PCMCIA %d at i/o %#x\n",
|
||||
ret, link->io.BasePort1);
|
||||
sedlbauer_release(link);
|
||||
return -ENODEV;
|
||||
} else
|
||||
((local_info_t*)link->priv)->cardnr = last_ret;
|
||||
((local_info_t *)link->priv)->cardnr = ret;
|
||||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
sedlbauer_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -410,7 +392,7 @@ failed:
|
|||
static void sedlbauer_release(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *local = link->priv;
|
||||
DEBUG(0, "sedlbauer_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "sedlbauer_release(0x%p)\n", link);
|
||||
|
||||
if (local) {
|
||||
if (local->cardnr >= 0) {
|
||||
|
|
|
@ -38,23 +38,6 @@ MODULE_DESCRIPTION("ISDN4Linux: PCMCIA client driver for Teles PCMCIA cards");
|
|||
MODULE_AUTHOR("Christof Petig, christof.petig@wtal.de, Karsten Keil, kkeil@suse.de");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
||||
static char *version =
|
||||
"teles_cs.c 2.10 2002/07/30 22:23:34 kkeil";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -133,7 +116,7 @@ static int teles_probe(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "teles_attach()\n");
|
||||
dev_dbg(&link->dev, "teles_attach()\n");
|
||||
|
||||
/* Allocate space for private device-specific data */
|
||||
local = kzalloc(sizeof(local_info_t), GFP_KERNEL);
|
||||
|
@ -145,7 +128,6 @@ static int teles_probe(struct pcmcia_device *link)
|
|||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID|IRQ_SHARE_ID;
|
||||
link->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
|
@ -178,7 +160,7 @@ static void teles_detach(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "teles_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "teles_detach(0x%p)\n", link);
|
||||
|
||||
info->busy = 1;
|
||||
teles_cs_release(link);
|
||||
|
@ -221,30 +203,25 @@ static int teles_cs_configcheck(struct pcmcia_device *p_dev,
|
|||
static int teles_cs_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev;
|
||||
int i, last_fn;
|
||||
int i;
|
||||
IsdnCard_t icard;
|
||||
|
||||
DEBUG(0, "teles_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "teles_config(0x%p)\n", link);
|
||||
dev = link->priv;
|
||||
|
||||
i = pcmcia_loop_config(link, teles_cs_configcheck, NULL);
|
||||
if (i != 0) {
|
||||
last_fn = RequestIO;
|
||||
if (i != 0)
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0) {
|
||||
link->irq.AssignedIRQ = 0;
|
||||
last_fn = RequestIRQ;
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
if (i != 0) {
|
||||
last_fn = RequestConfiguration;
|
||||
if (i != 0)
|
||||
goto cs_failed;
|
||||
}
|
||||
|
||||
/* At this point, the dev_node_t structure(s) should be
|
||||
initialized and arranged in a linked list at link->dev. *//* */
|
||||
|
@ -283,7 +260,6 @@ static int teles_cs_config(struct pcmcia_device *link)
|
|||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, i);
|
||||
teles_cs_release(link);
|
||||
return -ENODEV;
|
||||
} /* teles_cs_config */
|
||||
|
@ -300,7 +276,7 @@ static void teles_cs_release(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *local = link->priv;
|
||||
|
||||
DEBUG(0, "teles_cs_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "teles_cs_release(0x%p)\n", link);
|
||||
|
||||
if (local) {
|
||||
if (local->cardnr >= 0) {
|
||||
|
|
|
@ -1650,11 +1650,12 @@ static void raid1d(mddev_t *mddev)
|
|||
r1_bio->sector,
|
||||
r1_bio->sectors);
|
||||
unfreeze_array(conf);
|
||||
}
|
||||
} else
|
||||
md_error(mddev,
|
||||
conf->mirrors[r1_bio->read_disk].rdev);
|
||||
|
||||
bio = r1_bio->bios[r1_bio->read_disk];
|
||||
if ((disk=read_balance(conf, r1_bio)) == -1 ||
|
||||
disk == r1_bio->read_disk) {
|
||||
if ((disk=read_balance(conf, r1_bio)) == -1) {
|
||||
printk(KERN_ALERT "raid1: %s: unrecoverable I/O"
|
||||
" read error for block %llu\n",
|
||||
bdevname(bio->bi_bdev,b),
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <linux/wait.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/semaphore.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/freezer.h>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
/* Current settings - values are 2*2^(reg_val/4) microamps. These are
|
||||
* exported since they are used by multiple drivers.
|
||||
*/
|
||||
int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL] = {
|
||||
int wm831x_isinkv_values[WM831X_ISINK_MAX_ISEL + 1] = {
|
||||
2,
|
||||
2,
|
||||
3,
|
||||
|
|
|
@ -760,6 +760,8 @@ static int pxamci_remove(struct platform_device *pdev)
|
|||
if (mmc) {
|
||||
struct pxamci_host *host = mmc_priv(mmc);
|
||||
|
||||
mmc_remove_host(mmc);
|
||||
|
||||
if (host->pdata) {
|
||||
gpio_cd = host->pdata->gpio_card_detect;
|
||||
gpio_ro = host->pdata->gpio_card_ro;
|
||||
|
@ -779,8 +781,6 @@ static int pxamci_remove(struct platform_device *pdev)
|
|||
if (host->pdata && host->pdata->exit)
|
||||
host->pdata->exit(&pdev->dev, mmc);
|
||||
|
||||
mmc_remove_host(mmc);
|
||||
|
||||
pxamci_stop_clock(host);
|
||||
writel(TXFIFO_WR_REQ|RXFIFO_RD_REQ|CLK_IS_OFF|STOP_CMD|
|
||||
END_CMD_RES|PRG_DONE|DATA_TRAN_DONE,
|
||||
|
|
|
@ -118,11 +118,9 @@ static caddr_t remap_window(struct map_info *map, unsigned long to)
|
|||
DEBUG(2, "Remapping window from 0x%8.8x to 0x%8.8x",
|
||||
dev->offset, mrq.CardOffset);
|
||||
mrq.Page = 0;
|
||||
ret = pcmcia_map_mem_page(win, &mrq);
|
||||
if (ret != 0) {
|
||||
cs_error(dev->p_dev, MapMemPage, ret);
|
||||
ret = pcmcia_map_mem_page(dev->p_dev, win, &mrq);
|
||||
if (ret != 0)
|
||||
return NULL;
|
||||
}
|
||||
dev->offset = mrq.CardOffset;
|
||||
}
|
||||
return dev->win_base + (to & (dev->win_size-1));
|
||||
|
@ -327,8 +325,6 @@ static void pcmciamtd_set_vpp(struct map_info *map, int on)
|
|||
|
||||
DEBUG(2, "dev = %p on = %d vpp = %d\n", dev, on, dev->vpp);
|
||||
ret = pcmcia_modify_configuration(link, &mod);
|
||||
if (ret != 0)
|
||||
cs_error(link, ModifyConfiguration, ret);
|
||||
}
|
||||
|
||||
|
||||
|
@ -348,107 +344,116 @@ static void pcmciamtd_release(struct pcmcia_device *link)
|
|||
iounmap(dev->win_base);
|
||||
dev->win_base = NULL;
|
||||
}
|
||||
pcmcia_release_window(link->win);
|
||||
pcmcia_release_window(link, link->win);
|
||||
}
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_MTD_DEBUG
|
||||
static int pcmciamtd_cistpl_format(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv_data)
|
||||
{
|
||||
cisparse_t parse;
|
||||
|
||||
if (!pcmcia_parse_tuple(tuple, &parse)) {
|
||||
cistpl_format_t *t = &parse.format;
|
||||
(void)t; /* Shut up, gcc */
|
||||
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
|
||||
t->type, t->edc, t->offset, t->length);
|
||||
}
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
static int pcmciamtd_cistpl_jedec(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv_data)
|
||||
{
|
||||
cisparse_t parse;
|
||||
int i;
|
||||
|
||||
if (!pcmcia_parse_tuple(tuple, &parse)) {
|
||||
cistpl_jedec_t *t = &parse.jedec;
|
||||
for (i = 0; i < t->nid; i++)
|
||||
DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
|
||||
}
|
||||
return -ENOSPC;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int pcmciamtd_cistpl_device(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv_data)
|
||||
{
|
||||
struct pcmciamtd_dev *dev = priv_data;
|
||||
cisparse_t parse;
|
||||
cistpl_device_t *t = &parse.device;
|
||||
int i;
|
||||
|
||||
if (pcmcia_parse_tuple(tuple, &parse))
|
||||
return -EINVAL;
|
||||
|
||||
DEBUG(2, "Common memory:");
|
||||
dev->pcmcia_map.size = t->dev[0].size;
|
||||
/* from here on: DEBUG only */
|
||||
for (i = 0; i < t->ndev; i++) {
|
||||
DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
|
||||
DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
|
||||
DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
|
||||
DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcmciamtd_cistpl_geo(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv_data)
|
||||
{
|
||||
struct pcmciamtd_dev *dev = priv_data;
|
||||
cisparse_t parse;
|
||||
cistpl_device_geo_t *t = &parse.device_geo;
|
||||
int i;
|
||||
|
||||
if (pcmcia_parse_tuple(tuple, &parse))
|
||||
return -EINVAL;
|
||||
|
||||
dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
|
||||
/* from here on: DEBUG only */
|
||||
for (i = 0; i < t->ngeo; i++) {
|
||||
DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
|
||||
DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
|
||||
DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
|
||||
DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
|
||||
DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
|
||||
DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link, int *new_name)
|
||||
{
|
||||
int rc;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
u_char buf[64];
|
||||
int i;
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = RETURN_FIRST_TUPLE;
|
||||
|
||||
rc = pcmcia_get_first_tuple(link, &tuple);
|
||||
while (rc == 0) {
|
||||
rc = pcmcia_get_tuple_data(link, &tuple);
|
||||
if (rc != 0) {
|
||||
cs_error(link, GetTupleData, rc);
|
||||
break;
|
||||
if (p_dev->prod_id[0]) {
|
||||
dev->mtd_name[0] = '\0';
|
||||
for (i = 0; i < 4; i++) {
|
||||
if (i)
|
||||
strcat(dev->mtd_name, " ");
|
||||
if (p_dev->prod_id[i])
|
||||
strcat(dev->mtd_name, p_dev->prod_id[i]);
|
||||
}
|
||||
rc = pcmcia_parse_tuple(&tuple, &parse);
|
||||
if (rc != 0) {
|
||||
cs_error(link, ParseTuple, rc);
|
||||
break;
|
||||
}
|
||||
|
||||
switch(tuple.TupleCode) {
|
||||
case CISTPL_FORMAT: {
|
||||
cistpl_format_t *t = &parse.format;
|
||||
(void)t; /* Shut up, gcc */
|
||||
DEBUG(2, "Format type: %u, Error Detection: %u, offset = %u, length =%u",
|
||||
t->type, t->edc, t->offset, t->length);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case CISTPL_DEVICE: {
|
||||
cistpl_device_t *t = &parse.device;
|
||||
int i;
|
||||
DEBUG(2, "Common memory:");
|
||||
dev->pcmcia_map.size = t->dev[0].size;
|
||||
for(i = 0; i < t->ndev; i++) {
|
||||
DEBUG(2, "Region %d, type = %u", i, t->dev[i].type);
|
||||
DEBUG(2, "Region %d, wp = %u", i, t->dev[i].wp);
|
||||
DEBUG(2, "Region %d, speed = %u ns", i, t->dev[i].speed);
|
||||
DEBUG(2, "Region %d, size = %u bytes", i, t->dev[i].size);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CISTPL_VERS_1: {
|
||||
cistpl_vers_1_t *t = &parse.version_1;
|
||||
int i;
|
||||
if(t->ns) {
|
||||
dev->mtd_name[0] = '\0';
|
||||
for(i = 0; i < t->ns; i++) {
|
||||
if(i)
|
||||
strcat(dev->mtd_name, " ");
|
||||
strcat(dev->mtd_name, t->str+t->ofs[i]);
|
||||
}
|
||||
}
|
||||
DEBUG(2, "Found name: %s", dev->mtd_name);
|
||||
break;
|
||||
}
|
||||
|
||||
case CISTPL_JEDEC_C: {
|
||||
cistpl_jedec_t *t = &parse.jedec;
|
||||
int i;
|
||||
for(i = 0; i < t->nid; i++) {
|
||||
DEBUG(2, "JEDEC: 0x%02x 0x%02x", t->id[i].mfr, t->id[i].info);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CISTPL_DEVICE_GEO: {
|
||||
cistpl_device_geo_t *t = &parse.device_geo;
|
||||
int i;
|
||||
dev->pcmcia_map.bankwidth = t->geo[0].buswidth;
|
||||
for(i = 0; i < t->ngeo; i++) {
|
||||
DEBUG(2, "region: %d bankwidth = %u", i, t->geo[i].buswidth);
|
||||
DEBUG(2, "region: %d erase_block = %u", i, t->geo[i].erase_block);
|
||||
DEBUG(2, "region: %d read_block = %u", i, t->geo[i].read_block);
|
||||
DEBUG(2, "region: %d write_block = %u", i, t->geo[i].write_block);
|
||||
DEBUG(2, "region: %d partition = %u", i, t->geo[i].partition);
|
||||
DEBUG(2, "region: %d interleave = %u", i, t->geo[i].interleave);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
DEBUG(2, "Unknown tuple code %d", tuple.TupleCode);
|
||||
}
|
||||
|
||||
rc = pcmcia_get_next_tuple(link, &tuple);
|
||||
DEBUG(2, "Found name: %s", dev->mtd_name);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_DEBUG
|
||||
pcmcia_loop_tuple(p_dev, CISTPL_FORMAT, pcmciamtd_cistpl_format, NULL);
|
||||
pcmcia_loop_tuple(p_dev, CISTPL_JEDEC_C, pcmciamtd_cistpl_jedec, NULL);
|
||||
#endif
|
||||
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE, pcmciamtd_cistpl_device, dev);
|
||||
pcmcia_loop_tuple(p_dev, CISTPL_DEVICE_GEO, pcmciamtd_cistpl_geo, dev);
|
||||
|
||||
if(!dev->pcmcia_map.size)
|
||||
dev->pcmcia_map.size = MAX_PCMCIA_ADDR;
|
||||
|
||||
|
@ -481,16 +486,12 @@ static void card_settings(struct pcmciamtd_dev *dev, struct pcmcia_device *link,
|
|||
* MTD device available to the system.
|
||||
*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int pcmciamtd_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct pcmciamtd_dev *dev = link->priv;
|
||||
struct mtd_info *mtd = NULL;
|
||||
cs_status_t status;
|
||||
win_req_t req;
|
||||
int last_ret = 0, last_fn = 0;
|
||||
int ret;
|
||||
int i;
|
||||
static char *probes[] = { "jedec_probe", "cfi_probe" };
|
||||
|
@ -529,7 +530,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||
int ret;
|
||||
DEBUG(2, "requesting window with size = %dKiB memspeed = %d",
|
||||
req.Size >> 10, req.AccessSpeed);
|
||||
ret = pcmcia_request_window(&link, &req, &link->win);
|
||||
ret = pcmcia_request_window(link, &req, &link->win);
|
||||
DEBUG(2, "ret = %d dev->win_size = %d", ret, dev->win_size);
|
||||
if(ret) {
|
||||
req.Size >>= 1;
|
||||
|
@ -577,7 +578,6 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||
DEBUG(2, "Setting Configuration");
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret != 0) {
|
||||
cs_error(link, RequestConfiguration, ret);
|
||||
if (dev->win_base) {
|
||||
iounmap(dev->win_base);
|
||||
dev->win_base = NULL;
|
||||
|
@ -652,8 +652,7 @@ static int pcmciamtd_config(struct pcmcia_device *link)
|
|||
link->dev_node = &dev->node;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
err("CS Error, exiting");
|
||||
pcmciamtd_release(link);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -118,14 +118,6 @@ INT_MODULE_PARM(full_duplex, 0);
|
|||
/* Autodetect link polarity reversal? */
|
||||
INT_MODULE_PARM(auto_polarity, 1);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"3c574_cs.c 1.65ac1 2003/04/07 Donald Becker/David Hinds, becker@scyld.com.\n";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -278,7 +270,7 @@ static int tc574_probe(struct pcmcia_device *link)
|
|||
struct el3_private *lp;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "3c574_attach()\n");
|
||||
dev_dbg(&link->dev, "3c574_attach()\n");
|
||||
|
||||
/* Create the PC card device object. */
|
||||
dev = alloc_etherdev(sizeof(struct el3_private));
|
||||
|
@ -291,10 +283,8 @@ static int tc574_probe(struct pcmcia_device *link)
|
|||
spin_lock_init(&lp->window_lock);
|
||||
link->io.NumPorts1 = 32;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = &el3_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -319,7 +309,7 @@ static void tc574_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "3c574_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "3c574_detach()\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -335,26 +325,23 @@ static void tc574_detach(struct pcmcia_device *link)
|
|||
ethernet device available to the system.
|
||||
*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static const char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
||||
|
||||
static int tc574_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct el3_private *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
__le16 buf[32];
|
||||
int last_fn, last_ret, i, j;
|
||||
int ret, i, j;
|
||||
unsigned int ioaddr;
|
||||
__be16 *phys_addr;
|
||||
char *cardname;
|
||||
__u32 config;
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
|
||||
phys_addr = (__be16 *)dev->dev_addr;
|
||||
|
||||
DEBUG(0, "3c574_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "3c574_config()\n");
|
||||
|
||||
link->io.IOAddrLines = 16;
|
||||
for (i = j = 0; j < 0x400; j += 0x20) {
|
||||
|
@ -363,12 +350,16 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIO, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -378,16 +369,14 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
/* The 3c574 normally uses an EEPROM for configuration info, including
|
||||
the hardware address. The future products may include a modem chip
|
||||
and put the address in the CIS. */
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = 0x88;
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
||||
pcmcia_get_tuple_data(link, &tuple);
|
||||
|
||||
len = pcmcia_get_tuple(link, 0x88, &buf);
|
||||
if (buf && len >= 6) {
|
||||
for (i = 0; i < 3; i++)
|
||||
phys_addr[i] = htons(le16_to_cpu(buf[i]));
|
||||
phys_addr[i] = htons(le16_to_cpu(buf[i * 2]));
|
||||
kfree(buf);
|
||||
} else {
|
||||
kfree(buf); /* 0 < len < 6 */
|
||||
EL3WINDOW(0);
|
||||
for (i = 0; i < 3; i++)
|
||||
phys_addr[i] = htons(read_eeprom(ioaddr, i + 10));
|
||||
|
@ -435,7 +424,8 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
mii_status = mdio_read(ioaddr, phy & 0x1f, 1);
|
||||
if (mii_status != 0xffff) {
|
||||
lp->phys = phy & 0x1f;
|
||||
DEBUG(0, " MII transceiver at index %d, status %x.\n",
|
||||
dev_dbg(&link->dev, " MII transceiver at "
|
||||
"index %d, status %x.\n",
|
||||
phy, mii_status);
|
||||
if ((mii_status & 0x0040) == 0)
|
||||
mii_preamble_required = 1;
|
||||
|
@ -457,7 +447,7 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "3c574_cs: register_netdev() failed\n");
|
||||
|
@ -478,8 +468,6 @@ static int tc574_config(struct pcmcia_device *link)
|
|||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
tc574_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -738,7 +726,7 @@ static int el3_open(struct net_device *dev)
|
|||
lp->media.expires = jiffies + HZ;
|
||||
add_timer(&lp->media);
|
||||
|
||||
DEBUG(2, "%s: opened, status %4.4x.\n",
|
||||
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
|
||||
dev->name, inw(dev->base_addr + EL3_STATUS));
|
||||
|
||||
return 0;
|
||||
|
@ -772,7 +760,7 @@ static void pop_tx_status(struct net_device *dev)
|
|||
if (tx_status & 0x30)
|
||||
tc574_wait_for_completion(dev, TxReset);
|
||||
if (tx_status & 0x38) {
|
||||
DEBUG(1, "%s: transmit error: status 0x%02x\n",
|
||||
pr_debug("%s: transmit error: status 0x%02x\n",
|
||||
dev->name, tx_status);
|
||||
outw(TxEnable, ioaddr + EL3_CMD);
|
||||
dev->stats.tx_aborted_errors++;
|
||||
|
@ -788,7 +776,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
|
|||
struct el3_private *lp = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
|
||||
pr_debug("%s: el3_start_xmit(length = %ld) called, "
|
||||
"status %4.4x.\n", dev->name, (long)skb->len,
|
||||
inw(ioaddr + EL3_STATUS));
|
||||
|
||||
|
@ -827,7 +815,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
return IRQ_NONE;
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(3, "%s: interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: interrupt, status %4.4x.\n",
|
||||
dev->name, inw(ioaddr + EL3_STATUS));
|
||||
|
||||
spin_lock(&lp->window_lock);
|
||||
|
@ -836,7 +824,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
(IntLatch | RxComplete | RxEarly | StatsFull)) {
|
||||
if (!netif_device_present(dev) ||
|
||||
((status & 0xe000) != 0x2000)) {
|
||||
DEBUG(1, "%s: Interrupt from dead card\n", dev->name);
|
||||
pr_debug("%s: Interrupt from dead card\n", dev->name);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -846,7 +834,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
work_budget = el3_rx(dev, work_budget);
|
||||
|
||||
if (status & TxAvailable) {
|
||||
DEBUG(3, " TX room bit was handled.\n");
|
||||
pr_debug(" TX room bit was handled.\n");
|
||||
/* There's room in the FIFO for a full-sized packet. */
|
||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||
netif_wake_queue(dev);
|
||||
|
@ -886,7 +874,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (--work_budget < 0) {
|
||||
DEBUG(0, "%s: Too much work in interrupt, "
|
||||
pr_debug("%s: Too much work in interrupt, "
|
||||
"status %4.4x.\n", dev->name, status);
|
||||
/* Clear all interrupts */
|
||||
outw(AckIntr | 0xFF, ioaddr + EL3_CMD);
|
||||
|
@ -896,7 +884,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
|
||||
}
|
||||
|
||||
DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||
dev->name, inw(ioaddr + EL3_STATUS));
|
||||
|
||||
spin_unlock(&lp->window_lock);
|
||||
|
@ -1003,7 +991,7 @@ static void update_stats(struct net_device *dev)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
u8 rx, tx, up;
|
||||
|
||||
DEBUG(2, "%s: updating the statistics.\n", dev->name);
|
||||
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||
|
||||
if (inw(ioaddr+EL3_STATUS) == 0xffff) /* No card. */
|
||||
return;
|
||||
|
@ -1039,7 +1027,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
short rx_status;
|
||||
|
||||
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
|
||||
while (!((rx_status = inw(ioaddr + RxStatus)) & 0x8000) &&
|
||||
worklimit > 0) {
|
||||
|
@ -1061,7 +1049,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||
|
||||
skb = dev_alloc_skb(pkt_len+5);
|
||||
|
||||
DEBUG(3, " Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug(" Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
if (skb != NULL) {
|
||||
skb_reserve(skb, 2);
|
||||
|
@ -1072,7 +1060,7 @@ static int el3_rx(struct net_device *dev, int worklimit)
|
|||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += pkt_len;
|
||||
} else {
|
||||
DEBUG(1, "%s: couldn't allocate a sk_buff of"
|
||||
pr_debug("%s: couldn't allocate a sk_buff of"
|
||||
" size %d.\n", dev->name, pkt_len);
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
|
@ -1101,7 +1089,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
struct mii_ioctl_data *data = if_mii(rq);
|
||||
int phy = lp->phys & 0x1f;
|
||||
|
||||
DEBUG(2, "%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
|
||||
pr_debug("%s: In ioct(%-.6s, %#4.4x) %4.4x %4.4x %4.4x %4.4x.\n",
|
||||
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
||||
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
||||
|
||||
|
@ -1178,7 +1166,7 @@ static int el3_close(struct net_device *dev)
|
|||
struct el3_private *lp = netdev_priv(dev);
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
|
||||
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||
|
||||
if (pcmcia_dev_present(link)) {
|
||||
unsigned long flags;
|
||||
|
|
|
@ -130,14 +130,6 @@ MODULE_LICENSE("GPL");
|
|||
/* Special hook for setting if_port when module is loaded */
|
||||
INT_MODULE_PARM(if_port, 0);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
DRV_NAME ".c " DRV_VERSION " 2001/10/13 00:08:50 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -189,7 +181,7 @@ static int tc589_probe(struct pcmcia_device *link)
|
|||
struct el3_private *lp;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "3c589_attach()\n");
|
||||
dev_dbg(&link->dev, "3c589_attach()\n");
|
||||
|
||||
/* Create new ethernet device */
|
||||
dev = alloc_etherdev(sizeof(struct el3_private));
|
||||
|
@ -202,10 +194,8 @@ static int tc589_probe(struct pcmcia_device *link)
|
|||
spin_lock_init(&lp->lock);
|
||||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = &el3_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -231,7 +221,7 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "3c589_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "3c589_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -249,29 +239,20 @@ static void tc589_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int tc589_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct el3_private *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
__le16 buf[32];
|
||||
__be16 *phys_addr;
|
||||
int last_fn, last_ret, i, j, multi = 0, fifo;
|
||||
int ret, i, j, multi = 0, fifo;
|
||||
unsigned int ioaddr;
|
||||
char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
|
||||
DEBUG(0, "3c589_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "3c589_config\n");
|
||||
|
||||
phys_addr = (__be16 *)dev->dev_addr;
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = (cisdata_t *)buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
||||
|
||||
/* Is this a 3c562? */
|
||||
if (link->manf_id != MANFID_3COM)
|
||||
printk(KERN_INFO "3c589_cs: hmmm, is this really a "
|
||||
|
@ -287,12 +268,16 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIO, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -301,12 +286,13 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
|
||||
/* The 3c589 has an extra EEPROM for configuration info, including
|
||||
the hardware address. The 3c562 puts the address in the CIS. */
|
||||
tuple.DesiredTuple = 0x88;
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
||||
pcmcia_get_tuple_data(link, &tuple);
|
||||
for (i = 0; i < 3; i++)
|
||||
phys_addr[i] = htons(le16_to_cpu(buf[i]));
|
||||
len = pcmcia_get_tuple(link, 0x88, &buf);
|
||||
if (buf && len >= 6) {
|
||||
for (i = 0; i < 3; i++)
|
||||
phys_addr[i] = htons(le16_to_cpu(buf[i*2]));
|
||||
kfree(buf);
|
||||
} else {
|
||||
kfree(buf); /* 0 < len < 6 */
|
||||
for (i = 0; i < 3; i++)
|
||||
phys_addr[i] = htons(read_eeprom(ioaddr, i));
|
||||
if (phys_addr[0] == htons(0x6060)) {
|
||||
|
@ -328,7 +314,7 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
printk(KERN_ERR "3c589_cs: invalid if_port requested\n");
|
||||
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR "3c589_cs: register_netdev() failed\n");
|
||||
|
@ -347,8 +333,6 @@ static int tc589_config(struct pcmcia_device *link)
|
|||
if_names[dev->if_port]);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
tc589_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -511,24 +495,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||
}
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
return pc_debug;
|
||||
}
|
||||
|
||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
||||
{
|
||||
pc_debug = level;
|
||||
}
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
|
||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||
.get_drvinfo = netdev_get_drvinfo,
|
||||
#ifdef PCMCIA_DEBUG
|
||||
.get_msglevel = netdev_get_msglevel,
|
||||
.set_msglevel = netdev_set_msglevel,
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
};
|
||||
|
||||
static int el3_config(struct net_device *dev, struct ifmap *map)
|
||||
|
@ -563,7 +531,7 @@ static int el3_open(struct net_device *dev)
|
|||
lp->media.expires = jiffies + HZ;
|
||||
add_timer(&lp->media);
|
||||
|
||||
DEBUG(1, "%s: opened, status %4.4x.\n",
|
||||
dev_dbg(&link->dev, "%s: opened, status %4.4x.\n",
|
||||
dev->name, inw(dev->base_addr + EL3_STATUS));
|
||||
|
||||
return 0;
|
||||
|
@ -596,7 +564,7 @@ static void pop_tx_status(struct net_device *dev)
|
|||
if (tx_status & 0x30)
|
||||
tc589_wait_for_completion(dev, TxReset);
|
||||
if (tx_status & 0x38) {
|
||||
DEBUG(1, "%s: transmit error: status 0x%02x\n",
|
||||
pr_debug("%s: transmit error: status 0x%02x\n",
|
||||
dev->name, tx_status);
|
||||
outw(TxEnable, ioaddr + EL3_CMD);
|
||||
dev->stats.tx_aborted_errors++;
|
||||
|
@ -612,7 +580,7 @@ static netdev_tx_t el3_start_xmit(struct sk_buff *skb,
|
|||
struct el3_private *priv = netdev_priv(dev);
|
||||
unsigned long flags;
|
||||
|
||||
DEBUG(3, "%s: el3_start_xmit(length = %ld) called, "
|
||||
pr_debug("%s: el3_start_xmit(length = %ld) called, "
|
||||
"status %4.4x.\n", dev->name, (long)skb->len,
|
||||
inw(ioaddr + EL3_STATUS));
|
||||
|
||||
|
@ -654,14 +622,14 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(3, "%s: interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: interrupt, status %4.4x.\n",
|
||||
dev->name, inw(ioaddr + EL3_STATUS));
|
||||
|
||||
spin_lock(&lp->lock);
|
||||
while ((status = inw(ioaddr + EL3_STATUS)) &
|
||||
(IntLatch | RxComplete | StatsFull)) {
|
||||
if ((status & 0xe000) != 0x2000) {
|
||||
DEBUG(1, "%s: interrupt from dead card\n", dev->name);
|
||||
pr_debug("%s: interrupt from dead card\n", dev->name);
|
||||
handled = 0;
|
||||
break;
|
||||
}
|
||||
|
@ -670,7 +638,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
el3_rx(dev);
|
||||
|
||||
if (status & TxAvailable) {
|
||||
DEBUG(3, " TX room bit was handled.\n");
|
||||
pr_debug(" TX room bit was handled.\n");
|
||||
/* There's room in the FIFO for a full-sized packet. */
|
||||
outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
|
||||
netif_wake_queue(dev);
|
||||
|
@ -722,7 +690,7 @@ static irqreturn_t el3_interrupt(int irq, void *dev_id)
|
|||
|
||||
lp->last_irq = jiffies;
|
||||
spin_unlock(&lp->lock);
|
||||
DEBUG(3, "%s: exiting interrupt, status %4.4x.\n",
|
||||
pr_debug("%s: exiting interrupt, status %4.4x.\n",
|
||||
dev->name, inw(ioaddr + EL3_STATUS));
|
||||
return IRQ_RETVAL(handled);
|
||||
}
|
||||
|
@ -833,7 +801,7 @@ static void update_stats(struct net_device *dev)
|
|||
{
|
||||
unsigned int ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(2, "%s: updating the statistics.\n", dev->name);
|
||||
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||
/* Turn off statistics updates while reading. */
|
||||
outw(StatsDisable, ioaddr + EL3_CMD);
|
||||
/* Switch to the stats window, and read everything. */
|
||||
|
@ -861,7 +829,7 @@ static int el3_rx(struct net_device *dev)
|
|||
int worklimit = 32;
|
||||
short rx_status;
|
||||
|
||||
DEBUG(3, "%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
pr_debug("%s: in rx_packet(), status %4.4x, rx_status %4.4x.\n",
|
||||
dev->name, inw(ioaddr+EL3_STATUS), inw(ioaddr+RX_STATUS));
|
||||
while (!((rx_status = inw(ioaddr + RX_STATUS)) & 0x8000) &&
|
||||
worklimit > 0) {
|
||||
|
@ -883,7 +851,7 @@ static int el3_rx(struct net_device *dev)
|
|||
|
||||
skb = dev_alloc_skb(pkt_len+5);
|
||||
|
||||
DEBUG(3, " Receiving packet size %d status %4.4x.\n",
|
||||
pr_debug(" Receiving packet size %d status %4.4x.\n",
|
||||
pkt_len, rx_status);
|
||||
if (skb != NULL) {
|
||||
skb_reserve(skb, 2);
|
||||
|
@ -894,7 +862,7 @@ static int el3_rx(struct net_device *dev)
|
|||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += pkt_len;
|
||||
} else {
|
||||
DEBUG(1, "%s: couldn't allocate a sk_buff of"
|
||||
pr_debug("%s: couldn't allocate a sk_buff of"
|
||||
" size %d.\n", dev->name, pkt_len);
|
||||
dev->stats.rx_dropped++;
|
||||
}
|
||||
|
@ -935,7 +903,7 @@ static int el3_close(struct net_device *dev)
|
|||
struct pcmcia_device *link = lp->p_dev;
|
||||
unsigned int ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(1, "%s: shutting down ethercard.\n", dev->name);
|
||||
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||
|
||||
if (pcmcia_dev_present(link)) {
|
||||
/* Turn off statistics ASAP. We update dev->stats below. */
|
||||
|
|
|
@ -75,16 +75,6 @@ MODULE_AUTHOR("David Hinds <dahinds@users.sourceforge.net>");
|
|||
MODULE_DESCRIPTION("Asix AX88190 PCMCIA ethernet driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
#define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0)
|
||||
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"axnet_cs.c 1.28 2002/06/29 06:27:37 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -167,7 +157,7 @@ static int axnet_probe(struct pcmcia_device *link)
|
|||
struct net_device *dev;
|
||||
struct ei_device *ei_local;
|
||||
|
||||
DEBUG(0, "axnet_attach()\n");
|
||||
dev_dbg(&link->dev, "axnet_attach()\n");
|
||||
|
||||
dev = alloc_etherdev(sizeof(struct ei_device) + sizeof(axnet_dev_t));
|
||||
if (!dev)
|
||||
|
@ -180,7 +170,6 @@ static int axnet_probe(struct pcmcia_device *link)
|
|||
info->p_dev = link;
|
||||
link->priv = dev;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -205,7 +194,7 @@ static void axnet_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "axnet_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "axnet_detach(0x%p)\n", link);
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -272,9 +261,6 @@ static int get_prom(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int j, ret;
|
||||
|
@ -341,26 +327,29 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
axnet_dev_t *info = PRIV(dev);
|
||||
int i, j, j2, last_ret, last_fn;
|
||||
int i, j, j2, ret;
|
||||
|
||||
DEBUG(0, "axnet_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "axnet_config(0x%p)\n", link);
|
||||
|
||||
/* don't trust the CIS on this; Linksys got it wrong */
|
||||
link->conf.Present = 0x63;
|
||||
last_ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
|
||||
if (last_ret != 0) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
ret = pcmcia_loop_config(link, axnet_configcheck, NULL);
|
||||
if (ret != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
|
@ -410,7 +399,7 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
|
||||
info->phy_id = (i < 32) ? i : -1;
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "axnet_cs: register_netdev() failed\n");
|
||||
|
@ -426,14 +415,12 @@ static int axnet_config(struct pcmcia_device *link)
|
|||
dev->base_addr, dev->irq,
|
||||
dev->dev_addr);
|
||||
if (info->phy_id != -1) {
|
||||
DEBUG(0, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
|
||||
dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n", info->phy_id, j);
|
||||
} else {
|
||||
printk(KERN_NOTICE " No MII transceivers found!\n");
|
||||
}
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
axnet_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -543,7 +530,7 @@ static int axnet_open(struct net_device *dev)
|
|||
struct pcmcia_device *link = info->p_dev;
|
||||
unsigned int nic_base = dev->base_addr;
|
||||
|
||||
DEBUG(2, "axnet_open('%s')\n", dev->name);
|
||||
dev_dbg(&link->dev, "axnet_open('%s')\n", dev->name);
|
||||
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
@ -572,7 +559,7 @@ static int axnet_close(struct net_device *dev)
|
|||
axnet_dev_t *info = PRIV(dev);
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "axnet_close('%s')\n", dev->name);
|
||||
dev_dbg(&link->dev, "axnet_close('%s')\n", dev->name);
|
||||
|
||||
ax_close(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
|
@ -741,10 +728,8 @@ static void block_input(struct net_device *dev, int count,
|
|||
int xfer_count = count;
|
||||
char *buf = skb->data;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if ((ei_debug > 4) && (count != 4))
|
||||
printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
|
||||
#endif
|
||||
pr_debug("%s: [bi=%d]\n", dev->name, count+4);
|
||||
outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
|
||||
outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
|
||||
outb_p(E8390_RREAD+E8390_START, nic_base + AXNET_CMD);
|
||||
|
@ -762,10 +747,7 @@ static void block_output(struct net_device *dev, int count,
|
|||
{
|
||||
unsigned int nic_base = dev->base_addr;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (ei_debug > 4)
|
||||
printk(KERN_DEBUG "%s: [bo=%d]\n", dev->name, count);
|
||||
#endif
|
||||
pr_debug("%s: [bo=%d]\n", dev->name, count);
|
||||
|
||||
/* Round the count up for word writes. Do we need to do this?
|
||||
What effect will an odd byte count have on the 8390?
|
||||
|
|
|
@ -53,11 +53,7 @@
|
|||
|
||||
#define VERSION "arcnet: COM20020 PCMCIA support loaded.\n"
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
#ifdef DEBUG
|
||||
|
||||
static void regdump(struct net_device *dev)
|
||||
{
|
||||
|
@ -92,7 +88,6 @@ static void regdump(struct net_device *dev)
|
|||
|
||||
#else
|
||||
|
||||
#define DEBUG(n, args...) do { } while (0)
|
||||
static inline void regdump(struct net_device *dev) { }
|
||||
|
||||
#endif
|
||||
|
@ -144,7 +139,7 @@ static int com20020_probe(struct pcmcia_device *p_dev)
|
|||
struct net_device *dev;
|
||||
struct arcnet_local *lp;
|
||||
|
||||
DEBUG(0, "com20020_attach()\n");
|
||||
dev_dbg(&p_dev->dev, "com20020_attach()\n");
|
||||
|
||||
/* Create new network device */
|
||||
info = kzalloc(sizeof(struct com20020_dev_t), GFP_KERNEL);
|
||||
|
@ -169,11 +164,10 @@ static int com20020_probe(struct pcmcia_device *p_dev)
|
|||
p_dev->io.NumPorts1 = 16;
|
||||
p_dev->io.IOAddrLines = 16;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
p_dev->irq.Instance = info->dev = dev;
|
||||
info->dev = dev;
|
||||
p_dev->priv = info;
|
||||
|
||||
return com20020_config(p_dev);
|
||||
|
@ -198,12 +192,12 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||
struct com20020_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
DEBUG(1,"detach...\n");
|
||||
dev_dbg(&link->dev, "detach...\n");
|
||||
|
||||
DEBUG(0, "com20020_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "com20020_detach\n");
|
||||
|
||||
if (link->dev_node) {
|
||||
DEBUG(1,"unregister...\n");
|
||||
dev_dbg(&link->dev, "unregister...\n");
|
||||
|
||||
unregister_netdev(dev);
|
||||
|
||||
|
@ -218,16 +212,16 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||
com20020_release(link);
|
||||
|
||||
/* Unlink device structure, free bits */
|
||||
DEBUG(1,"unlinking...\n");
|
||||
dev_dbg(&link->dev, "unlinking...\n");
|
||||
if (link->priv)
|
||||
{
|
||||
dev = info->dev;
|
||||
if (dev)
|
||||
{
|
||||
DEBUG(1,"kfree...\n");
|
||||
dev_dbg(&link->dev, "kfree...\n");
|
||||
free_netdev(dev);
|
||||
}
|
||||
DEBUG(1,"kfree2...\n");
|
||||
dev_dbg(&link->dev, "kfree2...\n");
|
||||
kfree(info);
|
||||
}
|
||||
|
||||
|
@ -241,25 +235,22 @@ static void com20020_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int com20020_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct arcnet_local *lp;
|
||||
com20020_dev_t *info;
|
||||
struct net_device *dev;
|
||||
int i, last_ret, last_fn;
|
||||
int i, ret;
|
||||
int ioaddr;
|
||||
|
||||
info = link->priv;
|
||||
dev = info->dev;
|
||||
|
||||
DEBUG(1,"config...\n");
|
||||
dev_dbg(&link->dev, "config...\n");
|
||||
|
||||
DEBUG(0, "com20020_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "com20020_config\n");
|
||||
|
||||
DEBUG(1,"arcnet: baseport1 is %Xh\n", link->io.BasePort1);
|
||||
dev_dbg(&link->dev, "baseport1 is %Xh\n", link->io.BasePort1);
|
||||
i = -ENODEV;
|
||||
if (!link->io.BasePort1)
|
||||
{
|
||||
|
@ -276,26 +267,27 @@ static int com20020_config(struct pcmcia_device *link)
|
|||
|
||||
if (i != 0)
|
||||
{
|
||||
DEBUG(1,"arcnet: requestIO failed totally!\n");
|
||||
dev_dbg(&link->dev, "requestIO failed totally!\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
ioaddr = dev->base_addr = link->io.BasePort1;
|
||||
DEBUG(1,"arcnet: got ioaddr %Xh\n", ioaddr);
|
||||
dev_dbg(&link->dev, "got ioaddr %Xh\n", ioaddr);
|
||||
|
||||
DEBUG(1,"arcnet: request IRQ %d (%Xh/%Xh)\n",
|
||||
link->irq.AssignedIRQ,
|
||||
link->irq.IRQInfo1, link->irq.IRQInfo2);
|
||||
dev_dbg(&link->dev, "request IRQ %d\n",
|
||||
link->irq.AssignedIRQ);
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
if (i != 0)
|
||||
{
|
||||
DEBUG(1,"arcnet: requestIRQ failed totally!\n");
|
||||
dev_dbg(&link->dev, "requestIRQ failed totally!\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (com20020_check(dev))
|
||||
{
|
||||
|
@ -308,26 +300,25 @@ static int com20020_config(struct pcmcia_device *link)
|
|||
lp->card_flags = ARC_CAN_10MBIT; /* pretend all of them can 10Mbit */
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = com20020_found(dev, 0); /* calls register_netdev */
|
||||
|
||||
if (i != 0) {
|
||||
DEBUG(1,KERN_NOTICE "com20020_cs: com20020_found() failed\n");
|
||||
dev_printk(KERN_NOTICE, &link->dev,
|
||||
"com20020_cs: com20020_found() failed\n");
|
||||
link->dev_node = NULL;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
strcpy(info->node.dev_name, dev->name);
|
||||
|
||||
DEBUG(1,KERN_INFO "%s: port %#3lx, irq %d\n",
|
||||
dev_dbg(&link->dev,KERN_INFO "%s: port %#3lx, irq %d\n",
|
||||
dev->name, dev->base_addr, dev->irq);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
DEBUG(1,"com20020_config failed...\n");
|
||||
dev_dbg(&link->dev, "com20020_config failed...\n");
|
||||
com20020_release(link);
|
||||
return -ENODEV;
|
||||
} /* com20020_config */
|
||||
|
@ -342,7 +333,7 @@ failed:
|
|||
|
||||
static void com20020_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "com20020_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "com20020_release\n");
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,13 +72,6 @@ MODULE_LICENSE("GPL");
|
|||
/* 0:4KB*2 TX buffer else:8KB*2 TX buffer */
|
||||
INT_MODULE_PARM(sram_config, 0);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version = DRV_NAME ".c " DRV_VERSION " 2002/03/23";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
/*
|
||||
|
@ -245,7 +238,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
|
|||
local_info_t *lp;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "fmvj18x_attach()\n");
|
||||
dev_dbg(&link->dev, "fmvj18x_attach()\n");
|
||||
|
||||
/* Make up a FMVJ18x specific data structure */
|
||||
dev = alloc_etherdev(sizeof(local_info_t));
|
||||
|
@ -262,10 +255,8 @@ static int fmvj18x_probe(struct pcmcia_device *link)
|
|||
link->io.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = fjn_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
|
||||
/* General socket configuration */
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
|
@ -285,7 +276,7 @@ static void fmvj18x_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "fmvj18x_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "fmvj18x_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -297,9 +288,6 @@ static void fmvj18x_detach(struct pcmcia_device *link)
|
|||
|
||||
/*====================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int mfc_try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int i, ret;
|
||||
|
@ -341,33 +329,38 @@ static int ungermann_try_io_port(struct pcmcia_device *link)
|
|||
return ret; /* RequestIO failed */
|
||||
}
|
||||
|
||||
static int fmvj18x_ioprobe(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
return 0; /* strange, but that's what the code did already before... */
|
||||
}
|
||||
|
||||
static int fmvj18x_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
u_short buf[32];
|
||||
int i, last_fn = 0, last_ret = 0, ret;
|
||||
int i, ret;
|
||||
unsigned int ioaddr;
|
||||
cardtype_t cardtype;
|
||||
char *card_name = "unknown";
|
||||
u_char *node_id;
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
u_char buggybuf[32];
|
||||
|
||||
DEBUG(0, "fmvj18x_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "fmvj18x_config\n");
|
||||
|
||||
tuple.TupleData = (u_char *)buf;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
tuple.TupleOffset = 0;
|
||||
if (pcmcia_get_first_tuple(link, &tuple) == 0) {
|
||||
len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
|
||||
kfree(buf);
|
||||
|
||||
if (len) {
|
||||
/* Yes, I have CISTPL_FUNCE. Let's check CISTPL_MANFID */
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
CS_CHECK(ParseTuple, pcmcia_parse_tuple(&tuple, &parse));
|
||||
link->conf.ConfigIndex = parse.cftable_entry.index;
|
||||
ret = pcmcia_loop_config(link, fmvj18x_ioprobe, NULL);
|
||||
if (ret != 0)
|
||||
goto failed;
|
||||
|
||||
switch (link->manf_id) {
|
||||
case MANFID_TDK:
|
||||
cardtype = TDK;
|
||||
|
@ -433,17 +426,24 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
|
||||
if (link->io.NumPorts2 != 0) {
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
ret = mfc_try_io_port(link);
|
||||
if (ret != 0) goto cs_failed;
|
||||
if (ret != 0) goto failed;
|
||||
} else if (cardtype == UNGERMANN) {
|
||||
ret = ungermann_try_io_port(link);
|
||||
if (ret != 0) goto cs_failed;
|
||||
if (ret != 0) goto failed;
|
||||
} else {
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
|
@ -474,21 +474,21 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
case CONTEC:
|
||||
case NEC:
|
||||
case KME:
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
tuple.TupleOffset = 0;
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
if (cardtype == MBH10304) {
|
||||
/* MBH10304's CIS_FUNCE is corrupted */
|
||||
node_id = &(tuple.TupleData[5]);
|
||||
card_name = "FMV-J182";
|
||||
} else {
|
||||
while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {
|
||||
CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
|
||||
len = pcmcia_get_tuple(link, CISTPL_FUNCE, &buf);
|
||||
if (len < 11) {
|
||||
kfree(buf);
|
||||
goto failed;
|
||||
}
|
||||
node_id = &(tuple.TupleData[2]);
|
||||
/* Read MACID from CIS */
|
||||
for (i = 5; i < 11; i++)
|
||||
dev->dev_addr[i] = buf[i];
|
||||
kfree(buf);
|
||||
} else {
|
||||
if (pcmcia_get_mac_from_cis(link, dev))
|
||||
goto failed;
|
||||
if( cardtype == TDK ) {
|
||||
card_name = "TDK LAK-CD021";
|
||||
} else if( cardtype == LA501 ) {
|
||||
|
@ -501,9 +501,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
card_name = "C-NET(PC)C";
|
||||
}
|
||||
}
|
||||
/* Read MACID from CIS */
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = node_id[i];
|
||||
break;
|
||||
case UNGERMANN:
|
||||
/* Read MACID from register */
|
||||
|
@ -513,12 +510,12 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
break;
|
||||
case XXX10304:
|
||||
/* Read MACID from Buggy CIS */
|
||||
if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {
|
||||
if (fmvj18x_get_hwinfo(link, buggybuf) == -1) {
|
||||
printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");
|
||||
goto failed;
|
||||
}
|
||||
for (i = 0 ; i < 6; i++) {
|
||||
dev->dev_addr[i] = tuple.TupleData[i];
|
||||
dev->dev_addr[i] = buggybuf[i];
|
||||
}
|
||||
card_name = "FMV-J182";
|
||||
break;
|
||||
|
@ -533,7 +530,7 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
|
||||
lp->cardtype = cardtype;
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");
|
||||
|
@ -551,9 +548,6 @@ static int fmvj18x_config(struct pcmcia_device *link)
|
|||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
/* All Card Services errors end up here */
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
fmvj18x_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -571,16 +565,14 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestWindow, i);
|
||||
i = pcmcia_request_window(link, &req, &link->win);
|
||||
if (i != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
base = ioremap(req.Base, req.Size);
|
||||
mem.Page = 0;
|
||||
mem.CardOffset = 0;
|
||||
pcmcia_map_mem_page(link->win, &mem);
|
||||
pcmcia_map_mem_page(link, link->win, &mem);
|
||||
|
||||
/*
|
||||
* MBH10304 CISTPL_FUNCE_LAN_NODE_ID format
|
||||
|
@ -605,9 +597,7 @@ static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id)
|
|||
}
|
||||
|
||||
iounmap(base);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != 0)
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
j = pcmcia_release_window(link, link->win);
|
||||
return (i != 0x200) ? 0 : -1;
|
||||
|
||||
} /* fmvj18x_get_hwinfo */
|
||||
|
@ -626,11 +616,9 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestWindow, i);
|
||||
i = pcmcia_request_window(link, &req, &link->win);
|
||||
if (i != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
lp->base = ioremap(req.Base, req.Size);
|
||||
if (lp->base == NULL) {
|
||||
|
@ -640,11 +628,10 @@ static int fmvj18x_setup_mfc(struct pcmcia_device *link)
|
|||
|
||||
mem.Page = 0;
|
||||
mem.CardOffset = 0;
|
||||
i = pcmcia_map_mem_page(link->win, &mem);
|
||||
i = pcmcia_map_mem_page(link, link->win, &mem);
|
||||
if (i != 0) {
|
||||
iounmap(lp->base);
|
||||
lp->base = NULL;
|
||||
cs_error(link, MapMemPage, i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -671,15 +658,13 @@ static void fmvj18x_release(struct pcmcia_device *link)
|
|||
u_char __iomem *tmp;
|
||||
int j;
|
||||
|
||||
DEBUG(0, "fmvj18x_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "fmvj18x_release\n");
|
||||
|
||||
if (lp->base != NULL) {
|
||||
tmp = lp->base;
|
||||
lp->base = NULL; /* set NULL before iounmap */
|
||||
iounmap(tmp);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != 0)
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
j = pcmcia_release_window(link, link->win);
|
||||
}
|
||||
|
||||
pcmcia_disable_device(link);
|
||||
|
@ -788,8 +773,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
|
|||
outb(tx_stat, ioaddr + TX_STATUS);
|
||||
outb(rx_stat, ioaddr + RX_STATUS);
|
||||
|
||||
DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
|
||||
DEBUG(4, " tx_status %02x.\n", tx_stat);
|
||||
pr_debug("%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);
|
||||
pr_debug(" tx_status %02x.\n", tx_stat);
|
||||
|
||||
if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
||||
/* there is packet(s) in rx buffer */
|
||||
|
@ -809,8 +794,8 @@ static irqreturn_t fjn_interrupt(int dummy, void *dev_id)
|
|||
}
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
DEBUG(4, "%s: exiting interrupt,\n", dev->name);
|
||||
DEBUG(4, " tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
|
||||
pr_debug("%s: exiting interrupt,\n", dev->name);
|
||||
pr_debug(" tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);
|
||||
|
||||
outb(D_TX_INTR, ioaddr + TX_INTR);
|
||||
outb(D_RX_INTR, ioaddr + RX_INTR);
|
||||
|
@ -882,7 +867,7 @@ static netdev_tx_t fjn_start_xmit(struct sk_buff *skb,
|
|||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
DEBUG(4, "%s: Transmitting a packet of length %lu.\n",
|
||||
pr_debug("%s: Transmitting a packet of length %lu.\n",
|
||||
dev->name, (unsigned long)skb->len);
|
||||
dev->stats.tx_bytes += skb->len;
|
||||
|
||||
|
@ -937,7 +922,7 @@ static void fjn_reset(struct net_device *dev)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
int i;
|
||||
|
||||
DEBUG(4, "fjn_reset(%s) called.\n",dev->name);
|
||||
pr_debug("fjn_reset(%s) called.\n",dev->name);
|
||||
|
||||
/* Reset controller */
|
||||
if( sram_config == 0 )
|
||||
|
@ -1015,13 +1000,13 @@ static void fjn_rx(struct net_device *dev)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
int boguscount = 10; /* 5 -> 10: by agy 19940922 */
|
||||
|
||||
DEBUG(4, "%s: in rx_packet(), rx_status %02x.\n",
|
||||
pr_debug("%s: in rx_packet(), rx_status %02x.\n",
|
||||
dev->name, inb(ioaddr + RX_STATUS));
|
||||
|
||||
while ((inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {
|
||||
u_short status = inw(ioaddr + DATAPORT);
|
||||
|
||||
DEBUG(4, "%s: Rxing packet mode %02x status %04x.\n",
|
||||
pr_debug("%s: Rxing packet mode %02x status %04x.\n",
|
||||
dev->name, inb(ioaddr + RX_MODE), status);
|
||||
#ifndef final_version
|
||||
if (status == 0) {
|
||||
|
@ -1061,16 +1046,14 @@ static void fjn_rx(struct net_device *dev)
|
|||
(pkt_len + 1) >> 1);
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug > 5) {
|
||||
{
|
||||
int i;
|
||||
printk(KERN_DEBUG "%s: Rxed packet of length %d: ",
|
||||
dev->name, pkt_len);
|
||||
pr_debug("%s: Rxed packet of length %d: ",
|
||||
dev->name, pkt_len);
|
||||
for (i = 0; i < 14; i++)
|
||||
printk(" %02x", skb->data[i]);
|
||||
printk(".\n");
|
||||
pr_debug(" %02x", skb->data[i]);
|
||||
pr_debug(".\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
netif_rx(skb);
|
||||
dev->stats.rx_packets++;
|
||||
|
@ -1094,7 +1077,7 @@ static void fjn_rx(struct net_device *dev)
|
|||
}
|
||||
|
||||
if (i > 0)
|
||||
DEBUG(5, "%s: Exint Rx packet with mode %02x after "
|
||||
pr_debug("%s: Exint Rx packet with mode %02x after "
|
||||
"%d ticks.\n", dev->name, inb(ioaddr + RX_MODE), i);
|
||||
}
|
||||
*/
|
||||
|
@ -1112,24 +1095,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||
}
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
return pc_debug;
|
||||
}
|
||||
|
||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
||||
{
|
||||
pc_debug = level;
|
||||
}
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
|
||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||
.get_drvinfo = netdev_get_drvinfo,
|
||||
#ifdef PCMCIA_DEBUG
|
||||
.get_msglevel = netdev_get_msglevel,
|
||||
.set_msglevel = netdev_set_msglevel,
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
};
|
||||
|
||||
static int fjn_config(struct net_device *dev, struct ifmap *map){
|
||||
|
@ -1141,7 +1108,7 @@ static int fjn_open(struct net_device *dev)
|
|||
struct local_info_t *lp = netdev_priv(dev);
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(4, "fjn_open('%s').\n", dev->name);
|
||||
pr_debug("fjn_open('%s').\n", dev->name);
|
||||
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
@ -1167,7 +1134,7 @@ static int fjn_close(struct net_device *dev)
|
|||
struct pcmcia_device *link = lp->p_dev;
|
||||
unsigned int ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(4, "fjn_close('%s').\n", dev->name);
|
||||
pr_debug("fjn_close('%s').\n", dev->name);
|
||||
|
||||
lp->open_time = 0;
|
||||
netif_stop_queue(dev);
|
||||
|
|
|
@ -69,17 +69,6 @@
|
|||
#define PCMCIA
|
||||
#include "../tokenring/ibmtr.c"
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"ibmtr_cs.c 1.10 1996/01/06 05:19:00 (Steve Kipisz)\n"
|
||||
" 2.2.7 1999/05/03 12:00:00 (Mike Phillips)\n"
|
||||
" 2.4.2 2001/30/28 Midnight (Burt Silverman)\n";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -130,6 +119,12 @@ static const struct ethtool_ops netdev_ethtool_ops = {
|
|||
.get_drvinfo = netdev_get_drvinfo,
|
||||
};
|
||||
|
||||
static irqreturn_t ibmtr_interrupt(int irq, void *dev_id) {
|
||||
ibmtr_dev_t *info = dev_id;
|
||||
struct net_device *dev = info->dev;
|
||||
return tok_interrupt(irq, dev);
|
||||
};
|
||||
|
||||
/*======================================================================
|
||||
|
||||
ibmtr_attach() creates an "instance" of the driver, allocating
|
||||
|
@ -143,7 +138,7 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
|
|||
ibmtr_dev_t *info;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "ibmtr_attach()\n");
|
||||
dev_dbg(&link->dev, "ibmtr_attach()\n");
|
||||
|
||||
/* Create new token-ring device */
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
|
@ -161,14 +156,13 @@ static int __devinit ibmtr_attach(struct pcmcia_device *link)
|
|||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts1 = 4;
|
||||
link->io.IOAddrLines = 16;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Handler = &tok_interrupt;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = ibmtr_interrupt;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.Present = PRESENT_OPTION;
|
||||
|
||||
link->irq.Instance = info->dev = dev;
|
||||
info->dev = dev;
|
||||
|
||||
SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops);
|
||||
|
||||
|
@ -190,7 +184,7 @@ static void ibmtr_detach(struct pcmcia_device *link)
|
|||
struct net_device *dev = info->dev;
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
|
||||
DEBUG(0, "ibmtr_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ibmtr_detach\n");
|
||||
|
||||
/*
|
||||
* When the card removal interrupt hits tok_interrupt(),
|
||||
|
@ -217,9 +211,6 @@ static void ibmtr_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int __devinit ibmtr_config(struct pcmcia_device *link)
|
||||
{
|
||||
ibmtr_dev_t *info = link->priv;
|
||||
|
@ -227,9 +218,9 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
struct tok_info *ti = netdev_priv(dev);
|
||||
win_req_t req;
|
||||
memreq_t mem;
|
||||
int i, last_ret, last_fn;
|
||||
int i, ret;
|
||||
|
||||
DEBUG(0, "ibmtr_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ibmtr_config\n");
|
||||
|
||||
link->conf.ConfigIndex = 0x61;
|
||||
|
||||
|
@ -241,11 +232,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
if (i != 0) {
|
||||
/* Couldn't get 0xA20-0xA23. Try ALTERNATE at 0xA24-0xA27. */
|
||||
link->io.BasePort1 = 0xA24;
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
ti->irq = link->irq.AssignedIRQ;
|
||||
ti->global_int_enable=GLOBAL_INT_ENABLE+((dev->irq==9) ? 2 : dev->irq);
|
||||
|
@ -256,11 +251,15 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
req.Base = 0;
|
||||
req.Size = 0x2000;
|
||||
req.AccessSpeed = 250;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
ret = pcmcia_request_window(link, &req, &link->win);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
mem.CardOffset = mmiobase;
|
||||
mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
||||
ret = pcmcia_map_mem_page(link, link->win, &mem);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ti->mmio = ioremap(req.Base, req.Size);
|
||||
|
||||
/* Allocate the SRAM memory window */
|
||||
|
@ -269,17 +268,23 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
req.Base = 0;
|
||||
req.Size = sramsize * 1024;
|
||||
req.AccessSpeed = 250;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &info->sram_win_handle));
|
||||
ret = pcmcia_request_window(link, &req, &info->sram_win_handle);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
mem.CardOffset = srambase;
|
||||
mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(info->sram_win_handle, &mem));
|
||||
ret = pcmcia_map_mem_page(link, info->sram_win_handle, &mem);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
ti->sram_base = mem.CardOffset >> 12;
|
||||
ti->sram_virt = ioremap(req.Base, req.Size);
|
||||
ti->sram_phys = req.Base;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Set up the Token-Ring Controller Configuration Register and
|
||||
turn on the card. Check the "Local Area Network Credit Card
|
||||
|
@ -287,7 +292,7 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
ibmtr_hw_setup(dev, mmiobase);
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = ibmtr_probe_card(dev);
|
||||
if (i != 0) {
|
||||
|
@ -305,8 +310,6 @@ static int __devinit ibmtr_config(struct pcmcia_device *link)
|
|||
dev->dev_addr);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
ibmtr_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -325,12 +328,12 @@ static void ibmtr_release(struct pcmcia_device *link)
|
|||
ibmtr_dev_t *info = link->priv;
|
||||
struct net_device *dev = info->dev;
|
||||
|
||||
DEBUG(0, "ibmtr_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "ibmtr_release\n");
|
||||
|
||||
if (link->win) {
|
||||
struct tok_info *ti = netdev_priv(dev);
|
||||
iounmap(ti->mmio);
|
||||
pcmcia_release_window(info->sram_win_handle);
|
||||
pcmcia_release_window(link, info->sram_win_handle);
|
||||
}
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
|
|
@ -381,13 +381,6 @@ typedef struct _mace_private {
|
|||
Private Global Variables
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static char rcsid[] =
|
||||
"nmclan_cs.c,v 0.16 1995/07/01 06:42:17 rpao Exp rpao";
|
||||
static char *version =
|
||||
DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
|
||||
#endif
|
||||
|
||||
static const char *if_names[]={
|
||||
"Auto", "10baseT", "BNC",
|
||||
};
|
||||
|
@ -406,12 +399,6 @@ MODULE_LICENSE("GPL");
|
|||
/* 0=auto, 1=10baseT, 2 = 10base2, default=auto */
|
||||
INT_MODULE_PARM(if_port, 0);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
Function Prototypes
|
||||
|
@ -462,8 +449,7 @@ static int nmclan_probe(struct pcmcia_device *link)
|
|||
mace_private *lp;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "nmclan_attach()\n");
|
||||
DEBUG(1, "%s\n", rcsid);
|
||||
dev_dbg(&link->dev, "nmclan_attach()\n");
|
||||
|
||||
/* Create new ethernet device */
|
||||
dev = alloc_etherdev(sizeof(mace_private));
|
||||
|
@ -477,10 +463,8 @@ static int nmclan_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 32;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 5;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
|
||||
link->irq.Handler = mace_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
|
@ -507,7 +491,7 @@ static void nmclan_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "nmclan_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "nmclan_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -654,37 +638,40 @@ nmclan_config
|
|||
ethernet device available to the system.
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int nmclan_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
mace_private *lp = netdev_priv(dev);
|
||||
tuple_t tuple;
|
||||
u_char buf[64];
|
||||
int i, last_ret, last_fn;
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
int i, ret;
|
||||
unsigned int ioaddr;
|
||||
|
||||
DEBUG(0, "nmclan_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "nmclan_config\n");
|
||||
|
||||
ret = pcmcia_request_io(link, &link->io);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
CS_CHECK(RequestIO, pcmcia_request_io(link, &link->io));
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
/* Read the ethernet address from the CIS. */
|
||||
tuple.DesiredTuple = 0x80 /* CISTPL_CFTABLE_ENTRY_MISC */;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.Attributes = 0;
|
||||
CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
|
||||
CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
|
||||
memcpy(dev->dev_addr, tuple.TupleData, ETHER_ADDR_LEN);
|
||||
len = pcmcia_get_tuple(link, 0x80, &buf);
|
||||
if (!buf || len < ETHER_ADDR_LEN) {
|
||||
kfree(buf);
|
||||
goto failed;
|
||||
}
|
||||
memcpy(dev->dev_addr, buf, ETHER_ADDR_LEN);
|
||||
kfree(buf);
|
||||
|
||||
/* Verify configuration by reading the MACE ID. */
|
||||
{
|
||||
|
@ -693,7 +680,7 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||
sig[0] = mace_read(lp, ioaddr, MACE_CHIPIDL);
|
||||
sig[1] = mace_read(lp, ioaddr, MACE_CHIPIDH);
|
||||
if ((sig[0] == 0x40) && ((sig[1] & 0x0F) == 0x09)) {
|
||||
DEBUG(0, "nmclan_cs configured: mace id=%x %x\n",
|
||||
dev_dbg(&link->dev, "nmclan_cs configured: mace id=%x %x\n",
|
||||
sig[0], sig[1]);
|
||||
} else {
|
||||
printk(KERN_NOTICE "nmclan_cs: mace id not found: %x %x should"
|
||||
|
@ -712,7 +699,7 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||
printk(KERN_NOTICE "nmclan_cs: invalid if_port requested\n");
|
||||
|
||||
link->dev_node = &lp->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
i = register_netdev(dev);
|
||||
if (i != 0) {
|
||||
|
@ -729,8 +716,6 @@ static int nmclan_config(struct pcmcia_device *link)
|
|||
dev->dev_addr);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
nmclan_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -744,7 +729,7 @@ nmclan_release
|
|||
---------------------------------------------------------------------------- */
|
||||
static void nmclan_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "nmclan_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "nmclan_release\n");
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
|
@ -795,7 +780,7 @@ static void nmclan_reset(struct net_device *dev)
|
|||
/* Reset Xilinx */
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_COR;
|
||||
DEBUG(1, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
|
||||
dev_dbg(&link->dev, "nmclan_reset: OrigCorValue=0x%lX, resetting...\n",
|
||||
OrigCorValue);
|
||||
reg.Value = COR_SOFT_RESET;
|
||||
pcmcia_access_configuration_register(link, ®);
|
||||
|
@ -872,7 +857,7 @@ static int mace_close(struct net_device *dev)
|
|||
mace_private *lp = netdev_priv(dev);
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(2, "%s: shutting down ethercard.\n", dev->name);
|
||||
dev_dbg(&link->dev, "%s: shutting down ethercard.\n", dev->name);
|
||||
|
||||
/* Mask off all interrupts from the MACE chip. */
|
||||
outb(0xFF, ioaddr + AM2150_MACE_BASE + MACE_IMR);
|
||||
|
@ -891,24 +876,8 @@ static void netdev_get_drvinfo(struct net_device *dev,
|
|||
sprintf(info->bus_info, "PCMCIA 0x%lx", dev->base_addr);
|
||||
}
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static u32 netdev_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
return pc_debug;
|
||||
}
|
||||
|
||||
static void netdev_set_msglevel(struct net_device *dev, u32 level)
|
||||
{
|
||||
pc_debug = level;
|
||||
}
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
|
||||
static const struct ethtool_ops netdev_ethtool_ops = {
|
||||
.get_drvinfo = netdev_get_drvinfo,
|
||||
#ifdef PCMCIA_DEBUG
|
||||
.get_msglevel = netdev_get_msglevel,
|
||||
.set_msglevel = netdev_set_msglevel,
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
};
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
|
@ -946,7 +915,7 @@ static netdev_tx_t mace_start_xmit(struct sk_buff *skb,
|
|||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
DEBUG(3, "%s: mace_start_xmit(length = %ld) called.\n",
|
||||
pr_debug("%s: mace_start_xmit(length = %ld) called.\n",
|
||||
dev->name, (long)skb->len);
|
||||
|
||||
#if (!TX_INTERRUPTABLE)
|
||||
|
@ -1008,7 +977,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||
int IntrCnt = MACE_MAX_IR_ITERATIONS;
|
||||
|
||||
if (dev == NULL) {
|
||||
DEBUG(2, "mace_interrupt(): irq 0x%X for unknown device.\n",
|
||||
pr_debug("mace_interrupt(): irq 0x%X for unknown device.\n",
|
||||
irq);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
@ -1031,7 +1000,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||
}
|
||||
|
||||
if (!netif_device_present(dev)) {
|
||||
DEBUG(2, "%s: interrupt from dead card\n", dev->name);
|
||||
pr_debug("%s: interrupt from dead card\n", dev->name);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
|
||||
|
@ -1039,7 +1008,7 @@ static irqreturn_t mace_interrupt(int irq, void *dev_id)
|
|||
/* WARNING: MACE_IR is a READ/CLEAR port! */
|
||||
status = inb(ioaddr + AM2150_MACE_BASE + MACE_IR);
|
||||
|
||||
DEBUG(3, "mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
|
||||
pr_debug("mace_interrupt: irq 0x%X status 0x%X.\n", irq, status);
|
||||
|
||||
if (status & MACE_IR_RCVINT) {
|
||||
mace_rx(dev, MACE_MAX_RX_ITERATIONS);
|
||||
|
@ -1158,7 +1127,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||
) {
|
||||
rx_status = inw(ioaddr + AM2150_RCV);
|
||||
|
||||
DEBUG(3, "%s: in mace_rx(), framecnt 0x%X, rx_status"
|
||||
pr_debug("%s: in mace_rx(), framecnt 0x%X, rx_status"
|
||||
" 0x%X.\n", dev->name, rx_framecnt, rx_status);
|
||||
|
||||
if (rx_status & MACE_RCVFS_RCVSTS) { /* Error, update stats. */
|
||||
|
@ -1185,7 +1154,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||
lp->mace_stats.rfs_rcvcc += inb(ioaddr + AM2150_RCV);
|
||||
/* rcv collision count */
|
||||
|
||||
DEBUG(3, " receiving packet size 0x%X rx_status"
|
||||
pr_debug(" receiving packet size 0x%X rx_status"
|
||||
" 0x%X.\n", pkt_len, rx_status);
|
||||
|
||||
skb = dev_alloc_skb(pkt_len+2);
|
||||
|
@ -1204,7 +1173,7 @@ static int mace_rx(struct net_device *dev, unsigned char RxCnt)
|
|||
outb(0xFF, ioaddr + AM2150_RCV_NEXT); /* skip to next frame */
|
||||
continue;
|
||||
} else {
|
||||
DEBUG(1, "%s: couldn't allocate a sk_buff of size"
|
||||
pr_debug("%s: couldn't allocate a sk_buff of size"
|
||||
" %d.\n", dev->name, pkt_len);
|
||||
lp->linux_stats.rx_dropped++;
|
||||
}
|
||||
|
@ -1220,28 +1189,28 @@ pr_linux_stats
|
|||
---------------------------------------------------------------------------- */
|
||||
static void pr_linux_stats(struct net_device_stats *pstats)
|
||||
{
|
||||
DEBUG(2, "pr_linux_stats\n");
|
||||
DEBUG(2, " rx_packets=%-7ld tx_packets=%ld\n",
|
||||
pr_debug("pr_linux_stats\n");
|
||||
pr_debug(" rx_packets=%-7ld tx_packets=%ld\n",
|
||||
(long)pstats->rx_packets, (long)pstats->tx_packets);
|
||||
DEBUG(2, " rx_errors=%-7ld tx_errors=%ld\n",
|
||||
pr_debug(" rx_errors=%-7ld tx_errors=%ld\n",
|
||||
(long)pstats->rx_errors, (long)pstats->tx_errors);
|
||||
DEBUG(2, " rx_dropped=%-7ld tx_dropped=%ld\n",
|
||||
pr_debug(" rx_dropped=%-7ld tx_dropped=%ld\n",
|
||||
(long)pstats->rx_dropped, (long)pstats->tx_dropped);
|
||||
DEBUG(2, " multicast=%-7ld collisions=%ld\n",
|
||||
pr_debug(" multicast=%-7ld collisions=%ld\n",
|
||||
(long)pstats->multicast, (long)pstats->collisions);
|
||||
|
||||
DEBUG(2, " rx_length_errors=%-7ld rx_over_errors=%ld\n",
|
||||
pr_debug(" rx_length_errors=%-7ld rx_over_errors=%ld\n",
|
||||
(long)pstats->rx_length_errors, (long)pstats->rx_over_errors);
|
||||
DEBUG(2, " rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
|
||||
pr_debug(" rx_crc_errors=%-7ld rx_frame_errors=%ld\n",
|
||||
(long)pstats->rx_crc_errors, (long)pstats->rx_frame_errors);
|
||||
DEBUG(2, " rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
|
||||
pr_debug(" rx_fifo_errors=%-7ld rx_missed_errors=%ld\n",
|
||||
(long)pstats->rx_fifo_errors, (long)pstats->rx_missed_errors);
|
||||
|
||||
DEBUG(2, " tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
|
||||
pr_debug(" tx_aborted_errors=%-7ld tx_carrier_errors=%ld\n",
|
||||
(long)pstats->tx_aborted_errors, (long)pstats->tx_carrier_errors);
|
||||
DEBUG(2, " tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
|
||||
pr_debug(" tx_fifo_errors=%-7ld tx_heartbeat_errors=%ld\n",
|
||||
(long)pstats->tx_fifo_errors, (long)pstats->tx_heartbeat_errors);
|
||||
DEBUG(2, " tx_window_errors=%ld\n",
|
||||
pr_debug(" tx_window_errors=%ld\n",
|
||||
(long)pstats->tx_window_errors);
|
||||
} /* pr_linux_stats */
|
||||
|
||||
|
@ -1250,48 +1219,48 @@ pr_mace_stats
|
|||
---------------------------------------------------------------------------- */
|
||||
static void pr_mace_stats(mace_statistics *pstats)
|
||||
{
|
||||
DEBUG(2, "pr_mace_stats\n");
|
||||
pr_debug("pr_mace_stats\n");
|
||||
|
||||
DEBUG(2, " xmtsv=%-7d uflo=%d\n",
|
||||
pr_debug(" xmtsv=%-7d uflo=%d\n",
|
||||
pstats->xmtsv, pstats->uflo);
|
||||
DEBUG(2, " lcol=%-7d more=%d\n",
|
||||
pr_debug(" lcol=%-7d more=%d\n",
|
||||
pstats->lcol, pstats->more);
|
||||
DEBUG(2, " one=%-7d defer=%d\n",
|
||||
pr_debug(" one=%-7d defer=%d\n",
|
||||
pstats->one, pstats->defer);
|
||||
DEBUG(2, " lcar=%-7d rtry=%d\n",
|
||||
pr_debug(" lcar=%-7d rtry=%d\n",
|
||||
pstats->lcar, pstats->rtry);
|
||||
|
||||
/* MACE_XMTRC */
|
||||
DEBUG(2, " exdef=%-7d xmtrc=%d\n",
|
||||
pr_debug(" exdef=%-7d xmtrc=%d\n",
|
||||
pstats->exdef, pstats->xmtrc);
|
||||
|
||||
/* RFS1--Receive Status (RCVSTS) */
|
||||
DEBUG(2, " oflo=%-7d clsn=%d\n",
|
||||
pr_debug(" oflo=%-7d clsn=%d\n",
|
||||
pstats->oflo, pstats->clsn);
|
||||
DEBUG(2, " fram=%-7d fcs=%d\n",
|
||||
pr_debug(" fram=%-7d fcs=%d\n",
|
||||
pstats->fram, pstats->fcs);
|
||||
|
||||
/* RFS2--Runt Packet Count (RNTPC) */
|
||||
/* RFS3--Receive Collision Count (RCVCC) */
|
||||
DEBUG(2, " rfs_rntpc=%-7d rfs_rcvcc=%d\n",
|
||||
pr_debug(" rfs_rntpc=%-7d rfs_rcvcc=%d\n",
|
||||
pstats->rfs_rntpc, pstats->rfs_rcvcc);
|
||||
|
||||
/* MACE_IR */
|
||||
DEBUG(2, " jab=%-7d babl=%d\n",
|
||||
pr_debug(" jab=%-7d babl=%d\n",
|
||||
pstats->jab, pstats->babl);
|
||||
DEBUG(2, " cerr=%-7d rcvcco=%d\n",
|
||||
pr_debug(" cerr=%-7d rcvcco=%d\n",
|
||||
pstats->cerr, pstats->rcvcco);
|
||||
DEBUG(2, " rntpco=%-7d mpco=%d\n",
|
||||
pr_debug(" rntpco=%-7d mpco=%d\n",
|
||||
pstats->rntpco, pstats->mpco);
|
||||
|
||||
/* MACE_MPC */
|
||||
DEBUG(2, " mpc=%d\n", pstats->mpc);
|
||||
pr_debug(" mpc=%d\n", pstats->mpc);
|
||||
|
||||
/* MACE_RNTPC */
|
||||
DEBUG(2, " rntpc=%d\n", pstats->rntpc);
|
||||
pr_debug(" rntpc=%d\n", pstats->rntpc);
|
||||
|
||||
/* MACE_RCVCC */
|
||||
DEBUG(2, " rcvcc=%d\n", pstats->rcvcc);
|
||||
pr_debug(" rcvcc=%d\n", pstats->rcvcc);
|
||||
|
||||
} /* pr_mace_stats */
|
||||
|
||||
|
@ -1360,7 +1329,7 @@ static struct net_device_stats *mace_get_stats(struct net_device *dev)
|
|||
|
||||
update_stats(dev->base_addr, dev);
|
||||
|
||||
DEBUG(1, "%s: updating the statistics.\n", dev->name);
|
||||
pr_debug("%s: updating the statistics.\n", dev->name);
|
||||
pr_linux_stats(&lp->linux_stats);
|
||||
pr_mace_stats(&lp->mace_stats);
|
||||
|
||||
|
@ -1427,7 +1396,7 @@ static void BuildLAF(int *ladrf, int *adr)
|
|||
ladrf[byte] |= (1 << (hashcode & 7));
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug > 2)
|
||||
if (0)
|
||||
printk(KERN_DEBUG " adr =%pM\n", adr);
|
||||
printk(KERN_DEBUG " hashcode = %d(decimal), ladrf[0:63] =", hashcode);
|
||||
for (i = 0; i < 8; i++)
|
||||
|
@ -1454,12 +1423,12 @@ static void restore_multicast_list(struct net_device *dev)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
int i;
|
||||
|
||||
DEBUG(2, "%s: restoring Rx mode to %d addresses.\n",
|
||||
pr_debug("%s: restoring Rx mode to %d addresses.\n",
|
||||
dev->name, num_addrs);
|
||||
|
||||
if (num_addrs > 0) {
|
||||
|
||||
DEBUG(1, "Attempt to restore multicast list detected.\n");
|
||||
pr_debug("Attempt to restore multicast list detected.\n");
|
||||
|
||||
mace_write(lp, ioaddr, MACE_IAC, MACE_IAC_ADDRCHG | MACE_IAC_LOGADDR);
|
||||
/* Poll ADDRCHG bit */
|
||||
|
@ -1511,11 +1480,11 @@ static void set_multicast_list(struct net_device *dev)
|
|||
struct dev_mc_list *dmi = dev->mc_list;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug > 1) {
|
||||
{
|
||||
static int old;
|
||||
if (dev->mc_count != old) {
|
||||
old = dev->mc_count;
|
||||
DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
|
||||
pr_debug("%s: setting Rx mode to %d addresses.\n",
|
||||
dev->name, old);
|
||||
}
|
||||
}
|
||||
|
@ -1546,7 +1515,7 @@ static void restore_multicast_list(struct net_device *dev)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
mace_private *lp = netdev_priv(dev);
|
||||
|
||||
DEBUG(2, "%s: restoring Rx mode to %d addresses.\n", dev->name,
|
||||
pr_debug("%s: restoring Rx mode to %d addresses.\n", dev->name,
|
||||
lp->multicast_num_addrs);
|
||||
|
||||
if (dev->flags & IFF_PROMISC) {
|
||||
|
@ -1567,11 +1536,11 @@ static void set_multicast_list(struct net_device *dev)
|
|||
mace_private *lp = netdev_priv(dev);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug > 1) {
|
||||
{
|
||||
static int old;
|
||||
if (dev->mc_count != old) {
|
||||
old = dev->mc_count;
|
||||
DEBUG(0, "%s: setting Rx mode to %d addresses.\n",
|
||||
pr_debug("%s: setting Rx mode to %d addresses.\n",
|
||||
dev->name, old);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,15 +71,6 @@
|
|||
|
||||
static const char *if_names[] = { "auto", "10baseT", "10base2"};
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"pcnet_cs.c 1.153 2003/11/09 18:53:09 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -265,7 +256,7 @@ static int pcnet_probe(struct pcmcia_device *link)
|
|||
pcnet_dev_t *info;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "pcnet_attach()\n");
|
||||
dev_dbg(&link->dev, "pcnet_attach()\n");
|
||||
|
||||
/* Create new ethernet device */
|
||||
dev = __alloc_ei_netdev(sizeof(pcnet_dev_t));
|
||||
|
@ -275,7 +266,6 @@ static int pcnet_probe(struct pcmcia_device *link)
|
|||
link->priv = dev;
|
||||
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -297,7 +287,7 @@ static void pcnet_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "pcnet_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "pcnet_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -326,17 +316,15 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = 0; req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestWindow, i);
|
||||
i = pcmcia_request_window(link, &req, &link->win);
|
||||
if (i != 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
virt = ioremap(req.Base, req.Size);
|
||||
mem.Page = 0;
|
||||
for (i = 0; i < NR_INFO; i++) {
|
||||
mem.CardOffset = hw_info[i].offset & ~(req.Size-1);
|
||||
pcmcia_map_mem_page(link->win, &mem);
|
||||
pcmcia_map_mem_page(link, link->win, &mem);
|
||||
base = &virt[hw_info[i].offset & (req.Size-1)];
|
||||
if ((readb(base+0) == hw_info[i].a0) &&
|
||||
(readb(base+2) == hw_info[i].a1) &&
|
||||
|
@ -348,9 +336,7 @@ static hw_info_t *get_hwinfo(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
iounmap(virt);
|
||||
j = pcmcia_release_window(link->win);
|
||||
if (j != 0)
|
||||
cs_error(link, ReleaseWindow, j);
|
||||
j = pcmcia_release_window(link, link->win);
|
||||
return (i < NR_INFO) ? hw_info+i : NULL;
|
||||
} /* get_hwinfo */
|
||||
|
||||
|
@ -495,9 +481,6 @@ static hw_info_t *get_hwired(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int try_io_port(struct pcmcia_device *link)
|
||||
{
|
||||
int j, ret;
|
||||
|
@ -567,19 +550,19 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
pcnet_dev_t *info = PRIV(dev);
|
||||
int last_ret, last_fn, start_pg, stop_pg, cm_offset;
|
||||
int ret, start_pg, stop_pg, cm_offset;
|
||||
int has_shmem = 0;
|
||||
hw_info_t *local_hw_info;
|
||||
|
||||
DEBUG(0, "pcnet_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "pcnet_config\n");
|
||||
|
||||
last_ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
|
||||
if (last_ret) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
ret = pcmcia_loop_config(link, pcnet_confcheck, &has_shmem);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (link->io.NumPorts2 == 8) {
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
|
@ -589,7 +572,9 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
(link->card_id == PRODID_IBM_HOME_AND_AWAY))
|
||||
link->conf.ConfigIndex |= 0x10;
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
if (info->flags & HAS_MISC_REG) {
|
||||
|
@ -660,7 +645,7 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
mii_phy_probe(dev);
|
||||
|
||||
link->dev_node = &info->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_NOTICE "pcnet_cs: register_netdev() failed\n");
|
||||
|
@ -687,8 +672,6 @@ static int pcnet_config(struct pcmcia_device *link)
|
|||
printk(" hw_addr %pM\n", dev->dev_addr);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
pcnet_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -706,7 +689,7 @@ static void pcnet_release(struct pcmcia_device *link)
|
|||
{
|
||||
pcnet_dev_t *info = PRIV(link->priv);
|
||||
|
||||
DEBUG(0, "pcnet_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "pcnet_release\n");
|
||||
|
||||
if (info->flags & USE_SHMEM)
|
||||
iounmap(info->base);
|
||||
|
@ -960,7 +943,7 @@ static void mii_phy_probe(struct net_device *dev)
|
|||
phyid = tmp << 16;
|
||||
phyid |= mdio_read(mii_addr, i, MII_PHYID_REG2);
|
||||
phyid &= MII_PHYID_REV_MASK;
|
||||
DEBUG(0, "%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
|
||||
pr_debug("%s: MII at %d is 0x%08x\n", dev->name, i, phyid);
|
||||
if (phyid == AM79C9XX_HOME_PHY) {
|
||||
info->pna_phy = i;
|
||||
} else if (phyid != AM79C9XX_ETH_PHY) {
|
||||
|
@ -976,7 +959,7 @@ static int pcnet_open(struct net_device *dev)
|
|||
struct pcmcia_device *link = info->p_dev;
|
||||
unsigned int nic_base = dev->base_addr;
|
||||
|
||||
DEBUG(2, "pcnet_open('%s')\n", dev->name);
|
||||
dev_dbg(&link->dev, "pcnet_open('%s')\n", dev->name);
|
||||
|
||||
if (!pcmcia_dev_present(link))
|
||||
return -ENODEV;
|
||||
|
@ -1008,7 +991,7 @@ static int pcnet_close(struct net_device *dev)
|
|||
pcnet_dev_t *info = PRIV(dev);
|
||||
struct pcmcia_device *link = info->p_dev;
|
||||
|
||||
DEBUG(2, "pcnet_close('%s')\n", dev->name);
|
||||
dev_dbg(&link->dev, "pcnet_close('%s')\n", dev->name);
|
||||
|
||||
ei_close(dev);
|
||||
free_irq(dev->irq, dev);
|
||||
|
@ -1251,10 +1234,8 @@ static void dma_block_input(struct net_device *dev, int count,
|
|||
int xfer_count = count;
|
||||
char *buf = skb->data;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if ((ei_debug > 4) && (count != 4))
|
||||
printk(KERN_DEBUG "%s: [bi=%d]\n", dev->name, count+4);
|
||||
#endif
|
||||
pr_debug("%s: [bi=%d]\n", dev->name, count+4);
|
||||
if (ei_status.dmaing) {
|
||||
printk(KERN_NOTICE "%s: DMAing conflict in dma_block_input."
|
||||
"[DMAstat:%1x][irqlock:%1x]\n",
|
||||
|
@ -1495,7 +1476,7 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||
pcnet_dev_t *info = PRIV(dev);
|
||||
win_req_t req;
|
||||
memreq_t mem;
|
||||
int i, window_size, offset, last_ret, last_fn;
|
||||
int i, window_size, offset, ret;
|
||||
|
||||
window_size = (stop_pg - start_pg) << 8;
|
||||
if (window_size > 32 * 1024)
|
||||
|
@ -1509,13 +1490,17 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||
req.Attributes |= WIN_USE_WAIT;
|
||||
req.Base = 0; req.Size = window_size;
|
||||
req.AccessSpeed = mem_speed;
|
||||
CS_CHECK(RequestWindow, pcmcia_request_window(&link, &req, &link->win));
|
||||
ret = pcmcia_request_window(link, &req, &link->win);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
mem.CardOffset = (start_pg << 8) + cm_offset;
|
||||
offset = mem.CardOffset % window_size;
|
||||
mem.CardOffset -= offset;
|
||||
mem.Page = 0;
|
||||
CS_CHECK(MapMemPage, pcmcia_map_mem_page(link->win, &mem));
|
||||
ret = pcmcia_map_mem_page(link, link->win, &mem);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Try scribbling on the buffer */
|
||||
info->base = ioremap(req.Base, window_size);
|
||||
|
@ -1527,8 +1512,8 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||
pcnet_reset_8390(dev);
|
||||
if (i != (TX_PAGES<<8)) {
|
||||
iounmap(info->base);
|
||||
pcmcia_release_window(link->win);
|
||||
info->base = NULL; link->win = NULL;
|
||||
pcmcia_release_window(link, link->win);
|
||||
info->base = NULL; link->win = 0;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -1549,8 +1534,6 @@ static int setup_shmem_window(struct pcmcia_device *link, int start_pg,
|
|||
info->flags |= USE_SHMEM;
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
return 1;
|
||||
}
|
||||
|
@ -1795,7 +1778,6 @@ static int __init init_pcnet_cs(void)
|
|||
|
||||
static void __exit exit_pcnet_cs(void)
|
||||
{
|
||||
DEBUG(0, "pcnet_cs: unloading\n");
|
||||
pcmcia_unregister_driver(&pcnet_driver);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,14 +79,6 @@ MODULE_FIRMWARE(FIRMWARE_NAME);
|
|||
*/
|
||||
INT_MODULE_PARM(if_port, 0);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
static const char *version =
|
||||
"smc91c92_cs.c 1.123 2006/11/09 Donald Becker, becker@scyld.com.\n";
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
#define DRV_NAME "smc91c92_cs"
|
||||
#define DRV_VERSION "1.123"
|
||||
|
@ -126,12 +118,6 @@ struct smc_private {
|
|||
int rx_ovrn;
|
||||
};
|
||||
|
||||
struct smc_cfg_mem {
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
u_char buf[255];
|
||||
};
|
||||
|
||||
/* Special definitions for Megahertz multifunction cards */
|
||||
#define MEGAHERTZ_ISR 0x0380
|
||||
|
||||
|
@ -329,7 +315,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
|
|||
struct smc_private *smc;
|
||||
struct net_device *dev;
|
||||
|
||||
DEBUG(0, "smc91c92_attach()\n");
|
||||
dev_dbg(&link->dev, "smc91c92_attach()\n");
|
||||
|
||||
/* Create new ethernet device */
|
||||
dev = alloc_etherdev(sizeof(struct smc_private));
|
||||
|
@ -343,10 +329,8 @@ static int smc91c92_probe(struct pcmcia_device *link)
|
|||
link->io.NumPorts1 = 16;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
link->io.IOAddrLines = 4;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = &smc_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -377,7 +361,7 @@ static void smc91c92_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "smc91c92_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "smc91c92_detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -408,34 +392,7 @@ static int cvt_ascii_address(struct net_device *dev, char *s)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
static int first_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
||||
cisparse_t *parse)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = pcmcia_get_first_tuple(handle, tuple);
|
||||
if (i != 0)
|
||||
return i;
|
||||
i = pcmcia_get_tuple_data(handle, tuple);
|
||||
if (i != 0)
|
||||
return i;
|
||||
return pcmcia_parse_tuple(tuple, parse);
|
||||
}
|
||||
|
||||
static int next_tuple(struct pcmcia_device *handle, tuple_t *tuple,
|
||||
cisparse_t *parse)
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((i = pcmcia_get_next_tuple(handle, tuple)) != 0 ||
|
||||
(i = pcmcia_get_tuple_data(handle, tuple)) != 0)
|
||||
return i;
|
||||
return pcmcia_parse_tuple(tuple, parse);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
/*====================================================================
|
||||
|
||||
Configuration stuff for Megahertz cards
|
||||
|
||||
|
@ -490,19 +447,14 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
win_req_t req;
|
||||
memreq_t mem;
|
||||
int i;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -ENOMEM;
|
||||
|
||||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
link->io.IOAddrLines = 16;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts2 = 8;
|
||||
|
@ -510,91 +462,80 @@ static int mhz_mfc_config(struct pcmcia_device *link)
|
|||
/* The Megahertz combo cards have modem-like CIS entries, so
|
||||
we have to explicitly try a bunch of port combinations. */
|
||||
if (pcmcia_loop_config(link, mhz_mfc_config_check, NULL))
|
||||
goto free_cfg_mem;
|
||||
return -ENODEV;
|
||||
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
||||
/* Allocate a memory window, for accessing the ISR */
|
||||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
i = pcmcia_request_window(&link, &req, &link->win);
|
||||
i = pcmcia_request_window(link, &req, &link->win);
|
||||
if (i != 0)
|
||||
goto free_cfg_mem;
|
||||
return -ENODEV;
|
||||
|
||||
smc->base = ioremap(req.Base, req.Size);
|
||||
mem.CardOffset = mem.Page = 0;
|
||||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
mem.CardOffset = link->conf.ConfigBase;
|
||||
i = pcmcia_map_mem_page(link->win, &mem);
|
||||
i = pcmcia_map_mem_page(link, link->win, &mem);
|
||||
|
||||
if ((i == 0) &&
|
||||
(smc->manfid == MANFID_MEGAHERTZ) &&
|
||||
(smc->cardid == PRODID_MEGAHERTZ_EM3288))
|
||||
mhz_3288_power(link);
|
||||
|
||||
free_cfg_mem:
|
||||
kfree(cfg_mem);
|
||||
return -ENODEV;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pcmcia_get_versmac(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv)
|
||||
{
|
||||
struct net_device *dev = priv;
|
||||
cisparse_t parse;
|
||||
|
||||
if (pcmcia_parse_tuple(tuple, &parse))
|
||||
return -EINVAL;
|
||||
|
||||
if ((parse.version_1.ns > 3) &&
|
||||
(cvt_ascii_address(dev,
|
||||
(parse.version_1.str + parse.version_1.ofs[3]))))
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
};
|
||||
|
||||
static int mhz_setup(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
cisparse_t *parse;
|
||||
u_char *buf, *station_addr;
|
||||
size_t len;
|
||||
u8 *buf;
|
||||
int rc;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -1;
|
||||
|
||||
tuple = &cfg_mem->tuple;
|
||||
parse = &cfg_mem->parse;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
tuple->Attributes = tuple->TupleOffset = 0;
|
||||
tuple->TupleData = (cisdata_t *)buf;
|
||||
tuple->TupleDataMax = 255;
|
||||
|
||||
/* Read the station address from the CIS. It is stored as the last
|
||||
(fourth) string in the Version 1 Version/ID tuple. */
|
||||
tuple->DesiredTuple = CISTPL_VERS_1;
|
||||
if (first_tuple(link, tuple, parse) != 0) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
if ((link->prod_id[3]) &&
|
||||
(cvt_ascii_address(dev, link->prod_id[3]) == 0))
|
||||
return 0;
|
||||
|
||||
/* Workarounds for broken cards start here. */
|
||||
/* Ugh -- the EM1144 card has two VERS_1 tuples!?! */
|
||||
if (next_tuple(link, tuple, parse) != 0)
|
||||
first_tuple(link, tuple, parse);
|
||||
if (parse->version_1.ns > 3) {
|
||||
station_addr = parse->version_1.str + parse->version_1.ofs[3];
|
||||
if (cvt_ascii_address(dev, station_addr) == 0) {
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
}
|
||||
if (!pcmcia_loop_tuple(link, CISTPL_VERS_1, pcmcia_get_versmac, dev))
|
||||
return 0;
|
||||
|
||||
/* Another possibility: for the EM3288, in a special tuple */
|
||||
tuple->DesiredTuple = 0x81;
|
||||
if (pcmcia_get_first_tuple(link, tuple) != 0) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
if (pcmcia_get_tuple_data(link, tuple) != 0) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
buf[12] = '\0';
|
||||
if (cvt_ascii_address(dev, buf) == 0) {
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
rc = -1;
|
||||
free_cfg_mem:
|
||||
kfree(cfg_mem);
|
||||
return rc;
|
||||
}
|
||||
len = pcmcia_get_tuple(link, 0x81, &buf);
|
||||
if (buf && len >= 13) {
|
||||
buf[12] = '\0';
|
||||
if (cvt_ascii_address(dev, buf))
|
||||
rc = 0;
|
||||
}
|
||||
kfree(buf);
|
||||
|
||||
return rc;
|
||||
};
|
||||
|
||||
/*======================================================================
|
||||
|
||||
|
@ -684,58 +625,21 @@ static int smc_config(struct pcmcia_device *link)
|
|||
return i;
|
||||
}
|
||||
|
||||
|
||||
static int smc_setup(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
cisparse_t *parse;
|
||||
cistpl_lan_node_id_t *node_id;
|
||||
u_char *buf, *station_addr;
|
||||
int i, rc;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -ENOMEM;
|
||||
|
||||
tuple = &cfg_mem->tuple;
|
||||
parse = &cfg_mem->parse;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
tuple->Attributes = tuple->TupleOffset = 0;
|
||||
tuple->TupleData = (cisdata_t *)buf;
|
||||
tuple->TupleDataMax = 255;
|
||||
|
||||
/* Check for a LAN function extension tuple */
|
||||
tuple->DesiredTuple = CISTPL_FUNCE;
|
||||
i = first_tuple(link, tuple, parse);
|
||||
while (i == 0) {
|
||||
if (parse->funce.type == CISTPL_FUNCE_LAN_NODE_ID)
|
||||
break;
|
||||
i = next_tuple(link, tuple, parse);
|
||||
}
|
||||
if (i == 0) {
|
||||
node_id = (cistpl_lan_node_id_t *)parse->funce.data;
|
||||
if (node_id->nb == 6) {
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = node_id->id[i];
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
}
|
||||
if (!pcmcia_get_mac_from_cis(link, dev))
|
||||
return 0;
|
||||
|
||||
/* Try the third string in the Version 1 Version/ID tuple. */
|
||||
if (link->prod_id[2]) {
|
||||
station_addr = link->prod_id[2];
|
||||
if (cvt_ascii_address(dev, station_addr) == 0) {
|
||||
rc = 0;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
if (cvt_ascii_address(dev, link->prod_id[2]) == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
rc = -1;
|
||||
free_cfg_mem:
|
||||
kfree(cfg_mem);
|
||||
return rc;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*====================================================================*/
|
||||
|
@ -749,7 +653,7 @@ static int osi_config(struct pcmcia_device *link)
|
|||
link->conf.Attributes |= CONF_ENABLE_SPKR;
|
||||
link->conf.Status = CCSR_AUDIO_ENA;
|
||||
link->irq.Attributes =
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;
|
||||
IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED;
|
||||
link->io.NumPorts1 = 64;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.NumPorts2 = 8;
|
||||
|
@ -794,41 +698,31 @@ static int osi_load_firmware(struct pcmcia_device *link)
|
|||
return err;
|
||||
}
|
||||
|
||||
static int pcmcia_osi_mac(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv)
|
||||
{
|
||||
struct net_device *dev = priv;
|
||||
int i;
|
||||
|
||||
if (tuple->TupleDataLen < 8)
|
||||
return -EINVAL;
|
||||
if (tuple->TupleData[0] != 0x04)
|
||||
return -EINVAL;
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = tuple->TupleData[i+2];
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_cfg_mem *cfg_mem;
|
||||
tuple_t *tuple;
|
||||
u_char *buf;
|
||||
int i, rc;
|
||||
|
||||
cfg_mem = kmalloc(sizeof(struct smc_cfg_mem), GFP_KERNEL);
|
||||
if (!cfg_mem)
|
||||
return -1;
|
||||
|
||||
tuple = &cfg_mem->tuple;
|
||||
buf = cfg_mem->buf;
|
||||
|
||||
tuple->Attributes = TUPLE_RETURN_COMMON;
|
||||
tuple->TupleData = (cisdata_t *)buf;
|
||||
tuple->TupleDataMax = 255;
|
||||
tuple->TupleOffset = 0;
|
||||
int rc;
|
||||
|
||||
/* Read the station address from tuple 0x90, subtuple 0x04 */
|
||||
tuple->DesiredTuple = 0x90;
|
||||
i = pcmcia_get_first_tuple(link, tuple);
|
||||
while (i == 0) {
|
||||
i = pcmcia_get_tuple_data(link, tuple);
|
||||
if ((i != 0) || (buf[0] == 0x04))
|
||||
break;
|
||||
i = pcmcia_get_next_tuple(link, tuple);
|
||||
}
|
||||
if (i != 0) {
|
||||
rc = -1;
|
||||
goto free_cfg_mem;
|
||||
}
|
||||
for (i = 0; i < 6; i++)
|
||||
dev->dev_addr[i] = buf[i+2];
|
||||
if (pcmcia_loop_tuple(link, 0x90, pcmcia_osi_mac, dev))
|
||||
return -1;
|
||||
|
||||
if (((manfid == MANFID_OSITECH) &&
|
||||
(cardid == PRODID_OSITECH_SEVEN)) ||
|
||||
|
@ -836,20 +730,17 @@ static int osi_setup(struct pcmcia_device *link, u_short manfid, u_short cardid)
|
|||
(cardid == PRODID_PSION_NET100))) {
|
||||
rc = osi_load_firmware(link);
|
||||
if (rc)
|
||||
goto free_cfg_mem;
|
||||
return rc;
|
||||
} else if (manfid == MANFID_OSITECH) {
|
||||
/* Make sure both functions are powered up */
|
||||
set_bits(0x300, link->io.BasePort1 + OSITECH_AUI_PWR);
|
||||
/* Now, turn on the interrupt for both card functions */
|
||||
set_bits(0x300, link->io.BasePort1 + OSITECH_RESET_ISR);
|
||||
DEBUG(2, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
|
||||
dev_dbg(&link->dev, "AUI/PWR: %4.4x RESET/ISR: %4.4x\n",
|
||||
inw(link->io.BasePort1 + OSITECH_AUI_PWR),
|
||||
inw(link->io.BasePort1 + OSITECH_RESET_ISR));
|
||||
}
|
||||
rc = 0;
|
||||
free_cfg_mem:
|
||||
kfree(cfg_mem);
|
||||
return rc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smc91c92_suspend(struct pcmcia_device *link)
|
||||
|
@ -959,12 +850,6 @@ static int check_sig(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_EXIT_TEST(ret, svc, label) \
|
||||
if (ret != 0) { \
|
||||
cs_error(link, svc, ret); \
|
||||
goto label; \
|
||||
}
|
||||
|
||||
static int smc91c92_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
@ -974,7 +859,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
unsigned int ioaddr;
|
||||
u_long mir;
|
||||
|
||||
DEBUG(0, "smc91c92_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "smc91c92_config\n");
|
||||
|
||||
smc->manfid = link->manf_id;
|
||||
smc->cardid = link->card_id;
|
||||
|
@ -990,12 +875,15 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
} else {
|
||||
i = smc_config(link);
|
||||
}
|
||||
CS_EXIT_TEST(i, RequestIO, config_failed);
|
||||
if (i)
|
||||
goto config_failed;
|
||||
|
||||
i = pcmcia_request_irq(link, &link->irq);
|
||||
CS_EXIT_TEST(i, RequestIRQ, config_failed);
|
||||
if (i)
|
||||
goto config_failed;
|
||||
i = pcmcia_request_configuration(link, &link->conf);
|
||||
CS_EXIT_TEST(i, RequestConfiguration, config_failed);
|
||||
if (i)
|
||||
goto config_failed;
|
||||
|
||||
if (smc->manfid == MANFID_MOTOROLA)
|
||||
mot_config(link);
|
||||
|
@ -1074,7 +962,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
link->dev_node = &smc->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if (register_netdev(dev) != 0) {
|
||||
printk(KERN_ERR "smc91c92_cs: register_netdev() failed\n");
|
||||
|
@ -1100,7 +988,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
|
||||
if (smc->cfg & CFG_MII_SELECT) {
|
||||
if (smc->mii_if.phy_id != -1) {
|
||||
DEBUG(0, " MII transceiver at index %d, status %x.\n",
|
||||
dev_dbg(&link->dev, " MII transceiver at index %d, status %x.\n",
|
||||
smc->mii_if.phy_id, j);
|
||||
} else {
|
||||
printk(KERN_NOTICE " No MII transceivers found!\n");
|
||||
|
@ -1110,7 +998,7 @@ static int smc91c92_config(struct pcmcia_device *link)
|
|||
|
||||
config_undo:
|
||||
unregister_netdev(dev);
|
||||
config_failed: /* CS_EXIT_TEST() calls jump to here... */
|
||||
config_failed:
|
||||
smc91c92_release(link);
|
||||
return -ENODEV;
|
||||
} /* smc91c92_config */
|
||||
|
@ -1125,7 +1013,7 @@ config_failed: /* CS_EXIT_TEST() calls jump to here... */
|
|||
|
||||
static void smc91c92_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "smc91c92_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "smc91c92_release\n");
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
|
@ -1222,10 +1110,10 @@ static int smc_open(struct net_device *dev)
|
|||
struct smc_private *smc = netdev_priv(dev);
|
||||
struct pcmcia_device *link = smc->p_dev;
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
DEBUG(0, "%s: smc_open(%p), ID/Window %4.4x.\n",
|
||||
dev_dbg(&link->dev, "%s: smc_open(%p), ID/Window %4.4x.\n",
|
||||
dev->name, dev, inw(dev->base_addr + BANK_SELECT));
|
||||
if (pc_debug > 1) smc_dump(dev);
|
||||
#ifdef PCMCIA_DEBUG
|
||||
smc_dump(dev);
|
||||
#endif
|
||||
|
||||
/* Check that the PCMCIA card is still here. */
|
||||
|
@ -1260,7 +1148,7 @@ static int smc_close(struct net_device *dev)
|
|||
struct pcmcia_device *link = smc->p_dev;
|
||||
unsigned int ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(0, "%s: smc_close(), status %4.4x.\n",
|
||||
dev_dbg(&link->dev, "%s: smc_close(), status %4.4x.\n",
|
||||
dev->name, inw(ioaddr + BANK_SELECT));
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
@ -1327,7 +1215,7 @@ static void smc_hardware_send_packet(struct net_device * dev)
|
|||
u_char *buf = skb->data;
|
||||
u_int length = skb->len; /* The chip will pad to ethernet min. */
|
||||
|
||||
DEBUG(2, "%s: Trying to xmit packet of length %d.\n",
|
||||
pr_debug("%s: Trying to xmit packet of length %d.\n",
|
||||
dev->name, length);
|
||||
|
||||
/* send the packet length: +6 for status word, length, and ctl */
|
||||
|
@ -1382,7 +1270,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
|
|||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
DEBUG(2, "%s: smc_start_xmit(length = %d) called,"
|
||||
pr_debug("%s: smc_start_xmit(length = %d) called,"
|
||||
" status %4.4x.\n", dev->name, skb->len, inw(ioaddr + 2));
|
||||
|
||||
if (smc->saved_skb) {
|
||||
|
@ -1429,7 +1317,7 @@ static netdev_tx_t smc_start_xmit(struct sk_buff *skb,
|
|||
}
|
||||
|
||||
/* Otherwise defer until the Tx-space-allocated interrupt. */
|
||||
DEBUG(2, "%s: memory allocation deferred.\n", dev->name);
|
||||
pr_debug("%s: memory allocation deferred.\n", dev->name);
|
||||
outw((IM_ALLOC_INT << 8) | (ir & 0xff00), ioaddr + INTERRUPT);
|
||||
spin_unlock_irqrestore(&smc->lock, flags);
|
||||
|
||||
|
@ -1494,7 +1382,7 @@ static void smc_eph_irq(struct net_device *dev)
|
|||
|
||||
SMC_SELECT_BANK(0);
|
||||
ephs = inw(ioaddr + EPH);
|
||||
DEBUG(2, "%s: Ethernet protocol handler interrupt, status"
|
||||
pr_debug("%s: Ethernet protocol handler interrupt, status"
|
||||
" %4.4x.\n", dev->name, ephs);
|
||||
/* Could be a counter roll-over warning: update stats. */
|
||||
card_stats = inw(ioaddr + COUNTER);
|
||||
|
@ -1534,7 +1422,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||
|
||||
ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(3, "%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
|
||||
pr_debug("%s: SMC91c92 interrupt %d at %#x.\n", dev->name,
|
||||
irq, ioaddr);
|
||||
|
||||
spin_lock(&smc->lock);
|
||||
|
@ -1543,7 +1431,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||
if ((saved_bank & 0xff00) != 0x3300) {
|
||||
/* The device does not exist -- the card could be off-line, or
|
||||
maybe it has been ejected. */
|
||||
DEBUG(1, "%s: SMC91c92 interrupt %d for non-existent"
|
||||
pr_debug("%s: SMC91c92 interrupt %d for non-existent"
|
||||
"/ejected device.\n", dev->name, irq);
|
||||
handled = 0;
|
||||
goto irq_done;
|
||||
|
@ -1557,7 +1445,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||
|
||||
do { /* read the status flag, and mask it */
|
||||
status = inw(ioaddr + INTERRUPT) & 0xff;
|
||||
DEBUG(3, "%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
|
||||
pr_debug("%s: Status is %#2.2x (mask %#2.2x).\n", dev->name,
|
||||
status, mask);
|
||||
if ((status & mask) == 0) {
|
||||
if (bogus_cnt == INTR_WORK)
|
||||
|
@ -1602,7 +1490,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||
smc_eph_irq(dev);
|
||||
} while (--bogus_cnt);
|
||||
|
||||
DEBUG(3, " Restoring saved registers mask %2.2x bank %4.4x"
|
||||
pr_debug(" Restoring saved registers mask %2.2x bank %4.4x"
|
||||
" pointer %4.4x.\n", mask, saved_bank, saved_pointer);
|
||||
|
||||
/* restore state register */
|
||||
|
@ -1610,7 +1498,7 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
|
|||
outw(saved_pointer, ioaddr + POINTER);
|
||||
SMC_SELECT_BANK(saved_bank);
|
||||
|
||||
DEBUG(3, "%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
|
||||
pr_debug("%s: Exiting interrupt IRQ%d.\n", dev->name, irq);
|
||||
|
||||
irq_done:
|
||||
|
||||
|
@ -1661,7 +1549,7 @@ static void smc_rx(struct net_device *dev)
|
|||
rx_status = inw(ioaddr + DATA_1);
|
||||
packet_length = inw(ioaddr + DATA_1) & 0x07ff;
|
||||
|
||||
DEBUG(2, "%s: Receive status %4.4x length %d.\n",
|
||||
pr_debug("%s: Receive status %4.4x length %d.\n",
|
||||
dev->name, rx_status, packet_length);
|
||||
|
||||
if (!(rx_status & RS_ERRORS)) {
|
||||
|
@ -1672,7 +1560,7 @@ static void smc_rx(struct net_device *dev)
|
|||
skb = dev_alloc_skb(packet_length+2);
|
||||
|
||||
if (skb == NULL) {
|
||||
DEBUG(1, "%s: Low memory, packet dropped.\n", dev->name);
|
||||
pr_debug("%s: Low memory, packet dropped.\n", dev->name);
|
||||
dev->stats.rx_dropped++;
|
||||
outw(MC_RELEASE, ioaddr + MMU_CMD);
|
||||
return;
|
||||
|
@ -1832,7 +1720,7 @@ static void smc_reset(struct net_device *dev)
|
|||
struct smc_private *smc = netdev_priv(dev);
|
||||
int i;
|
||||
|
||||
DEBUG(0, "%s: smc91c92 reset called.\n", dev->name);
|
||||
pr_debug("%s: smc91c92 reset called.\n", dev->name);
|
||||
|
||||
/* The first interaction must be a write to bring the chip out
|
||||
of sleep mode. */
|
||||
|
@ -2149,18 +2037,6 @@ static u32 smc_get_link(struct net_device *dev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static u32 smc_get_msglevel(struct net_device *dev)
|
||||
{
|
||||
return pc_debug;
|
||||
}
|
||||
|
||||
static void smc_set_msglevel(struct net_device *dev, u32 val)
|
||||
{
|
||||
pc_debug = val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int smc_nway_reset(struct net_device *dev)
|
||||
{
|
||||
struct smc_private *smc = netdev_priv(dev);
|
||||
|
@ -2184,10 +2060,6 @@ static const struct ethtool_ops ethtool_ops = {
|
|||
.get_settings = smc_get_settings,
|
||||
.set_settings = smc_set_settings,
|
||||
.get_link = smc_get_link,
|
||||
#ifdef PCMCIA_DEBUG
|
||||
.get_msglevel = smc_get_msglevel,
|
||||
.set_msglevel = smc_set_msglevel,
|
||||
#endif
|
||||
.nway_reset = smc_nway_reset,
|
||||
};
|
||||
|
||||
|
|
|
@ -211,20 +211,6 @@ enum xirc_cmd { /* Commands */
|
|||
|
||||
static const char *if_names[] = { "Auto", "10BaseT", "10Base2", "AUI", "100BaseT" };
|
||||
|
||||
/****************
|
||||
* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
* you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
* left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
* be present but disabled -- but it can then be enabled for specific
|
||||
* modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KDBG_XIRC args)
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
#define KDBG_XIRC KERN_DEBUG "xirc2ps_cs: "
|
||||
#define KERR_XIRC KERN_ERR "xirc2ps_cs: "
|
||||
|
@ -359,7 +345,7 @@ static void xirc_tx_timeout(struct net_device *dev);
|
|||
static void xirc2ps_tx_timeout_task(struct work_struct *work);
|
||||
static void set_addresses(struct net_device *dev);
|
||||
static void set_multicast_list(struct net_device *dev);
|
||||
static int set_card_type(struct pcmcia_device *link, const void *s);
|
||||
static int set_card_type(struct pcmcia_device *link);
|
||||
static int do_config(struct net_device *dev, struct ifmap *map);
|
||||
static int do_open(struct net_device *dev);
|
||||
static int do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
|
||||
|
@ -371,28 +357,6 @@ static void do_powerdown(struct net_device *dev);
|
|||
static int do_stop(struct net_device *dev);
|
||||
|
||||
/*=============== Helper functions =========================*/
|
||||
static int
|
||||
first_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = pcmcia_get_first_tuple(handle, tuple)) == 0 &&
|
||||
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
|
||||
err = pcmcia_parse_tuple(tuple, parse);
|
||||
return err;
|
||||
}
|
||||
|
||||
static int
|
||||
next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
||||
{
|
||||
int err;
|
||||
|
||||
if ((err = pcmcia_get_next_tuple(handle, tuple)) == 0 &&
|
||||
(err = pcmcia_get_tuple_data(handle, tuple)) == 0)
|
||||
err = pcmcia_parse_tuple(tuple, parse);
|
||||
return err;
|
||||
}
|
||||
|
||||
#define SelectPage(pgnr) outb((pgnr), ioaddr + XIRCREG_PR)
|
||||
#define GetByte(reg) ((unsigned)inb(ioaddr + (reg)))
|
||||
#define GetWord(reg) ((unsigned)inw(ioaddr + (reg)))
|
||||
|
@ -400,7 +364,7 @@ next_tuple(struct pcmcia_device *handle, tuple_t *tuple, cisparse_t *parse)
|
|||
#define PutWord(reg,value) outw((value), ioaddr+(reg))
|
||||
|
||||
/*====== Functions used for debugging =================================*/
|
||||
#if defined(PCMCIA_DEBUG) && 0 /* reading regs may change system status */
|
||||
#if 0 /* reading regs may change system status */
|
||||
static void
|
||||
PrintRegisters(struct net_device *dev)
|
||||
{
|
||||
|
@ -432,7 +396,7 @@ PrintRegisters(struct net_device *dev)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif /* PCMCIA_DEBUG */
|
||||
#endif /* 0 */
|
||||
|
||||
/*============== MII Management functions ===============*/
|
||||
|
||||
|
@ -576,7 +540,7 @@ xirc2ps_probe(struct pcmcia_device *link)
|
|||
struct net_device *dev;
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "attach()\n");
|
||||
dev_dbg(&link->dev, "attach()\n");
|
||||
|
||||
/* Allocate the device structure */
|
||||
dev = alloc_etherdev(sizeof(local_info_t));
|
||||
|
@ -592,7 +556,6 @@ xirc2ps_probe(struct pcmcia_device *link)
|
|||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
link->conf.ConfigIndex = 1;
|
||||
link->irq.Handler = xirc2ps_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
|
||||
/* Fill in card specific entries */
|
||||
dev->netdev_ops = &netdev_ops;
|
||||
|
@ -615,7 +578,7 @@ xirc2ps_detach(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = link->priv;
|
||||
|
||||
DEBUG(0, "detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "detach\n");
|
||||
|
||||
if (link->dev_node)
|
||||
unregister_netdev(dev);
|
||||
|
@ -644,17 +607,25 @@ xirc2ps_detach(struct pcmcia_device *link)
|
|||
*
|
||||
*/
|
||||
static int
|
||||
set_card_type(struct pcmcia_device *link, const void *s)
|
||||
set_card_type(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
#ifdef PCMCIA_DEBUG
|
||||
unsigned cisrev = ((const unsigned char *)s)[2];
|
||||
#endif
|
||||
unsigned mediaid= ((const unsigned char *)s)[3];
|
||||
unsigned prodid = ((const unsigned char *)s)[4];
|
||||
u8 *buf;
|
||||
unsigned int cisrev, mediaid, prodid;
|
||||
size_t len;
|
||||
|
||||
DEBUG(0, "cisrev=%02x mediaid=%02x prodid=%02x\n",
|
||||
len = pcmcia_get_tuple(link, CISTPL_MANFID, &buf);
|
||||
if (len < 5) {
|
||||
dev_err(&link->dev, "invalid CIS -- sorry\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
cisrev = buf[2];
|
||||
mediaid = buf[3];
|
||||
prodid = buf[4];
|
||||
|
||||
dev_dbg(&link->dev, "cisrev=%02x mediaid=%02x prodid=%02x\n",
|
||||
cisrev, mediaid, prodid);
|
||||
|
||||
local->mohawk = 0;
|
||||
|
@ -761,6 +732,26 @@ xirc2ps_config_check(struct pcmcia_device *p_dev,
|
|||
|
||||
}
|
||||
|
||||
|
||||
static int pcmcia_get_mac_ce(struct pcmcia_device *p_dev,
|
||||
tuple_t *tuple,
|
||||
void *priv)
|
||||
{
|
||||
struct net_device *dev = priv;
|
||||
int i;
|
||||
|
||||
if (tuple->TupleDataLen != 13)
|
||||
return -EINVAL;
|
||||
if ((tuple->TupleData[0] != 2) || (tuple->TupleData[1] != 1) ||
|
||||
(tuple->TupleData[2] != 6))
|
||||
return -EINVAL;
|
||||
/* another try (James Lehmer's CE2 version 4.1)*/
|
||||
for (i = 2; i < 6; i++)
|
||||
dev->dev_addr[i] = tuple->TupleData[i+2];
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
||||
/****************
|
||||
* xirc2ps_config() is scheduled to run after a CARD_INSERTION event
|
||||
* is received, to configure the PCMCIA socket, and to make the
|
||||
|
@ -772,33 +763,21 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
struct net_device *dev = link->priv;
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
unsigned int ioaddr;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int err, i;
|
||||
u_char buf[64];
|
||||
cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;
|
||||
int err;
|
||||
u8 *buf;
|
||||
size_t len;
|
||||
|
||||
local->dingo_ccr = NULL;
|
||||
|
||||
DEBUG(0, "config(0x%p)\n", link);
|
||||
|
||||
/*
|
||||
* This reads the card's CONFIG tuple to find its configuration
|
||||
* registers.
|
||||
*/
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = 64;
|
||||
tuple.TupleOffset = 0;
|
||||
dev_dbg(&link->dev, "config\n");
|
||||
|
||||
/* Is this a valid card */
|
||||
tuple.DesiredTuple = CISTPL_MANFID;
|
||||
if ((err=first_tuple(link, &tuple, &parse))) {
|
||||
if (link->has_manf_id == 0) {
|
||||
printk(KNOT_XIRC "manfid not found in CIS\n");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
switch(parse.manfid.manf) {
|
||||
switch (link->manf_id) {
|
||||
case MANFID_XIRCOM:
|
||||
local->manf_str = "Xircom";
|
||||
break;
|
||||
|
@ -817,65 +796,44 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
break;
|
||||
default:
|
||||
printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",
|
||||
(unsigned)parse.manfid.manf);
|
||||
(unsigned)link->manf_id);
|
||||
goto failure;
|
||||
}
|
||||
DEBUG(0, "found %s card\n", local->manf_str);
|
||||
dev_dbg(&link->dev, "found %s card\n", local->manf_str);
|
||||
|
||||
if (!set_card_type(link, buf)) {
|
||||
if (!set_card_type(link)) {
|
||||
printk(KNOT_XIRC "this card is not supported\n");
|
||||
goto failure;
|
||||
}
|
||||
|
||||
/* get the ethernet address from the CIS */
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:
|
||||
* the first one with a length of zero the second correct -
|
||||
* so I skip all entries with length 0 */
|
||||
if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID &&
|
||||
((cistpl_lan_node_id_t *)parse.funce.data)->nb)
|
||||
break;
|
||||
}
|
||||
if (err) { /* not found: try to get the node-id from tuple 0x89 */
|
||||
tuple.DesiredTuple = 0x89; /* data layout looks like tuple 0x22 */
|
||||
if ((err = pcmcia_get_first_tuple(link, &tuple)) == 0 &&
|
||||
(err = pcmcia_get_tuple_data(link, &tuple)) == 0) {
|
||||
if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)
|
||||
memcpy(&parse, buf, 8);
|
||||
else
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
if (err) { /* another try (James Lehmer's CE2 version 4.1)*/
|
||||
tuple.DesiredTuple = CISTPL_FUNCE;
|
||||
for (err = first_tuple(link, &tuple, &parse); !err;
|
||||
err = next_tuple(link, &tuple, &parse)) {
|
||||
if (parse.funce.type == 0x02 && parse.funce.data[0] == 1 &&
|
||||
parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {
|
||||
buf[1] = 4;
|
||||
memcpy(&parse, buf+1, 8);
|
||||
break;
|
||||
err = pcmcia_get_mac_from_cis(link, dev);
|
||||
|
||||
/* not found: try to get the node-id from tuple 0x89 */
|
||||
if (err) {
|
||||
len = pcmcia_get_tuple(link, 0x89, &buf);
|
||||
/* data layout looks like tuple 0x22 */
|
||||
if (buf && len == 8) {
|
||||
if (*buf == CISTPL_FUNCE_LAN_NODE_ID) {
|
||||
int i;
|
||||
for (i = 2; i < 6; i++)
|
||||
dev->dev_addr[i] = buf[i+2];
|
||||
} else
|
||||
err = -1;
|
||||
}
|
||||
}
|
||||
kfree(buf);
|
||||
}
|
||||
|
||||
if (err)
|
||||
err = pcmcia_loop_tuple(link, CISTPL_FUNCE, pcmcia_get_mac_ce, dev);
|
||||
|
||||
if (err) {
|
||||
printk(KNOT_XIRC "node-id not found in CIS\n");
|
||||
goto failure;
|
||||
}
|
||||
node_id = (cistpl_lan_node_id_t *)parse.funce.data;
|
||||
if (node_id->nb != 6) {
|
||||
printk(KNOT_XIRC "malformed node-id in CIS\n");
|
||||
goto failure;
|
||||
}
|
||||
for (i=0; i < 6; i++)
|
||||
dev->dev_addr[i] = node_id->id[i];
|
||||
|
||||
link->io.IOAddrLines =10;
|
||||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
|
||||
link->irq.Attributes = IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
if (local->modem) {
|
||||
int pass;
|
||||
|
||||
|
@ -916,10 +874,8 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
goto port_found;
|
||||
}
|
||||
link->io.BasePort1 = 0; /* let CS decide */
|
||||
if ((err=pcmcia_request_io(link, &link->io))) {
|
||||
cs_error(link, RequestIO, err);
|
||||
if ((err=pcmcia_request_io(link, &link->io)))
|
||||
goto config_error;
|
||||
}
|
||||
}
|
||||
port_found:
|
||||
if (err)
|
||||
|
@ -929,19 +885,15 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
* Now allocate an interrupt line. Note that this does not
|
||||
* actually assign a handler to the interrupt.
|
||||
*/
|
||||
if ((err=pcmcia_request_irq(link, &link->irq))) {
|
||||
cs_error(link, RequestIRQ, err);
|
||||
if ((err=pcmcia_request_irq(link, &link->irq)))
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
/****************
|
||||
* This actually configures the PCMCIA socket -- setting up
|
||||
* the I/O windows and the interrupt mapping.
|
||||
*/
|
||||
if ((err=pcmcia_request_configuration(link, &link->conf))) {
|
||||
cs_error(link, RequestConfiguration, err);
|
||||
if ((err=pcmcia_request_configuration(link, &link->conf)))
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
if (local->dingo) {
|
||||
conf_reg_t reg;
|
||||
|
@ -956,17 +908,13 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_IOBASE_0;
|
||||
reg.Value = link->io.BasePort2 & 0xff;
|
||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
||||
cs_error(link, AccessConfigurationRegister, err);
|
||||
if ((err = pcmcia_access_configuration_register(link, ®)))
|
||||
goto config_error;
|
||||
}
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_IOBASE_1;
|
||||
reg.Value = (link->io.BasePort2 >> 8) & 0xff;
|
||||
if ((err = pcmcia_access_configuration_register(link, ®))) {
|
||||
cs_error(link, AccessConfigurationRegister, err);
|
||||
if ((err = pcmcia_access_configuration_register(link, ®)))
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
/* There is no config entry for the Ethernet part which
|
||||
* is at 0x0800. So we allocate a window into the attribute
|
||||
|
@ -975,17 +923,14 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;
|
||||
req.Base = req.Size = 0;
|
||||
req.AccessSpeed = 0;
|
||||
if ((err = pcmcia_request_window(&link, &req, &link->win))) {
|
||||
cs_error(link, RequestWindow, err);
|
||||
if ((err = pcmcia_request_window(link, &req, &link->win)))
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;
|
||||
mem.CardOffset = 0x0;
|
||||
mem.Page = 0;
|
||||
if ((err = pcmcia_map_mem_page(link->win, &mem))) {
|
||||
cs_error(link, MapMemPage, err);
|
||||
if ((err = pcmcia_map_mem_page(link, link->win, &mem)))
|
||||
goto config_error;
|
||||
}
|
||||
|
||||
/* Setup the CCRs; there are no infos in the CIS about the Ethernet
|
||||
* part.
|
||||
|
@ -1044,7 +989,7 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
do_reset(dev, 1); /* a kludge to make the cem56 work */
|
||||
|
||||
link->dev_node = &local->node;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
|
||||
if ((err=register_netdev(dev))) {
|
||||
printk(KNOT_XIRC "register_netdev() failed\n");
|
||||
|
@ -1077,7 +1022,7 @@ xirc2ps_config(struct pcmcia_device * link)
|
|||
static void
|
||||
xirc2ps_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "release\n");
|
||||
|
||||
if (link->win) {
|
||||
struct net_device *dev = link->priv;
|
||||
|
@ -1144,7 +1089,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
PutByte(XIRCREG_CR, 0);
|
||||
}
|
||||
|
||||
DEBUG(6, "%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
|
||||
pr_debug("%s: interrupt %d at %#x.\n", dev->name, irq, ioaddr);
|
||||
|
||||
saved_page = GetByte(XIRCREG_PR);
|
||||
/* Read the ISR to see whats the cause for the interrupt.
|
||||
|
@ -1154,7 +1099,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
bytes_rcvd = 0;
|
||||
loop_entry:
|
||||
if (int_status == 0xff) { /* card may be ejected */
|
||||
DEBUG(3, "%s: interrupt %d for dead card\n", dev->name, irq);
|
||||
pr_debug("%s: interrupt %d for dead card\n", dev->name, irq);
|
||||
goto leave;
|
||||
}
|
||||
eth_status = GetByte(XIRCREG_ESR);
|
||||
|
@ -1167,7 +1112,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
PutByte(XIRCREG40_TXST0, 0);
|
||||
PutByte(XIRCREG40_TXST1, 0);
|
||||
|
||||
DEBUG(3, "%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
|
||||
pr_debug("%s: ISR=%#2.2x ESR=%#2.2x RSR=%#2.2x TSR=%#4.4x\n",
|
||||
dev->name, int_status, eth_status, rx_status, tx_status);
|
||||
|
||||
/***** receive section ******/
|
||||
|
@ -1178,14 +1123,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
/* too many bytes received during this int, drop the rest of the
|
||||
* packets */
|
||||
dev->stats.rx_dropped++;
|
||||
DEBUG(2, "%s: RX drop, too much done\n", dev->name);
|
||||
pr_debug("%s: RX drop, too much done\n", dev->name);
|
||||
} else if (rsr & PktRxOk) {
|
||||
struct sk_buff *skb;
|
||||
|
||||
pktlen = GetWord(XIRCREG0_RBC);
|
||||
bytes_rcvd += pktlen;
|
||||
|
||||
DEBUG(5, "rsr=%#02x packet_length=%u\n", rsr, pktlen);
|
||||
pr_debug("rsr=%#02x packet_length=%u\n", rsr, pktlen);
|
||||
|
||||
skb = dev_alloc_skb(pktlen+3); /* 1 extra so we can use insw */
|
||||
if (!skb) {
|
||||
|
@ -1253,19 +1198,19 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
dev->stats.multicast++;
|
||||
}
|
||||
} else { /* bad packet */
|
||||
DEBUG(5, "rsr=%#02x\n", rsr);
|
||||
pr_debug("rsr=%#02x\n", rsr);
|
||||
}
|
||||
if (rsr & PktTooLong) {
|
||||
dev->stats.rx_frame_errors++;
|
||||
DEBUG(3, "%s: Packet too long\n", dev->name);
|
||||
pr_debug("%s: Packet too long\n", dev->name);
|
||||
}
|
||||
if (rsr & CRCErr) {
|
||||
dev->stats.rx_crc_errors++;
|
||||
DEBUG(3, "%s: CRC error\n", dev->name);
|
||||
pr_debug("%s: CRC error\n", dev->name);
|
||||
}
|
||||
if (rsr & AlignErr) {
|
||||
dev->stats.rx_fifo_errors++; /* okay ? */
|
||||
DEBUG(3, "%s: Alignment error\n", dev->name);
|
||||
pr_debug("%s: Alignment error\n", dev->name);
|
||||
}
|
||||
|
||||
/* clear the received/dropped/error packet */
|
||||
|
@ -1277,7 +1222,7 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
if (rx_status & 0x10) { /* Receive overrun */
|
||||
dev->stats.rx_over_errors++;
|
||||
PutByte(XIRCREG_CR, ClearRxOvrun);
|
||||
DEBUG(3, "receive overrun cleared\n");
|
||||
pr_debug("receive overrun cleared\n");
|
||||
}
|
||||
|
||||
/***** transmit section ******/
|
||||
|
@ -1290,13 +1235,13 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
if (nn < n) /* rollover */
|
||||
dev->stats.tx_packets += 256 - n;
|
||||
else if (n == nn) { /* happens sometimes - don't know why */
|
||||
DEBUG(0, "PTR not changed?\n");
|
||||
pr_debug("PTR not changed?\n");
|
||||
} else
|
||||
dev->stats.tx_packets += lp->last_ptr_value - n;
|
||||
netif_wake_queue(dev);
|
||||
}
|
||||
if (tx_status & 0x0002) { /* Execessive collissions */
|
||||
DEBUG(0, "tx restarted due to execssive collissions\n");
|
||||
pr_debug("tx restarted due to execssive collissions\n");
|
||||
PutByte(XIRCREG_CR, RestartTx); /* restart transmitter process */
|
||||
}
|
||||
if (tx_status & 0x0040)
|
||||
|
@ -1315,14 +1260,14 @@ xirc2ps_interrupt(int irq, void *dev_id)
|
|||
maxrx_bytes = 2000;
|
||||
else if (maxrx_bytes > 22000)
|
||||
maxrx_bytes = 22000;
|
||||
DEBUG(1, "set maxrx=%u (rcvd=%u ticks=%lu)\n",
|
||||
pr_debug("set maxrx=%u (rcvd=%u ticks=%lu)\n",
|
||||
maxrx_bytes, bytes_rcvd, duration);
|
||||
} else if (!duration && maxrx_bytes < 22000) {
|
||||
/* now much faster */
|
||||
maxrx_bytes += 2000;
|
||||
if (maxrx_bytes > 22000)
|
||||
maxrx_bytes = 22000;
|
||||
DEBUG(1, "set maxrx=%u\n", maxrx_bytes);
|
||||
pr_debug("set maxrx=%u\n", maxrx_bytes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1372,7 +1317,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
unsigned freespace;
|
||||
unsigned pktlen = skb->len;
|
||||
|
||||
DEBUG(1, "do_start_xmit(skb=%p, dev=%p) len=%u\n",
|
||||
pr_debug("do_start_xmit(skb=%p, dev=%p) len=%u\n",
|
||||
skb, dev, pktlen);
|
||||
|
||||
|
||||
|
@ -1398,7 +1343,7 @@ do_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
|||
freespace &= 0x7fff;
|
||||
/* TRS doesn't work - (indeed it is eliminated with sil-rev 1) */
|
||||
okay = pktlen +2 < freespace;
|
||||
DEBUG(2 + (okay ? 2 : 0), "%s: avail. tx space=%u%s\n",
|
||||
pr_debug("%s: avail. tx space=%u%s\n",
|
||||
dev->name, freespace, okay ? " (okay)":" (not enough)");
|
||||
if (!okay) { /* not enough space */
|
||||
return NETDEV_TX_BUSY; /* upper layer may decide to requeue this packet */
|
||||
|
@ -1500,7 +1445,7 @@ do_config(struct net_device *dev, struct ifmap *map)
|
|||
{
|
||||
local_info_t *local = netdev_priv(dev);
|
||||
|
||||
DEBUG(0, "do_config(%p)\n", dev);
|
||||
pr_debug("do_config(%p)\n", dev);
|
||||
if (map->port != 255 && map->port != dev->if_port) {
|
||||
if (map->port > 4)
|
||||
return -EINVAL;
|
||||
|
@ -1527,7 +1472,7 @@ do_open(struct net_device *dev)
|
|||
local_info_t *lp = netdev_priv(dev);
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(0, "do_open(%p)\n", dev);
|
||||
dev_dbg(&link->dev, "do_open(%p)\n", dev);
|
||||
|
||||
/* Check that the PCMCIA card is still here. */
|
||||
/* Physical device present signature. */
|
||||
|
@ -1561,7 +1506,7 @@ do_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
struct mii_ioctl_data *data = if_mii(rq);
|
||||
|
||||
DEBUG(1, "%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
|
||||
pr_debug("%s: ioctl(%-.6s, %#04x) %04x %04x %04x %04x\n",
|
||||
dev->name, rq->ifr_ifrn.ifrn_name, cmd,
|
||||
data->phy_id, data->reg_num, data->val_in, data->val_out);
|
||||
|
||||
|
@ -1610,7 +1555,7 @@ do_reset(struct net_device *dev, int full)
|
|||
unsigned int ioaddr = dev->base_addr;
|
||||
unsigned value;
|
||||
|
||||
DEBUG(0, "%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
|
||||
pr_debug("%s: do_reset(%p,%d)\n", dev? dev->name:"eth?", dev, full);
|
||||
|
||||
hardreset(dev);
|
||||
PutByte(XIRCREG_CR, SoftReset); /* set */
|
||||
|
@ -1648,8 +1593,8 @@ do_reset(struct net_device *dev, int full)
|
|||
}
|
||||
msleep(40); /* wait 40 msec to let it complete */
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
if (pc_debug) {
|
||||
#if 0
|
||||
{
|
||||
SelectPage(0);
|
||||
value = GetByte(XIRCREG_ESR); /* read the ESR */
|
||||
printk(KERN_DEBUG "%s: ESR is: %#02x\n", dev->name, value);
|
||||
|
@ -1666,7 +1611,7 @@ do_reset(struct net_device *dev, int full)
|
|||
value |= DisableLinkPulse;
|
||||
PutByte(XIRCREG1_ECR, value);
|
||||
#endif
|
||||
DEBUG(0, "%s: ECR is: %#02x\n", dev->name, value);
|
||||
pr_debug("%s: ECR is: %#02x\n", dev->name, value);
|
||||
|
||||
SelectPage(0x42);
|
||||
PutByte(XIRCREG42_SWC0, 0x20); /* disable source insertion */
|
||||
|
@ -1844,7 +1789,7 @@ do_powerdown(struct net_device *dev)
|
|||
|
||||
unsigned int ioaddr = dev->base_addr;
|
||||
|
||||
DEBUG(0, "do_powerdown(%p)\n", dev);
|
||||
pr_debug("do_powerdown(%p)\n", dev);
|
||||
|
||||
SelectPage(4);
|
||||
PutByte(XIRCREG4_GPR1, 0); /* clear bit 0: power down */
|
||||
|
@ -1858,7 +1803,7 @@ do_stop(struct net_device *dev)
|
|||
local_info_t *lp = netdev_priv(dev);
|
||||
struct pcmcia_device *link = lp->p_dev;
|
||||
|
||||
DEBUG(0, "do_stop(%p)\n", dev);
|
||||
dev_dbg(&link->dev, "do_stop(%p)\n", dev);
|
||||
|
||||
if (!link)
|
||||
return -ENODEV;
|
||||
|
|
|
@ -43,21 +43,6 @@
|
|||
|
||||
#include "airo.h"
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
static char *version = "$Revision: 1.2 $";
|
||||
#define DEBUG(n, args...) if (pc_debug > (n)) printk(KERN_DEBUG args);
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -145,11 +130,10 @@ static int airo_probe(struct pcmcia_device *p_dev)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "airo_attach()\n");
|
||||
dev_dbg(&p_dev->dev, "airo_attach()\n");
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
|
@ -184,7 +168,7 @@ static int airo_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
static void airo_detach(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "airo_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "airo_detach\n");
|
||||
|
||||
airo_release(link);
|
||||
|
||||
|
@ -204,9 +188,6 @@ static void airo_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
|
@ -275,11 +256,11 @@ static int airo_cs_config_check(struct pcmcia_device *p_dev,
|
|||
req->Base = mem->win[0].host_addr;
|
||||
req->Size = mem->win[0].len;
|
||||
req->AccessSpeed = 0;
|
||||
if (pcmcia_request_window(&p_dev, req, &p_dev->win) != 0)
|
||||
if (pcmcia_request_window(p_dev, req, &p_dev->win) != 0)
|
||||
return -ENODEV;
|
||||
map.Page = 0;
|
||||
map.CardOffset = mem->win[0].card_addr;
|
||||
if (pcmcia_map_mem_page(p_dev->win, &map) != 0)
|
||||
if (pcmcia_map_mem_page(p_dev, p_dev->win, &map) != 0)
|
||||
return -ENODEV;
|
||||
}
|
||||
/* If we got this far, we're cool! */
|
||||
|
@ -291,11 +272,11 @@ static int airo_config(struct pcmcia_device *link)
|
|||
{
|
||||
local_info_t *dev;
|
||||
win_req_t *req;
|
||||
int last_fn, last_ret;
|
||||
int ret;
|
||||
|
||||
dev = link->priv;
|
||||
|
||||
DEBUG(0, "airo_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "airo_config\n");
|
||||
|
||||
req = kzalloc(sizeof(win_req_t), GFP_KERNEL);
|
||||
if (!req)
|
||||
|
@ -315,8 +296,8 @@ static int airo_config(struct pcmcia_device *link)
|
|||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, airo_cs_config_check, req);
|
||||
if (last_ret)
|
||||
ret = pcmcia_loop_config(link, airo_cs_config_check, req);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
|
@ -324,21 +305,25 @@ static int airo_config(struct pcmcia_device *link)
|
|||
handler to the interrupt, unless the 'Handler' member of the
|
||||
irq structure is initialized.
|
||||
*/
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
the I/O windows and the interrupt mapping, and putting the
|
||||
card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
((local_info_t *)link->priv)->eth_dev =
|
||||
init_airo_card(link->irq.AssignedIRQ,
|
||||
link->io.BasePort1, 1, &handle_to_dev(link));
|
||||
link->io.BasePort1, 1, &link->dev);
|
||||
if (!((local_info_t *)link->priv)->eth_dev)
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
At this point, the dev_node_t structure(s) need to be
|
||||
|
@ -368,8 +353,6 @@ static int airo_config(struct pcmcia_device *link)
|
|||
kfree(req);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
airo_release(link);
|
||||
kfree(req);
|
||||
|
@ -386,7 +369,7 @@ static int airo_config(struct pcmcia_device *link)
|
|||
|
||||
static void airo_release(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "airo_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "airo_release\n");
|
||||
pcmcia_disable_device(link);
|
||||
}
|
||||
|
||||
|
|
|
@ -55,22 +55,6 @@
|
|||
|
||||
#include "atmel.h"
|
||||
|
||||
/*
|
||||
All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If
|
||||
you do not define PCMCIA_DEBUG at all, all the debug code will be
|
||||
left out. If you compile with PCMCIA_DEBUG=0, the debug code will
|
||||
be present but disabled -- but it can then be enabled for specific
|
||||
modules at load time with a 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
static char *version = "$Revision: 1.2 $";
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args);
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -155,11 +139,10 @@ static int atmel_probe(struct pcmcia_device *p_dev)
|
|||
{
|
||||
local_info_t *local;
|
||||
|
||||
DEBUG(0, "atmel_attach()\n");
|
||||
dev_dbg(&p_dev->dev, "atmel_attach()\n");
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Handler = NULL;
|
||||
|
||||
/*
|
||||
|
@ -194,7 +177,7 @@ static int atmel_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
static void atmel_detach(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "atmel_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "atmel_detach\n");
|
||||
|
||||
atmel_release(link);
|
||||
|
||||
|
@ -209,9 +192,6 @@ static void atmel_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
/* Call-back function to interrogate PCMCIA-specific information
|
||||
about the current existance of the card */
|
||||
static int card_present(void *arg)
|
||||
|
@ -275,13 +255,13 @@ static int atmel_config_check(struct pcmcia_device *p_dev,
|
|||
static int atmel_config(struct pcmcia_device *link)
|
||||
{
|
||||
local_info_t *dev;
|
||||
int last_fn, last_ret;
|
||||
int ret;
|
||||
struct pcmcia_device_id *did;
|
||||
|
||||
dev = link->priv;
|
||||
did = dev_get_drvdata(&handle_to_dev(link));
|
||||
did = dev_get_drvdata(&link->dev);
|
||||
|
||||
DEBUG(0, "atmel_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "atmel_config\n");
|
||||
|
||||
/*
|
||||
In this loop, we scan the CIS for configuration table entries,
|
||||
|
@ -303,31 +283,36 @@ static int atmel_config(struct pcmcia_device *link)
|
|||
handler to the interrupt, unless the 'Handler' member of the
|
||||
irq structure is initialized.
|
||||
*/
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ)
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
This actually configures the PCMCIA socket -- setting up
|
||||
the I/O windows and the interrupt mapping, and putting the
|
||||
card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
if (link->irq.AssignedIRQ == 0) {
|
||||
printk(KERN_ALERT
|
||||
"atmel: cannot assign IRQ: check that CONFIG_ISA is set in kernel config.");
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
}
|
||||
|
||||
((local_info_t*)link->priv)->eth_dev =
|
||||
init_atmel_card(link->irq.AssignedIRQ,
|
||||
link->io.BasePort1,
|
||||
did ? did->driver_info : ATMEL_FW_TYPE_NONE,
|
||||
&handle_to_dev(link),
|
||||
&link->dev,
|
||||
card_present,
|
||||
link);
|
||||
if (!((local_info_t*)link->priv)->eth_dev)
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
|
||||
|
||||
/*
|
||||
|
@ -340,8 +325,6 @@ static int atmel_config(struct pcmcia_device *link)
|
|||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
atmel_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -359,7 +342,7 @@ static void atmel_release(struct pcmcia_device *link)
|
|||
{
|
||||
struct net_device *dev = ((local_info_t*)link->priv)->eth_dev;
|
||||
|
||||
DEBUG(0, "atmel_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "atmel_release\n");
|
||||
|
||||
if (dev)
|
||||
stop_atmel_card(dev);
|
||||
|
|
|
@ -65,35 +65,15 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
|||
struct ssb_bus *ssb;
|
||||
win_req_t win;
|
||||
memreq_t mem;
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
int err = -ENOMEM;
|
||||
int res = 0;
|
||||
unsigned char buf[64];
|
||||
|
||||
ssb = kzalloc(sizeof(*ssb), GFP_KERNEL);
|
||||
if (!ssb)
|
||||
goto out_error;
|
||||
|
||||
err = -ENODEV;
|
||||
tuple.DesiredTuple = CISTPL_CONFIG;
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
res = pcmcia_get_first_tuple(dev, &tuple);
|
||||
if (res != 0)
|
||||
goto err_kfree_ssb;
|
||||
res = pcmcia_get_tuple_data(dev, &tuple);
|
||||
if (res != 0)
|
||||
goto err_kfree_ssb;
|
||||
res = pcmcia_parse_tuple(&tuple, &parse);
|
||||
if (res != 0)
|
||||
goto err_kfree_ssb;
|
||||
|
||||
dev->conf.ConfigBase = parse.config.base;
|
||||
dev->conf.Present = parse.config.rmask[0];
|
||||
dev->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -107,20 +87,18 @@ static int __devinit b43_pcmcia_probe(struct pcmcia_device *dev)
|
|||
win.Base = 0;
|
||||
win.Size = SSB_CORE_SIZE;
|
||||
win.AccessSpeed = 250;
|
||||
res = pcmcia_request_window(&dev, &win, &dev->win);
|
||||
res = pcmcia_request_window(dev, &win, &dev->win);
|
||||
if (res != 0)
|
||||
goto err_kfree_ssb;
|
||||
|
||||
mem.CardOffset = 0;
|
||||
mem.Page = 0;
|
||||
res = pcmcia_map_mem_page(dev->win, &mem);
|
||||
res = pcmcia_map_mem_page(dev, dev->win, &mem);
|
||||
if (res != 0)
|
||||
goto err_disable;
|
||||
|
||||
dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
dev->irq.Handler = NULL; /* The handler is registered later. */
|
||||
dev->irq.Instance = NULL;
|
||||
res = pcmcia_request_irq(dev, &dev->irq);
|
||||
if (res != 0)
|
||||
goto err_disable;
|
||||
|
|
|
@ -274,9 +274,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
conf_reg_t reg;
|
||||
struct hostap_interface *iface = netdev_priv(dev);
|
||||
local_info_t *local = iface->local;
|
||||
tuple_t tuple;
|
||||
cisparse_t *parse = NULL;
|
||||
u_char buf[64];
|
||||
struct hostap_cs_priv *hw_priv = local->hw_priv;
|
||||
|
||||
if (hw_priv->link->io.NumPorts1 < 0x42) {
|
||||
|
@ -285,28 +282,13 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
goto done;
|
||||
}
|
||||
|
||||
parse = kmalloc(sizeof(cisparse_t), GFP_KERNEL);
|
||||
if (parse == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tuple.Attributes = TUPLE_RETURN_COMMON;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
if (hw_priv->link->manf_id != 0xd601 || hw_priv->link->card_id != 0x0101) {
|
||||
/* No SanDisk manfid found */
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
}
|
||||
|
||||
tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
|
||||
if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
|
||||
pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
|
||||
pcmcia_parse_tuple(&tuple, parse) ||
|
||||
parse->longlink_mfc.nfn < 2) {
|
||||
if (hw_priv->link->socket->functions < 2) {
|
||||
/* No multi-function links found */
|
||||
ret = -ENODEV;
|
||||
goto done;
|
||||
|
@ -354,7 +336,6 @@ static int sandisk_enable_wireless(struct net_device *dev)
|
|||
udelay(10);
|
||||
|
||||
done:
|
||||
kfree(parse);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -529,10 +510,6 @@ static void prism2_detach(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
|
||||
/* run after a CARD_INSERTION event is received to configure the PCMCIA
|
||||
* socket and make the device available to the system */
|
||||
|
||||
|
@ -624,7 +601,6 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
struct hostap_interface *iface;
|
||||
local_info_t *local;
|
||||
int ret = 1;
|
||||
int last_fn, last_ret;
|
||||
struct hostap_cs_priv *hw_priv;
|
||||
|
||||
PDEBUG(DEBUG_FLOW, "prism2_config()\n");
|
||||
|
@ -636,19 +612,18 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
}
|
||||
|
||||
/* Look for an appropriate configuration table entry in the CIS */
|
||||
last_ret = pcmcia_loop_config(link, prism2_config_check, NULL);
|
||||
if (last_ret) {
|
||||
ret = pcmcia_loop_config(link, prism2_config_check, NULL);
|
||||
if (ret) {
|
||||
if (!ignore_cis_vcc)
|
||||
printk(KERN_ERR "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
"ignore_cis_vcc=1 parameter.\n");
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Need to allocate net_device before requesting IRQ handler */
|
||||
dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
|
||||
&handle_to_dev(link));
|
||||
&link->dev);
|
||||
if (dev == NULL)
|
||||
goto failed;
|
||||
link->priv = dev;
|
||||
|
@ -666,13 +641,11 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
* irq structure is initialized.
|
||||
*/
|
||||
if (link->conf.Attributes & CONF_ENABLE_IRQ) {
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
|
||||
IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = prism2_interrupt;
|
||||
link->irq.Instance = dev;
|
||||
CS_CHECK(RequestIRQ,
|
||||
pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -680,8 +653,9 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
* the I/O windows and the interrupt mapping, and putting the
|
||||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
|
@ -714,9 +688,6 @@ static int prism2_config(struct pcmcia_device *link)
|
|||
}
|
||||
return ret;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
kfree(hw_priv);
|
||||
prism2_release((u_long)link);
|
||||
|
|
|
@ -591,7 +591,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
|
|||
|
||||
/* TODO: make firmware file configurable */
|
||||
ret = request_firmware(&fw, "libertas_cs_helper.fw",
|
||||
&handle_to_dev(card->p_dev));
|
||||
&card->p_dev->dev);
|
||||
if (ret) {
|
||||
lbs_pr_err("can't load helper firmware\n");
|
||||
ret = -ENODEV;
|
||||
|
@ -664,7 +664,7 @@ static int if_cs_prog_real(struct if_cs_card *card)
|
|||
|
||||
/* TODO: make firmware file configurable */
|
||||
ret = request_firmware(&fw, "libertas_cs.fw",
|
||||
&handle_to_dev(card->p_dev));
|
||||
&card->p_dev->dev);
|
||||
if (ret) {
|
||||
lbs_pr_err("can't load firmware\n");
|
||||
ret = -ENODEV;
|
||||
|
@ -794,18 +794,37 @@ static void if_cs_release(struct pcmcia_device *p_dev)
|
|||
* configure the card at this point -- we wait until we receive a card
|
||||
* insertion event.
|
||||
*/
|
||||
|
||||
static int if_cs_ioprobe(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
unsigned int vcc,
|
||||
void *priv_data)
|
||||
{
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
p_dev->io.BasePort1 = cfg->io.win[0].base;
|
||||
p_dev->io.NumPorts1 = cfg->io.win[0].len;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1)
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
|
||||
/* IO window settings */
|
||||
if (cfg->io.nwin != 1) {
|
||||
lbs_pr_err("wrong CIS (check number of IO windows)\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
return pcmcia_request_io(p_dev, &p_dev->io);
|
||||
}
|
||||
|
||||
static int if_cs_probe(struct pcmcia_device *p_dev)
|
||||
{
|
||||
int ret = -ENOMEM;
|
||||
unsigned int prod_id;
|
||||
struct lbs_private *priv;
|
||||
struct if_cs_card *card;
|
||||
/* CIS parsing */
|
||||
tuple_t tuple;
|
||||
cisparse_t parse;
|
||||
cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
|
||||
cistpl_io_t *io = &cfg->io;
|
||||
u_char buf[64];
|
||||
|
||||
lbs_deb_enter(LBS_DEB_CS);
|
||||
|
||||
|
@ -819,48 +838,15 @@ static int if_cs_probe(struct pcmcia_device *p_dev)
|
|||
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.Handler = NULL;
|
||||
p_dev->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;
|
||||
|
||||
p_dev->conf.Attributes = 0;
|
||||
p_dev->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
tuple.Attributes = 0;
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = sizeof(buf);
|
||||
tuple.TupleOffset = 0;
|
||||
|
||||
tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
|
||||
if ((ret = pcmcia_get_first_tuple(p_dev, &tuple)) != 0 ||
|
||||
(ret = pcmcia_get_tuple_data(p_dev, &tuple)) != 0 ||
|
||||
(ret = pcmcia_parse_tuple(&tuple, &parse)) != 0)
|
||||
{
|
||||
lbs_pr_err("error in pcmcia_get_first_tuple etc\n");
|
||||
if (pcmcia_loop_config(p_dev, if_cs_ioprobe, NULL)) {
|
||||
lbs_pr_err("error in pcmcia_loop_config\n");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
p_dev->conf.ConfigIndex = cfg->index;
|
||||
|
||||
/* Do we need to allocate an interrupt? */
|
||||
if (cfg->irq.IRQInfo1) {
|
||||
p_dev->conf.Attributes |= CONF_ENABLE_IRQ;
|
||||
}
|
||||
|
||||
/* IO window settings */
|
||||
if (cfg->io.nwin != 1) {
|
||||
lbs_pr_err("wrong CIS (check number of IO windows)\n");
|
||||
ret = -ENODEV;
|
||||
goto out1;
|
||||
}
|
||||
p_dev->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
|
||||
p_dev->io.BasePort1 = io->win[0].base;
|
||||
p_dev->io.NumPorts1 = io->win[0].len;
|
||||
|
||||
/* This reserves IO space but doesn't actually enable it */
|
||||
ret = pcmcia_request_io(p_dev, &p_dev->io);
|
||||
if (ret) {
|
||||
lbs_pr_err("error in pcmcia_request_io\n");
|
||||
goto out1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate an interrupt line. Note that this does not assign
|
||||
|
|
|
@ -109,7 +109,7 @@ orinoco_cs_probe(struct pcmcia_device *link)
|
|||
struct orinoco_private *priv;
|
||||
struct orinoco_pccard *card;
|
||||
|
||||
priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
|
||||
priv = alloc_orinocodev(sizeof(*card), &link->dev,
|
||||
orinoco_cs_hard_reset, NULL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
@ -120,10 +120,8 @@ orinoco_cs_probe(struct pcmcia_device *link)
|
|||
link->priv = priv;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = orinoco_interrupt;
|
||||
link->irq.Instance = priv;
|
||||
|
||||
/* General socket configuration defaults can go here. In this
|
||||
* client, we assume very little, and rely on the CIS for
|
||||
|
@ -160,12 +158,6 @@ static void orinoco_cs_detach(struct pcmcia_device *link)
|
|||
* device available to the system.
|
||||
*/
|
||||
|
||||
#define CS_CHECK(fn, ret) do { \
|
||||
last_fn = (fn); \
|
||||
if ((last_ret = (ret)) != 0) \
|
||||
goto cs_failed; \
|
||||
} while (0)
|
||||
|
||||
static int orinoco_cs_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
|
@ -240,7 +232,7 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
struct orinoco_private *priv = link->priv;
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
int last_fn, last_ret;
|
||||
int ret;
|
||||
void __iomem *mem;
|
||||
|
||||
/*
|
||||
|
@ -257,13 +249,12 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
|
||||
if (last_ret) {
|
||||
ret = pcmcia_loop_config(link, orinoco_cs_config_check, NULL);
|
||||
if (ret) {
|
||||
if (!ignore_cis_vcc)
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
"ignore_cis_vcc=1 parameter.\n");
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -272,14 +263,16 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
* a handler to the interrupt, unless the 'Handler' member of
|
||||
* the irq structure is initialized.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
* called. */
|
||||
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
if (!mem)
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
|
||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||
|
||||
|
@ -288,8 +281,9 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
* the I/O windows and the interrupt mapping, and putting the
|
||||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
card->node.major = card->node.minor = 0;
|
||||
|
@ -315,9 +309,6 @@ orinoco_cs_config(struct pcmcia_device *link)
|
|||
* net_device has been registered */
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
orinoco_cs_release(link);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -73,9 +73,6 @@ static void spectrum_cs_release(struct pcmcia_device *link);
|
|||
#define HCR_MEM16 0x10 /* memory width bit, should be preserved */
|
||||
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
/*
|
||||
* Reset the card using configuration registers COR and CCSR.
|
||||
* If IDLE is 1, stop the firmware, so that it can be safely rewritten.
|
||||
|
@ -83,7 +80,7 @@ static void spectrum_cs_release(struct pcmcia_device *link);
|
|||
static int
|
||||
spectrum_reset(struct pcmcia_device *link, int idle)
|
||||
{
|
||||
int last_ret, last_fn;
|
||||
int ret;
|
||||
conf_reg_t reg;
|
||||
u_int save_cor;
|
||||
|
||||
|
@ -95,23 +92,26 @@ spectrum_reset(struct pcmcia_device *link, int idle)
|
|||
reg.Function = 0;
|
||||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_COR;
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (ret)
|
||||
goto failed;
|
||||
save_cor = reg.Value;
|
||||
|
||||
/* Soft-Reset card */
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = (save_cor | COR_SOFT_RESET);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (ret)
|
||||
goto failed;
|
||||
udelay(1000);
|
||||
|
||||
/* Read CCSR */
|
||||
reg.Action = CS_READ;
|
||||
reg.Offset = CISREG_CCSR;
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/*
|
||||
* Start or stop the firmware. Memory width bit should be
|
||||
|
@ -120,21 +120,22 @@ spectrum_reset(struct pcmcia_device *link, int idle)
|
|||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_CCSR;
|
||||
reg.Value = (idle ? HCR_IDLE : HCR_RUN) | (reg.Value & HCR_MEM16);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (ret)
|
||||
goto failed;
|
||||
udelay(1000);
|
||||
|
||||
/* Restore original COR configuration index */
|
||||
reg.Action = CS_WRITE;
|
||||
reg.Offset = CISREG_COR;
|
||||
reg.Value = (save_cor & ~COR_SOFT_RESET);
|
||||
CS_CHECK(AccessConfigurationRegister,
|
||||
pcmcia_access_configuration_register(link, ®));
|
||||
ret = pcmcia_access_configuration_register(link, ®);
|
||||
if (ret)
|
||||
goto failed;
|
||||
udelay(1000);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
@ -181,7 +182,7 @@ spectrum_cs_probe(struct pcmcia_device *link)
|
|||
struct orinoco_private *priv;
|
||||
struct orinoco_pccard *card;
|
||||
|
||||
priv = alloc_orinocodev(sizeof(*card), &handle_to_dev(link),
|
||||
priv = alloc_orinocodev(sizeof(*card), &link->dev,
|
||||
spectrum_cs_hard_reset,
|
||||
spectrum_cs_stop_firmware);
|
||||
if (!priv)
|
||||
|
@ -193,10 +194,8 @@ spectrum_cs_probe(struct pcmcia_device *link)
|
|||
link->priv = priv;
|
||||
|
||||
/* Interrupt setup */
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.Handler = orinoco_interrupt;
|
||||
link->irq.Instance = priv;
|
||||
|
||||
/* General socket configuration defaults can go here. In this
|
||||
* client, we assume very little, and rely on the CIS for
|
||||
|
@ -307,7 +306,7 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
struct orinoco_private *priv = link->priv;
|
||||
struct orinoco_pccard *card = priv->card;
|
||||
hermes_t *hw = &priv->hw;
|
||||
int last_fn, last_ret;
|
||||
int ret;
|
||||
void __iomem *mem;
|
||||
|
||||
/*
|
||||
|
@ -324,13 +323,12 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
* and most client drivers will only use the CIS to fill in
|
||||
* implementation-defined details.
|
||||
*/
|
||||
last_ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
|
||||
if (last_ret) {
|
||||
ret = pcmcia_loop_config(link, spectrum_cs_config_check, NULL);
|
||||
if (ret) {
|
||||
if (!ignore_cis_vcc)
|
||||
printk(KERN_ERR PFX "GetNextTuple(): No matching "
|
||||
"CIS configuration. Maybe you need the "
|
||||
"ignore_cis_vcc=1 parameter.\n");
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@ -339,14 +337,16 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
* a handler to the interrupt, unless the 'Handler' member of
|
||||
* the irq structure is initialized.
|
||||
*/
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* We initialize the hermes structure before completing PCMCIA
|
||||
* configuration just in case the interrupt handler gets
|
||||
* called. */
|
||||
mem = ioport_map(link->io.BasePort1, link->io.NumPorts1);
|
||||
if (!mem)
|
||||
goto cs_failed;
|
||||
goto failed;
|
||||
|
||||
hermes_struct_init(hw, mem, HERMES_16BIT_REGSPACING);
|
||||
|
||||
|
@ -355,8 +355,9 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
* the I/O windows and the interrupt mapping, and putting the
|
||||
* card and host interface into "Memory and IO" mode.
|
||||
*/
|
||||
CS_CHECK(RequestConfiguration,
|
||||
pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* Ok, we have the configuration, prepare to register the netdev */
|
||||
card->node.major = card->node.minor = 0;
|
||||
|
@ -386,9 +387,6 @@ spectrum_cs_config(struct pcmcia_device *link)
|
|||
* net_device has been registered */
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
|
||||
failed:
|
||||
spectrum_cs_release(link);
|
||||
return -ENODEV;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -67,23 +67,7 @@
|
|||
/* For rough constant delay */
|
||||
#define WL3501_NOPLOOP(n) { int x = 0; while (x++ < n) slow_down_io(); }
|
||||
|
||||
/*
|
||||
* All the PCMCIA modules use PCMCIA_DEBUG to control debugging. If you do not
|
||||
* define PCMCIA_DEBUG at all, all the debug code will be left out. If you
|
||||
* compile with PCMCIA_DEBUG=0, the debug code will be present but disabled --
|
||||
* but it can then be enabled for specific modules at load time with a
|
||||
* 'pc_debug=#' option to insmod.
|
||||
*/
|
||||
#define PCMCIA_DEBUG 0
|
||||
#ifdef PCMCIA_DEBUG
|
||||
static int pc_debug = PCMCIA_DEBUG;
|
||||
module_param(pc_debug, int, 0);
|
||||
#define dprintk(n, format, args...) \
|
||||
{ if (pc_debug > (n)) \
|
||||
printk(KERN_INFO "%s: " format "\n", __func__ , ##args); }
|
||||
#else
|
||||
#define dprintk(n, format, args...)
|
||||
#endif
|
||||
|
||||
|
||||
#define wl3501_outb(a, b) { outb(a, b); slow_down_io(); }
|
||||
#define wl3501_outb_p(a, b) { outb_p(a, b); slow_down_io(); }
|
||||
|
@ -684,10 +668,10 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
|
|||
int matchflag = 0;
|
||||
struct wl3501_scan_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
if (sig.status == WL3501_STATUS_SUCCESS) {
|
||||
dprintk(3, "success");
|
||||
pr_debug("success");
|
||||
if ((this->net_type == IW_MODE_INFRA &&
|
||||
(sig.cap_info & WL3501_MGMT_CAPABILITY_ESS)) ||
|
||||
(this->net_type == IW_MODE_ADHOC &&
|
||||
|
@ -722,7 +706,7 @@ static void wl3501_mgmt_scan_confirm(struct wl3501_card *this, u16 addr)
|
|||
}
|
||||
}
|
||||
} else if (sig.status == WL3501_STATUS_TIMEOUT) {
|
||||
dprintk(3, "timeout");
|
||||
pr_debug("timeout");
|
||||
this->join_sta_bss = 0;
|
||||
for (i = this->join_sta_bss; i < this->bss_cnt; i++)
|
||||
if (!wl3501_mgmt_join(this, i))
|
||||
|
@ -879,7 +863,7 @@ static int wl3501_mgmt_auth(struct wl3501_card *this)
|
|||
.timeout = 1000,
|
||||
};
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
||||
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
||||
}
|
||||
|
@ -893,7 +877,7 @@ static int wl3501_mgmt_association(struct wl3501_card *this)
|
|||
.cap_info = this->cap_info,
|
||||
};
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
memcpy(sig.mac_addr, this->bssid, ETH_ALEN);
|
||||
return wl3501_esbq_exec(this, &sig, sizeof(sig));
|
||||
}
|
||||
|
@ -903,7 +887,7 @@ static void wl3501_mgmt_join_confirm(struct net_device *dev, u16 addr)
|
|||
struct wl3501_card *this = netdev_priv(dev);
|
||||
struct wl3501_join_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
if (sig.status == WL3501_STATUS_SUCCESS) {
|
||||
if (this->net_type == IW_MODE_INFRA) {
|
||||
|
@ -962,7 +946,7 @@ static inline void wl3501_md_confirm_interrupt(struct net_device *dev,
|
|||
{
|
||||
struct wl3501_md_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
wl3501_free_tx_buffer(this, sig.data);
|
||||
if (netif_queue_stopped(dev))
|
||||
|
@ -1017,7 +1001,7 @@ static inline void wl3501_md_ind_interrupt(struct net_device *dev,
|
|||
static inline void wl3501_get_confirm_interrupt(struct wl3501_card *this,
|
||||
u16 addr, void *sig, int size)
|
||||
{
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &this->sig_get_confirm,
|
||||
sizeof(this->sig_get_confirm));
|
||||
wake_up(&this->wait);
|
||||
|
@ -1029,7 +1013,7 @@ static inline void wl3501_start_confirm_interrupt(struct net_device *dev,
|
|||
{
|
||||
struct wl3501_start_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||
netif_wake_queue(dev);
|
||||
|
@ -1041,7 +1025,7 @@ static inline void wl3501_assoc_confirm_interrupt(struct net_device *dev,
|
|||
struct wl3501_card *this = netdev_priv(dev);
|
||||
struct wl3501_assoc_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
|
||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||
|
@ -1053,7 +1037,7 @@ static inline void wl3501_auth_confirm_interrupt(struct wl3501_card *this,
|
|||
{
|
||||
struct wl3501_auth_confirm sig;
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
wl3501_get_from_wla(this, addr, &sig, sizeof(sig));
|
||||
|
||||
if (sig.status == WL3501_STATUS_SUCCESS)
|
||||
|
@ -1069,7 +1053,7 @@ static inline void wl3501_rx_interrupt(struct net_device *dev)
|
|||
u8 sig_id;
|
||||
struct wl3501_card *this = netdev_priv(dev);
|
||||
|
||||
dprintk(3, "entry");
|
||||
pr_debug("entry");
|
||||
loop:
|
||||
morepkts = 0;
|
||||
if (!wl3501_esbq_confirm(this))
|
||||
|
@ -1302,7 +1286,7 @@ static int wl3501_reset(struct net_device *dev)
|
|||
wl3501_ack_interrupt(this);
|
||||
wl3501_unblock_interrupt(this);
|
||||
wl3501_mgmt_scan(this, 100);
|
||||
dprintk(1, "%s: device reset", dev->name);
|
||||
pr_debug("%s: device reset", dev->name);
|
||||
rc = 0;
|
||||
out:
|
||||
return rc;
|
||||
|
@ -1376,7 +1360,7 @@ static int wl3501_open(struct net_device *dev)
|
|||
link->open++;
|
||||
|
||||
/* Initial WL3501 firmware */
|
||||
dprintk(1, "%s: Initialize WL3501 firmware...", dev->name);
|
||||
pr_debug("%s: Initialize WL3501 firmware...", dev->name);
|
||||
if (wl3501_init_firmware(this))
|
||||
goto fail;
|
||||
/* Initial device variables */
|
||||
|
@ -1388,7 +1372,7 @@ static int wl3501_open(struct net_device *dev)
|
|||
wl3501_unblock_interrupt(this);
|
||||
wl3501_mgmt_scan(this, 100);
|
||||
rc = 0;
|
||||
dprintk(1, "%s: WL3501 opened", dev->name);
|
||||
pr_debug("%s: WL3501 opened", dev->name);
|
||||
printk(KERN_INFO "%s: Card Name: %s\n"
|
||||
"%s: Firmware Date: %s\n",
|
||||
dev->name, this->card_name,
|
||||
|
@ -1914,8 +1898,7 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
|
|||
p_dev->io.IOAddrLines = 5;
|
||||
|
||||
/* Interrupt setup */
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING | IRQ_HANDLE_PRESENT;
|
||||
p_dev->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
p_dev->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
p_dev->irq.Handler = wl3501_interrupt;
|
||||
|
||||
/* General socket configuration */
|
||||
|
@ -1938,16 +1921,13 @@ static int wl3501_probe(struct pcmcia_device *p_dev)
|
|||
dev->wireless_handlers = &wl3501_handler_def;
|
||||
SET_ETHTOOL_OPS(dev, &ops);
|
||||
netif_stop_queue(dev);
|
||||
p_dev->priv = p_dev->irq.Instance = dev;
|
||||
p_dev->priv = dev;
|
||||
|
||||
return wl3501_config(p_dev);
|
||||
out_link:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
/**
|
||||
* wl3501_config - configure the PCMCIA socket and make eth device available
|
||||
* @link - FILL_IN
|
||||
|
@ -1959,7 +1939,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
|||
static int wl3501_config(struct pcmcia_device *link)
|
||||
{
|
||||
struct net_device *dev = link->priv;
|
||||
int i = 0, j, last_fn, last_ret;
|
||||
int i = 0, j, ret;
|
||||
struct wl3501_card *this;
|
||||
|
||||
/* Try allocating IO ports. This tries a few fixed addresses. If you
|
||||
|
@ -1975,24 +1955,26 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||
if (i == 0)
|
||||
break;
|
||||
}
|
||||
if (i != 0) {
|
||||
cs_error(link, RequestIO, i);
|
||||
if (i != 0)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
/* Now allocate an interrupt line. Note that this does not actually
|
||||
* assign a handler to the interrupt. */
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
/* This actually configures the PCMCIA socket -- setting up the I/O
|
||||
* windows and the interrupt mapping. */
|
||||
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
dev->irq = link->irq.AssignedIRQ;
|
||||
dev->base_addr = link->io.BasePort1;
|
||||
SET_NETDEV_DEV(dev, &handle_to_dev(link));
|
||||
SET_NETDEV_DEV(dev, &link->dev);
|
||||
if (register_netdev(dev)) {
|
||||
printk(KERN_NOTICE "wl3501_cs: register_netdev() failed\n");
|
||||
goto failed;
|
||||
|
@ -2041,8 +2023,6 @@ static int wl3501_config(struct pcmcia_device *link)
|
|||
netif_start_queue(dev);
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
wl3501_release(link);
|
||||
return -ENODEV;
|
||||
|
|
|
@ -67,14 +67,6 @@ MODULE_LICENSE("Dual MPL/GPL");
|
|||
|
||||
INT_MODULE_PARM(epp_mode, 1);
|
||||
|
||||
#ifdef PCMCIA_DEBUG
|
||||
INT_MODULE_PARM(pc_debug, PCMCIA_DEBUG);
|
||||
#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
|
||||
static char *version =
|
||||
"parport_cs.c 1.29 2002/10/11 06:57:41 (David Hinds)";
|
||||
#else
|
||||
#define DEBUG(n, args...)
|
||||
#endif
|
||||
|
||||
/*====================================================================*/
|
||||
|
||||
|
@ -103,7 +95,7 @@ static int parport_probe(struct pcmcia_device *link)
|
|||
{
|
||||
parport_info_t *info;
|
||||
|
||||
DEBUG(0, "parport_attach()\n");
|
||||
dev_dbg(&link->dev, "parport_attach()\n");
|
||||
|
||||
/* Create new parport device */
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
|
@ -114,7 +106,6 @@ static int parport_probe(struct pcmcia_device *link)
|
|||
link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
|
||||
link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
|
||||
link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
|
||||
link->irq.IRQInfo1 = IRQ_LEVEL_ID;
|
||||
link->conf.Attributes = CONF_ENABLE_IRQ;
|
||||
link->conf.IntType = INT_MEMORY_AND_IO;
|
||||
|
||||
|
@ -132,7 +123,7 @@ static int parport_probe(struct pcmcia_device *link)
|
|||
|
||||
static void parport_detach(struct pcmcia_device *link)
|
||||
{
|
||||
DEBUG(0, "parport_detach(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "parport_detach\n");
|
||||
|
||||
parport_cs_release(link);
|
||||
|
||||
|
@ -147,9 +138,6 @@ static void parport_detach(struct pcmcia_device *link)
|
|||
|
||||
======================================================================*/
|
||||
|
||||
#define CS_CHECK(fn, ret) \
|
||||
do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
|
||||
|
||||
static int parport_config_check(struct pcmcia_device *p_dev,
|
||||
cistpl_cftable_entry_t *cfg,
|
||||
cistpl_cftable_entry_t *dflt,
|
||||
|
@ -178,18 +166,20 @@ static int parport_config(struct pcmcia_device *link)
|
|||
{
|
||||
parport_info_t *info = link->priv;
|
||||
struct parport *p;
|
||||
int last_ret, last_fn;
|
||||
int ret;
|
||||
|
||||
DEBUG(0, "parport_config(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "parport_config\n");
|
||||
|
||||
last_ret = pcmcia_loop_config(link, parport_config_check, NULL);
|
||||
if (last_ret) {
|
||||
cs_error(link, RequestIO, last_ret);
|
||||
ret = pcmcia_loop_config(link, parport_config_check, NULL);
|
||||
if (ret)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
|
||||
CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
|
||||
ret = pcmcia_request_irq(link, &link->irq);
|
||||
if (ret)
|
||||
goto failed;
|
||||
ret = pcmcia_request_configuration(link, &link->conf);
|
||||
if (ret)
|
||||
goto failed;
|
||||
|
||||
p = parport_pc_probe_port(link->io.BasePort1, link->io.BasePort2,
|
||||
link->irq.AssignedIRQ, PARPORT_DMA_NONE,
|
||||
|
@ -213,8 +203,6 @@ static int parport_config(struct pcmcia_device *link)
|
|||
|
||||
return 0;
|
||||
|
||||
cs_failed:
|
||||
cs_error(link, last_fn, last_ret);
|
||||
failed:
|
||||
parport_cs_release(link);
|
||||
return -ENODEV;
|
||||
|
@ -232,7 +220,7 @@ static void parport_cs_release(struct pcmcia_device *link)
|
|||
{
|
||||
parport_info_t *info = link->priv;
|
||||
|
||||
DEBUG(0, "parport_release(0x%p)\n", link);
|
||||
dev_dbg(&link->dev, "parport_release\n");
|
||||
|
||||
if (info->ndev) {
|
||||
struct parport *p = info->port;
|
||||
|
|
|
@ -645,9 +645,12 @@ void __init detect_intel_iommu(void)
|
|||
"x2apic and Intr-remapping.\n");
|
||||
#endif
|
||||
#ifdef CONFIG_DMAR
|
||||
if (ret && !no_iommu && !iommu_detected && !swiotlb &&
|
||||
!dmar_disabled)
|
||||
if (ret && !no_iommu && !iommu_detected && !dmar_disabled)
|
||||
iommu_detected = 1;
|
||||
#endif
|
||||
#ifdef CONFIG_X86
|
||||
if (ret)
|
||||
x86_init.iommu.iommu_init = intel_iommu_init;
|
||||
#endif
|
||||
}
|
||||
early_acpi_os_unmap_memory(dmar_tbl, dmar_tbl_size);
|
||||
|
|
|
@ -3266,7 +3266,7 @@ int __init intel_iommu_init(void)
|
|||
* Check the need for DMA-remapping initialization now.
|
||||
* Above initialization will also be used by Interrupt-remapping.
|
||||
*/
|
||||
if (no_iommu || swiotlb || dmar_disabled)
|
||||
if (no_iommu || dmar_disabled)
|
||||
return -ENODEV;
|
||||
|
||||
iommu_init_mempool();
|
||||
|
@ -3287,7 +3287,9 @@ int __init intel_iommu_init(void)
|
|||
"PCI-DMA: Intel(R) Virtualization Technology for Directed I/O\n");
|
||||
|
||||
init_timer(&unmap_timer);
|
||||
force_iommu = 1;
|
||||
#ifdef CONFIG_SWIOTLB
|
||||
swiotlb = 0;
|
||||
#endif
|
||||
dma_ops = &intel_dma_ops;
|
||||
|
||||
init_iommu_sysfs();
|
||||
|
|
|
@ -17,24 +17,6 @@ menuconfig PCCARD
|
|||
|
||||
if PCCARD
|
||||
|
||||
config PCMCIA_DEBUG
|
||||
bool "Enable PCCARD debugging"
|
||||
help
|
||||
Say Y here to enable PCMCIA subsystem debugging. You
|
||||
will need to choose the debugging level either via the
|
||||
kernel command line, or module options depending whether
|
||||
you build the PCMCIA as modules.
|
||||
|
||||
The kernel command line options are:
|
||||
pcmcia_core.pc_debug=N
|
||||
pcmcia.pc_debug=N
|
||||
sa11xx_core.pc_debug=N
|
||||
|
||||
The module option is called pc_debug=N
|
||||
|
||||
In all the above examples, N is the debugging verbosity
|
||||
level.
|
||||
|
||||
config PCMCIA
|
||||
tristate "16-bit PCMCIA support"
|
||||
select CRC32
|
||||
|
@ -196,9 +178,13 @@ config PCMCIA_BCM63XX
|
|||
tristate "bcm63xx pcmcia support"
|
||||
depends on BCM63XX && PCMCIA
|
||||
|
||||
config PCMCIA_SOC_COMMON
|
||||
bool
|
||||
|
||||
config PCMCIA_SA1100
|
||||
tristate "SA1100 support"
|
||||
depends on ARM && ARCH_SA1100 && PCMCIA
|
||||
select PCMCIA_SOC_COMMON
|
||||
help
|
||||
Say Y here to include support for SA11x0-based PCMCIA or CF
|
||||
sockets, found on HP iPAQs, Yopy, and other StrongARM(R)/
|
||||
|
@ -209,6 +195,7 @@ config PCMCIA_SA1100
|
|||
config PCMCIA_SA1111
|
||||
tristate "SA1111 support"
|
||||
depends on ARM && ARCH_SA1100 && SA1111 && PCMCIA
|
||||
select PCMCIA_SOC_COMMON
|
||||
help
|
||||
Say Y here to include support for SA1111-based PCMCIA or CF
|
||||
sockets, found on the Jornada 720, Graphicsmaster and other
|
||||
|
@ -222,9 +209,28 @@ config PCMCIA_PXA2XX
|
|||
depends on (ARCH_LUBBOCK || MACH_MAINSTONE || PXA_SHARPSL \
|
||||
|| MACH_ARMCORE || ARCH_PXA_PALM || TRIZEPS_PCMCIA \
|
||||
|| ARCH_VIPER || ARCH_PXA_ESERIES || MACH_STARGATE2)
|
||||
select PCMCIA_SOC_COMMON
|
||||
help
|
||||
Say Y here to include support for the PXA2xx PCMCIA controller
|
||||
|
||||
config PCMCIA_DEBUG
|
||||
bool "Enable debugging"
|
||||
depends on (PCMCIA_SA1111 || PCMCIA_SA1100 || PCMCIA_PXA2XX)
|
||||
help
|
||||
Say Y here to enable debugging for the SoC PCMCIA layer.
|
||||
You will need to choose the debugging level either via the
|
||||
kernel command line, or module options depending whether
|
||||
you build the drivers as modules.
|
||||
|
||||
The kernel command line options are:
|
||||
sa11xx_core.pc_debug=N
|
||||
pxa2xx_core.pc_debug=N
|
||||
|
||||
The module option is called pc_debug=N
|
||||
|
||||
In all the above examples, N is the debugging verbosity
|
||||
level.
|
||||
|
||||
config PCMCIA_PROBE
|
||||
bool
|
||||
default y if ISA && !ARCH_SA1100 && !ARCH_CLPS711X && !PARISC
|
||||
|
|
|
@ -22,8 +22,9 @@ obj-$(CONFIG_I82365) += i82365.o
|
|||
obj-$(CONFIG_I82092) += i82092.o
|
||||
obj-$(CONFIG_TCIC) += tcic.o
|
||||
obj-$(CONFIG_PCMCIA_M8XX) += m8xx_pcmcia.o
|
||||
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_core.o sa1100_cs.o
|
||||
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_core.o sa1111_cs.o
|
||||
obj-$(CONFIG_PCMCIA_SOC_COMMON) += soc_common.o
|
||||
obj-$(CONFIG_PCMCIA_SA1100) += sa11xx_base.o sa1100_cs.o
|
||||
obj-$(CONFIG_PCMCIA_SA1111) += sa11xx_base.o sa1111_cs.o
|
||||
obj-$(CONFIG_M32R_PCC) += m32r_pcc.o
|
||||
obj-$(CONFIG_M32R_CFC) += m32r_cfc.o
|
||||
obj-$(CONFIG_PCMCIA_AU1X00) += au1x00_ss.o
|
||||
|
@ -35,9 +36,6 @@ obj-$(CONFIG_BFIN_CFPCMCIA) += bfin_cf_pcmcia.o
|
|||
obj-$(CONFIG_AT91_CF) += at91_cf.o
|
||||
obj-$(CONFIG_ELECTRA_CF) += electra_cf.o
|
||||
|
||||
sa11xx_core-y += soc_common.o sa11xx_base.o
|
||||
pxa2xx_core-y += soc_common.o pxa2xx_base.o
|
||||
|
||||
au1x00_ss-y += au1000_generic.o
|
||||
au1x00_ss-$(CONFIG_MIPS_PB1000) += au1000_pb1x00.o
|
||||
au1x00_ss-$(CONFIG_MIPS_PB1100) += au1000_pb1x00.o
|
||||
|
@ -77,4 +75,4 @@ pxa2xx-obj-$(CONFIG_MACH_PALMLD) += pxa2xx_palmld.o
|
|||
pxa2xx-obj-$(CONFIG_MACH_E740) += pxa2xx_e740.o
|
||||
pxa2xx-obj-$(CONFIG_MACH_STARGATE2) += pxa2xx_stargate2.o
|
||||
|
||||
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_core.o $(pxa2xx-obj-y)
|
||||
obj-$(CONFIG_PCMCIA_PXA2XX) += pxa2xx_base.o $(pxa2xx-obj-y)
|
||||
|
|
|
@ -91,7 +91,7 @@ static u_int xlate_rom_addr(void __iomem *b, u_int addr)
|
|||
static void cb_release_cis_mem(struct pcmcia_socket * s)
|
||||
{
|
||||
if (s->cb_cis_virt) {
|
||||
cs_dbg(s, 1, "cb_release_cis_mem()\n");
|
||||
dev_dbg(&s->dev, "cb_release_cis_mem()\n");
|
||||
iounmap(s->cb_cis_virt);
|
||||
s->cb_cis_virt = NULL;
|
||||
s->cb_cis_res = NULL;
|
||||
|
@ -132,7 +132,7 @@ int read_cb_mem(struct pcmcia_socket * s, int space, u_int addr, u_int len, void
|
|||
struct pci_dev *dev;
|
||||
struct resource *res;
|
||||
|
||||
cs_dbg(s, 3, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
|
||||
dev_dbg(&s->dev, "read_cb_mem(%d, %#x, %u)\n", space, addr, len);
|
||||
|
||||
dev = pci_get_slot(s->cb_dev->subordinate, 0);
|
||||
if (!dev)
|
||||
|
|
|
@ -30,16 +30,6 @@
|
|||
#ifndef _LINUX_CIRRUS_H
|
||||
#define _LINUX_CIRRUS_H
|
||||
|
||||
#ifndef PCI_VENDOR_ID_CIRRUS
|
||||
#define PCI_VENDOR_ID_CIRRUS 0x1013
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_CIRRUS_6729
|
||||
#define PCI_DEVICE_ID_CIRRUS_6729 0x1100
|
||||
#endif
|
||||
#ifndef PCI_DEVICE_ID_CIRRUS_6832
|
||||
#define PCI_DEVICE_ID_CIRRUS_6832 0x1110
|
||||
#endif
|
||||
|
||||
#define PD67_MISC_CTL_1 0x16 /* Misc control 1 */
|
||||
#define PD67_FIFO_CTL 0x17 /* FIFO control */
|
||||
#define PD67_MISC_CTL_2 0x1E /* Misc control 2 */
|
||||
|
|
|
@ -138,7 +138,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
void __iomem *sys, *end;
|
||||
unsigned char *buf = ptr;
|
||||
|
||||
cs_dbg(s, 3, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||
dev_dbg(&s->dev, "pcmcia_read_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||
|
||||
if (attr & IS_INDIRECT) {
|
||||
/* Indirect accesses use a bunch of special registers at fixed
|
||||
|
@ -190,7 +190,7 @@ int pcmcia_read_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
addr = 0;
|
||||
}
|
||||
}
|
||||
cs_dbg(s, 3, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
||||
dev_dbg(&s->dev, " %#2.2x %#2.2x %#2.2x %#2.2x ...\n",
|
||||
*(u_char *)(ptr+0), *(u_char *)(ptr+1),
|
||||
*(u_char *)(ptr+2), *(u_char *)(ptr+3));
|
||||
return 0;
|
||||
|
@ -204,7 +204,7 @@ void pcmcia_write_cis_mem(struct pcmcia_socket *s, int attr, u_int addr,
|
|||
void __iomem *sys, *end;
|
||||
unsigned char *buf = ptr;
|
||||
|
||||
cs_dbg(s, 3, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||
dev_dbg(&s->dev, "pcmcia_write_cis_mem(%d, %#x, %u)\n", attr, addr, len);
|
||||
|
||||
if (attr & IS_INDIRECT) {
|
||||
/* Indirect accesses use a bunch of special registers at fixed
|
||||
|
@ -584,7 +584,7 @@ int pccard_get_next_tuple(struct pcmcia_socket *s, unsigned int function, tuple_
|
|||
ofs += link[1] + 2;
|
||||
}
|
||||
if (i == MAX_TUPLES) {
|
||||
cs_dbg(s, 1, "cs: overrun in pcmcia_get_next_tuple\n");
|
||||
dev_dbg(&s->dev, "cs: overrun in pcmcia_get_next_tuple\n");
|
||||
return -ENOSPC;
|
||||
}
|
||||
|
||||
|
@ -1440,7 +1440,7 @@ int pcmcia_parse_tuple(tuple_t *tuple, cisparse_t *parse)
|
|||
break;
|
||||
}
|
||||
if (ret)
|
||||
__cs_dbg(0, "parse_tuple failed %d\n", ret);
|
||||
pr_debug("parse_tuple failed %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pcmcia_parse_tuple);
|
||||
|
@ -1482,6 +1482,67 @@ done:
|
|||
}
|
||||
EXPORT_SYMBOL(pccard_read_tuple);
|
||||
|
||||
|
||||
/**
|
||||
* pccard_loop_tuple() - loop over tuples in the CIS
|
||||
* @s: the struct pcmcia_socket where the card is inserted
|
||||
* @function: the device function we loop for
|
||||
* @code: which CIS code shall we look for?
|
||||
* @parse: buffer where the tuple shall be parsed (or NULL, if no parse)
|
||||
* @priv_data: private data to be passed to the loop_tuple function.
|
||||
* @loop_tuple: function to call for each CIS entry of type @function. IT
|
||||
* gets passed the raw tuple, the paresed tuple (if @parse is
|
||||
* set) and @priv_data.
|
||||
*
|
||||
* pccard_loop_tuple() loops over all CIS entries of type @function, and
|
||||
* calls the @loop_tuple function for each entry. If the call to @loop_tuple
|
||||
* returns 0, the loop exits. Returns 0 on success or errorcode otherwise.
|
||||
*/
|
||||
int pccard_loop_tuple(struct pcmcia_socket *s, unsigned int function,
|
||||
cisdata_t code, cisparse_t *parse, void *priv_data,
|
||||
int (*loop_tuple) (tuple_t *tuple,
|
||||
cisparse_t *parse,
|
||||
void *priv_data))
|
||||
{
|
||||
tuple_t tuple;
|
||||
cisdata_t *buf;
|
||||
int ret;
|
||||
|
||||
buf = kzalloc(256, GFP_KERNEL);
|
||||
if (buf == NULL) {
|
||||
dev_printk(KERN_WARNING, &s->dev, "no memory to read tuple\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
tuple.TupleData = buf;
|
||||
tuple.TupleDataMax = 255;
|
||||
tuple.TupleOffset = 0;
|
||||
tuple.DesiredTuple = code;
|
||||
tuple.Attributes = 0;
|
||||
|
||||
ret = pccard_get_first_tuple(s, function, &tuple);
|
||||
while (!ret) {
|
||||
if (pccard_get_tuple_data(s, &tuple))
|
||||
goto next_entry;
|
||||
|
||||
if (parse)
|
||||
if (pcmcia_parse_tuple(&tuple, parse))
|
||||
goto next_entry;
|
||||
|
||||
ret = loop_tuple(&tuple, parse, priv_data);
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
next_entry:
|
||||
ret = pccard_get_next_tuple(s, function, &tuple);
|
||||
}
|
||||
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(pccard_loop_tuple);
|
||||
|
||||
|
||||
/*======================================================================
|
||||
|
||||
This tries to determine if a card has a sensible CIS. It returns
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue