diff options
308 files changed, 9981 insertions, 5014 deletions
@@ -2423,8 +2423,7 @@ S: Toronto, Ontario | |||
2423 | S: Canada | 2423 | S: Canada |
2424 | 2424 | ||
2425 | N: Zwane Mwaikambo | 2425 | N: Zwane Mwaikambo |
2426 | E: zwane@linuxpower.ca | 2426 | E: zwane@arm.linux.org.uk |
2427 | W: http://function.linuxpower.ca | ||
2428 | D: Various driver hacking | 2427 | D: Various driver hacking |
2429 | D: Lowlevel x86 kernel hacking | 2428 | D: Lowlevel x86 kernel hacking |
2430 | D: General debugging | 2429 | D: General debugging |
diff --git a/Documentation/networking/phy.txt b/Documentation/networking/phy.txt new file mode 100644 index 000000000000..29ccae409031 --- /dev/null +++ b/Documentation/networking/phy.txt | |||
@@ -0,0 +1,288 @@ | |||
1 | |||
2 | ------- | ||
3 | PHY Abstraction Layer | ||
4 | (Updated 2005-07-21) | ||
5 | |||
6 | Purpose | ||
7 | |||
8 | Most network devices consist of set of registers which provide an interface | ||
9 | to a MAC layer, which communicates with the physical connection through a | ||
10 | PHY. The PHY concerns itself with negotiating link parameters with the link | ||
11 | partner on the other side of the network connection (typically, an ethernet | ||
12 | cable), and provides a register interface to allow drivers to determine what | ||
13 | settings were chosen, and to configure what settings are allowed. | ||
14 | |||
15 | While these devices are distinct from the network devices, and conform to a | ||
16 | standard layout for the registers, it has been common practice to integrate | ||
17 | the PHY management code with the network driver. This has resulted in large | ||
18 | amounts of redundant code. Also, on embedded systems with multiple (and | ||
19 | sometimes quite different) ethernet controllers connected to the same | ||
20 | management bus, it is difficult to ensure safe use of the bus. | ||
21 | |||
22 | Since the PHYs are devices, and the management busses through which they are | ||
23 | accessed are, in fact, busses, the PHY Abstraction Layer treats them as such. | ||
24 | In doing so, it has these goals: | ||
25 | |||
26 | 1) Increase code-reuse | ||
27 | 2) Increase overall code-maintainability | ||
28 | 3) Speed development time for new network drivers, and for new systems | ||
29 | |||
30 | Basically, this layer is meant to provide an interface to PHY devices which | ||
31 | allows network driver writers to write as little code as possible, while | ||
32 | still providing a full feature set. | ||
33 | |||
34 | The MDIO bus | ||
35 | |||
36 | Most network devices are connected to a PHY by means of a management bus. | ||
37 | Different devices use different busses (though some share common interfaces). | ||
38 | In order to take advantage of the PAL, each bus interface needs to be | ||
39 | registered as a distinct device. | ||
40 | |||
41 | 1) read and write functions must be implemented. Their prototypes are: | ||
42 | |||
43 | int write(struct mii_bus *bus, int mii_id, int regnum, u16 value); | ||
44 | int read(struct mii_bus *bus, int mii_id, int regnum); | ||
45 | |||
46 | mii_id is the address on the bus for the PHY, and regnum is the register | ||
47 | number. These functions are guaranteed not to be called from interrupt | ||
48 | time, so it is safe for them to block, waiting for an interrupt to signal | ||
49 | the operation is complete | ||
50 | |||
51 | 2) A reset function is necessary. This is used to return the bus to an | ||
52 | initialized state. | ||
53 | |||
54 | 3) A probe function is needed. This function should set up anything the bus | ||
55 | driver needs, setup the mii_bus structure, and register with the PAL using | ||
56 | mdiobus_register. Similarly, there's a remove function to undo all of | ||
57 | that (use mdiobus_unregister). | ||
58 | |||
59 | 4) Like any driver, the device_driver structure must be configured, and init | ||
60 | exit functions are used to register the driver. | ||
61 | |||
62 | 5) The bus must also be declared somewhere as a device, and registered. | ||
63 | |||
64 | As an example for how one driver implemented an mdio bus driver, see | ||
65 | drivers/net/gianfar_mii.c and arch/ppc/syslib/mpc85xx_devices.c | ||
66 | |||
67 | Connecting to a PHY | ||
68 | |||
69 | Sometime during startup, the network driver needs to establish a connection | ||
70 | between the PHY device, and the network device. At this time, the PHY's bus | ||
71 | and drivers need to all have been loaded, so it is ready for the connection. | ||
72 | At this point, there are several ways to connect to the PHY: | ||
73 | |||
74 | 1) The PAL handles everything, and only calls the network driver when | ||
75 | the link state changes, so it can react. | ||
76 | |||
77 | 2) The PAL handles everything except interrupts (usually because the | ||
78 | controller has the interrupt registers). | ||
79 | |||
80 | 3) The PAL handles everything, but checks in with the driver every second, | ||
81 | allowing the network driver to react first to any changes before the PAL | ||
82 | does. | ||
83 | |||
84 | 4) The PAL serves only as a library of functions, with the network device | ||
85 | manually calling functions to update status, and configure the PHY | ||
86 | |||
87 | |||
88 | Letting the PHY Abstraction Layer do Everything | ||
89 | |||
90 | If you choose option 1 (The hope is that every driver can, but to still be | ||
91 | useful to drivers that can't), connecting to the PHY is simple: | ||
92 | |||
93 | First, you need a function to react to changes in the link state. This | ||
94 | function follows this protocol: | ||
95 | |||
96 | static void adjust_link(struct net_device *dev); | ||
97 | |||
98 | Next, you need to know the device name of the PHY connected to this device. | ||
99 | The name will look something like, "phy0:0", where the first number is the | ||
100 | bus id, and the second is the PHY's address on that bus. | ||
101 | |||
102 | Now, to connect, just call this function: | ||
103 | |||
104 | phydev = phy_connect(dev, phy_name, &adjust_link, flags); | ||
105 | |||
106 | phydev is a pointer to the phy_device structure which represents the PHY. If | ||
107 | phy_connect is successful, it will return the pointer. dev, here, is the | ||
108 | pointer to your net_device. Once done, this function will have started the | ||
109 | PHY's software state machine, and registered for the PHY's interrupt, if it | ||
110 | has one. The phydev structure will be populated with information about the | ||
111 | current state, though the PHY will not yet be truly operational at this | ||
112 | point. | ||
113 | |||
114 | flags is a u32 which can optionally contain phy-specific flags. | ||
115 | This is useful if the system has put hardware restrictions on | ||
116 | the PHY/controller, of which the PHY needs to be aware. | ||
117 | |||
118 | Now just make sure that phydev->supported and phydev->advertising have any | ||
119 | values pruned from them which don't make sense for your controller (a 10/100 | ||
120 | controller may be connected to a gigabit capable PHY, so you would need to | ||
121 | mask off SUPPORTED_1000baseT*). See include/linux/ethtool.h for definitions | ||
122 | for these bitfields. Note that you should not SET any bits, or the PHY may | ||
123 | get put into an unsupported state. | ||
124 | |||
125 | Lastly, once the controller is ready to handle network traffic, you call | ||
126 | phy_start(phydev). This tells the PAL that you are ready, and configures the | ||
127 | PHY to connect to the network. If you want to handle your own interrupts, | ||
128 | just set phydev->irq to PHY_IGNORE_INTERRUPT before you call phy_start. | ||
129 | Similarly, if you don't want to use interrupts, set phydev->irq to PHY_POLL. | ||
130 | |||
131 | When you want to disconnect from the network (even if just briefly), you call | ||
132 | phy_stop(phydev). | ||
133 | |||
134 | Keeping Close Tabs on the PAL | ||
135 | |||
136 | It is possible that the PAL's built-in state machine needs a little help to | ||
137 | keep your network device and the PHY properly in sync. If so, you can | ||
138 | register a helper function when connecting to the PHY, which will be called | ||
139 | every second before the state machine reacts to any changes. To do this, you | ||
140 | need to manually call phy_attach() and phy_prepare_link(), and then call | ||
141 | phy_start_machine() with the second argument set to point to your special | ||
142 | handler. | ||
143 | |||
144 | Currently there are no examples of how to use this functionality, and testing | ||
145 | on it has been limited because the author does not have any drivers which use | ||
146 | it (they all use option 1). So Caveat Emptor. | ||
147 | |||
148 | Doing it all yourself | ||
149 | |||
150 | There's a remote chance that the PAL's built-in state machine cannot track | ||
151 | the complex interactions between the PHY and your network device. If this is | ||
152 | so, you can simply call phy_attach(), and not call phy_start_machine or | ||
153 | phy_prepare_link(). This will mean that phydev->state is entirely yours to | ||
154 | handle (phy_start and phy_stop toggle between some of the states, so you | ||
155 | might need to avoid them). | ||
156 | |||
157 | An effort has been made to make sure that useful functionality can be | ||
158 | accessed without the state-machine running, and most of these functions are | ||
159 | descended from functions which did not interact with a complex state-machine. | ||
160 | However, again, no effort has been made so far to test running without the | ||
161 | state machine, so tryer beware. | ||
162 | |||
163 | Here is a brief rundown of the functions: | ||
164 | |||
165 | int phy_read(struct phy_device *phydev, u16 regnum); | ||
166 | int phy_write(struct phy_device *phydev, u16 regnum, u16 val); | ||
167 | |||
168 | Simple read/write primitives. They invoke the bus's read/write function | ||
169 | pointers. | ||
170 | |||
171 | void phy_print_status(struct phy_device *phydev); | ||
172 | |||
173 | A convenience function to print out the PHY status neatly. | ||
174 | |||
175 | int phy_clear_interrupt(struct phy_device *phydev); | ||
176 | int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); | ||
177 | |||
178 | Clear the PHY's interrupt, and configure which ones are allowed, | ||
179 | respectively. Currently only supports all on, or all off. | ||
180 | |||
181 | int phy_enable_interrupts(struct phy_device *phydev); | ||
182 | int phy_disable_interrupts(struct phy_device *phydev); | ||
183 | |||
184 | Functions which enable/disable PHY interrupts, clearing them | ||
185 | before and after, respectively. | ||
186 | |||
187 | int phy_start_interrupts(struct phy_device *phydev); | ||
188 | int phy_stop_interrupts(struct phy_device *phydev); | ||
189 | |||
190 | Requests the IRQ for the PHY interrupts, then enables them for | ||
191 | start, or disables then frees them for stop. | ||
192 | |||
193 | struct phy_device * phy_attach(struct net_device *dev, const char *phy_id, | ||
194 | u32 flags); | ||
195 | |||
196 | Attaches a network device to a particular PHY, binding the PHY to a generic | ||
197 | driver if none was found during bus initialization. Passes in | ||
198 | any phy-specific flags as needed. | ||
199 | |||
200 | int phy_start_aneg(struct phy_device *phydev); | ||
201 | |||
202 | Using variables inside the phydev structure, either configures advertising | ||
203 | and resets autonegotiation, or disables autonegotiation, and configures | ||
204 | forced settings. | ||
205 | |||
206 | static inline int phy_read_status(struct phy_device *phydev); | ||
207 | |||
208 | Fills the phydev structure with up-to-date information about the current | ||
209 | settings in the PHY. | ||
210 | |||
211 | void phy_sanitize_settings(struct phy_device *phydev) | ||
212 | |||
213 | Resolves differences between currently desired settings, and | ||
214 | supported settings for the given PHY device. Does not make | ||
215 | the changes in the hardware, though. | ||
216 | |||
217 | int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); | ||
218 | int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); | ||
219 | |||
220 | Ethtool convenience functions. | ||
221 | |||
222 | int phy_mii_ioctl(struct phy_device *phydev, | ||
223 | struct mii_ioctl_data *mii_data, int cmd); | ||
224 | |||
225 | The MII ioctl. Note that this function will completely screw up the state | ||
226 | machine if you write registers like BMCR, BMSR, ADVERTISE, etc. Best to | ||
227 | use this only to write registers which are not standard, and don't set off | ||
228 | a renegotiation. | ||
229 | |||
230 | |||
231 | PHY Device Drivers | ||
232 | |||
233 | With the PHY Abstraction Layer, adding support for new PHYs is | ||
234 | quite easy. In some cases, no work is required at all! However, | ||
235 | many PHYs require a little hand-holding to get up-and-running. | ||
236 | |||
237 | Generic PHY driver | ||
238 | |||
239 | If the desired PHY doesn't have any errata, quirks, or special | ||
240 | features you want to support, then it may be best to not add | ||
241 | support, and let the PHY Abstraction Layer's Generic PHY Driver | ||
242 | do all of the work. | ||
243 | |||
244 | Writing a PHY driver | ||
245 | |||
246 | If you do need to write a PHY driver, the first thing to do is | ||
247 | make sure it can be matched with an appropriate PHY device. | ||
248 | This is done during bus initialization by reading the device's | ||
249 | UID (stored in registers 2 and 3), then comparing it to each | ||
250 | driver's phy_id field by ANDing it with each driver's | ||
251 | phy_id_mask field. Also, it needs a name. Here's an example: | ||
252 | |||
253 | static struct phy_driver dm9161_driver = { | ||
254 | .phy_id = 0x0181b880, | ||
255 | .name = "Davicom DM9161E", | ||
256 | .phy_id_mask = 0x0ffffff0, | ||
257 | ... | ||
258 | } | ||
259 | |||
260 | Next, you need to specify what features (speed, duplex, autoneg, | ||
261 | etc) your PHY device and driver support. Most PHYs support | ||
262 | PHY_BASIC_FEATURES, but you can look in include/mii.h for other | ||
263 | features. | ||
264 | |||
265 | Each driver consists of a number of function pointers: | ||
266 | |||
267 | config_init: configures PHY into a sane state after a reset. | ||
268 | For instance, a Davicom PHY requires descrambling disabled. | ||
269 | probe: Does any setup needed by the driver | ||
270 | suspend/resume: power management | ||
271 | config_aneg: Changes the speed/duplex/negotiation settings | ||
272 | read_status: Reads the current speed/duplex/negotiation settings | ||
273 | ack_interrupt: Clear a pending interrupt | ||
274 | config_intr: Enable or disable interrupts | ||
275 | remove: Does any driver take-down | ||
276 | |||
277 | Of these, only config_aneg and read_status are required to be | ||
278 | assigned by the driver code. The rest are optional. Also, it is | ||
279 | preferred to use the generic phy driver's versions of these two | ||
280 | functions if at all possible: genphy_read_status and | ||
281 | genphy_config_aneg. If this is not possible, it is likely that | ||
282 | you only need to perform some actions before and after invoking | ||
283 | these functions, and so your functions will wrap the generic | ||
284 | ones. | ||
285 | |||
286 | Feel free to look at the Marvell, Cicada, and Davicom drivers in | ||
287 | drivers/net/phy/ for examples (the lxt and qsemi drivers have | ||
288 | not been tested as of this writing) | ||
diff --git a/MAINTAINERS b/MAINTAINERS index 33122b1519ca..564a03e61a0c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -1739,7 +1739,7 @@ S: Maintained | |||
1739 | 1739 | ||
1740 | OPL3-SA2, SA3, and SAx DRIVER | 1740 | OPL3-SA2, SA3, and SAx DRIVER |
1741 | P: Zwane Mwaikambo | 1741 | P: Zwane Mwaikambo |
1742 | M: zwane@commfireservices.com | 1742 | M: zwane@arm.linux.org.uk |
1743 | L: linux-sound@vger.kernel.org | 1743 | L: linux-sound@vger.kernel.org |
1744 | S: Maintained | 1744 | S: Maintained |
1745 | 1745 | ||
@@ -1995,7 +1995,7 @@ S: Maintained | |||
1995 | 1995 | ||
1996 | SC1200 WDT DRIVER | 1996 | SC1200 WDT DRIVER |
1997 | P: Zwane Mwaikambo | 1997 | P: Zwane Mwaikambo |
1998 | M: zwane@commfireservices.com | 1998 | M: zwane@arm.linux.org.uk |
1999 | S: Maintained | 1999 | S: Maintained |
2000 | 2000 | ||
2001 | SCHEDULER | 2001 | SCHEDULER |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 13 | 3 | SUBLEVEL = 13 |
4 | EXTRAVERSION =-rc6 | 4 | EXTRAVERSION = |
5 | NAME=Woozy Numbat | 5 | NAME=Woozy Numbat |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index 083c5df42d35..189d5eababa8 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -522,7 +522,7 @@ source "mm/Kconfig" | |||
522 | 522 | ||
523 | config NUMA | 523 | config NUMA |
524 | bool "NUMA Support (EXPERIMENTAL)" | 524 | bool "NUMA Support (EXPERIMENTAL)" |
525 | depends on DISCONTIGMEM | 525 | depends on DISCONTIGMEM && BROKEN |
526 | help | 526 | help |
527 | Say Y to compile the kernel to support NUMA (Non-Uniform Memory | 527 | Say Y to compile the kernel to support NUMA (Non-Uniform Memory |
528 | Access). This option is for configuring high-end multiprocessor | 528 | Access). This option is for configuring high-end multiprocessor |
diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index 08fe8071a7f8..2e45e8604e32 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c | |||
@@ -566,13 +566,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
566 | if (ka->sa.sa_flags & SA_RESETHAND) | 566 | if (ka->sa.sa_flags & SA_RESETHAND) |
567 | ka->sa.sa_handler = SIG_DFL; | 567 | ka->sa.sa_handler = SIG_DFL; |
568 | 568 | ||
569 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 569 | spin_lock_irq(¤t->sighand->siglock); |
570 | spin_lock_irq(¤t->sighand->siglock); | 570 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
571 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 571 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
572 | sigaddset(¤t->blocked,sig); | 572 | sigaddset(¤t->blocked,sig); |
573 | recalc_sigpending(); | 573 | recalc_sigpending(); |
574 | spin_unlock_irq(¤t->sighand->siglock); | 574 | spin_unlock_irq(¤t->sighand->siglock); |
575 | } | ||
576 | } | 575 | } |
577 | 576 | ||
578 | static inline void | 577 | static inline void |
diff --git a/arch/alpha/kernel/smp.c b/arch/alpha/kernel/smp.c index 8f1e78551b1e..e211aa7404e6 100644 --- a/arch/alpha/kernel/smp.c +++ b/arch/alpha/kernel/smp.c | |||
@@ -1036,7 +1036,7 @@ debug_spin_lock(spinlock_t * lock, const char *base_file, int line_no) | |||
1036 | " br 1b\n" | 1036 | " br 1b\n" |
1037 | ".previous" | 1037 | ".previous" |
1038 | : "=r" (tmp), "=m" (lock->lock), "=r" (stuck) | 1038 | : "=r" (tmp), "=m" (lock->lock), "=r" (stuck) |
1039 | : "1" (lock->lock), "2" (stuck) : "memory"); | 1039 | : "m" (lock->lock), "2" (stuck) : "memory"); |
1040 | 1040 | ||
1041 | if (stuck < 0) { | 1041 | if (stuck < 0) { |
1042 | printk(KERN_WARNING | 1042 | printk(KERN_WARNING |
@@ -1115,7 +1115,7 @@ void _raw_write_lock(rwlock_t * lock) | |||
1115 | ".previous" | 1115 | ".previous" |
1116 | : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy), | 1116 | : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (regy), |
1117 | "=&r" (stuck_lock), "=&r" (stuck_reader) | 1117 | "=&r" (stuck_lock), "=&r" (stuck_reader) |
1118 | : "0" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory"); | 1118 | : "m" (*(volatile int *)lock), "3" (stuck_lock), "4" (stuck_reader) : "memory"); |
1119 | 1119 | ||
1120 | if (stuck_lock < 0) { | 1120 | if (stuck_lock < 0) { |
1121 | printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc); | 1121 | printk(KERN_WARNING "write_lock stuck at %p\n", inline_pc); |
@@ -1153,7 +1153,7 @@ void _raw_read_lock(rwlock_t * lock) | |||
1153 | " br 1b\n" | 1153 | " br 1b\n" |
1154 | ".previous" | 1154 | ".previous" |
1155 | : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock) | 1155 | : "=m" (*(volatile int *)lock), "=&r" (regx), "=&r" (stuck_lock) |
1156 | : "0" (*(volatile int *)lock), "2" (stuck_lock) : "memory"); | 1156 | : "m" (*(volatile int *)lock), "2" (stuck_lock) : "memory"); |
1157 | 1157 | ||
1158 | if (stuck_lock < 0) { | 1158 | if (stuck_lock < 0) { |
1159 | printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc); | 1159 | printk(KERN_WARNING "read_lock stuck at %p\n", inline_pc); |
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index 908eb4af8dec..ba788cfdc3c6 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c | |||
@@ -65,7 +65,7 @@ op_axp_setup(void) | |||
65 | model->reg_setup(®, ctr, &sys); | 65 | model->reg_setup(®, ctr, &sys); |
66 | 66 | ||
67 | /* Configure the registers on all cpus. */ | 67 | /* Configure the registers on all cpus. */ |
68 | smp_call_function(model->cpu_setup, ®, 0, 1); | 68 | (void)smp_call_function(model->cpu_setup, ®, 0, 1); |
69 | model->cpu_setup(®); | 69 | model->cpu_setup(®); |
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
@@ -86,7 +86,7 @@ op_axp_cpu_start(void *dummy) | |||
86 | static int | 86 | static int |
87 | op_axp_start(void) | 87 | op_axp_start(void) |
88 | { | 88 | { |
89 | smp_call_function(op_axp_cpu_start, NULL, 0, 1); | 89 | (void)smp_call_function(op_axp_cpu_start, NULL, 0, 1); |
90 | op_axp_cpu_start(NULL); | 90 | op_axp_cpu_start(NULL); |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
@@ -101,7 +101,7 @@ op_axp_cpu_stop(void *dummy) | |||
101 | static void | 101 | static void |
102 | op_axp_stop(void) | 102 | op_axp_stop(void) |
103 | { | 103 | { |
104 | smp_call_function(op_axp_cpu_stop, NULL, 0, 1); | 104 | (void)smp_call_function(op_axp_cpu_stop, NULL, 0, 1); |
105 | op_axp_cpu_stop(NULL); | 105 | op_axp_cpu_stop(NULL); |
106 | } | 106 | } |
107 | 107 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 0a7700ae8dee..e85097bceff4 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -310,7 +310,7 @@ menu "Kernel Features" | |||
310 | 310 | ||
311 | config SMP | 311 | config SMP |
312 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" | 312 | bool "Symmetric Multi-Processing (EXPERIMENTAL)" |
313 | depends on EXPERIMENTAL #&& n | 313 | depends on EXPERIMENTAL && BROKEN #&& n |
314 | help | 314 | help |
315 | This enables support for systems with more than one CPU. If you have | 315 | This enables support for systems with more than one CPU. If you have |
316 | a system with only one CPU, like most personal computers, say N. If | 316 | a system with only one CPU, like most personal computers, say N. If |
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5e435e42dacd..a94d75fef598 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -658,11 +658,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
658 | /* | 658 | /* |
659 | * Block the signal if we were unsuccessful. | 659 | * Block the signal if we were unsuccessful. |
660 | */ | 660 | */ |
661 | if (ret != 0 || !(ka->sa.sa_flags & SA_NODEFER)) { | 661 | if (ret != 0) { |
662 | spin_lock_irq(&tsk->sighand->siglock); | 662 | spin_lock_irq(&tsk->sighand->siglock); |
663 | sigorsets(&tsk->blocked, &tsk->blocked, | 663 | sigorsets(&tsk->blocked, &tsk->blocked, |
664 | &ka->sa.sa_mask); | 664 | &ka->sa.sa_mask); |
665 | sigaddset(&tsk->blocked, sig); | 665 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
666 | sigaddset(&tsk->blocked, sig); | ||
666 | recalc_sigpending(); | 667 | recalc_sigpending(); |
667 | spin_unlock_irq(&tsk->sighand->siglock); | 668 | spin_unlock_irq(&tsk->sighand->siglock); |
668 | } | 669 | } |
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index d571c37ac30c..4554c961251c 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c | |||
@@ -617,7 +617,7 @@ baddataabort(int code, unsigned long instr, struct pt_regs *regs) | |||
617 | notify_die("unknown data abort code", regs, &info, instr, 0); | 617 | notify_die("unknown data abort code", regs, &info, instr, 0); |
618 | } | 618 | } |
619 | 619 | ||
620 | volatile void __bug(const char *file, int line, void *data) | 620 | void __attribute__((noreturn)) __bug(const char *file, int line, void *data) |
621 | { | 621 | { |
622 | printk(KERN_CRIT"kernel BUG at %s:%d!", file, line); | 622 | printk(KERN_CRIT"kernel BUG at %s:%d!", file, line); |
623 | if (data) | 623 | if (data) |
diff --git a/arch/arm/mach-ixp4xx/coyote-setup.c b/arch/arm/mach-ixp4xx/coyote-setup.c index 7f58afb27e71..411ea9996190 100644 --- a/arch/arm/mach-ixp4xx/coyote-setup.c +++ b/arch/arm/mach-ixp4xx/coyote-setup.c | |||
@@ -36,7 +36,7 @@ static struct flash_platform_data coyote_flash_data = { | |||
36 | 36 | ||
37 | static struct resource coyote_flash_resource = { | 37 | static struct resource coyote_flash_resource = { |
38 | .start = COYOTE_FLASH_BASE, | 38 | .start = COYOTE_FLASH_BASE, |
39 | .end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE, | 39 | .end = COYOTE_FLASH_BASE + COYOTE_FLASH_SIZE - 1, |
40 | .flags = IORESOURCE_MEM, | 40 | .flags = IORESOURCE_MEM, |
41 | }; | 41 | }; |
42 | 42 | ||
diff --git a/arch/arm/mach-ixp4xx/gtwx5715-setup.c b/arch/arm/mach-ixp4xx/gtwx5715-setup.c index 65e356bd10d6..333459d6aa46 100644 --- a/arch/arm/mach-ixp4xx/gtwx5715-setup.c +++ b/arch/arm/mach-ixp4xx/gtwx5715-setup.c | |||
@@ -114,7 +114,7 @@ static struct flash_platform_data gtwx5715_flash_data = { | |||
114 | 114 | ||
115 | static struct resource gtwx5715_flash_resource = { | 115 | static struct resource gtwx5715_flash_resource = { |
116 | .start = GTWX5715_FLASH_BASE, | 116 | .start = GTWX5715_FLASH_BASE, |
117 | .end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE, | 117 | .end = GTWX5715_FLASH_BASE + GTWX5715_FLASH_SIZE - 1, |
118 | .flags = IORESOURCE_MEM, | 118 | .flags = IORESOURCE_MEM, |
119 | }; | 119 | }; |
120 | 120 | ||
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c index 4633470a6a37..fa0646c8693b 100644 --- a/arch/arm/mach-ixp4xx/ixdp425-setup.c +++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c | |||
@@ -36,7 +36,7 @@ static struct flash_platform_data ixdp425_flash_data = { | |||
36 | 36 | ||
37 | static struct resource ixdp425_flash_resource = { | 37 | static struct resource ixdp425_flash_resource = { |
38 | .start = IXDP425_FLASH_BASE, | 38 | .start = IXDP425_FLASH_BASE, |
39 | .end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE, | 39 | .end = IXDP425_FLASH_BASE + IXDP425_FLASH_SIZE - 1, |
40 | .flags = IORESOURCE_MEM, | 40 | .flags = IORESOURCE_MEM, |
41 | }; | 41 | }; |
42 | 42 | ||
diff --git a/arch/arm/nwfpe/fpopcode.h b/arch/arm/nwfpe/fpopcode.h index 8035f4faafbf..1777e92a88e6 100644 --- a/arch/arm/nwfpe/fpopcode.h +++ b/arch/arm/nwfpe/fpopcode.h | |||
@@ -370,20 +370,20 @@ TABLE 5 | |||
370 | #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) | 370 | #define getRoundingMode(opcode) ((opcode & MASK_ROUNDING_MODE) >> 5) |
371 | 371 | ||
372 | #ifdef CONFIG_FPE_NWFPE_XP | 372 | #ifdef CONFIG_FPE_NWFPE_XP |
373 | static inline const floatx80 getExtendedConstant(const unsigned int nIndex) | 373 | static inline __attribute_pure__ floatx80 getExtendedConstant(const unsigned int nIndex) |
374 | { | 374 | { |
375 | extern const floatx80 floatx80Constant[]; | 375 | extern const floatx80 floatx80Constant[]; |
376 | return floatx80Constant[nIndex]; | 376 | return floatx80Constant[nIndex]; |
377 | } | 377 | } |
378 | #endif | 378 | #endif |
379 | 379 | ||
380 | static inline const float64 getDoubleConstant(const unsigned int nIndex) | 380 | static inline __attribute_pure__ float64 getDoubleConstant(const unsigned int nIndex) |
381 | { | 381 | { |
382 | extern const float64 float64Constant[]; | 382 | extern const float64 float64Constant[]; |
383 | return float64Constant[nIndex]; | 383 | return float64Constant[nIndex]; |
384 | } | 384 | } |
385 | 385 | ||
386 | static inline const float32 getSingleConstant(const unsigned int nIndex) | 386 | static inline __attribute_pure__ float32 getSingleConstant(const unsigned int nIndex) |
387 | { | 387 | { |
388 | extern const float32 float32Constant[]; | 388 | extern const float32 float32Constant[]; |
389 | return float32Constant[nIndex]; | 389 | return float32Constant[nIndex]; |
diff --git a/arch/arm26/kernel/signal.c b/arch/arm26/kernel/signal.c index 356d9809cc0b..ce2055bdc9ee 100644 --- a/arch/arm26/kernel/signal.c +++ b/arch/arm26/kernel/signal.c | |||
@@ -454,14 +454,13 @@ handle_signal(unsigned long sig, siginfo_t *info, sigset_t *oldset, | |||
454 | if (ka->sa.sa_flags & SA_ONESHOT) | 454 | if (ka->sa.sa_flags & SA_ONESHOT) |
455 | ka->sa.sa_handler = SIG_DFL; | 455 | ka->sa.sa_handler = SIG_DFL; |
456 | 456 | ||
457 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 457 | spin_lock_irq(&tsk->sighand->siglock); |
458 | spin_lock_irq(&tsk->sighand->siglock); | 458 | sigorsets(&tsk->blocked, &tsk->blocked, |
459 | sigorsets(&tsk->blocked, &tsk->blocked, | 459 | &ka->sa.sa_mask); |
460 | &ka->sa.sa_mask); | 460 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
461 | sigaddset(&tsk->blocked, sig); | 461 | sigaddset(&tsk->blocked, sig); |
462 | recalc_sigpending(); | 462 | recalc_sigpending(); |
463 | spin_unlock_irq(&tsk->sighand->siglock); | 463 | spin_unlock_irq(&tsk->sighand->siglock); |
464 | } | ||
465 | return; | 464 | return; |
466 | } | 465 | } |
467 | 466 | ||
diff --git a/arch/cris/arch-v10/kernel/signal.c b/arch/cris/arch-v10/kernel/signal.c index 85e0032e664f..693771961f85 100644 --- a/arch/cris/arch-v10/kernel/signal.c +++ b/arch/cris/arch-v10/kernel/signal.c | |||
@@ -517,13 +517,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
517 | if (ka->sa.sa_flags & SA_ONESHOT) | 517 | if (ka->sa.sa_flags & SA_ONESHOT) |
518 | ka->sa.sa_handler = SIG_DFL; | 518 | ka->sa.sa_handler = SIG_DFL; |
519 | 519 | ||
520 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 520 | spin_lock_irq(¤t->sighand->siglock); |
521 | spin_lock_irq(¤t->sighand->siglock); | 521 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
522 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 522 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
523 | sigaddset(¤t->blocked,sig); | 523 | sigaddset(¤t->blocked,sig); |
524 | recalc_sigpending(); | 524 | recalc_sigpending(); |
525 | spin_unlock_irq(¤t->sighand->siglock); | 525 | spin_unlock_irq(¤t->sighand->siglock); |
526 | } | ||
527 | } | 526 | } |
528 | 527 | ||
529 | /* | 528 | /* |
diff --git a/arch/cris/arch-v32/kernel/signal.c b/arch/cris/arch-v32/kernel/signal.c index fb4c79d5b76b..0a3614dab887 100644 --- a/arch/cris/arch-v32/kernel/signal.c +++ b/arch/cris/arch-v32/kernel/signal.c | |||
@@ -568,13 +568,12 @@ handle_signal(int canrestart, unsigned long sig, | |||
568 | if (ka->sa.sa_flags & SA_ONESHOT) | 568 | if (ka->sa.sa_flags & SA_ONESHOT) |
569 | ka->sa.sa_handler = SIG_DFL; | 569 | ka->sa.sa_handler = SIG_DFL; |
570 | 570 | ||
571 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 571 | spin_lock_irq(¤t->sighand->siglock); |
572 | spin_lock_irq(¤t->sighand->siglock); | 572 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
573 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 573 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
574 | sigaddset(¤t->blocked,sig); | 574 | sigaddset(¤t->blocked,sig); |
575 | recalc_sigpending(); | 575 | recalc_sigpending(); |
576 | spin_unlock_irq(¤t->sighand->siglock); | 576 | spin_unlock_irq(¤t->sighand->siglock); |
577 | } | ||
578 | } | 577 | } |
579 | 578 | ||
580 | /* | 579 | /* |
diff --git a/arch/frv/kernel/signal.c b/arch/frv/kernel/signal.c index 36a2dffc8ebd..d4ccc0728dfe 100644 --- a/arch/frv/kernel/signal.c +++ b/arch/frv/kernel/signal.c | |||
@@ -506,13 +506,12 @@ static void handle_signal(unsigned long sig, siginfo_t *info, | |||
506 | else | 506 | else |
507 | setup_frame(sig, ka, oldset, regs); | 507 | setup_frame(sig, ka, oldset, regs); |
508 | 508 | ||
509 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 509 | spin_lock_irq(¤t->sighand->siglock); |
510 | spin_lock_irq(¤t->sighand->siglock); | 510 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
511 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 511 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
512 | sigaddset(¤t->blocked, sig); | 512 | sigaddset(¤t->blocked, sig); |
513 | recalc_sigpending(); | 513 | recalc_sigpending(); |
514 | spin_unlock_irq(¤t->sighand->siglock); | 514 | spin_unlock_irq(¤t->sighand->siglock); |
515 | } | ||
516 | } /* end handle_signal() */ | 515 | } /* end handle_signal() */ |
517 | 516 | ||
518 | /*****************************************************************************/ | 517 | /*****************************************************************************/ |
diff --git a/arch/h8300/kernel/signal.c b/arch/h8300/kernel/signal.c index 5aab87eae1f9..f13d5e82d4b9 100644 --- a/arch/h8300/kernel/signal.c +++ b/arch/h8300/kernel/signal.c | |||
@@ -488,13 +488,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
488 | else | 488 | else |
489 | setup_frame(sig, ka, oldset, regs); | 489 | setup_frame(sig, ka, oldset, regs); |
490 | 490 | ||
491 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 491 | spin_lock_irq(¤t->sighand->siglock); |
492 | spin_lock_irq(¤t->sighand->siglock); | 492 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
493 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 493 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
494 | sigaddset(¤t->blocked,sig); | 494 | sigaddset(¤t->blocked,sig); |
495 | recalc_sigpending(); | 495 | recalc_sigpending(); |
496 | spin_unlock_irq(¤t->sighand->siglock); | 496 | spin_unlock_irq(¤t->sighand->siglock); |
497 | } | ||
498 | } | 497 | } |
499 | 498 | ||
500 | /* | 499 | /* |
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c index bd1dbf3bd223..a22a866de8f9 100644 --- a/arch/i386/kernel/apic.c +++ b/arch/i386/kernel/apic.c | |||
@@ -726,15 +726,11 @@ __setup("apic=", apic_set_verbosity); | |||
726 | static int __init detect_init_APIC (void) | 726 | static int __init detect_init_APIC (void) |
727 | { | 727 | { |
728 | u32 h, l, features; | 728 | u32 h, l, features; |
729 | extern void get_cpu_vendor(struct cpuinfo_x86*); | ||
730 | 729 | ||
731 | /* Disabled by kernel option? */ | 730 | /* Disabled by kernel option? */ |
732 | if (enable_local_apic < 0) | 731 | if (enable_local_apic < 0) |
733 | return -1; | 732 | return -1; |
734 | 733 | ||
735 | /* Workaround for us being called before identify_cpu(). */ | ||
736 | get_cpu_vendor(&boot_cpu_data); | ||
737 | |||
738 | switch (boot_cpu_data.x86_vendor) { | 734 | switch (boot_cpu_data.x86_vendor) { |
739 | case X86_VENDOR_AMD: | 735 | case X86_VENDOR_AMD: |
740 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || | 736 | if ((boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model > 1) || |
diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index da6c46d667cb..8c242bb1ef45 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c | |||
@@ -195,7 +195,7 @@ static void disable_lapic_nmi_watchdog(void) | |||
195 | wrmsr(MSR_P6_EVNTSEL0, 0, 0); | 195 | wrmsr(MSR_P6_EVNTSEL0, 0, 0); |
196 | break; | 196 | break; |
197 | case 15: | 197 | case 15: |
198 | if (boot_cpu_data.x86_model > 0x3) | 198 | if (boot_cpu_data.x86_model > 0x4) |
199 | break; | 199 | break; |
200 | 200 | ||
201 | wrmsr(MSR_P4_IQ_CCCR0, 0, 0); | 201 | wrmsr(MSR_P4_IQ_CCCR0, 0, 0); |
@@ -432,7 +432,7 @@ void setup_apic_nmi_watchdog (void) | |||
432 | setup_p6_watchdog(); | 432 | setup_p6_watchdog(); |
433 | break; | 433 | break; |
434 | case 15: | 434 | case 15: |
435 | if (boot_cpu_data.x86_model > 0x3) | 435 | if (boot_cpu_data.x86_model > 0x4) |
436 | return; | 436 | return; |
437 | 437 | ||
438 | if (!setup_p4_watchdog()) | 438 | if (!setup_p4_watchdog()) |
diff --git a/arch/i386/kernel/signal.c b/arch/i386/kernel/signal.c index 89ef7adc63a4..140e340569c6 100644 --- a/arch/i386/kernel/signal.c +++ b/arch/i386/kernel/signal.c | |||
@@ -577,10 +577,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
577 | else | 577 | else |
578 | ret = setup_frame(sig, ka, oldset, regs); | 578 | ret = setup_frame(sig, ka, oldset, regs); |
579 | 579 | ||
580 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 580 | if (ret) { |
581 | spin_lock_irq(¤t->sighand->siglock); | 581 | spin_lock_irq(¤t->sighand->siglock); |
582 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 582 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
583 | sigaddset(¤t->blocked,sig); | 583 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
584 | sigaddset(¤t->blocked,sig); | ||
584 | recalc_sigpending(); | 585 | recalc_sigpending(); |
585 | spin_unlock_irq(¤t->sighand->siglock); | 586 | spin_unlock_irq(¤t->sighand->siglock); |
586 | } | 587 | } |
diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index a61f33d06ea3..cd2d5d5514fe 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c | |||
@@ -803,15 +803,17 @@ void math_error(void __user *eip) | |||
803 | */ | 803 | */ |
804 | cwd = get_fpu_cwd(task); | 804 | cwd = get_fpu_cwd(task); |
805 | swd = get_fpu_swd(task); | 805 | swd = get_fpu_swd(task); |
806 | switch (((~cwd) & swd & 0x3f) | (swd & 0x240)) { | 806 | switch (swd & ~cwd & 0x3f) { |
807 | case 0x000: | 807 | case 0x000: |
808 | default: | 808 | default: |
809 | break; | 809 | break; |
810 | case 0x001: /* Invalid Op */ | 810 | case 0x001: /* Invalid Op */ |
811 | case 0x041: /* Stack Fault */ | 811 | /* |
812 | case 0x241: /* Stack Fault | Direction */ | 812 | * swd & 0x240 == 0x040: Stack Underflow |
813 | * swd & 0x240 == 0x240: Stack Overflow | ||
814 | * User must clear the SF bit (0x40) if set | ||
815 | */ | ||
813 | info.si_code = FPE_FLTINV; | 816 | info.si_code = FPE_FLTINV; |
814 | /* Should we clear the SF or let user space do it ???? */ | ||
815 | break; | 817 | break; |
816 | case 0x002: /* Denormalize */ | 818 | case 0x002: /* Denormalize */ |
817 | case 0x010: /* Underflow */ | 819 | case 0x010: /* Underflow */ |
diff --git a/arch/ia64/hp/sim/boot/boot_head.S b/arch/ia64/hp/sim/boot/boot_head.S index 9364199e5632..1c8c7e6a9a5e 100644 --- a/arch/ia64/hp/sim/boot/boot_head.S +++ b/arch/ia64/hp/sim/boot/boot_head.S | |||
@@ -22,7 +22,7 @@ GLOBAL_ENTRY(_start) | |||
22 | .save rp, r0 | 22 | .save rp, r0 |
23 | .body | 23 | .body |
24 | movl gp = __gp | 24 | movl gp = __gp |
25 | movl sp = stack_mem | 25 | movl sp = stack_mem+16384-16 |
26 | bsw.1 | 26 | bsw.1 |
27 | br.call.sptk.many rp=start_bootloader | 27 | br.call.sptk.many rp=start_bootloader |
28 | END(_start) | 28 | END(_start) |
diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index b8a0a7d257a9..774f34b675cf 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c | |||
@@ -467,15 +467,12 @@ handle_signal (unsigned long sig, struct k_sigaction *ka, siginfo_t *info, sigse | |||
467 | if (!setup_frame(sig, ka, info, oldset, scr)) | 467 | if (!setup_frame(sig, ka, info, oldset, scr)) |
468 | return 0; | 468 | return 0; |
469 | 469 | ||
470 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 470 | spin_lock_irq(¤t->sighand->siglock); |
471 | spin_lock_irq(¤t->sighand->siglock); | 471 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
472 | { | 472 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
473 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 473 | sigaddset(¤t->blocked, sig); |
474 | sigaddset(¤t->blocked, sig); | 474 | recalc_sigpending(); |
475 | recalc_sigpending(); | 475 | spin_unlock_irq(¤t->sighand->siglock); |
476 | } | ||
477 | spin_unlock_irq(¤t->sighand->siglock); | ||
478 | } | ||
479 | return 1; | 476 | return 1; |
480 | } | 477 | } |
481 | 478 | ||
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c index 54d9ed444e4a..f9472c50ab42 100644 --- a/arch/ia64/pci/pci.c +++ b/arch/ia64/pci/pci.c | |||
@@ -380,6 +380,7 @@ void pcibios_bus_to_resource(struct pci_dev *dev, | |||
380 | res->start = region->start + offset; | 380 | res->start = region->start + offset; |
381 | res->end = region->end + offset; | 381 | res->end = region->end + offset; |
382 | } | 382 | } |
383 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
383 | 384 | ||
384 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) | 385 | static int __devinit is_valid_resource(struct pci_dev *dev, int idx) |
385 | { | 386 | { |
diff --git a/arch/ia64/sn/kernel/io_init.c b/arch/ia64/sn/kernel/io_init.c index 37e10e010a2f..414cdf2e3c96 100644 --- a/arch/ia64/sn/kernel/io_init.c +++ b/arch/ia64/sn/kernel/io_init.c | |||
@@ -323,7 +323,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
323 | struct pci_controller *controller; | 323 | struct pci_controller *controller; |
324 | struct pcibus_bussoft *prom_bussoft_ptr; | 324 | struct pcibus_bussoft *prom_bussoft_ptr; |
325 | struct hubdev_info *hubdev_info; | 325 | struct hubdev_info *hubdev_info; |
326 | void *provider_soft; | 326 | void *provider_soft = NULL; |
327 | struct sn_pcibus_provider *provider; | 327 | struct sn_pcibus_provider *provider; |
328 | 328 | ||
329 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, | 329 | status = sal_get_pcibus_info((u64) segment, (u64) busnum, |
@@ -339,7 +339,7 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
339 | if (bus == NULL) { | 339 | if (bus == NULL) { |
340 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); | 340 | bus = pci_scan_bus(busnum, &pci_root_ops, controller); |
341 | if (bus == NULL) | 341 | if (bus == NULL) |
342 | return; /* error, or bus already scanned */ | 342 | goto error_return; /* error, or bus already scanned */ |
343 | bus->sysdata = NULL; | 343 | bus->sysdata = NULL; |
344 | } | 344 | } |
345 | 345 | ||
@@ -352,28 +352,30 @@ void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) | |||
352 | */ | 352 | */ |
353 | 353 | ||
354 | if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) | 354 | if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) |
355 | return; /* unsupported asic type */ | 355 | goto error_return; /* unsupported asic type */ |
356 | 356 | ||
357 | if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) | 357 | if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) |
358 | goto error_return; /* no further fixup necessary */ | 358 | goto error_return; /* no further fixup necessary */ |
359 | 359 | ||
360 | provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; | 360 | provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; |
361 | if (provider == NULL) | 361 | if (provider == NULL) |
362 | return; /* no provider registerd for this asic */ | 362 | goto error_return; /* no provider registerd for this asic */ |
363 | 363 | ||
364 | provider_soft = NULL; | 364 | bus->sysdata = controller; |
365 | if (provider->bus_fixup) | 365 | if (provider->bus_fixup) |
366 | provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); | 366 | provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); |
367 | 367 | ||
368 | if (provider_soft == NULL) | 368 | if (provider_soft == NULL) { |
369 | return; /* fixup failed or not applicable */ | 369 | /* fixup failed or not applicable */ |
370 | bus->sysdata = NULL; | ||
371 | goto error_return; | ||
372 | } | ||
370 | 373 | ||
371 | /* | 374 | /* |
372 | * Generic bus fixup goes here. Don't reference prom_bussoft_ptr | 375 | * Generic bus fixup goes here. Don't reference prom_bussoft_ptr |
373 | * after this point. | 376 | * after this point. |
374 | */ | 377 | */ |
375 | 378 | ||
376 | bus->sysdata = controller; | ||
377 | PCI_CONTROLLER(bus)->platform_data = provider_soft; | 379 | PCI_CONTROLLER(bus)->platform_data = provider_soft; |
378 | nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); | 380 | nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); |
379 | cnode = nasid_to_cnodeid(nasid); | 381 | cnode = nasid_to_cnodeid(nasid); |
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig index 7772951df313..7622d4ec5f08 100644 --- a/arch/m32r/Kconfig +++ b/arch/m32r/Kconfig | |||
@@ -269,7 +269,7 @@ config NR_CPUS | |||
269 | # Common NUMA Features | 269 | # Common NUMA Features |
270 | config NUMA | 270 | config NUMA |
271 | bool "Numa Memory Allocation Support" | 271 | bool "Numa Memory Allocation Support" |
272 | depends on SMP | 272 | depends on SMP && BROKEN |
273 | default n | 273 | default n |
274 | 274 | ||
275 | # turning this on wastes a bunch of space. | 275 | # turning this on wastes a bunch of space. |
@@ -286,6 +286,7 @@ menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)" | |||
286 | 286 | ||
287 | config PCI | 287 | config PCI |
288 | bool "PCI support" | 288 | bool "PCI support" |
289 | depends on BROKEN | ||
289 | default n | 290 | default n |
290 | help | 291 | help |
291 | Find out whether you have a PCI motherboard. PCI is the name of a | 292 | Find out whether you have a PCI motherboard. PCI is the name of a |
diff --git a/arch/m32r/Kconfig.debug b/arch/m32r/Kconfig.debug index 31039723804f..bbf711bab69e 100644 --- a/arch/m32r/Kconfig.debug +++ b/arch/m32r/Kconfig.debug | |||
@@ -20,7 +20,7 @@ config DEBUG_STACK_USAGE | |||
20 | 20 | ||
21 | config DEBUG_PAGEALLOC | 21 | config DEBUG_PAGEALLOC |
22 | bool "Page alloc debugging" | 22 | bool "Page alloc debugging" |
23 | depends on DEBUG_KERNEL | 23 | depends on DEBUG_KERNEL && BROKEN |
24 | help | 24 | help |
25 | Unmap pages from the kernel linear mapping after free_pages(). | 25 | Unmap pages from the kernel linear mapping after free_pages(). |
26 | This results in a large slowdown, but helps to find certain types | 26 | This results in a large slowdown, but helps to find certain types |
diff --git a/arch/m32r/kernel/setup_m32700ut.c b/arch/m32r/kernel/setup_m32700ut.c index a146b24a556b..708634b685e4 100644 --- a/arch/m32r/kernel/setup_m32700ut.c +++ b/arch/m32r/kernel/setup_m32700ut.c | |||
@@ -30,9 +30,11 @@ | |||
30 | typedef struct { | 30 | typedef struct { |
31 | unsigned long icucr; /* ICU Control Register */ | 31 | unsigned long icucr; /* ICU Control Register */ |
32 | } icu_data_t; | 32 | } icu_data_t; |
33 | static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | ||
34 | #else | ||
35 | icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | ||
33 | #endif /* CONFIG_SMP */ | 36 | #endif /* CONFIG_SMP */ |
34 | 37 | ||
35 | static icu_data_t icu_data[M32700UT_NUM_CPU_IRQ]; | ||
36 | 38 | ||
37 | static void disable_m32700ut_irq(unsigned int irq) | 39 | static void disable_m32700ut_irq(unsigned int irq) |
38 | { | 40 | { |
diff --git a/arch/m32r/kernel/setup_opsput.c b/arch/m32r/kernel/setup_opsput.c index f0301f58bcce..d7b7ec6d30f8 100644 --- a/arch/m32r/kernel/setup_opsput.c +++ b/arch/m32r/kernel/setup_opsput.c | |||
@@ -31,9 +31,11 @@ | |||
31 | typedef struct { | 31 | typedef struct { |
32 | unsigned long icucr; /* ICU Control Register */ | 32 | unsigned long icucr; /* ICU Control Register */ |
33 | } icu_data_t; | 33 | } icu_data_t; |
34 | static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; | ||
35 | #else | ||
36 | icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; | ||
34 | #endif /* CONFIG_SMP */ | 37 | #endif /* CONFIG_SMP */ |
35 | 38 | ||
36 | static icu_data_t icu_data[OPSPUT_NUM_CPU_IRQ]; | ||
37 | 39 | ||
38 | static void disable_opsput_irq(unsigned int irq) | 40 | static void disable_opsput_irq(unsigned int irq) |
39 | { | 41 | { |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index 5aef7e406ef5..71763f7a1d19 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -341,13 +341,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
341 | /* Set up the stack frame */ | 341 | /* Set up the stack frame */ |
342 | setup_rt_frame(sig, ka, info, oldset, regs); | 342 | setup_rt_frame(sig, ka, info, oldset, regs); |
343 | 343 | ||
344 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 344 | spin_lock_irq(¤t->sighand->siglock); |
345 | spin_lock_irq(¤t->sighand->siglock); | 345 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
346 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 346 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
347 | sigaddset(¤t->blocked,sig); | 347 | sigaddset(¤t->blocked,sig); |
348 | recalc_sigpending(); | 348 | recalc_sigpending(); |
349 | spin_unlock_irq(¤t->sighand->siglock); | 349 | spin_unlock_irq(¤t->sighand->siglock); |
350 | } | ||
351 | } | 350 | } |
352 | 351 | ||
353 | /* | 352 | /* |
diff --git a/arch/m32r/kernel/smpboot.c b/arch/m32r/kernel/smpboot.c index f9a0e723478d..640d592ea072 100644 --- a/arch/m32r/kernel/smpboot.c +++ b/arch/m32r/kernel/smpboot.c | |||
@@ -91,6 +91,7 @@ extern struct { | |||
91 | 91 | ||
92 | /* which physical physical ID maps to which logical CPU number */ | 92 | /* which physical physical ID maps to which logical CPU number */ |
93 | static volatile int physid_2_cpu[NR_CPUS]; | 93 | static volatile int physid_2_cpu[NR_CPUS]; |
94 | #define physid_to_cpu(physid) physid_2_cpu[physid] | ||
94 | 95 | ||
95 | /* which logical CPU number maps to which physical ID */ | 96 | /* which logical CPU number maps to which physical ID */ |
96 | volatile int cpu_2_physid[NR_CPUS]; | 97 | volatile int cpu_2_physid[NR_CPUS]; |
diff --git a/arch/m32r/lib/csum_partial_copy.c b/arch/m32r/lib/csum_partial_copy.c index c871b4606b07..ddb16a83a8ce 100644 --- a/arch/m32r/lib/csum_partial_copy.c +++ b/arch/m32r/lib/csum_partial_copy.c | |||
@@ -58,3 +58,4 @@ csum_partial_copy_from_user (const unsigned char __user *src, | |||
58 | return csum_partial(dst, len-missing, sum); | 58 | return csum_partial(dst, len-missing, sum); |
59 | } | 59 | } |
60 | EXPORT_SYMBOL(csum_partial_copy_from_user); | 60 | EXPORT_SYMBOL(csum_partial_copy_from_user); |
61 | EXPORT_SYMBOL(csum_partial); | ||
diff --git a/arch/m32r/mm/discontig.c b/arch/m32r/mm/discontig.c index 1d1a01e54b3f..08e727955555 100644 --- a/arch/m32r/mm/discontig.c +++ b/arch/m32r/mm/discontig.c | |||
@@ -12,12 +12,14 @@ | |||
12 | #include <linux/mmzone.h> | 12 | #include <linux/mmzone.h> |
13 | #include <linux/initrd.h> | 13 | #include <linux/initrd.h> |
14 | #include <linux/nodemask.h> | 14 | #include <linux/nodemask.h> |
15 | #include <linux/module.h> | ||
15 | 16 | ||
16 | #include <asm/setup.h> | 17 | #include <asm/setup.h> |
17 | 18 | ||
18 | extern char _end[]; | 19 | extern char _end[]; |
19 | 20 | ||
20 | struct pglist_data *node_data[MAX_NUMNODES]; | 21 | struct pglist_data *node_data[MAX_NUMNODES]; |
22 | EXPORT_SYMBOL(node_data); | ||
21 | static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata; | 23 | static bootmem_data_t node_bdata[MAX_NUMNODES] __initdata; |
22 | 24 | ||
23 | pg_data_t m32r_node_data[MAX_NUMNODES]; | 25 | pg_data_t m32r_node_data[MAX_NUMNODES]; |
diff --git a/arch/m68knommu/kernel/signal.c b/arch/m68knommu/kernel/signal.c index 30dceb59a462..43a2726c0d0a 100644 --- a/arch/m68knommu/kernel/signal.c +++ b/arch/m68knommu/kernel/signal.c | |||
@@ -732,13 +732,12 @@ handle_signal(int sig, struct k_sigaction *ka, siginfo_t *info, | |||
732 | if (ka->sa.sa_flags & SA_ONESHOT) | 732 | if (ka->sa.sa_flags & SA_ONESHOT) |
733 | ka->sa.sa_handler = SIG_DFL; | 733 | ka->sa.sa_handler = SIG_DFL; |
734 | 734 | ||
735 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 735 | spin_lock_irq(¤t->sighand->siglock); |
736 | spin_lock_irq(¤t->sighand->siglock); | 736 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
737 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 737 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
738 | sigaddset(¤t->blocked,sig); | 738 | sigaddset(¤t->blocked,sig); |
739 | recalc_sigpending(); | 739 | recalc_sigpending(); |
740 | spin_unlock_irq(¤t->sighand->siglock); | 740 | spin_unlock_irq(¤t->sighand->siglock); |
741 | } | ||
742 | } | 741 | } |
743 | 742 | ||
744 | /* | 743 | /* |
diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 40244782a8e5..4c114ae21793 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c | |||
@@ -155,13 +155,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
155 | else | 155 | else |
156 | setup_irix_frame(ka, regs, sig, oldset); | 156 | setup_irix_frame(ka, regs, sig, oldset); |
157 | 157 | ||
158 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 158 | spin_lock_irq(¤t->sighand->siglock); |
159 | spin_lock_irq(¤t->sighand->siglock); | 159 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
160 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 160 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
161 | sigaddset(¤t->blocked,sig); | 161 | sigaddset(¤t->blocked,sig); |
162 | recalc_sigpending(); | 162 | recalc_sigpending(); |
163 | spin_unlock_irq(¤t->sighand->siglock); | 163 | spin_unlock_irq(¤t->sighand->siglock); |
164 | } | ||
165 | } | 164 | } |
166 | 165 | ||
167 | asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) | 166 | asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) |
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 65ee15396ffd..0209c1dd1429 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c | |||
@@ -425,13 +425,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
425 | setup_frame(ka, regs, sig, oldset); | 425 | setup_frame(ka, regs, sig, oldset); |
426 | #endif | 426 | #endif |
427 | 427 | ||
428 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 428 | spin_lock_irq(¤t->sighand->siglock); |
429 | spin_lock_irq(¤t->sighand->siglock); | 429 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
430 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 430 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
431 | sigaddset(¤t->blocked,sig); | 431 | sigaddset(¤t->blocked,sig); |
432 | recalc_sigpending(); | 432 | recalc_sigpending(); |
433 | spin_unlock_irq(¤t->sighand->siglock); | 433 | spin_unlock_irq(¤t->sighand->siglock); |
434 | } | ||
435 | } | 434 | } |
436 | 435 | ||
437 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); | 436 | extern int do_signal32(sigset_t *oldset, struct pt_regs *regs); |
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index c1a69cf232f9..f6875f023a29 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -751,13 +751,12 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
751 | else | 751 | else |
752 | setup_frame(ka, regs, sig, oldset); | 752 | setup_frame(ka, regs, sig, oldset); |
753 | 753 | ||
754 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 754 | spin_lock_irq(¤t->sighand->siglock); |
755 | spin_lock_irq(¤t->sighand->siglock); | 755 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
756 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 756 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
757 | sigaddset(¤t->blocked,sig); | 757 | sigaddset(¤t->blocked,sig); |
758 | recalc_sigpending(); | 758 | recalc_sigpending(); |
759 | spin_unlock_irq(¤t->sighand->siglock); | 759 | spin_unlock_irq(¤t->sighand->siglock); |
760 | } | ||
761 | } | 760 | } |
762 | 761 | ||
763 | int do_signal32(sigset_t *oldset, struct pt_regs *regs) | 762 | int do_signal32(sigset_t *oldset, struct pt_regs *regs) |
diff --git a/arch/parisc/kernel/signal.c b/arch/parisc/kernel/signal.c index 9421bb98ea63..55d71c15e1f7 100644 --- a/arch/parisc/kernel/signal.c +++ b/arch/parisc/kernel/signal.c | |||
@@ -517,13 +517,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
517 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) | 517 | if (!setup_rt_frame(sig, ka, info, oldset, regs, in_syscall)) |
518 | return 0; | 518 | return 0; |
519 | 519 | ||
520 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 520 | spin_lock_irq(¤t->sighand->siglock); |
521 | spin_lock_irq(¤t->sighand->siglock); | 521 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
522 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 522 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
523 | sigaddset(¤t->blocked,sig); | 523 | sigaddset(¤t->blocked,sig); |
524 | recalc_sigpending(); | 524 | recalc_sigpending(); |
525 | spin_unlock_irq(¤t->sighand->siglock); | 525 | spin_unlock_irq(¤t->sighand->siglock); |
526 | } | ||
527 | return 1; | 526 | return 1; |
528 | } | 527 | } |
529 | 528 | ||
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig index f6db3b385fea..e6fa1d1cc03a 100644 --- a/arch/ppc/Kconfig +++ b/arch/ppc/Kconfig | |||
@@ -911,6 +911,7 @@ config PPCBUG_NVRAM | |||
911 | default y if PPC_PREP | 911 | default y if PPC_PREP |
912 | 912 | ||
913 | config SMP | 913 | config SMP |
914 | depends on PPC_STD_MMU | ||
914 | bool "Symmetric multi-processing support" | 915 | bool "Symmetric multi-processing support" |
915 | ---help--- | 916 | ---help--- |
916 | This enables support for systems with more than one CPU. If you have | 917 | This enables support for systems with more than one CPU. If you have |
@@ -930,7 +931,7 @@ config SMP | |||
930 | 931 | ||
931 | config IRQ_ALL_CPUS | 932 | config IRQ_ALL_CPUS |
932 | bool "Distribute interrupts on all CPUs by default" | 933 | bool "Distribute interrupts on all CPUs by default" |
933 | depends on SMP | 934 | depends on SMP && !MV64360 |
934 | help | 935 | help |
935 | This option gives the kernel permission to distribute IRQs across | 936 | This option gives the kernel permission to distribute IRQs across |
936 | multiple CPUs. Saying N here will route all IRQs to the first | 937 | multiple CPUs. Saying N here will route all IRQs to the first |
@@ -1121,7 +1122,9 @@ config PROC_HARDWARE | |||
1121 | 1122 | ||
1122 | source "drivers/zorro/Kconfig" | 1123 | source "drivers/zorro/Kconfig" |
1123 | 1124 | ||
1125 | if !44x || BROKEN | ||
1124 | source kernel/power/Kconfig | 1126 | source kernel/power/Kconfig |
1127 | endif | ||
1125 | 1128 | ||
1126 | config SECCOMP | 1129 | config SECCOMP |
1127 | bool "Enable seccomp to safely compute untrusted bytecode" | 1130 | bool "Enable seccomp to safely compute untrusted bytecode" |
diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 8aaeb6f4e750..2244bf91e593 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c | |||
@@ -759,13 +759,12 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) | |||
759 | else | 759 | else |
760 | handle_signal(signr, &ka, &info, oldset, regs, newsp); | 760 | handle_signal(signr, &ka, &info, oldset, regs, newsp); |
761 | 761 | ||
762 | if (!(ka.sa.sa_flags & SA_NODEFER)) { | 762 | spin_lock_irq(¤t->sighand->siglock); |
763 | spin_lock_irq(¤t->sighand->siglock); | 763 | sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); |
764 | sigorsets(¤t->blocked,¤t->blocked,&ka.sa.sa_mask); | 764 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
765 | sigaddset(¤t->blocked, signr); | 765 | sigaddset(¤t->blocked, signr); |
766 | recalc_sigpending(); | 766 | recalc_sigpending(); |
767 | spin_unlock_irq(¤t->sighand->siglock); | 767 | spin_unlock_irq(¤t->sighand->siglock); |
768 | } | ||
769 | 768 | ||
770 | return 1; | 769 | return 1; |
771 | } | 770 | } |
diff --git a/arch/ppc/platforms/4xx/Kconfig b/arch/ppc/platforms/4xx/Kconfig index f7c045764e04..805dd98908a3 100644 --- a/arch/ppc/platforms/4xx/Kconfig +++ b/arch/ppc/platforms/4xx/Kconfig | |||
@@ -3,6 +3,11 @@ config 4xx | |||
3 | depends on 40x || 44x | 3 | depends on 40x || 44x |
4 | default y | 4 | default y |
5 | 5 | ||
6 | config WANT_EARLY_SERIAL | ||
7 | bool | ||
8 | select SERIAL_8250 | ||
9 | default n | ||
10 | |||
6 | menu "IBM 4xx options" | 11 | menu "IBM 4xx options" |
7 | depends on 4xx | 12 | depends on 4xx |
8 | 13 | ||
@@ -18,6 +23,7 @@ config ASH | |||
18 | 23 | ||
19 | config BUBINGA | 24 | config BUBINGA |
20 | bool "Bubinga" | 25 | bool "Bubinga" |
26 | select WANT_EARLY_SERIAL | ||
21 | help | 27 | help |
22 | This option enables support for the IBM 405EP evaluation board. | 28 | This option enables support for the IBM 405EP evaluation board. |
23 | 29 | ||
@@ -70,21 +76,25 @@ choice | |||
70 | 76 | ||
71 | config BAMBOO | 77 | config BAMBOO |
72 | bool "Bamboo" | 78 | bool "Bamboo" |
79 | select WANT_EARLY_SERIAL | ||
73 | help | 80 | help |
74 | This option enables support for the IBM PPC440EP evaluation board. | 81 | This option enables support for the IBM PPC440EP evaluation board. |
75 | 82 | ||
76 | config EBONY | 83 | config EBONY |
77 | bool "Ebony" | 84 | bool "Ebony" |
85 | select WANT_EARLY_SERIAL | ||
78 | help | 86 | help |
79 | This option enables support for the IBM PPC440GP evaluation board. | 87 | This option enables support for the IBM PPC440GP evaluation board. |
80 | 88 | ||
81 | config LUAN | 89 | config LUAN |
82 | bool "Luan" | 90 | bool "Luan" |
91 | select WANT_EARLY_SERIAL | ||
83 | help | 92 | help |
84 | This option enables support for the IBM PPC440SP evaluation board. | 93 | This option enables support for the IBM PPC440SP evaluation board. |
85 | 94 | ||
86 | config OCOTEA | 95 | config OCOTEA |
87 | bool "Ocotea" | 96 | bool "Ocotea" |
97 | select WANT_EARLY_SERIAL | ||
88 | help | 98 | help |
89 | This option enables support for the IBM PPC440GX evaluation board. | 99 | This option enables support for the IBM PPC440GX evaluation board. |
90 | 100 | ||
@@ -230,10 +240,6 @@ config PPC_GEN550 | |||
230 | depends on 4xx | 240 | depends on 4xx |
231 | default y | 241 | default y |
232 | 242 | ||
233 | config PM | ||
234 | bool "Power Management support (EXPERIMENTAL)" | ||
235 | depends on 4xx && EXPERIMENTAL | ||
236 | |||
237 | choice | 243 | choice |
238 | prompt "TTYS0 device and default console" | 244 | prompt "TTYS0 device and default console" |
239 | depends on 40x | 245 | depends on 40x |
diff --git a/arch/ppc/syslib/m8xx_setup.c b/arch/ppc/syslib/m8xx_setup.c index 55a381af4e37..a3702cfe8f7c 100644 --- a/arch/ppc/syslib/m8xx_setup.c +++ b/arch/ppc/syslib/m8xx_setup.c | |||
@@ -423,7 +423,7 @@ platform_init(unsigned long r3, unsigned long r4, unsigned long r5, | |||
423 | ppc_md.find_end_of_memory = m8xx_find_end_of_memory; | 423 | ppc_md.find_end_of_memory = m8xx_find_end_of_memory; |
424 | ppc_md.setup_io_mappings = m8xx_map_io; | 424 | ppc_md.setup_io_mappings = m8xx_map_io; |
425 | 425 | ||
426 | #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE) | 426 | #if defined(CONFIG_BLK_DEV_MPC8xx_IDE) |
427 | m8xx_ide_init(); | 427 | m8xx_ide_init(); |
428 | #endif | 428 | #endif |
429 | } | 429 | } |
diff --git a/arch/ppc/syslib/ppc4xx_dma.c b/arch/ppc/syslib/ppc4xx_dma.c index 5015ab99afd2..f15e64285f96 100644 --- a/arch/ppc/syslib/ppc4xx_dma.c +++ b/arch/ppc/syslib/ppc4xx_dma.c | |||
@@ -620,6 +620,7 @@ ppc4xx_clr_dma_status(unsigned int dmanr) | |||
620 | return DMA_STATUS_GOOD; | 620 | return DMA_STATUS_GOOD; |
621 | } | 621 | } |
622 | 622 | ||
623 | #ifdef CONFIG_PPC4xx_EDMA | ||
623 | /* | 624 | /* |
624 | * Enables the burst on the channel (BTEN bit in the control/count register) | 625 | * Enables the burst on the channel (BTEN bit in the control/count register) |
625 | * Note: | 626 | * Note: |
@@ -685,6 +686,11 @@ ppc4xx_set_burst_size(unsigned int dmanr, unsigned int bsize) | |||
685 | return DMA_STATUS_GOOD; | 686 | return DMA_STATUS_GOOD; |
686 | } | 687 | } |
687 | 688 | ||
689 | EXPORT_SYMBOL(ppc4xx_enable_burst); | ||
690 | EXPORT_SYMBOL(ppc4xx_disable_burst); | ||
691 | EXPORT_SYMBOL(ppc4xx_set_burst_size); | ||
692 | #endif /* CONFIG_PPC4xx_EDMA */ | ||
693 | |||
688 | EXPORT_SYMBOL(ppc4xx_init_dma_channel); | 694 | EXPORT_SYMBOL(ppc4xx_init_dma_channel); |
689 | EXPORT_SYMBOL(ppc4xx_get_channel_config); | 695 | EXPORT_SYMBOL(ppc4xx_get_channel_config); |
690 | EXPORT_SYMBOL(ppc4xx_set_channel_priority); | 696 | EXPORT_SYMBOL(ppc4xx_set_channel_priority); |
@@ -703,6 +709,4 @@ EXPORT_SYMBOL(ppc4xx_enable_dma_interrupt); | |||
703 | EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt); | 709 | EXPORT_SYMBOL(ppc4xx_disable_dma_interrupt); |
704 | EXPORT_SYMBOL(ppc4xx_get_dma_status); | 710 | EXPORT_SYMBOL(ppc4xx_get_dma_status); |
705 | EXPORT_SYMBOL(ppc4xx_clr_dma_status); | 711 | EXPORT_SYMBOL(ppc4xx_clr_dma_status); |
706 | EXPORT_SYMBOL(ppc4xx_enable_burst); | 712 | |
707 | EXPORT_SYMBOL(ppc4xx_disable_burst); | ||
708 | EXPORT_SYMBOL(ppc4xx_set_burst_size); | ||
diff --git a/arch/ppc64/kernel/setup.c b/arch/ppc64/kernel/setup.c index 687e85595208..e9c24d2dbd91 100644 --- a/arch/ppc64/kernel/setup.c +++ b/arch/ppc64/kernel/setup.c | |||
@@ -706,6 +706,8 @@ void machine_power_off(void) | |||
706 | local_irq_disable(); | 706 | local_irq_disable(); |
707 | while (1) ; | 707 | while (1) ; |
708 | } | 708 | } |
709 | /* Used by the G5 thermal driver */ | ||
710 | EXPORT_SYMBOL_GPL(machine_power_off); | ||
709 | 711 | ||
710 | void machine_halt(void) | 712 | void machine_halt(void) |
711 | { | 713 | { |
diff --git a/arch/ppc64/kernel/signal.c b/arch/ppc64/kernel/signal.c index bf782276984c..49a79a55c32d 100644 --- a/arch/ppc64/kernel/signal.c +++ b/arch/ppc64/kernel/signal.c | |||
@@ -481,10 +481,11 @@ static int handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
481 | /* Set up Signal Frame */ | 481 | /* Set up Signal Frame */ |
482 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 482 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
483 | 483 | ||
484 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 484 | if (ret) { |
485 | spin_lock_irq(¤t->sighand->siglock); | 485 | spin_lock_irq(¤t->sighand->siglock); |
486 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); | 486 | sigorsets(¤t->blocked, ¤t->blocked, &ka->sa.sa_mask); |
487 | sigaddset(¤t->blocked,sig); | 487 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
488 | sigaddset(¤t->blocked,sig); | ||
488 | recalc_sigpending(); | 489 | recalc_sigpending(); |
489 | spin_unlock_irq(¤t->sighand->siglock); | 490 | spin_unlock_irq(¤t->sighand->siglock); |
490 | } | 491 | } |
diff --git a/arch/ppc64/kernel/signal32.c b/arch/ppc64/kernel/signal32.c index 3c2fa5c284c0..46f4d6cc7fc9 100644 --- a/arch/ppc64/kernel/signal32.c +++ b/arch/ppc64/kernel/signal32.c | |||
@@ -976,11 +976,12 @@ int do_signal32(sigset_t *oldset, struct pt_regs *regs) | |||
976 | else | 976 | else |
977 | ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); | 977 | ret = handle_signal32(signr, &ka, &info, oldset, regs, newsp); |
978 | 978 | ||
979 | if (ret && !(ka.sa.sa_flags & SA_NODEFER)) { | 979 | if (ret) { |
980 | spin_lock_irq(¤t->sighand->siglock); | 980 | spin_lock_irq(¤t->sighand->siglock); |
981 | sigorsets(¤t->blocked, ¤t->blocked, | 981 | sigorsets(¤t->blocked, ¤t->blocked, |
982 | &ka.sa.sa_mask); | 982 | &ka.sa.sa_mask); |
983 | sigaddset(¤t->blocked, signr); | 983 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
984 | sigaddset(¤t->blocked, signr); | ||
984 | recalc_sigpending(); | 985 | recalc_sigpending(); |
985 | spin_unlock_irq(¤t->sighand->siglock); | 986 | spin_unlock_irq(¤t->sighand->siglock); |
986 | } | 987 | } |
diff --git a/arch/s390/kernel/compat_signal.c b/arch/s390/kernel/compat_signal.c index d05d65ac9694..7358cdb8441f 100644 --- a/arch/s390/kernel/compat_signal.c +++ b/arch/s390/kernel/compat_signal.c | |||
@@ -637,12 +637,11 @@ handle_signal32(unsigned long sig, struct k_sigaction *ka, | |||
637 | else | 637 | else |
638 | setup_frame32(sig, ka, oldset, regs); | 638 | setup_frame32(sig, ka, oldset, regs); |
639 | 639 | ||
640 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 640 | spin_lock_irq(¤t->sighand->siglock); |
641 | spin_lock_irq(¤t->sighand->siglock); | 641 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
642 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 642 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
643 | sigaddset(¤t->blocked,sig); | 643 | sigaddset(¤t->blocked,sig); |
644 | recalc_sigpending(); | 644 | recalc_sigpending(); |
645 | spin_unlock_irq(¤t->sighand->siglock); | 645 | spin_unlock_irq(¤t->sighand->siglock); |
646 | } | ||
647 | } | 646 | } |
648 | 647 | ||
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c index 20062145e84e..d47fecb42cc5 100644 --- a/arch/s390/kernel/cpcmd.c +++ b/arch/s390/kernel/cpcmd.c | |||
@@ -46,9 +46,9 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) | |||
46 | "lra 3,0(%4)\n" | 46 | "lra 3,0(%4)\n" |
47 | "lr 5,%5\n" | 47 | "lr 5,%5\n" |
48 | "diag 2,4,0x8\n" | 48 | "diag 2,4,0x8\n" |
49 | "brc 8, .Litfits\n" | 49 | "brc 8, 1f\n" |
50 | "ar 5, %5\n" | 50 | "ar 5, %5\n" |
51 | ".Litfits: \n" | 51 | "1: \n" |
52 | "lr %0,4\n" | 52 | "lr %0,4\n" |
53 | "lr %1,5\n" | 53 | "lr %1,5\n" |
54 | : "=d" (return_code), "=d" (return_len) | 54 | : "=d" (return_code), "=d" (return_len) |
@@ -64,9 +64,9 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) | |||
64 | "sam31\n" | 64 | "sam31\n" |
65 | "diag 2,4,0x8\n" | 65 | "diag 2,4,0x8\n" |
66 | "sam64\n" | 66 | "sam64\n" |
67 | "brc 8, .Litfits\n" | 67 | "brc 8, 1f\n" |
68 | "agr 5, %5\n" | 68 | "agr 5, %5\n" |
69 | ".Litfits: \n" | 69 | "1: \n" |
70 | "lgr %0,4\n" | 70 | "lgr %0,4\n" |
71 | "lgr %1,5\n" | 71 | "lgr %1,5\n" |
72 | : "=d" (return_code), "=d" (return_len) | 72 | : "=d" (return_code), "=d" (return_len) |
diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index 610c1d03e975..6a3f5b7473a9 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c | |||
@@ -429,13 +429,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, | |||
429 | else | 429 | else |
430 | setup_frame(sig, ka, oldset, regs); | 430 | setup_frame(sig, ka, oldset, regs); |
431 | 431 | ||
432 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 432 | spin_lock_irq(¤t->sighand->siglock); |
433 | spin_lock_irq(¤t->sighand->siglock); | 433 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
434 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 434 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
435 | sigaddset(¤t->blocked,sig); | 435 | sigaddset(¤t->blocked,sig); |
436 | recalc_sigpending(); | 436 | recalc_sigpending(); |
437 | spin_unlock_irq(¤t->sighand->siglock); | 437 | spin_unlock_irq(¤t->sighand->siglock); |
438 | } | ||
439 | } | 438 | } |
440 | 439 | ||
441 | /* | 440 | /* |
diff --git a/arch/sh/kernel/entry.S b/arch/sh/kernel/entry.S index 6615e4838ee4..fb6368159dd0 100644 --- a/arch/sh/kernel/entry.S +++ b/arch/sh/kernel/entry.S | |||
@@ -1145,5 +1145,10 @@ ENTRY(sys_call_table) | |||
1145 | .long sys_add_key /* 285 */ | 1145 | .long sys_add_key /* 285 */ |
1146 | .long sys_request_key | 1146 | .long sys_request_key |
1147 | .long sys_keyctl | 1147 | .long sys_keyctl |
1148 | .long sys_ioprio_set | ||
1149 | .long sys_ioprio_get | ||
1150 | .long sys_inotify_init /* 290 */ | ||
1151 | .long sys_inotify_add_watch | ||
1152 | .long sys_inotify_rm_watch | ||
1148 | 1153 | ||
1149 | /* End of entry.S */ | 1154 | /* End of entry.S */ |
diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 8022243f0178..b475c4d2405f 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c | |||
@@ -546,13 +546,12 @@ handle_signal(unsigned long sig, struct k_sigaction *ka, siginfo_t *info, | |||
546 | if (ka->sa.sa_flags & SA_ONESHOT) | 546 | if (ka->sa.sa_flags & SA_ONESHOT) |
547 | ka->sa.sa_handler = SIG_DFL; | 547 | ka->sa.sa_handler = SIG_DFL; |
548 | 548 | ||
549 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 549 | spin_lock_irq(¤t->sighand->siglock); |
550 | spin_lock_irq(¤t->sighand->siglock); | 550 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
551 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 551 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
552 | sigaddset(¤t->blocked,sig); | 552 | sigaddset(¤t->blocked,sig); |
553 | recalc_sigpending(); | 553 | recalc_sigpending(); |
554 | spin_unlock_irq(¤t->sighand->siglock); | 554 | spin_unlock_irq(¤t->sighand->siglock); |
555 | } | ||
556 | } | 555 | } |
557 | 556 | ||
558 | /* | 557 | /* |
diff --git a/arch/sh64/kernel/signal.c b/arch/sh64/kernel/signal.c index c6a14a87c59b..3ea8929e483b 100644 --- a/arch/sh64/kernel/signal.c +++ b/arch/sh64/kernel/signal.c | |||
@@ -664,13 +664,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
664 | else | 664 | else |
665 | setup_frame(sig, ka, oldset, regs); | 665 | setup_frame(sig, ka, oldset, regs); |
666 | 666 | ||
667 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 667 | spin_lock_irq(¤t->sighand->siglock); |
668 | spin_lock_irq(¤t->sighand->siglock); | 668 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
669 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 669 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
670 | sigaddset(¤t->blocked,sig); | 670 | sigaddset(¤t->blocked,sig); |
671 | recalc_sigpending(); | 671 | recalc_sigpending(); |
672 | spin_unlock_irq(¤t->sighand->siglock); | 672 | spin_unlock_irq(¤t->sighand->siglock); |
673 | } | ||
674 | } | 673 | } |
675 | 674 | ||
676 | /* | 675 | /* |
diff --git a/arch/sh64/kernel/syscalls.S b/arch/sh64/kernel/syscalls.S index 6aabc63e4518..a3d037805f1c 100644 --- a/arch/sh64/kernel/syscalls.S +++ b/arch/sh64/kernel/syscalls.S | |||
@@ -342,4 +342,9 @@ sys_call_table: | |||
342 | .long sys_add_key | 342 | .long sys_add_key |
343 | .long sys_request_key | 343 | .long sys_request_key |
344 | .long sys_keyctl /* 315 */ | 344 | .long sys_keyctl /* 315 */ |
345 | .long sys_ioprio_set | ||
346 | .long sys_ioprio_get | ||
347 | .long sys_inotify_init | ||
348 | .long sys_inotify_add_watch | ||
349 | .long sys_inotify_rm_watch /* 320 */ | ||
345 | 350 | ||
diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index 011ff35057a5..5f34d7dc2b89 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c | |||
@@ -1034,13 +1034,12 @@ handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
1034 | else | 1034 | else |
1035 | setup_frame(&ka->sa, regs, signr, oldset, info); | 1035 | setup_frame(&ka->sa, regs, signr, oldset, info); |
1036 | } | 1036 | } |
1037 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 1037 | spin_lock_irq(¤t->sighand->siglock); |
1038 | spin_lock_irq(¤t->sighand->siglock); | 1038 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1039 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 1039 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
1040 | sigaddset(¤t->blocked, signr); | 1040 | sigaddset(¤t->blocked, signr); |
1041 | recalc_sigpending(); | 1041 | recalc_sigpending(); |
1042 | spin_unlock_irq(¤t->sighand->siglock); | 1042 | spin_unlock_irq(¤t->sighand->siglock); |
1043 | } | ||
1044 | } | 1043 | } |
1045 | 1044 | ||
1046 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 1045 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc/kernel/sparc_ksyms.c b/arch/sparc/kernel/sparc_ksyms.c index 1bd430d0ca06..8faa8dc4de43 100644 --- a/arch/sparc/kernel/sparc_ksyms.c +++ b/arch/sparc/kernel/sparc_ksyms.c | |||
@@ -98,8 +98,9 @@ extern void ___rw_write_enter(void); | |||
98 | * The module references will be fixed up by module_frob_arch_sections. | 98 | * The module references will be fixed up by module_frob_arch_sections. |
99 | */ | 99 | */ |
100 | #define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \ | 100 | #define DOT_ALIAS2(__ret, __x, __arg1, __arg2) \ |
101 | extern __ret __x(__arg1, __arg2) \ | 101 | extern __ret __x(__arg1, __arg2); \ |
102 | __attribute__((weak, alias("." # __x))); | 102 | asm(".weak " #__x);\ |
103 | asm(#__x "=." #__x); | ||
103 | 104 | ||
104 | DOT_ALIAS2(int, div, int, int) | 105 | DOT_ALIAS2(int, div, int, int) |
105 | DOT_ALIAS2(int, mul, int, int) | 106 | DOT_ALIAS2(int, mul, int, int) |
diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 093281bdf85f..6f00ab8b9d23 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile | |||
@@ -8,7 +8,7 @@ EXTRA_CFLAGS := -Werror | |||
8 | extra-y := head.o init_task.o vmlinux.lds | 8 | extra-y := head.o init_task.o vmlinux.lds |
9 | 9 | ||
10 | obj-y := process.o setup.o cpu.o idprom.o \ | 10 | obj-y := process.o setup.o cpu.o idprom.o \ |
11 | traps.o devices.o auxio.o \ | 11 | traps.o devices.o auxio.o una_asm.o \ |
12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ | 12 | irq.o ptrace.o time.o sys_sparc.o signal.o \ |
13 | unaligned.o central.o pci.o starfire.o semaphore.o \ | 13 | unaligned.o central.o pci.o starfire.o semaphore.o \ |
14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o | 14 | power.o sbus.o iommu_common.o sparc64_ksyms.o chmc.o |
diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index bba140d98b1b..f21c993f8856 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c | |||
@@ -540,6 +540,7 @@ void pcibios_bus_to_resource(struct pci_dev *pdev, struct resource *res, | |||
540 | 540 | ||
541 | pbm->parent->resource_adjust(pdev, res, root); | 541 | pbm->parent->resource_adjust(pdev, res, root); |
542 | } | 542 | } |
543 | EXPORT_SYMBOL(pcibios_bus_to_resource); | ||
543 | 544 | ||
544 | char * __init pcibios_setup(char *str) | 545 | char * __init pcibios_setup(char *str) |
545 | { | 546 | { |
diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index b27934671c35..60f5dfabb1e1 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c | |||
@@ -574,13 +574,12 @@ static inline void handle_signal(unsigned long signr, struct k_sigaction *ka, | |||
574 | { | 574 | { |
575 | setup_rt_frame(ka, regs, signr, oldset, | 575 | setup_rt_frame(ka, regs, signr, oldset, |
576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); | 576 | (ka->sa.sa_flags & SA_SIGINFO) ? info : NULL); |
577 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 577 | spin_lock_irq(¤t->sighand->siglock); |
578 | spin_lock_irq(¤t->sighand->siglock); | 578 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
579 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 579 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
580 | sigaddset(¤t->blocked,signr); | 580 | sigaddset(¤t->blocked,signr); |
581 | recalc_sigpending(); | 581 | recalc_sigpending(); |
582 | spin_unlock_irq(¤t->sighand->siglock); | 582 | spin_unlock_irq(¤t->sighand->siglock); |
583 | } | ||
584 | } | 583 | } |
585 | 584 | ||
586 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, | 585 | static inline void syscall_restart(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index f28428f4170e..b1ed23091fbb 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c | |||
@@ -1325,13 +1325,12 @@ static inline void handle_signal32(unsigned long signr, struct k_sigaction *ka, | |||
1325 | else | 1325 | else |
1326 | setup_frame32(&ka->sa, regs, signr, oldset, info); | 1326 | setup_frame32(&ka->sa, regs, signr, oldset, info); |
1327 | } | 1327 | } |
1328 | if (!(ka->sa.sa_flags & SA_NOMASK)) { | 1328 | spin_lock_irq(¤t->sighand->siglock); |
1329 | spin_lock_irq(¤t->sighand->siglock); | 1329 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
1330 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 1330 | if (!(ka->sa.sa_flags & SA_NOMASK)) |
1331 | sigaddset(¤t->blocked,signr); | 1331 | sigaddset(¤t->blocked,signr); |
1332 | recalc_sigpending(); | 1332 | recalc_sigpending(); |
1333 | spin_unlock_irq(¤t->sighand->siglock); | 1333 | spin_unlock_irq(¤t->sighand->siglock); |
1334 | } | ||
1335 | } | 1334 | } |
1336 | 1335 | ||
1337 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, | 1336 | static inline void syscall_restart32(unsigned long orig_i0, struct pt_regs *regs, |
diff --git a/arch/sparc64/kernel/traps.c b/arch/sparc64/kernel/traps.c index 100b0107c4be..0c9e54b2f0c8 100644 --- a/arch/sparc64/kernel/traps.c +++ b/arch/sparc64/kernel/traps.c | |||
@@ -2127,6 +2127,9 @@ void __init trap_init(void) | |||
2127 | TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || | 2127 | TI_PRE_COUNT != offsetof(struct thread_info, preempt_count) || |
2128 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || | 2128 | TI_NEW_CHILD != offsetof(struct thread_info, new_child) || |
2129 | TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || | 2129 | TI_SYS_NOERROR != offsetof(struct thread_info, syscall_noerror) || |
2130 | TI_RESTART_BLOCK != offsetof(struct thread_info, restart_block) || | ||
2131 | TI_KUNA_REGS != offsetof(struct thread_info, kern_una_regs) || | ||
2132 | TI_KUNA_INSN != offsetof(struct thread_info, kern_una_insn) || | ||
2130 | TI_FPREGS != offsetof(struct thread_info, fpregs) || | 2133 | TI_FPREGS != offsetof(struct thread_info, fpregs) || |
2131 | (TI_FPREGS & (64 - 1))) | 2134 | (TI_FPREGS & (64 - 1))) |
2132 | thread_info_offsets_are_bolixed_dave(); | 2135 | thread_info_offsets_are_bolixed_dave(); |
diff --git a/arch/sparc64/kernel/una_asm.S b/arch/sparc64/kernel/una_asm.S new file mode 100644 index 000000000000..cbb40585253c --- /dev/null +++ b/arch/sparc64/kernel/una_asm.S | |||
@@ -0,0 +1,153 @@ | |||
1 | /* una_asm.S: Kernel unaligned trap assembler helpers. | ||
2 | * | ||
3 | * Copyright (C) 1996,2005 David S. Miller (davem@davemloft.net) | ||
4 | * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) | ||
5 | */ | ||
6 | |||
7 | .text | ||
8 | |||
9 | kernel_unaligned_trap_fault: | ||
10 | call kernel_mna_trap_fault | ||
11 | nop | ||
12 | retl | ||
13 | nop | ||
14 | .size kern_unaligned_trap_fault, .-kern_unaligned_trap_fault | ||
15 | |||
16 | .globl __do_int_store | ||
17 | __do_int_store: | ||
18 | rd %asi, %o4 | ||
19 | wr %o3, 0, %asi | ||
20 | ldx [%o2], %g3 | ||
21 | cmp %o1, 2 | ||
22 | be,pn %icc, 2f | ||
23 | cmp %o1, 4 | ||
24 | be,pt %icc, 1f | ||
25 | srlx %g3, 24, %g2 | ||
26 | srlx %g3, 56, %g1 | ||
27 | srlx %g3, 48, %g7 | ||
28 | 4: stba %g1, [%o0] %asi | ||
29 | srlx %g3, 40, %g1 | ||
30 | 5: stba %g7, [%o0 + 1] %asi | ||
31 | srlx %g3, 32, %g7 | ||
32 | 6: stba %g1, [%o0 + 2] %asi | ||
33 | 7: stba %g7, [%o0 + 3] %asi | ||
34 | srlx %g3, 16, %g1 | ||
35 | 8: stba %g2, [%o0 + 4] %asi | ||
36 | srlx %g3, 8, %g7 | ||
37 | 9: stba %g1, [%o0 + 5] %asi | ||
38 | 10: stba %g7, [%o0 + 6] %asi | ||
39 | ba,pt %xcc, 0f | ||
40 | 11: stba %g3, [%o0 + 7] %asi | ||
41 | 1: srl %g3, 16, %g7 | ||
42 | 12: stba %g2, [%o0] %asi | ||
43 | srl %g3, 8, %g2 | ||
44 | 13: stba %g7, [%o0 + 1] %asi | ||
45 | 14: stba %g2, [%o0 + 2] %asi | ||
46 | ba,pt %xcc, 0f | ||
47 | 15: stba %g3, [%o0 + 3] %asi | ||
48 | 2: srl %g3, 8, %g2 | ||
49 | 16: stba %g2, [%o0] %asi | ||
50 | 17: stba %g3, [%o0 + 1] %asi | ||
51 | 0: | ||
52 | wr %o4, 0x0, %asi | ||
53 | retl | ||
54 | nop | ||
55 | .size __do_int_store, .-__do_int_store | ||
56 | |||
57 | .section __ex_table | ||
58 | .word 4b, kernel_unaligned_trap_fault | ||
59 | .word 5b, kernel_unaligned_trap_fault | ||
60 | .word 6b, kernel_unaligned_trap_fault | ||
61 | .word 7b, kernel_unaligned_trap_fault | ||
62 | .word 8b, kernel_unaligned_trap_fault | ||
63 | .word 9b, kernel_unaligned_trap_fault | ||
64 | .word 10b, kernel_unaligned_trap_fault | ||
65 | .word 11b, kernel_unaligned_trap_fault | ||
66 | .word 12b, kernel_unaligned_trap_fault | ||
67 | .word 13b, kernel_unaligned_trap_fault | ||
68 | .word 14b, kernel_unaligned_trap_fault | ||
69 | .word 15b, kernel_unaligned_trap_fault | ||
70 | .word 16b, kernel_unaligned_trap_fault | ||
71 | .word 17b, kernel_unaligned_trap_fault | ||
72 | .previous | ||
73 | |||
74 | .globl do_int_load | ||
75 | do_int_load: | ||
76 | rd %asi, %o5 | ||
77 | wr %o4, 0, %asi | ||
78 | cmp %o1, 8 | ||
79 | bge,pn %icc, 9f | ||
80 | cmp %o1, 4 | ||
81 | be,pt %icc, 6f | ||
82 | 4: lduba [%o2] %asi, %g2 | ||
83 | 5: lduba [%o2 + 1] %asi, %g3 | ||
84 | sll %g2, 8, %g2 | ||
85 | brz,pt %o3, 3f | ||
86 | add %g2, %g3, %g2 | ||
87 | sllx %g2, 48, %g2 | ||
88 | srax %g2, 48, %g2 | ||
89 | 3: ba,pt %xcc, 0f | ||
90 | stx %g2, [%o0] | ||
91 | 6: lduba [%o2 + 1] %asi, %g3 | ||
92 | sll %g2, 24, %g2 | ||
93 | 7: lduba [%o2 + 2] %asi, %g7 | ||
94 | sll %g3, 16, %g3 | ||
95 | 8: lduba [%o2 + 3] %asi, %g1 | ||
96 | sll %g7, 8, %g7 | ||
97 | or %g2, %g3, %g2 | ||
98 | or %g7, %g1, %g7 | ||
99 | or %g2, %g7, %g2 | ||
100 | brnz,a,pt %o3, 3f | ||
101 | sra %g2, 0, %g2 | ||
102 | 3: ba,pt %xcc, 0f | ||
103 | stx %g2, [%o0] | ||
104 | 9: lduba [%o2] %asi, %g2 | ||
105 | 10: lduba [%o2 + 1] %asi, %g3 | ||
106 | sllx %g2, 56, %g2 | ||
107 | 11: lduba [%o2 + 2] %asi, %g7 | ||
108 | sllx %g3, 48, %g3 | ||
109 | 12: lduba [%o2 + 3] %asi, %g1 | ||
110 | sllx %g7, 40, %g7 | ||
111 | sllx %g1, 32, %g1 | ||
112 | or %g2, %g3, %g2 | ||
113 | or %g7, %g1, %g7 | ||
114 | 13: lduba [%o2 + 4] %asi, %g3 | ||
115 | or %g2, %g7, %g7 | ||
116 | 14: lduba [%o2 + 5] %asi, %g1 | ||
117 | sllx %g3, 24, %g3 | ||
118 | 15: lduba [%o2 + 6] %asi, %g2 | ||
119 | sllx %g1, 16, %g1 | ||
120 | or %g7, %g3, %g7 | ||
121 | 16: lduba [%o2 + 7] %asi, %g3 | ||
122 | sllx %g2, 8, %g2 | ||
123 | or %g7, %g1, %g7 | ||
124 | or %g2, %g3, %g2 | ||
125 | or %g7, %g2, %g7 | ||
126 | cmp %o1, 8 | ||
127 | be,a,pt %icc, 0f | ||
128 | stx %g7, [%o0] | ||
129 | srlx %g7, 32, %g2 | ||
130 | sra %g7, 0, %g7 | ||
131 | stx %g2, [%o0] | ||
132 | stx %g7, [%o0 + 8] | ||
133 | 0: | ||
134 | wr %o5, 0x0, %asi | ||
135 | retl | ||
136 | nop | ||
137 | .size __do_int_load, .-__do_int_load | ||
138 | |||
139 | .section __ex_table | ||
140 | .word 4b, kernel_unaligned_trap_fault | ||
141 | .word 5b, kernel_unaligned_trap_fault | ||
142 | .word 6b, kernel_unaligned_trap_fault | ||
143 | .word 7b, kernel_unaligned_trap_fault | ||
144 | .word 8b, kernel_unaligned_trap_fault | ||
145 | .word 9b, kernel_unaligned_trap_fault | ||
146 | .word 10b, kernel_unaligned_trap_fault | ||
147 | .word 11b, kernel_unaligned_trap_fault | ||
148 | .word 12b, kernel_unaligned_trap_fault | ||
149 | .word 13b, kernel_unaligned_trap_fault | ||
150 | .word 14b, kernel_unaligned_trap_fault | ||
151 | .word 15b, kernel_unaligned_trap_fault | ||
152 | .word 16b, kernel_unaligned_trap_fault | ||
153 | .previous | ||
diff --git a/arch/sparc64/kernel/unaligned.c b/arch/sparc64/kernel/unaligned.c index 4372bf32ecf6..11c3e88732e4 100644 --- a/arch/sparc64/kernel/unaligned.c +++ b/arch/sparc64/kernel/unaligned.c | |||
@@ -180,169 +180,28 @@ static void __attribute_used__ unaligned_panic(char *str, struct pt_regs *regs) | |||
180 | die_if_kernel(str, regs); | 180 | die_if_kernel(str, regs); |
181 | } | 181 | } |
182 | 182 | ||
183 | #define do_integer_load(dest_reg, size, saddr, is_signed, asi, errh) ({ \ | 183 | extern void do_int_load(unsigned long *dest_reg, int size, |
184 | __asm__ __volatile__ ( \ | 184 | unsigned long *saddr, int is_signed, int asi); |
185 | "wr %4, 0, %%asi\n\t" \ | ||
186 | "cmp %1, 8\n\t" \ | ||
187 | "bge,pn %%icc, 9f\n\t" \ | ||
188 | " cmp %1, 4\n\t" \ | ||
189 | "be,pt %%icc, 6f\n" \ | ||
190 | "4:\t" " lduba [%2] %%asi, %%l1\n" \ | ||
191 | "5:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
192 | "sll %%l1, 8, %%l1\n\t" \ | ||
193 | "brz,pt %3, 3f\n\t" \ | ||
194 | " add %%l1, %%l2, %%l1\n\t" \ | ||
195 | "sllx %%l1, 48, %%l1\n\t" \ | ||
196 | "srax %%l1, 48, %%l1\n" \ | ||
197 | "3:\t" "ba,pt %%xcc, 0f\n\t" \ | ||
198 | " stx %%l1, [%0]\n" \ | ||
199 | "6:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
200 | "sll %%l1, 24, %%l1\n" \ | ||
201 | "7:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \ | ||
202 | "sll %%l2, 16, %%l2\n" \ | ||
203 | "8:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \ | ||
204 | "sll %%g7, 8, %%g7\n\t" \ | ||
205 | "or %%l1, %%l2, %%l1\n\t" \ | ||
206 | "or %%g7, %%g1, %%g7\n\t" \ | ||
207 | "or %%l1, %%g7, %%l1\n\t" \ | ||
208 | "brnz,a,pt %3, 3f\n\t" \ | ||
209 | " sra %%l1, 0, %%l1\n" \ | ||
210 | "3:\t" "ba,pt %%xcc, 0f\n\t" \ | ||
211 | " stx %%l1, [%0]\n" \ | ||
212 | "9:\t" "lduba [%2] %%asi, %%l1\n" \ | ||
213 | "10:\t" "lduba [%2 + 1] %%asi, %%l2\n\t" \ | ||
214 | "sllx %%l1, 56, %%l1\n" \ | ||
215 | "11:\t" "lduba [%2 + 2] %%asi, %%g7\n\t" \ | ||
216 | "sllx %%l2, 48, %%l2\n" \ | ||
217 | "12:\t" "lduba [%2 + 3] %%asi, %%g1\n\t" \ | ||
218 | "sllx %%g7, 40, %%g7\n\t" \ | ||
219 | "sllx %%g1, 32, %%g1\n\t" \ | ||
220 | "or %%l1, %%l2, %%l1\n\t" \ | ||
221 | "or %%g7, %%g1, %%g7\n" \ | ||
222 | "13:\t" "lduba [%2 + 4] %%asi, %%l2\n\t" \ | ||
223 | "or %%l1, %%g7, %%g7\n" \ | ||
224 | "14:\t" "lduba [%2 + 5] %%asi, %%g1\n\t" \ | ||
225 | "sllx %%l2, 24, %%l2\n" \ | ||
226 | "15:\t" "lduba [%2 + 6] %%asi, %%l1\n\t" \ | ||
227 | "sllx %%g1, 16, %%g1\n\t" \ | ||
228 | "or %%g7, %%l2, %%g7\n" \ | ||
229 | "16:\t" "lduba [%2 + 7] %%asi, %%l2\n\t" \ | ||
230 | "sllx %%l1, 8, %%l1\n\t" \ | ||
231 | "or %%g7, %%g1, %%g7\n\t" \ | ||
232 | "or %%l1, %%l2, %%l1\n\t" \ | ||
233 | "or %%g7, %%l1, %%g7\n\t" \ | ||
234 | "cmp %1, 8\n\t" \ | ||
235 | "be,a,pt %%icc, 0f\n\t" \ | ||
236 | " stx %%g7, [%0]\n\t" \ | ||
237 | "srlx %%g7, 32, %%l1\n\t" \ | ||
238 | "sra %%g7, 0, %%g7\n\t" \ | ||
239 | "stx %%l1, [%0]\n\t" \ | ||
240 | "stx %%g7, [%0 + 8]\n" \ | ||
241 | "0:\n\t" \ | ||
242 | "wr %%g0, %5, %%asi\n\n\t" \ | ||
243 | ".section __ex_table\n\t" \ | ||
244 | ".word 4b, " #errh "\n\t" \ | ||
245 | ".word 5b, " #errh "\n\t" \ | ||
246 | ".word 6b, " #errh "\n\t" \ | ||
247 | ".word 7b, " #errh "\n\t" \ | ||
248 | ".word 8b, " #errh "\n\t" \ | ||
249 | ".word 9b, " #errh "\n\t" \ | ||
250 | ".word 10b, " #errh "\n\t" \ | ||
251 | ".word 11b, " #errh "\n\t" \ | ||
252 | ".word 12b, " #errh "\n\t" \ | ||
253 | ".word 13b, " #errh "\n\t" \ | ||
254 | ".word 14b, " #errh "\n\t" \ | ||
255 | ".word 15b, " #errh "\n\t" \ | ||
256 | ".word 16b, " #errh "\n\n\t" \ | ||
257 | ".previous\n\t" \ | ||
258 | : : "r" (dest_reg), "r" (size), "r" (saddr), "r" (is_signed), \ | ||
259 | "r" (asi), "i" (ASI_AIUS) \ | ||
260 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
261 | }) | ||
262 | 185 | ||
263 | #define store_common(dst_addr, size, src_val, asi, errh) ({ \ | 186 | extern void __do_int_store(unsigned long *dst_addr, int size, |
264 | __asm__ __volatile__ ( \ | 187 | unsigned long *src_val, int asi); |
265 | "wr %3, 0, %%asi\n\t" \ | 188 | |
266 | "ldx [%2], %%l1\n" \ | 189 | static inline void do_int_store(int reg_num, int size, unsigned long *dst_addr, |
267 | "cmp %1, 2\n\t" \ | 190 | struct pt_regs *regs, int asi) |
268 | "be,pn %%icc, 2f\n\t" \ | 191 | { |
269 | " cmp %1, 4\n\t" \ | 192 | unsigned long zero = 0; |
270 | "be,pt %%icc, 1f\n\t" \ | 193 | unsigned long *src_val = &zero; |
271 | " srlx %%l1, 24, %%l2\n\t" \ | 194 | |
272 | "srlx %%l1, 56, %%g1\n\t" \ | 195 | if (size == 16) { |
273 | "srlx %%l1, 48, %%g7\n" \ | 196 | size = 8; |
274 | "4:\t" "stba %%g1, [%0] %%asi\n\t" \ | 197 | zero = (((long)(reg_num ? |
275 | "srlx %%l1, 40, %%g1\n" \ | 198 | (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | |
276 | "5:\t" "stba %%g7, [%0 + 1] %%asi\n\t" \ | 199 | (unsigned)fetch_reg(reg_num + 1, regs); |
277 | "srlx %%l1, 32, %%g7\n" \ | 200 | } else if (reg_num) { |
278 | "6:\t" "stba %%g1, [%0 + 2] %%asi\n" \ | 201 | src_val = fetch_reg_addr(reg_num, regs); |
279 | "7:\t" "stba %%g7, [%0 + 3] %%asi\n\t" \ | 202 | } |
280 | "srlx %%l1, 16, %%g1\n" \ | 203 | __do_int_store(dst_addr, size, src_val, asi); |
281 | "8:\t" "stba %%l2, [%0 + 4] %%asi\n\t" \ | 204 | } |
282 | "srlx %%l1, 8, %%g7\n" \ | ||
283 | "9:\t" "stba %%g1, [%0 + 5] %%asi\n" \ | ||
284 | "10:\t" "stba %%g7, [%0 + 6] %%asi\n\t" \ | ||
285 | "ba,pt %%xcc, 0f\n" \ | ||
286 | "11:\t" " stba %%l1, [%0 + 7] %%asi\n" \ | ||
287 | "1:\t" "srl %%l1, 16, %%g7\n" \ | ||
288 | "12:\t" "stba %%l2, [%0] %%asi\n\t" \ | ||
289 | "srl %%l1, 8, %%l2\n" \ | ||
290 | "13:\t" "stba %%g7, [%0 + 1] %%asi\n" \ | ||
291 | "14:\t" "stba %%l2, [%0 + 2] %%asi\n\t" \ | ||
292 | "ba,pt %%xcc, 0f\n" \ | ||
293 | "15:\t" " stba %%l1, [%0 + 3] %%asi\n" \ | ||
294 | "2:\t" "srl %%l1, 8, %%l2\n" \ | ||
295 | "16:\t" "stba %%l2, [%0] %%asi\n" \ | ||
296 | "17:\t" "stba %%l1, [%0 + 1] %%asi\n" \ | ||
297 | "0:\n\t" \ | ||
298 | "wr %%g0, %4, %%asi\n\n\t" \ | ||
299 | ".section __ex_table\n\t" \ | ||
300 | ".word 4b, " #errh "\n\t" \ | ||
301 | ".word 5b, " #errh "\n\t" \ | ||
302 | ".word 6b, " #errh "\n\t" \ | ||
303 | ".word 7b, " #errh "\n\t" \ | ||
304 | ".word 8b, " #errh "\n\t" \ | ||
305 | ".word 9b, " #errh "\n\t" \ | ||
306 | ".word 10b, " #errh "\n\t" \ | ||
307 | ".word 11b, " #errh "\n\t" \ | ||
308 | ".word 12b, " #errh "\n\t" \ | ||
309 | ".word 13b, " #errh "\n\t" \ | ||
310 | ".word 14b, " #errh "\n\t" \ | ||
311 | ".word 15b, " #errh "\n\t" \ | ||
312 | ".word 16b, " #errh "\n\t" \ | ||
313 | ".word 17b, " #errh "\n\n\t" \ | ||
314 | ".previous\n\t" \ | ||
315 | : : "r" (dst_addr), "r" (size), "r" (src_val), "r" (asi), "i" (ASI_AIUS)\ | ||
316 | : "l1", "l2", "g7", "g1", "cc"); \ | ||
317 | }) | ||
318 | |||
319 | #define do_integer_store(reg_num, size, dst_addr, regs, asi, errh) ({ \ | ||
320 | unsigned long zero = 0; \ | ||
321 | unsigned long *src_val = &zero; \ | ||
322 | \ | ||
323 | if (size == 16) { \ | ||
324 | size = 8; \ | ||
325 | zero = (((long)(reg_num ? \ | ||
326 | (unsigned)fetch_reg(reg_num, regs) : 0)) << 32) | \ | ||
327 | (unsigned)fetch_reg(reg_num + 1, regs); \ | ||
328 | } else if (reg_num) src_val = fetch_reg_addr(reg_num, regs); \ | ||
329 | store_common(dst_addr, size, src_val, asi, errh); \ | ||
330 | }) | ||
331 | |||
332 | extern void smp_capture(void); | ||
333 | extern void smp_release(void); | ||
334 | |||
335 | #define do_atomic(srcdest_reg, mem, errh) ({ \ | ||
336 | unsigned long flags, tmp; \ | ||
337 | \ | ||
338 | smp_capture(); \ | ||
339 | local_irq_save(flags); \ | ||
340 | tmp = *srcdest_reg; \ | ||
341 | do_integer_load(srcdest_reg, 4, mem, 0, errh); \ | ||
342 | store_common(mem, 4, &tmp, errh); \ | ||
343 | local_irq_restore(flags); \ | ||
344 | smp_release(); \ | ||
345 | }) | ||
346 | 205 | ||
347 | static inline void advance(struct pt_regs *regs) | 206 | static inline void advance(struct pt_regs *regs) |
348 | { | 207 | { |
@@ -364,24 +223,29 @@ static inline int ok_for_kernel(unsigned int insn) | |||
364 | return !floating_point_load_or_store_p(insn); | 223 | return !floating_point_load_or_store_p(insn); |
365 | } | 224 | } |
366 | 225 | ||
367 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) __asm__ ("kernel_mna_trap_fault"); | 226 | void kernel_mna_trap_fault(void) |
368 | |||
369 | void kernel_mna_trap_fault(struct pt_regs *regs, unsigned int insn) | ||
370 | { | 227 | { |
371 | unsigned long g2 = regs->u_regs [UREG_G2]; | 228 | struct pt_regs *regs = current_thread_info()->kern_una_regs; |
229 | unsigned int insn = current_thread_info()->kern_una_insn; | ||
230 | unsigned long g2 = regs->u_regs[UREG_G2]; | ||
372 | unsigned long fixup = search_extables_range(regs->tpc, &g2); | 231 | unsigned long fixup = search_extables_range(regs->tpc, &g2); |
373 | 232 | ||
374 | if (!fixup) { | 233 | if (!fixup) { |
375 | unsigned long address = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); | 234 | unsigned long address; |
235 | |||
236 | address = compute_effective_address(regs, insn, | ||
237 | ((insn >> 25) & 0x1f)); | ||
376 | if (address < PAGE_SIZE) { | 238 | if (address < PAGE_SIZE) { |
377 | printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference in mna handler"); | 239 | printk(KERN_ALERT "Unable to handle kernel NULL " |
240 | "pointer dereference in mna handler"); | ||
378 | } else | 241 | } else |
379 | printk(KERN_ALERT "Unable to handle kernel paging request in mna handler"); | 242 | printk(KERN_ALERT "Unable to handle kernel paging " |
243 | "request in mna handler"); | ||
380 | printk(KERN_ALERT " at virtual address %016lx\n",address); | 244 | printk(KERN_ALERT " at virtual address %016lx\n",address); |
381 | printk(KERN_ALERT "current->{mm,active_mm}->context = %016lx\n", | 245 | printk(KERN_ALERT "current->{active_,}mm->context = %016lx\n", |
382 | (current->mm ? CTX_HWBITS(current->mm->context) : | 246 | (current->mm ? CTX_HWBITS(current->mm->context) : |
383 | CTX_HWBITS(current->active_mm->context))); | 247 | CTX_HWBITS(current->active_mm->context))); |
384 | printk(KERN_ALERT "current->{mm,active_mm}->pgd = %016lx\n", | 248 | printk(KERN_ALERT "current->{active_,}mm->pgd = %016lx\n", |
385 | (current->mm ? (unsigned long) current->mm->pgd : | 249 | (current->mm ? (unsigned long) current->mm->pgd : |
386 | (unsigned long) current->active_mm->pgd)); | 250 | (unsigned long) current->active_mm->pgd)); |
387 | die_if_kernel("Oops", regs); | 251 | die_if_kernel("Oops", regs); |
@@ -400,48 +264,41 @@ asmlinkage void kernel_unaligned_trap(struct pt_regs *regs, unsigned int insn, u | |||
400 | enum direction dir = decode_direction(insn); | 264 | enum direction dir = decode_direction(insn); |
401 | int size = decode_access_size(insn); | 265 | int size = decode_access_size(insn); |
402 | 266 | ||
267 | current_thread_info()->kern_una_regs = regs; | ||
268 | current_thread_info()->kern_una_insn = insn; | ||
269 | |||
403 | if (!ok_for_kernel(insn) || dir == both) { | 270 | if (!ok_for_kernel(insn) || dir == both) { |
404 | printk("Unsupported unaligned load/store trap for kernel at <%016lx>.\n", | 271 | printk("Unsupported unaligned load/store trap for kernel " |
405 | regs->tpc); | 272 | "at <%016lx>.\n", regs->tpc); |
406 | unaligned_panic("Kernel does fpu/atomic unaligned load/store.", regs); | 273 | unaligned_panic("Kernel does fpu/atomic " |
407 | 274 | "unaligned load/store.", regs); | |
408 | __asm__ __volatile__ ("\n" | 275 | |
409 | "kernel_unaligned_trap_fault:\n\t" | 276 | kernel_mna_trap_fault(); |
410 | "mov %0, %%o0\n\t" | ||
411 | "call kernel_mna_trap_fault\n\t" | ||
412 | " mov %1, %%o1\n\t" | ||
413 | : | ||
414 | : "r" (regs), "r" (insn) | ||
415 | : "o0", "o1", "o2", "o3", "o4", "o5", "o7", | ||
416 | "g1", "g2", "g3", "g4", "g7", "cc"); | ||
417 | } else { | 277 | } else { |
418 | unsigned long addr = compute_effective_address(regs, insn, ((insn >> 25) & 0x1f)); | 278 | unsigned long addr; |
419 | 279 | ||
280 | addr = compute_effective_address(regs, insn, | ||
281 | ((insn >> 25) & 0x1f)); | ||
420 | #ifdef DEBUG_MNA | 282 | #ifdef DEBUG_MNA |
421 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] retpc[%016lx]\n", | 283 | printk("KMNA: pc=%016lx [dir=%s addr=%016lx size=%d] " |
422 | regs->tpc, dirstrings[dir], addr, size, regs->u_regs[UREG_RETPC]); | 284 | "retpc[%016lx]\n", |
285 | regs->tpc, dirstrings[dir], addr, size, | ||
286 | regs->u_regs[UREG_RETPC]); | ||
423 | #endif | 287 | #endif |
424 | switch (dir) { | 288 | switch (dir) { |
425 | case load: | 289 | case load: |
426 | do_integer_load(fetch_reg_addr(((insn>>25)&0x1f), regs), | 290 | do_int_load(fetch_reg_addr(((insn>>25)&0x1f), regs), |
427 | size, (unsigned long *) addr, | 291 | size, (unsigned long *) addr, |
428 | decode_signedness(insn), decode_asi(insn, regs), | 292 | decode_signedness(insn), |
429 | kernel_unaligned_trap_fault); | 293 | decode_asi(insn, regs)); |
430 | break; | 294 | break; |
431 | 295 | ||
432 | case store: | 296 | case store: |
433 | do_integer_store(((insn>>25)&0x1f), size, | 297 | do_int_store(((insn>>25)&0x1f), size, |
434 | (unsigned long *) addr, regs, | 298 | (unsigned long *) addr, regs, |
435 | decode_asi(insn, regs), | 299 | decode_asi(insn, regs)); |
436 | kernel_unaligned_trap_fault); | ||
437 | break; | ||
438 | #if 0 /* unsupported */ | ||
439 | case both: | ||
440 | do_atomic(fetch_reg_addr(((insn>>25)&0x1f), regs), | ||
441 | (unsigned long *) addr, | ||
442 | kernel_unaligned_trap_fault); | ||
443 | break; | 300 | break; |
444 | #endif | 301 | |
445 | default: | 302 | default: |
446 | panic("Impossible kernel unaligned trap."); | 303 | panic("Impossible kernel unaligned trap."); |
447 | /* Not reached... */ | 304 | /* Not reached... */ |
diff --git a/arch/sparc64/kernel/us2e_cpufreq.c b/arch/sparc64/kernel/us2e_cpufreq.c index 7aae0a18aabe..686e526bec04 100644 --- a/arch/sparc64/kernel/us2e_cpufreq.c +++ b/arch/sparc64/kernel/us2e_cpufreq.c | |||
@@ -88,7 +88,6 @@ static void frob_mem_refresh(int cpu_slowing_down, | |||
88 | { | 88 | { |
89 | unsigned long old_refr_count, refr_count, mctrl; | 89 | unsigned long old_refr_count, refr_count, mctrl; |
90 | 90 | ||
91 | |||
92 | refr_count = (clock_tick * MCTRL0_REFR_INTERVAL); | 91 | refr_count = (clock_tick * MCTRL0_REFR_INTERVAL); |
93 | refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); | 92 | refr_count /= (MCTRL0_REFR_CLKS_P_CNT * divisor * 1000000000UL); |
94 | 93 | ||
@@ -230,6 +229,25 @@ static unsigned long estar_to_divisor(unsigned long estar) | |||
230 | return ret; | 229 | return ret; |
231 | } | 230 | } |
232 | 231 | ||
232 | static unsigned int us2e_freq_get(unsigned int cpu) | ||
233 | { | ||
234 | cpumask_t cpus_allowed; | ||
235 | unsigned long clock_tick, estar; | ||
236 | |||
237 | if (!cpu_online(cpu)) | ||
238 | return 0; | ||
239 | |||
240 | cpus_allowed = current->cpus_allowed; | ||
241 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
242 | |||
243 | clock_tick = sparc64_get_clock_tick(cpu) / 1000; | ||
244 | estar = read_hbreg(HBIRD_ESTAR_MODE_ADDR); | ||
245 | |||
246 | set_cpus_allowed(current, cpus_allowed); | ||
247 | |||
248 | return clock_tick / estar_to_divisor(estar); | ||
249 | } | ||
250 | |||
233 | static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | 251 | static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) |
234 | { | 252 | { |
235 | unsigned long new_bits, new_freq; | 253 | unsigned long new_bits, new_freq; |
@@ -243,7 +261,7 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
243 | cpus_allowed = current->cpus_allowed; | 261 | cpus_allowed = current->cpus_allowed; |
244 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 262 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
245 | 263 | ||
246 | new_freq = clock_tick = sparc64_get_clock_tick(cpu); | 264 | new_freq = clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
247 | new_bits = index_to_estar_mode(index); | 265 | new_bits = index_to_estar_mode(index); |
248 | divisor = index_to_divisor(index); | 266 | divisor = index_to_divisor(index); |
249 | new_freq /= divisor; | 267 | new_freq /= divisor; |
@@ -258,7 +276,8 @@ static void us2e_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
258 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); | 276 | cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); |
259 | 277 | ||
260 | if (old_divisor != divisor) | 278 | if (old_divisor != divisor) |
261 | us2e_transition(estar, new_bits, clock_tick, old_divisor, divisor); | 279 | us2e_transition(estar, new_bits, clock_tick * 1000, |
280 | old_divisor, divisor); | ||
262 | 281 | ||
263 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); | 282 | cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); |
264 | 283 | ||
@@ -272,10 +291,8 @@ static int us2e_freq_target(struct cpufreq_policy *policy, | |||
272 | unsigned int new_index = 0; | 291 | unsigned int new_index = 0; |
273 | 292 | ||
274 | if (cpufreq_frequency_table_target(policy, | 293 | if (cpufreq_frequency_table_target(policy, |
275 | &us2e_freq_table[policy->cpu].table[0], | 294 | &us2e_freq_table[policy->cpu].table[0], |
276 | target_freq, | 295 | target_freq, relation, &new_index)) |
277 | relation, | ||
278 | &new_index)) | ||
279 | return -EINVAL; | 296 | return -EINVAL; |
280 | 297 | ||
281 | us2e_set_cpu_divider_index(policy->cpu, new_index); | 298 | us2e_set_cpu_divider_index(policy->cpu, new_index); |
@@ -292,7 +309,7 @@ static int us2e_freq_verify(struct cpufreq_policy *policy) | |||
292 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) | 309 | static int __init us2e_freq_cpu_init(struct cpufreq_policy *policy) |
293 | { | 310 | { |
294 | unsigned int cpu = policy->cpu; | 311 | unsigned int cpu = policy->cpu; |
295 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 312 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
296 | struct cpufreq_frequency_table *table = | 313 | struct cpufreq_frequency_table *table = |
297 | &us2e_freq_table[cpu].table[0]; | 314 | &us2e_freq_table[cpu].table[0]; |
298 | 315 | ||
@@ -351,9 +368,10 @@ static int __init us2e_freq_init(void) | |||
351 | memset(us2e_freq_table, 0, | 368 | memset(us2e_freq_table, 0, |
352 | (NR_CPUS * sizeof(struct us2e_freq_percpu_info))); | 369 | (NR_CPUS * sizeof(struct us2e_freq_percpu_info))); |
353 | 370 | ||
371 | driver->init = us2e_freq_cpu_init; | ||
354 | driver->verify = us2e_freq_verify; | 372 | driver->verify = us2e_freq_verify; |
355 | driver->target = us2e_freq_target; | 373 | driver->target = us2e_freq_target; |
356 | driver->init = us2e_freq_cpu_init; | 374 | driver->get = us2e_freq_get; |
357 | driver->exit = us2e_freq_cpu_exit; | 375 | driver->exit = us2e_freq_cpu_exit; |
358 | driver->owner = THIS_MODULE, | 376 | driver->owner = THIS_MODULE, |
359 | strcpy(driver->name, "UltraSPARC-IIe"); | 377 | strcpy(driver->name, "UltraSPARC-IIe"); |
diff --git a/arch/sparc64/kernel/us3_cpufreq.c b/arch/sparc64/kernel/us3_cpufreq.c index 18fe54b8aa55..9080e7cd4bb0 100644 --- a/arch/sparc64/kernel/us3_cpufreq.c +++ b/arch/sparc64/kernel/us3_cpufreq.c | |||
@@ -56,7 +56,7 @@ static void write_safari_cfg(unsigned long val) | |||
56 | 56 | ||
57 | static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) | 57 | static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg) |
58 | { | 58 | { |
59 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 59 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
60 | unsigned long ret; | 60 | unsigned long ret; |
61 | 61 | ||
62 | switch (safari_cfg & SAFARI_CFG_DIV_MASK) { | 62 | switch (safari_cfg & SAFARI_CFG_DIV_MASK) { |
@@ -76,6 +76,26 @@ static unsigned long get_current_freq(unsigned int cpu, unsigned long safari_cfg | |||
76 | return ret; | 76 | return ret; |
77 | } | 77 | } |
78 | 78 | ||
79 | static unsigned int us3_freq_get(unsigned int cpu) | ||
80 | { | ||
81 | cpumask_t cpus_allowed; | ||
82 | unsigned long reg; | ||
83 | unsigned int ret; | ||
84 | |||
85 | if (!cpu_online(cpu)) | ||
86 | return 0; | ||
87 | |||
88 | cpus_allowed = current->cpus_allowed; | ||
89 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | ||
90 | |||
91 | reg = read_safari_cfg(); | ||
92 | ret = get_current_freq(cpu, reg); | ||
93 | |||
94 | set_cpus_allowed(current, cpus_allowed); | ||
95 | |||
96 | return ret; | ||
97 | } | ||
98 | |||
79 | static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | 99 | static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) |
80 | { | 100 | { |
81 | unsigned long new_bits, new_freq, reg; | 101 | unsigned long new_bits, new_freq, reg; |
@@ -88,7 +108,7 @@ static void us3_set_cpu_divider_index(unsigned int cpu, unsigned int index) | |||
88 | cpus_allowed = current->cpus_allowed; | 108 | cpus_allowed = current->cpus_allowed; |
89 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 109 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
90 | 110 | ||
91 | new_freq = sparc64_get_clock_tick(cpu); | 111 | new_freq = sparc64_get_clock_tick(cpu) / 1000; |
92 | switch (index) { | 112 | switch (index) { |
93 | case 0: | 113 | case 0: |
94 | new_bits = SAFARI_CFG_DIV_1; | 114 | new_bits = SAFARI_CFG_DIV_1; |
@@ -150,7 +170,7 @@ static int us3_freq_verify(struct cpufreq_policy *policy) | |||
150 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) | 170 | static int __init us3_freq_cpu_init(struct cpufreq_policy *policy) |
151 | { | 171 | { |
152 | unsigned int cpu = policy->cpu; | 172 | unsigned int cpu = policy->cpu; |
153 | unsigned long clock_tick = sparc64_get_clock_tick(cpu); | 173 | unsigned long clock_tick = sparc64_get_clock_tick(cpu) / 1000; |
154 | struct cpufreq_frequency_table *table = | 174 | struct cpufreq_frequency_table *table = |
155 | &us3_freq_table[cpu].table[0]; | 175 | &us3_freq_table[cpu].table[0]; |
156 | 176 | ||
@@ -206,9 +226,10 @@ static int __init us3_freq_init(void) | |||
206 | memset(us3_freq_table, 0, | 226 | memset(us3_freq_table, 0, |
207 | (NR_CPUS * sizeof(struct us3_freq_percpu_info))); | 227 | (NR_CPUS * sizeof(struct us3_freq_percpu_info))); |
208 | 228 | ||
229 | driver->init = us3_freq_cpu_init; | ||
209 | driver->verify = us3_freq_verify; | 230 | driver->verify = us3_freq_verify; |
210 | driver->target = us3_freq_target; | 231 | driver->target = us3_freq_target; |
211 | driver->init = us3_freq_cpu_init; | 232 | driver->get = us3_freq_get; |
212 | driver->exit = us3_freq_cpu_exit; | 233 | driver->exit = us3_freq_cpu_exit; |
213 | driver->owner = THIS_MODULE, | 234 | driver->owner = THIS_MODULE, |
214 | strcpy(driver->name, "UltraSPARC-III"); | 235 | strcpy(driver->name, "UltraSPARC-III"); |
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c index a37a5ac13c22..022f67bb6873 100644 --- a/arch/um/drivers/mmapper_kern.c +++ b/arch/um/drivers/mmapper_kern.c | |||
@@ -9,19 +9,11 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/types.h> | 12 | #include <linux/init.h> |
13 | #include <linux/kdev_t.h> | ||
14 | #include <linux/time.h> | ||
15 | #include <linux/devfs_fs_kernel.h> | ||
16 | #include <linux/module.h> | 13 | #include <linux/module.h> |
17 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
18 | #include <linux/slab.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/smp_lock.h> | ||
21 | #include <linux/miscdevice.h> | 15 | #include <linux/miscdevice.h> |
22 | #include <asm/uaccess.h> | 16 | #include <asm/uaccess.h> |
23 | #include <asm/irq.h> | ||
24 | #include <asm/pgtable.h> | ||
25 | #include "mem_user.h" | 17 | #include "mem_user.h" |
26 | #include "user_util.h" | 18 | #include "user_util.h" |
27 | 19 | ||
@@ -31,35 +23,22 @@ static unsigned long p_buf = 0; | |||
31 | static char *v_buf = NULL; | 23 | static char *v_buf = NULL; |
32 | 24 | ||
33 | static ssize_t | 25 | static ssize_t |
34 | mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) | 26 | mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
35 | { | 27 | { |
36 | if(*ppos > mmapper_size) | 28 | return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); |
37 | return -EINVAL; | ||
38 | |||
39 | if(count + *ppos > mmapper_size) | ||
40 | count = count + *ppos - mmapper_size; | ||
41 | |||
42 | if(count < 0) | ||
43 | return -EINVAL; | ||
44 | |||
45 | copy_to_user(buf,&v_buf[*ppos],count); | ||
46 | |||
47 | return count; | ||
48 | } | 29 | } |
49 | 30 | ||
50 | static ssize_t | 31 | static ssize_t |
51 | mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) | 32 | mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) |
52 | { | 33 | { |
53 | if(*ppos > mmapper_size) | 34 | if (*ppos > mmapper_size) |
54 | return -EINVAL; | 35 | return -EINVAL; |
55 | 36 | ||
56 | if(count + *ppos > mmapper_size) | 37 | if (count > mmapper_size - *ppos) |
57 | count = count + *ppos - mmapper_size; | 38 | count = mmapper_size - *ppos; |
58 | |||
59 | if(count < 0) | ||
60 | return -EINVAL; | ||
61 | 39 | ||
62 | copy_from_user(&v_buf[*ppos],buf,count); | 40 | if (copy_from_user(&v_buf[*ppos], buf, count)) |
41 | return -EFAULT; | ||
63 | 42 | ||
64 | return count; | 43 | return count; |
65 | } | 44 | } |
@@ -77,7 +56,6 @@ mmapper_mmap(struct file *file, struct vm_area_struct * vma) | |||
77 | int ret = -EINVAL; | 56 | int ret = -EINVAL; |
78 | int size; | 57 | int size; |
79 | 58 | ||
80 | lock_kernel(); | ||
81 | if (vma->vm_pgoff != 0) | 59 | if (vma->vm_pgoff != 0) |
82 | goto out; | 60 | goto out; |
83 | 61 | ||
@@ -92,7 +70,6 @@ mmapper_mmap(struct file *file, struct vm_area_struct * vma) | |||
92 | goto out; | 70 | goto out; |
93 | ret = 0; | 71 | ret = 0; |
94 | out: | 72 | out: |
95 | unlock_kernel(); | ||
96 | return ret; | 73 | return ret; |
97 | } | 74 | } |
98 | 75 | ||
diff --git a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c index 7807a3e8c426..03618bd13d55 100644 --- a/arch/um/kernel/signal_kern.c +++ b/arch/um/kernel/signal_kern.c | |||
@@ -87,12 +87,12 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr, | |||
87 | recalc_sigpending(); | 87 | recalc_sigpending(); |
88 | spin_unlock_irq(¤t->sighand->siglock); | 88 | spin_unlock_irq(¤t->sighand->siglock); |
89 | force_sigsegv(signr, current); | 89 | force_sigsegv(signr, current); |
90 | } | 90 | } else { |
91 | else if(!(ka->sa.sa_flags & SA_NODEFER)){ | ||
92 | spin_lock_irq(¤t->sighand->siglock); | 91 | spin_lock_irq(¤t->sighand->siglock); |
93 | sigorsets(¤t->blocked, ¤t->blocked, | 92 | sigorsets(¤t->blocked, ¤t->blocked, |
94 | &ka->sa.sa_mask); | 93 | &ka->sa.sa_mask); |
95 | sigaddset(¤t->blocked, signr); | 94 | if(!(ka->sa.sa_flags & SA_NODEFER)) |
95 | sigaddset(¤t->blocked, signr); | ||
96 | recalc_sigpending(); | 96 | recalc_sigpending(); |
97 | spin_unlock_irq(¤t->sighand->siglock); | 97 | spin_unlock_irq(¤t->sighand->siglock); |
98 | } | 98 | } |
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 6dd9e5bf18ed..f228f8b54194 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c | |||
@@ -61,7 +61,11 @@ void wait_stub_done(int pid, int sig, char * fname) | |||
61 | 61 | ||
62 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); | 62 | CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); |
63 | } while((n >= 0) && WIFSTOPPED(status) && | 63 | } while((n >= 0) && WIFSTOPPED(status) && |
64 | (WSTOPSIG(status) == SIGVTALRM)); | 64 | ((WSTOPSIG(status) == SIGVTALRM) || |
65 | /* running UML inside a detached screen can cause | ||
66 | * SIGWINCHes | ||
67 | */ | ||
68 | (WSTOPSIG(status) == SIGWINCH))); | ||
65 | 69 | ||
66 | if((n < 0) || !WIFSTOPPED(status) || | 70 | if((n < 0) || !WIFSTOPPED(status) || |
67 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ | 71 | (WSTOPSIG(status) != SIGUSR1 && WSTOPSIG(status) != SIGTRAP)){ |
diff --git a/arch/um/os-Linux/elf_aux.c b/arch/um/os-Linux/elf_aux.c index 9416e1c29926..4cca3e9c23fe 100644 --- a/arch/um/os-Linux/elf_aux.c +++ b/arch/um/os-Linux/elf_aux.c | |||
@@ -9,7 +9,6 @@ | |||
9 | */ | 9 | */ |
10 | #include <elf.h> | 10 | #include <elf.h> |
11 | #include <stddef.h> | 11 | #include <stddef.h> |
12 | #include <asm/elf.h> | ||
13 | #include "init.h" | 12 | #include "init.h" |
14 | #include "elf_user.h" | 13 | #include "elf_user.h" |
15 | #include "mem_user.h" | 14 | #include "mem_user.h" |
diff --git a/arch/v850/kernel/signal.c b/arch/v850/kernel/signal.c index 37061e32e1a4..633e4e1b825f 100644 --- a/arch/v850/kernel/signal.c +++ b/arch/v850/kernel/signal.c | |||
@@ -462,13 +462,12 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
462 | else | 462 | else |
463 | setup_frame(sig, ka, oldset, regs); | 463 | setup_frame(sig, ka, oldset, regs); |
464 | 464 | ||
465 | if (!(ka->sa.sa_flags & SA_NODEFER)) { | 465 | spin_lock_irq(¤t->sighand->siglock); |
466 | spin_lock_irq(¤t->sighand->siglock); | 466 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
467 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 467 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
468 | sigaddset(¤t->blocked,sig); | 468 | sigaddset(¤t->blocked,sig); |
469 | recalc_sigpending(); | 469 | recalc_sigpending(); |
470 | spin_unlock_irq(¤t->sighand->siglock); | 470 | spin_unlock_irq(¤t->sighand->siglock); |
471 | } | ||
472 | } | 471 | } |
473 | 472 | ||
474 | /* | 473 | /* |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 776f3c866b70..b97a61e1c71c 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.13-rc3 | 3 | # Linux kernel version: 2.6.13-rc6-git3 |
4 | # Fri Jul 22 16:47:31 2005 | 4 | # Fri Aug 12 16:40:34 2005 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -284,10 +284,6 @@ CONFIG_IPV6=y | |||
284 | # Network testing | 284 | # Network testing |
285 | # | 285 | # |
286 | # CONFIG_NET_PKTGEN is not set | 286 | # CONFIG_NET_PKTGEN is not set |
287 | CONFIG_NETPOLL=y | ||
288 | # CONFIG_NETPOLL_RX is not set | ||
289 | # CONFIG_NETPOLL_TRAP is not set | ||
290 | CONFIG_NET_POLL_CONTROLLER=y | ||
291 | # CONFIG_HAMRADIO is not set | 287 | # CONFIG_HAMRADIO is not set |
292 | # CONFIG_IRDA is not set | 288 | # CONFIG_IRDA is not set |
293 | # CONFIG_BT is not set | 289 | # CONFIG_BT is not set |
@@ -463,6 +459,7 @@ CONFIG_AIC79XX_DEBUG_MASK=0 | |||
463 | # CONFIG_MEGARAID_NEWGEN is not set | 459 | # CONFIG_MEGARAID_NEWGEN is not set |
464 | # CONFIG_MEGARAID_LEGACY is not set | 460 | # CONFIG_MEGARAID_LEGACY is not set |
465 | CONFIG_SCSI_SATA=y | 461 | CONFIG_SCSI_SATA=y |
462 | # CONFIG_SCSI_SATA_AHCI is not set | ||
466 | # CONFIG_SCSI_SATA_SVW is not set | 463 | # CONFIG_SCSI_SATA_SVW is not set |
467 | CONFIG_SCSI_ATA_PIIX=y | 464 | CONFIG_SCSI_ATA_PIIX=y |
468 | # CONFIG_SCSI_SATA_NV is not set | 465 | # CONFIG_SCSI_SATA_NV is not set |
@@ -492,6 +489,7 @@ CONFIG_SCSI_QLA2XXX=y | |||
492 | # CONFIG_SCSI_QLA2300 is not set | 489 | # CONFIG_SCSI_QLA2300 is not set |
493 | # CONFIG_SCSI_QLA2322 is not set | 490 | # CONFIG_SCSI_QLA2322 is not set |
494 | # CONFIG_SCSI_QLA6312 is not set | 491 | # CONFIG_SCSI_QLA6312 is not set |
492 | # CONFIG_SCSI_QLA24XX is not set | ||
495 | # CONFIG_SCSI_LPFC is not set | 493 | # CONFIG_SCSI_LPFC is not set |
496 | # CONFIG_SCSI_DC395x is not set | 494 | # CONFIG_SCSI_DC395x is not set |
497 | # CONFIG_SCSI_DC390T is not set | 495 | # CONFIG_SCSI_DC390T is not set |
@@ -512,9 +510,11 @@ CONFIG_BLK_DEV_DM=y | |||
512 | # | 510 | # |
513 | # Fusion MPT device support | 511 | # Fusion MPT device support |
514 | # | 512 | # |
515 | # CONFIG_FUSION is not set | 513 | CONFIG_FUSION=y |
516 | # CONFIG_FUSION_SPI is not set | 514 | CONFIG_FUSION_SPI=y |
517 | # CONFIG_FUSION_FC is not set | 515 | # CONFIG_FUSION_FC is not set |
516 | CONFIG_FUSION_MAX_SGE=128 | ||
517 | # CONFIG_FUSION_CTL is not set | ||
518 | 518 | ||
519 | # | 519 | # |
520 | # IEEE 1394 (FireWire) support | 520 | # IEEE 1394 (FireWire) support |
@@ -585,6 +585,7 @@ CONFIG_8139TOO=y | |||
585 | # CONFIG_ACENIC is not set | 585 | # CONFIG_ACENIC is not set |
586 | # CONFIG_DL2K is not set | 586 | # CONFIG_DL2K is not set |
587 | CONFIG_E1000=y | 587 | CONFIG_E1000=y |
588 | # CONFIG_E1000_NAPI is not set | ||
588 | # CONFIG_NS83820 is not set | 589 | # CONFIG_NS83820 is not set |
589 | # CONFIG_HAMACHI is not set | 590 | # CONFIG_HAMACHI is not set |
590 | # CONFIG_YELLOWFIN is not set | 591 | # CONFIG_YELLOWFIN is not set |
@@ -624,6 +625,10 @@ CONFIG_S2IO=m | |||
624 | # CONFIG_NET_FC is not set | 625 | # CONFIG_NET_FC is not set |
625 | # CONFIG_SHAPER is not set | 626 | # CONFIG_SHAPER is not set |
626 | CONFIG_NETCONSOLE=y | 627 | CONFIG_NETCONSOLE=y |
628 | CONFIG_NETPOLL=y | ||
629 | # CONFIG_NETPOLL_RX is not set | ||
630 | # CONFIG_NETPOLL_TRAP is not set | ||
631 | CONFIG_NET_POLL_CONTROLLER=y | ||
627 | 632 | ||
628 | # | 633 | # |
629 | # ISDN subsystem | 634 | # ISDN subsystem |
diff --git a/arch/x86_64/kernel/e820.c b/arch/x86_64/kernel/e820.c index 6ded3a50dfe6..b548dea4e5b9 100644 --- a/arch/x86_64/kernel/e820.c +++ b/arch/x86_64/kernel/e820.c | |||
@@ -185,6 +185,40 @@ unsigned long __init e820_end_of_ram(void) | |||
185 | } | 185 | } |
186 | 186 | ||
187 | /* | 187 | /* |
188 | * Compute how much memory is missing in a range. | ||
189 | * Unlike the other functions in this file the arguments are in page numbers. | ||
190 | */ | ||
191 | unsigned long __init | ||
192 | e820_hole_size(unsigned long start_pfn, unsigned long end_pfn) | ||
193 | { | ||
194 | unsigned long ram = 0; | ||
195 | unsigned long start = start_pfn << PAGE_SHIFT; | ||
196 | unsigned long end = end_pfn << PAGE_SHIFT; | ||
197 | int i; | ||
198 | for (i = 0; i < e820.nr_map; i++) { | ||
199 | struct e820entry *ei = &e820.map[i]; | ||
200 | unsigned long last, addr; | ||
201 | |||
202 | if (ei->type != E820_RAM || | ||
203 | ei->addr+ei->size <= start || | ||
204 | ei->addr >= end) | ||
205 | continue; | ||
206 | |||
207 | addr = round_up(ei->addr, PAGE_SIZE); | ||
208 | if (addr < start) | ||
209 | addr = start; | ||
210 | |||
211 | last = round_down(ei->addr + ei->size, PAGE_SIZE); | ||
212 | if (last >= end) | ||
213 | last = end; | ||
214 | |||
215 | if (last > addr) | ||
216 | ram += last - addr; | ||
217 | } | ||
218 | return ((end - start) - ram) >> PAGE_SHIFT; | ||
219 | } | ||
220 | |||
221 | /* | ||
188 | * Mark e820 reserved areas as busy for the resource manager. | 222 | * Mark e820 reserved areas as busy for the resource manager. |
189 | */ | 223 | */ |
190 | void __init e820_reserve_resources(void) | 224 | void __init e820_reserve_resources(void) |
diff --git a/arch/x86_64/kernel/signal.c b/arch/x86_64/kernel/signal.c index 98590a989f3d..d642fbf3da29 100644 --- a/arch/x86_64/kernel/signal.c +++ b/arch/x86_64/kernel/signal.c | |||
@@ -394,10 +394,11 @@ handle_signal(unsigned long sig, siginfo_t *info, struct k_sigaction *ka, | |||
394 | #endif | 394 | #endif |
395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); | 395 | ret = setup_rt_frame(sig, ka, info, oldset, regs); |
396 | 396 | ||
397 | if (ret && !(ka->sa.sa_flags & SA_NODEFER)) { | 397 | if (ret) { |
398 | spin_lock_irq(¤t->sighand->siglock); | 398 | spin_lock_irq(¤t->sighand->siglock); |
399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 399 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |
400 | sigaddset(¤t->blocked,sig); | 400 | if (!(ka->sa.sa_flags & SA_NODEFER)) |
401 | sigaddset(¤t->blocked,sig); | ||
401 | recalc_sigpending(); | 402 | recalc_sigpending(); |
402 | spin_unlock_irq(¤t->sighand->siglock); | 403 | spin_unlock_irq(¤t->sighand->siglock); |
403 | } | 404 | } |
diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index b15761ff4101..fa25e39fe54d 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c | |||
@@ -492,6 +492,14 @@ void __cpuinit start_secondary(void) | |||
492 | */ | 492 | */ |
493 | set_cpu_sibling_map(smp_processor_id()); | 493 | set_cpu_sibling_map(smp_processor_id()); |
494 | 494 | ||
495 | /* | ||
496 | * Wait for TSC sync to not schedule things before. | ||
497 | * We still process interrupts, which could see an inconsistent | ||
498 | * time in that window unfortunately. | ||
499 | * Do this here because TSC sync has global unprotected state. | ||
500 | */ | ||
501 | tsc_sync_wait(); | ||
502 | |||
495 | /* | 503 | /* |
496 | * We need to hold call_lock, so there is no inconsistency | 504 | * We need to hold call_lock, so there is no inconsistency |
497 | * between the time smp_call_function() determines number of | 505 | * between the time smp_call_function() determines number of |
@@ -509,13 +517,6 @@ void __cpuinit start_secondary(void) | |||
509 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; | 517 | per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; |
510 | unlock_ipi_call_lock(); | 518 | unlock_ipi_call_lock(); |
511 | 519 | ||
512 | mb(); | ||
513 | |||
514 | /* Wait for TSC sync to not schedule things before. | ||
515 | We still process interrupts, which could see an inconsistent | ||
516 | time in that window unfortunately. */ | ||
517 | tsc_sync_wait(); | ||
518 | |||
519 | cpu_idle(); | 520 | cpu_idle(); |
520 | } | 521 | } |
521 | 522 | ||
diff --git a/arch/x86_64/mm/fault.c b/arch/x86_64/mm/fault.c index 493819e543a5..ca914c3bd49c 100644 --- a/arch/x86_64/mm/fault.c +++ b/arch/x86_64/mm/fault.c | |||
@@ -211,9 +211,7 @@ int unhandled_signal(struct task_struct *tsk, int sig) | |||
211 | { | 211 | { |
212 | if (tsk->pid == 1) | 212 | if (tsk->pid == 1) |
213 | return 1; | 213 | return 1; |
214 | /* Warn for strace, but not for gdb */ | 214 | if (tsk->ptrace & PT_PTRACED) |
215 | if (!test_ti_thread_flag(tsk->thread_info, TIF_SYSCALL_TRACE) && | ||
216 | (tsk->ptrace & PT_PTRACED)) | ||
217 | return 0; | 215 | return 0; |
218 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || | 216 | return (tsk->sighand->action[sig-1].sa.sa_handler == SIG_IGN) || |
219 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); | 217 | (tsk->sighand->action[sig-1].sa.sa_handler == SIG_DFL); |
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 72e4b364ed73..aa4a5189ecee 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c | |||
@@ -322,18 +322,26 @@ void zap_low_mappings(void) | |||
322 | void __init paging_init(void) | 322 | void __init paging_init(void) |
323 | { | 323 | { |
324 | { | 324 | { |
325 | unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0}; | 325 | unsigned long zones_size[MAX_NR_ZONES]; |
326 | unsigned long holes[MAX_NR_ZONES]; | ||
326 | unsigned int max_dma; | 327 | unsigned int max_dma; |
327 | 328 | ||
329 | memset(zones_size, 0, sizeof(zones_size)); | ||
330 | memset(holes, 0, sizeof(holes)); | ||
331 | |||
328 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 332 | max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
329 | 333 | ||
330 | if (end_pfn < max_dma) | 334 | if (end_pfn < max_dma) { |
331 | zones_size[ZONE_DMA] = end_pfn; | 335 | zones_size[ZONE_DMA] = end_pfn; |
332 | else { | 336 | holes[ZONE_DMA] = e820_hole_size(0, end_pfn); |
337 | } else { | ||
333 | zones_size[ZONE_DMA] = max_dma; | 338 | zones_size[ZONE_DMA] = max_dma; |
339 | holes[ZONE_DMA] = e820_hole_size(0, max_dma); | ||
334 | zones_size[ZONE_NORMAL] = end_pfn - max_dma; | 340 | zones_size[ZONE_NORMAL] = end_pfn - max_dma; |
341 | holes[ZONE_NORMAL] = e820_hole_size(max_dma, end_pfn); | ||
335 | } | 342 | } |
336 | free_area_init(zones_size); | 343 | free_area_init_node(0, NODE_DATA(0), zones_size, |
344 | __pa(PAGE_OFFSET) >> PAGE_SHIFT, holes); | ||
337 | } | 345 | } |
338 | return; | 346 | return; |
339 | } | 347 | } |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index 70cb2904a90f..6a156f5692ae 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -126,9 +126,11 @@ void __init setup_node_zones(int nodeid) | |||
126 | { | 126 | { |
127 | unsigned long start_pfn, end_pfn; | 127 | unsigned long start_pfn, end_pfn; |
128 | unsigned long zones[MAX_NR_ZONES]; | 128 | unsigned long zones[MAX_NR_ZONES]; |
129 | unsigned long holes[MAX_NR_ZONES]; | ||
129 | unsigned long dma_end_pfn; | 130 | unsigned long dma_end_pfn; |
130 | 131 | ||
131 | memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); | 132 | memset(zones, 0, sizeof(unsigned long) * MAX_NR_ZONES); |
133 | memset(holes, 0, sizeof(unsigned long) * MAX_NR_ZONES); | ||
132 | 134 | ||
133 | start_pfn = node_start_pfn(nodeid); | 135 | start_pfn = node_start_pfn(nodeid); |
134 | end_pfn = node_end_pfn(nodeid); | 136 | end_pfn = node_end_pfn(nodeid); |
@@ -139,13 +141,17 @@ void __init setup_node_zones(int nodeid) | |||
139 | dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; | 141 | dma_end_pfn = __pa(MAX_DMA_ADDRESS) >> PAGE_SHIFT; |
140 | if (start_pfn < dma_end_pfn) { | 142 | if (start_pfn < dma_end_pfn) { |
141 | zones[ZONE_DMA] = dma_end_pfn - start_pfn; | 143 | zones[ZONE_DMA] = dma_end_pfn - start_pfn; |
144 | holes[ZONE_DMA] = e820_hole_size(start_pfn, dma_end_pfn); | ||
142 | zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; | 145 | zones[ZONE_NORMAL] = end_pfn - dma_end_pfn; |
146 | holes[ZONE_NORMAL] = e820_hole_size(dma_end_pfn, end_pfn); | ||
147 | |||
143 | } else { | 148 | } else { |
144 | zones[ZONE_NORMAL] = end_pfn - start_pfn; | 149 | zones[ZONE_NORMAL] = end_pfn - start_pfn; |
150 | holes[ZONE_NORMAL] = e820_hole_size(start_pfn, end_pfn); | ||
145 | } | 151 | } |
146 | 152 | ||
147 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, | 153 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, |
148 | start_pfn, NULL); | 154 | start_pfn, holes); |
149 | } | 155 | } |
150 | 156 | ||
151 | void __init numa_init_array(void) | 157 | void __init numa_init_array(void) |
diff --git a/arch/x86_64/pci/k8-bus.c b/arch/x86_64/pci/k8-bus.c index c2c38b579939..d80c323669e0 100644 --- a/arch/x86_64/pci/k8-bus.c +++ b/arch/x86_64/pci/k8-bus.c | |||
@@ -47,13 +47,22 @@ fill_mp_bus_to_cpumask(void) | |||
47 | * if there are no busses hanging off of the current | 47 | * if there are no busses hanging off of the current |
48 | * ldt link then both the secondary and subordinate | 48 | * ldt link then both the secondary and subordinate |
49 | * bus number fields are set to 0. | 49 | * bus number fields are set to 0. |
50 | * | ||
51 | * RED-PEN | ||
52 | * This is slightly broken because it assumes | ||
53 | * HT node IDs == Linux node ids, which is not always | ||
54 | * true. However it is probably mostly true. | ||
50 | */ | 55 | */ |
51 | if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0 | 56 | if (!(SECONDARY_LDT_BUS_NUMBER(ldtbus) == 0 |
52 | && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) { | 57 | && SUBORDINATE_LDT_BUS_NUMBER(ldtbus) == 0)) { |
53 | for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); | 58 | for (j = SECONDARY_LDT_BUS_NUMBER(ldtbus); |
54 | j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); | 59 | j <= SUBORDINATE_LDT_BUS_NUMBER(ldtbus); |
55 | j++) | 60 | j++) { |
56 | pci_bus_to_node[j] = NODE_ID(nid); | 61 | int node = NODE_ID(nid); |
62 | if (!node_online(node)) | ||
63 | node = 0; | ||
64 | pci_bus_to_node[j] = node; | ||
65 | } | ||
57 | } | 66 | } |
58 | } | 67 | } |
59 | } | 68 | } |
diff --git a/arch/xtensa/kernel/signal.c b/arch/xtensa/kernel/signal.c index df6e1e17b096..dc42cede9394 100644 --- a/arch/xtensa/kernel/signal.c +++ b/arch/xtensa/kernel/signal.c | |||
@@ -702,12 +702,11 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) | |||
702 | if (ka.sa.sa_flags & SA_ONESHOT) | 702 | if (ka.sa.sa_flags & SA_ONESHOT) |
703 | ka.sa.sa_handler = SIG_DFL; | 703 | ka.sa.sa_handler = SIG_DFL; |
704 | 704 | ||
705 | if (!(ka.sa.sa_flags & SA_NODEFER)) { | 705 | spin_lock_irq(¤t->sighand->siglock); |
706 | spin_lock_irq(¤t->sighand->siglock); | 706 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); |
707 | sigorsets(¤t->blocked, ¤t->blocked, &ka.sa.sa_mask); | 707 | if (!(ka.sa.sa_flags & SA_NODEFER)) |
708 | sigaddset(¤t->blocked, signr); | 708 | sigaddset(¤t->blocked, signr); |
709 | recalc_sigpending(); | 709 | recalc_sigpending(); |
710 | spin_unlock_irq(¤t->sighand->siglock); | 710 | spin_unlock_irq(¤t->sighand->siglock); |
711 | } | ||
712 | return 1; | 711 | return 1; |
713 | } | 712 | } |
diff --git a/drivers/acpi/sleep/poweroff.c b/drivers/acpi/sleep/poweroff.c index 186b182c5825..f93d2ee54800 100644 --- a/drivers/acpi/sleep/poweroff.c +++ b/drivers/acpi/sleep/poweroff.c | |||
@@ -55,7 +55,11 @@ void acpi_power_off(void) | |||
55 | 55 | ||
56 | static int acpi_shutdown(struct sys_device *x) | 56 | static int acpi_shutdown(struct sys_device *x) |
57 | { | 57 | { |
58 | return acpi_sleep_prepare(ACPI_STATE_S5); | 58 | if (system_state == SYSTEM_POWER_OFF) { |
59 | /* Prepare if we are going to power off the system */ | ||
60 | return acpi_sleep_prepare(ACPI_STATE_S5); | ||
61 | } | ||
62 | return 0; | ||
59 | } | 63 | } |
60 | 64 | ||
61 | static struct sysdev_class acpi_sysclass = { | 65 | static struct sysdev_class acpi_sysclass = { |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 96fe2f956754..ab53832d57e5 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -180,7 +180,9 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
180 | up(&dev->sem); | 180 | up(&dev->sem); |
181 | put_device(dev); | 181 | put_device(dev); |
182 | } | 182 | } |
183 | return err; | 183 | if (err) |
184 | return err; | ||
185 | return count; | ||
184 | } | 186 | } |
185 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 187 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); |
186 | 188 | ||
diff --git a/drivers/block/cfq-iosched.c b/drivers/block/cfq-iosched.c index 2435a7c99b2b..cd056e7e64ec 100644 --- a/drivers/block/cfq-iosched.c +++ b/drivers/block/cfq-iosched.c | |||
@@ -47,7 +47,7 @@ static int cfq_slice_idle = HZ / 100; | |||
47 | /* | 47 | /* |
48 | * disable queueing at the driver/hardware level | 48 | * disable queueing at the driver/hardware level |
49 | */ | 49 | */ |
50 | static int cfq_max_depth = 1; | 50 | static int cfq_max_depth = 2; |
51 | 51 | ||
52 | /* | 52 | /* |
53 | * for the hash of cfqq inside the cfqd | 53 | * for the hash of cfqq inside the cfqd |
@@ -385,9 +385,15 @@ cfq_choose_req(struct cfq_data *cfqd, struct cfq_rq *crq1, struct cfq_rq *crq2) | |||
385 | return crq2; | 385 | return crq2; |
386 | if (crq2 == NULL) | 386 | if (crq2 == NULL) |
387 | return crq1; | 387 | return crq1; |
388 | if (cfq_crq_requeued(crq1)) | 388 | |
389 | if (cfq_crq_requeued(crq1) && !cfq_crq_requeued(crq2)) | ||
389 | return crq1; | 390 | return crq1; |
390 | if (cfq_crq_requeued(crq2)) | 391 | else if (cfq_crq_requeued(crq2) && !cfq_crq_requeued(crq1)) |
392 | return crq2; | ||
393 | |||
394 | if (cfq_crq_is_sync(crq1) && !cfq_crq_is_sync(crq2)) | ||
395 | return crq1; | ||
396 | else if (cfq_crq_is_sync(crq2) && !cfq_crq_is_sync(crq1)) | ||
391 | return crq2; | 397 | return crq2; |
392 | 398 | ||
393 | s1 = crq1->request->sector; | 399 | s1 = crq1->request->sector; |
@@ -1769,18 +1775,23 @@ static void | |||
1769 | cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, | 1775 | cfq_crq_enqueued(struct cfq_data *cfqd, struct cfq_queue *cfqq, |
1770 | struct cfq_rq *crq) | 1776 | struct cfq_rq *crq) |
1771 | { | 1777 | { |
1772 | const int sync = cfq_crq_is_sync(crq); | 1778 | struct cfq_io_context *cic; |
1773 | 1779 | ||
1774 | cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); | 1780 | cfqq->next_crq = cfq_choose_req(cfqd, cfqq->next_crq, crq); |
1775 | 1781 | ||
1776 | if (sync) { | 1782 | /* |
1777 | struct cfq_io_context *cic = crq->io_context; | 1783 | * we never wait for an async request and we don't allow preemption |
1784 | * of an async request. so just return early | ||
1785 | */ | ||
1786 | if (!cfq_crq_is_sync(crq)) | ||
1787 | return; | ||
1778 | 1788 | ||
1779 | cfq_update_io_thinktime(cfqd, cic); | 1789 | cic = crq->io_context; |
1780 | cfq_update_idle_window(cfqd, cfqq, cic); | ||
1781 | 1790 | ||
1782 | cic->last_queue = jiffies; | 1791 | cfq_update_io_thinktime(cfqd, cic); |
1783 | } | 1792 | cfq_update_idle_window(cfqd, cfqq, cic); |
1793 | |||
1794 | cic->last_queue = jiffies; | ||
1784 | 1795 | ||
1785 | if (cfqq == cfqd->active_queue) { | 1796 | if (cfqq == cfqd->active_queue) { |
1786 | /* | 1797 | /* |
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index 4f27e5519296..7333b41d4224 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig | |||
@@ -80,7 +80,7 @@ config SERIAL_NONSTANDARD | |||
80 | 80 | ||
81 | config COMPUTONE | 81 | config COMPUTONE |
82 | tristate "Computone IntelliPort Plus serial support" | 82 | tristate "Computone IntelliPort Plus serial support" |
83 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 83 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (BROKEN || !SPARC32) |
84 | ---help--- | 84 | ---help--- |
85 | This driver supports the entire family of Intelliport II/Plus | 85 | This driver supports the entire family of Intelliport II/Plus |
86 | controllers with the exception of the MicroChannel controllers and | 86 | controllers with the exception of the MicroChannel controllers and |
@@ -138,7 +138,7 @@ config CYZ_INTR | |||
138 | 138 | ||
139 | config DIGIEPCA | 139 | config DIGIEPCA |
140 | tristate "Digiboard Intelligent Async Support" | 140 | tristate "Digiboard Intelligent Async Support" |
141 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP | 141 | depends on SERIAL_NONSTANDARD && BROKEN_ON_SMP && (!64BIT || BROKEN) |
142 | ---help--- | 142 | ---help--- |
143 | This is a driver for Digi International's Xx, Xeve, and Xem series | 143 | This is a driver for Digi International's Xx, Xeve, and Xem series |
144 | of cards which provide multiple serial ports. You would need | 144 | of cards which provide multiple serial ports. You would need |
@@ -208,7 +208,7 @@ config SYNCLINK | |||
208 | 208 | ||
209 | config SYNCLINKMP | 209 | config SYNCLINKMP |
210 | tristate "SyncLink Multiport support" | 210 | tristate "SyncLink Multiport support" |
211 | depends on SERIAL_NONSTANDARD | 211 | depends on SERIAL_NONSTANDARD && (BROKEN || !SPARC32) |
212 | help | 212 | help |
213 | Enable support for the SyncLink Multiport (2 or 4 ports) | 213 | Enable support for the SyncLink Multiport (2 or 4 ports) |
214 | serial adapter, running asynchronous and HDLC communications up | 214 | serial adapter, running asynchronous and HDLC communications up |
@@ -735,7 +735,7 @@ config SGI_IP27_RTC | |||
735 | 735 | ||
736 | config GEN_RTC | 736 | config GEN_RTC |
737 | tristate "Generic /dev/rtc emulation" | 737 | tristate "Generic /dev/rtc emulation" |
738 | depends on RTC!=y && !IA64 && !ARM && !PPC64 | 738 | depends on RTC!=y && !IA64 && !ARM && !PPC64 && !M32R && !SPARC32 |
739 | ---help--- | 739 | ---help--- |
740 | If you say Y here and create a character special file /dev/rtc with | 740 | If you say Y here and create a character special file /dev/rtc with |
741 | major number 10 and minor number 135 using mknod ("man mknod"), you | 741 | major number 10 and minor number 135 using mknod ("man mknod"), you |
diff --git a/drivers/char/vt.c b/drivers/char/vt.c index 30d96739fb23..665103ccaee8 100644 --- a/drivers/char/vt.c +++ b/drivers/char/vt.c | |||
@@ -2433,7 +2433,7 @@ static int con_open(struct tty_struct *tty, struct file *filp) | |||
2433 | int ret = 0; | 2433 | int ret = 0; |
2434 | 2434 | ||
2435 | acquire_console_sem(); | 2435 | acquire_console_sem(); |
2436 | if (tty->count == 1) { | 2436 | if (tty->driver_data == NULL) { |
2437 | ret = vc_allocate(currcons); | 2437 | ret = vc_allocate(currcons); |
2438 | if (ret == 0) { | 2438 | if (ret == 0) { |
2439 | struct vc_data *vc = vc_cons[currcons].d; | 2439 | struct vc_data *vc = vc_cons[currcons].d; |
diff --git a/drivers/hwmon/adm1026.c b/drivers/hwmon/adm1026.c index 4fa17c76eea2..c8a7f47911f9 100644 --- a/drivers/hwmon/adm1026.c +++ b/drivers/hwmon/adm1026.c | |||
@@ -325,7 +325,7 @@ int adm1026_attach_adapter(struct i2c_adapter *adapter) | |||
325 | int adm1026_detach_client(struct i2c_client *client) | 325 | int adm1026_detach_client(struct i2c_client *client) |
326 | { | 326 | { |
327 | i2c_detach_client(client); | 327 | i2c_detach_client(client); |
328 | kfree(client); | 328 | kfree(i2c_get_clientdata(client)); |
329 | return 0; | 329 | return 0; |
330 | } | 330 | } |
331 | 331 | ||
@@ -1691,7 +1691,7 @@ int adm1026_detect(struct i2c_adapter *adapter, int address, | |||
1691 | 1691 | ||
1692 | /* Error out and cleanup code */ | 1692 | /* Error out and cleanup code */ |
1693 | exitfree: | 1693 | exitfree: |
1694 | kfree(new_client); | 1694 | kfree(data); |
1695 | exit: | 1695 | exit: |
1696 | return err; | 1696 | return err; |
1697 | } | 1697 | } |
diff --git a/drivers/hwmon/adm1031.c b/drivers/hwmon/adm1031.c index 9168e983ca1d..936250957270 100644 --- a/drivers/hwmon/adm1031.c +++ b/drivers/hwmon/adm1031.c | |||
@@ -834,7 +834,7 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind) | |||
834 | return 0; | 834 | return 0; |
835 | 835 | ||
836 | exit_free: | 836 | exit_free: |
837 | kfree(new_client); | 837 | kfree(data); |
838 | exit: | 838 | exit: |
839 | return err; | 839 | return err; |
840 | } | 840 | } |
@@ -845,7 +845,7 @@ static int adm1031_detach_client(struct i2c_client *client) | |||
845 | if ((ret = i2c_detach_client(client)) != 0) { | 845 | if ((ret = i2c_detach_client(client)) != 0) { |
846 | return ret; | 846 | return ret; |
847 | } | 847 | } |
848 | kfree(client); | 848 | kfree(i2c_get_clientdata(client)); |
849 | return 0; | 849 | return 0; |
850 | } | 850 | } |
851 | 851 | ||
diff --git a/drivers/hwmon/adm9240.c b/drivers/hwmon/adm9240.c index 5c68e9c311aa..ce2a6eb93f6e 100644 --- a/drivers/hwmon/adm9240.c +++ b/drivers/hwmon/adm9240.c | |||
@@ -616,7 +616,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind) | |||
616 | 616 | ||
617 | return 0; | 617 | return 0; |
618 | exit_free: | 618 | exit_free: |
619 | kfree(new_client); | 619 | kfree(data); |
620 | exit: | 620 | exit: |
621 | return err; | 621 | return err; |
622 | } | 622 | } |
diff --git a/drivers/hwmon/fscpos.c b/drivers/hwmon/fscpos.c index 270015b626ad..301ae98bd0ad 100644 --- a/drivers/hwmon/fscpos.c +++ b/drivers/hwmon/fscpos.c | |||
@@ -167,7 +167,7 @@ static ssize_t set_temp_reset(struct i2c_client *client, struct fscpos_data | |||
167 | "experience to the module author.\n"); | 167 | "experience to the module author.\n"); |
168 | 168 | ||
169 | /* Supported value: 2 (clears the status) */ | 169 | /* Supported value: 2 (clears the status) */ |
170 | fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr], 2); | 170 | fscpos_write_value(client, FSCPOS_REG_TEMP_STATE[nr - 1], 2); |
171 | return count; | 171 | return count; |
172 | } | 172 | } |
173 | 173 | ||
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c index 251ac2659554..fdeeb3ab6f2f 100644 --- a/drivers/hwmon/smsc47b397.c +++ b/drivers/hwmon/smsc47b397.c | |||
@@ -298,7 +298,7 @@ static int smsc47b397_detect(struct i2c_adapter *adapter, int addr, int kind) | |||
298 | return 0; | 298 | return 0; |
299 | 299 | ||
300 | error_free: | 300 | error_free: |
301 | kfree(new_client); | 301 | kfree(data); |
302 | error_release: | 302 | error_release: |
303 | release_region(addr, SMSC_EXTENT); | 303 | release_region(addr, SMSC_EXTENT); |
304 | return err; | 304 | return err; |
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 897117a7213f..7166ad0b2fda 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c | |||
@@ -495,7 +495,7 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind) | |||
495 | return 0; | 495 | return 0; |
496 | 496 | ||
497 | error_free: | 497 | error_free: |
498 | kfree(new_client); | 498 | kfree(data); |
499 | error_release: | 499 | error_release: |
500 | release_region(address, SMSC_EXTENT); | 500 | release_region(address, SMSC_EXTENT); |
501 | return err; | 501 | return err; |
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 5f33df47aa74..1cadd2c3cadd 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig | |||
@@ -764,6 +764,7 @@ config BLK_DEV_IDE_PMAC_ATA100FIRST | |||
764 | config BLK_DEV_IDEDMA_PMAC | 764 | config BLK_DEV_IDEDMA_PMAC |
765 | bool "PowerMac IDE DMA support" | 765 | bool "PowerMac IDE DMA support" |
766 | depends on BLK_DEV_IDE_PMAC | 766 | depends on BLK_DEV_IDE_PMAC |
767 | select BLK_DEV_IDEDMA_PCI | ||
767 | help | 768 | help |
768 | This option allows the driver for the built-in IDE controller on | 769 | This option allows the driver for the built-in IDE controller on |
769 | Power Macintoshes and PowerBooks to use DMA (direct memory access) | 770 | Power Macintoshes and PowerBooks to use DMA (direct memory access) |
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c index 9eab6426148e..29c22fc278c6 100644 --- a/drivers/ide/ide-floppy.c +++ b/drivers/ide/ide-floppy.c | |||
@@ -317,7 +317,7 @@ typedef struct ide_floppy_obj { | |||
317 | unsigned long flags; | 317 | unsigned long flags; |
318 | } idefloppy_floppy_t; | 318 | } idefloppy_floppy_t; |
319 | 319 | ||
320 | #define IDEFLOPPY_TICKS_DELAY 3 /* default delay for ZIP 100 */ | 320 | #define IDEFLOPPY_TICKS_DELAY HZ/20 /* default delay for ZIP 100 (50ms) */ |
321 | 321 | ||
322 | /* | 322 | /* |
323 | * Floppy flag bits values. | 323 | * Floppy flag bits values. |
diff --git a/drivers/ide/pci/generic.c b/drivers/ide/pci/generic.c index da46577380f3..6e3ab0c38c4d 100644 --- a/drivers/ide/pci/generic.c +++ b/drivers/ide/pci/generic.c | |||
@@ -173,6 +173,12 @@ static ide_pci_device_t generic_chipsets[] __devinitdata = { | |||
173 | .channels = 2, | 173 | .channels = 2, |
174 | .autodma = NOAUTODMA, | 174 | .autodma = NOAUTODMA, |
175 | .bootable = ON_BOARD, | 175 | .bootable = ON_BOARD, |
176 | },{ /* 14 */ | ||
177 | .name = "Revolution", | ||
178 | .init_hwif = init_hwif_generic, | ||
179 | .channels = 2, | ||
180 | .autodma = AUTODMA, | ||
181 | .bootable = OFF_BOARD, | ||
176 | } | 182 | } |
177 | }; | 183 | }; |
178 | 184 | ||
@@ -231,6 +237,7 @@ static struct pci_device_id generic_pci_tbl[] = { | |||
231 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11}, | 237 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 11}, |
232 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, | 238 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 12}, |
233 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, | 239 | { PCI_VENDOR_ID_TOSHIBA,PCI_DEVICE_ID_TOSHIBA_PICCOLO_2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 13}, |
240 | { PCI_VENDOR_ID_NETCELL,PCI_DEVICE_ID_REVOLUTION, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 14}, | ||
234 | /* Must come last. If you add entries adjust this table appropriately and the init_one code */ | 241 | /* Must come last. If you add entries adjust this table appropriately and the init_one code */ |
235 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0}, | 242 | { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xFFFFFF00UL, 0}, |
236 | { 0, }, | 243 | { 0, }, |
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c index c6f5fa4b4ca6..ff2e217a8c84 100644 --- a/drivers/ide/pci/serverworks.c +++ b/drivers/ide/pci/serverworks.c | |||
@@ -21,6 +21,9 @@ | |||
21 | * | 21 | * |
22 | * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) | 22 | * CSB6: `Champion South Bridge' IDE Interface (optional: third channel) |
23 | * | 23 | * |
24 | * HT1000: AKA BCM5785 - Hypertransport Southbridge for Opteron systems. IDE | ||
25 | * controller same as the CSB6. Single channel ATA100 only. | ||
26 | * | ||
24 | * Documentation: | 27 | * Documentation: |
25 | * Available under NDA only. Errata info very hard to get. | 28 | * Available under NDA only. Errata info very hard to get. |
26 | * | 29 | * |
@@ -71,6 +74,8 @@ static u8 svwks_ratemask (ide_drive_t *drive) | |||
71 | if (!svwks_revision) | 74 | if (!svwks_revision) |
72 | pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); | 75 | pci_read_config_byte(dev, PCI_REVISION_ID, &svwks_revision); |
73 | 76 | ||
77 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) | ||
78 | return 2; | ||
74 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { | 79 | if (dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) { |
75 | u32 reg = 0; | 80 | u32 reg = 0; |
76 | if (isa_dev) | 81 | if (isa_dev) |
@@ -109,6 +114,7 @@ static u8 svwks_csb_check (struct pci_dev *dev) | |||
109 | case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | 114 | case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: |
110 | case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: | 115 | case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE: |
111 | case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2: | 116 | case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2: |
117 | case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE: | ||
112 | return 1; | 118 | return 1; |
113 | default: | 119 | default: |
114 | break; | 120 | break; |
@@ -438,6 +444,13 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha | |||
438 | btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; | 444 | btr |= (svwks_revision >= SVWKS_CSB5_REVISION_NEW) ? 0x3 : 0x2; |
439 | pci_write_config_byte(dev, 0x5A, btr); | 445 | pci_write_config_byte(dev, 0x5A, btr); |
440 | } | 446 | } |
447 | /* Setup HT1000 SouthBridge Controller - Single Channel Only */ | ||
448 | else if (dev->device == PCI_DEVICE_ID_SERVERWORKS_HT1000IDE) { | ||
449 | pci_read_config_byte(dev, 0x5A, &btr); | ||
450 | btr &= ~0x40; | ||
451 | btr |= 0x3; | ||
452 | pci_write_config_byte(dev, 0x5A, btr); | ||
453 | } | ||
441 | 454 | ||
442 | return (dev->irq) ? dev->irq : 0; | 455 | return (dev->irq) ? dev->irq : 0; |
443 | } | 456 | } |
@@ -629,6 +642,15 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = { | |||
629 | .channels = 1, /* 2 */ | 642 | .channels = 1, /* 2 */ |
630 | .autodma = AUTODMA, | 643 | .autodma = AUTODMA, |
631 | .bootable = ON_BOARD, | 644 | .bootable = ON_BOARD, |
645 | },{ /* 4 */ | ||
646 | .name = "SvrWks HT1000", | ||
647 | .init_setup = init_setup_svwks, | ||
648 | .init_chipset = init_chipset_svwks, | ||
649 | .init_hwif = init_hwif_svwks, | ||
650 | .init_dma = init_dma_svwks, | ||
651 | .channels = 1, /* 2 */ | ||
652 | .autodma = AUTODMA, | ||
653 | .bootable = ON_BOARD, | ||
632 | } | 654 | } |
633 | }; | 655 | }; |
634 | 656 | ||
@@ -653,6 +675,7 @@ static struct pci_device_id svwks_pci_tbl[] = { | |||
653 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, | 675 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, |
654 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, | 676 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, |
655 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, | 677 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, |
678 | { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, | ||
656 | { 0, }, | 679 | { 0, }, |
657 | }; | 680 | }; |
658 | MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); | 681 | MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); |
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index be0fcc8f4b15..ea65b070a367 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c | |||
@@ -1664,7 +1664,7 @@ static struct macio_driver pmac_ide_macio_driver = | |||
1664 | }; | 1664 | }; |
1665 | 1665 | ||
1666 | static struct pci_device_id pmac_ide_pci_match[] = { | 1666 | static struct pci_device_id pmac_ide_pci_match[] = { |
1667 | { PCI_VENDOR_ID_APPLE, PCI_DEVIEC_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1667 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_UNI_N_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
1668 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1668 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_IPID_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
1669 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 1669 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_K2_ATA100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
1670 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA, | 1670 | { PCI_VENDOR_ID_APPLE, PCI_DEVICE_ID_APPLE_SH_ATA, |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 77da827b2898..18ed7765417c 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -229,6 +229,7 @@ second_chance_to_dma: | |||
229 | case PCI_DEVICE_ID_AMD_VIPER_7409: | 229 | case PCI_DEVICE_ID_AMD_VIPER_7409: |
230 | case PCI_DEVICE_ID_CMD_643: | 230 | case PCI_DEVICE_ID_CMD_643: |
231 | case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: | 231 | case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE: |
232 | case PCI_DEVICE_ID_REVOLUTION: | ||
232 | simplex_stat = hwif->INB(dma_base + 2); | 233 | simplex_stat = hwif->INB(dma_base + 2); |
233 | hwif->OUTB((simplex_stat&0x60),(dma_base + 2)); | 234 | hwif->OUTB((simplex_stat&0x60),(dma_base + 2)); |
234 | simplex_stat = hwif->INB(dma_base + 2); | 235 | simplex_stat = hwif->INB(dma_base + 2); |
diff --git a/drivers/ieee1394/ohci1394.c b/drivers/ieee1394/ohci1394.c index b12a970cc9a3..27018c8efc24 100644 --- a/drivers/ieee1394/ohci1394.c +++ b/drivers/ieee1394/ohci1394.c | |||
@@ -478,7 +478,6 @@ static void ohci_initialize(struct ti_ohci *ohci) | |||
478 | int num_ports, i; | 478 | int num_ports, i; |
479 | 479 | ||
480 | spin_lock_init(&ohci->phy_reg_lock); | 480 | spin_lock_init(&ohci->phy_reg_lock); |
481 | spin_lock_init(&ohci->event_lock); | ||
482 | 481 | ||
483 | /* Put some defaults to these undefined bus options */ | 482 | /* Put some defaults to these undefined bus options */ |
484 | buf = reg_read(ohci, OHCI1394_BusOptions); | 483 | buf = reg_read(ohci, OHCI1394_BusOptions); |
@@ -3402,7 +3401,14 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, | |||
3402 | /* We hopefully don't have to pre-allocate IT DMA like we did | 3401 | /* We hopefully don't have to pre-allocate IT DMA like we did |
3403 | * for IR DMA above. Allocate it on-demand and mark inactive. */ | 3402 | * for IR DMA above. Allocate it on-demand and mark inactive. */ |
3404 | ohci->it_legacy_context.ohci = NULL; | 3403 | ohci->it_legacy_context.ohci = NULL; |
3404 | spin_lock_init(&ohci->event_lock); | ||
3405 | 3405 | ||
3406 | /* | ||
3407 | * interrupts are disabled, all right, but... due to SA_SHIRQ we | ||
3408 | * might get called anyway. We'll see no event, of course, but | ||
3409 | * we need to get to that "no event", so enough should be initialized | ||
3410 | * by that point. | ||
3411 | */ | ||
3406 | if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, | 3412 | if (request_irq(dev->irq, ohci_irq_handler, SA_SHIRQ, |
3407 | OHCI1394_DRIVER_NAME, ohci)) | 3413 | OHCI1394_DRIVER_NAME, ohci)) |
3408 | FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq); | 3414 | FAIL(-ENOMEM, "Failed to allocate shared interrupt %d", dev->irq); |
diff --git a/drivers/infiniband/Kconfig b/drivers/infiniband/Kconfig index 79c8e2dd9c33..32cdfb30e9b4 100644 --- a/drivers/infiniband/Kconfig +++ b/drivers/infiniband/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | menu "InfiniBand support" | 1 | menu "InfiniBand support" |
2 | 2 | ||
3 | config INFINIBAND | 3 | config INFINIBAND |
4 | depends on PCI || BROKEN | ||
4 | tristate "InfiniBand support" | 5 | tristate "InfiniBand support" |
5 | ---help--- | 6 | ---help--- |
6 | Core support for InfiniBand (IB). Make sure to also select | 7 | Core support for InfiniBand (IB). Make sure to also select |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index eb99e693dec2..5f6e9ea29cd7 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -130,13 +130,14 @@ static int ib_dealloc_ucontext(struct ib_ucontext *context) | |||
130 | 130 | ||
131 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { | 131 | list_for_each_entry_safe(uobj, tmp, &context->mr_list, list) { |
132 | struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); | 132 | struct ib_mr *mr = idr_find(&ib_uverbs_mr_idr, uobj->id); |
133 | struct ib_device *mrdev = mr->device; | ||
133 | struct ib_umem_object *memobj; | 134 | struct ib_umem_object *memobj; |
134 | 135 | ||
135 | idr_remove(&ib_uverbs_mr_idr, uobj->id); | 136 | idr_remove(&ib_uverbs_mr_idr, uobj->id); |
136 | ib_dereg_mr(mr); | 137 | ib_dereg_mr(mr); |
137 | 138 | ||
138 | memobj = container_of(uobj, struct ib_umem_object, uobject); | 139 | memobj = container_of(uobj, struct ib_umem_object, uobject); |
139 | ib_umem_release_on_close(mr->device, &memobj->umem); | 140 | ib_umem_release_on_close(mrdev, &memobj->umem); |
140 | 141 | ||
141 | list_del(&uobj->list); | 142 | list_del(&uobj->list); |
142 | kfree(memobj); | 143 | kfree(memobj); |
diff --git a/drivers/isdn/capi/capifs.c b/drivers/isdn/capi/capifs.c index f8570fd9d2ab..3abd7fc6e5ef 100644 --- a/drivers/isdn/capi/capifs.c +++ b/drivers/isdn/capi/capifs.c | |||
@@ -191,8 +191,10 @@ static int __init capifs_init(void) | |||
191 | err = register_filesystem(&capifs_fs_type); | 191 | err = register_filesystem(&capifs_fs_type); |
192 | if (!err) { | 192 | if (!err) { |
193 | capifs_mnt = kern_mount(&capifs_fs_type); | 193 | capifs_mnt = kern_mount(&capifs_fs_type); |
194 | if (IS_ERR(capifs_mnt)) | 194 | if (IS_ERR(capifs_mnt)) { |
195 | err = PTR_ERR(capifs_mnt); | 195 | err = PTR_ERR(capifs_mnt); |
196 | unregister_filesystem(&capifs_fs_type); | ||
197 | } | ||
196 | } | 198 | } |
197 | if (!err) | 199 | if (!err) |
198 | printk(KERN_NOTICE "capifs: Rev %s\n", rev); | 200 | printk(KERN_NOTICE "capifs: Rev %s\n", rev); |
diff --git a/drivers/isdn/hisax/Kconfig b/drivers/isdn/hisax/Kconfig index 6c7b8bffc6fd..801c98f30e5c 100644 --- a/drivers/isdn/hisax/Kconfig +++ b/drivers/isdn/hisax/Kconfig | |||
@@ -134,6 +134,7 @@ config HISAX_AVM_A1 | |||
134 | 134 | ||
135 | config HISAX_FRITZPCI | 135 | config HISAX_FRITZPCI |
136 | bool "AVM PnP/PCI (Fritz!PnP/PCI)" | 136 | bool "AVM PnP/PCI (Fritz!PnP/PCI)" |
137 | depends on BROKEN || !PPC64 | ||
137 | help | 138 | help |
138 | This enables HiSax support for the AVM "Fritz!PnP" and "Fritz!PCI". | 139 | This enables HiSax support for the AVM "Fritz!PnP" and "Fritz!PCI". |
139 | See <file:Documentation/isdn/README.HiSax> on how to configure it. | 140 | See <file:Documentation/isdn/README.HiSax> on how to configure it. |
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 65ab64c43b3e..bc3e096d84f7 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig | |||
@@ -103,7 +103,7 @@ config PMAC_MEDIABAY | |||
103 | # on non-powerbook machines (but only on PMU based ones AFAIK) | 103 | # on non-powerbook machines (but only on PMU based ones AFAIK) |
104 | config PMAC_BACKLIGHT | 104 | config PMAC_BACKLIGHT |
105 | bool "Backlight control for LCD screens" | 105 | bool "Backlight control for LCD screens" |
106 | depends on ADB_PMU | 106 | depends on ADB_PMU && (BROKEN || !PPC64) |
107 | help | 107 | help |
108 | Say Y here to build in code to manage the LCD backlight on a | 108 | Say Y here to build in code to manage the LCD backlight on a |
109 | Macintosh PowerBook. With this code, the backlight will be turned | 109 | Macintosh PowerBook. With this code, the backlight will be turned |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 480f658db6f2..20ca80b7dc20 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -256,8 +256,7 @@ static inline void mddev_unlock(mddev_t * mddev) | |||
256 | { | 256 | { |
257 | up(&mddev->reconfig_sem); | 257 | up(&mddev->reconfig_sem); |
258 | 258 | ||
259 | if (mddev->thread) | 259 | md_wakeup_thread(mddev->thread); |
260 | md_wakeup_thread(mddev->thread); | ||
261 | } | 260 | } |
262 | 261 | ||
263 | mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) | 262 | mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr) |
@@ -623,6 +622,7 @@ static int super_90_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
623 | mddev->raid_disks = sb->raid_disks; | 622 | mddev->raid_disks = sb->raid_disks; |
624 | mddev->size = sb->size; | 623 | mddev->size = sb->size; |
625 | mddev->events = md_event(sb); | 624 | mddev->events = md_event(sb); |
625 | mddev->bitmap_offset = 0; | ||
626 | 626 | ||
627 | if (sb->state & (1<<MD_SB_CLEAN)) | 627 | if (sb->state & (1<<MD_SB_CLEAN)) |
628 | mddev->recovery_cp = MaxSector; | 628 | mddev->recovery_cp = MaxSector; |
@@ -938,6 +938,7 @@ static int super_1_validate(mddev_t *mddev, mdk_rdev_t *rdev) | |||
938 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); | 938 | mddev->raid_disks = le32_to_cpu(sb->raid_disks); |
939 | mddev->size = le64_to_cpu(sb->size)/2; | 939 | mddev->size = le64_to_cpu(sb->size)/2; |
940 | mddev->events = le64_to_cpu(sb->events); | 940 | mddev->events = le64_to_cpu(sb->events); |
941 | mddev->bitmap_offset = 0; | ||
941 | 942 | ||
942 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); | 943 | mddev->recovery_cp = le64_to_cpu(sb->resync_offset); |
943 | memcpy(mddev->uuid, sb->set_uuid, 16); | 944 | memcpy(mddev->uuid, sb->set_uuid, 16); |
@@ -1688,6 +1689,7 @@ static int do_md_run(mddev_t * mddev) | |||
1688 | mddev->pers = pers[pnum]; | 1689 | mddev->pers = pers[pnum]; |
1689 | spin_unlock(&pers_lock); | 1690 | spin_unlock(&pers_lock); |
1690 | 1691 | ||
1692 | mddev->recovery = 0; | ||
1691 | mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ | 1693 | mddev->resync_max_sectors = mddev->size << 1; /* may be over-ridden by personality */ |
1692 | 1694 | ||
1693 | /* before we start the array running, initialise the bitmap */ | 1695 | /* before we start the array running, initialise the bitmap */ |
@@ -1712,6 +1714,7 @@ static int do_md_run(mddev_t * mddev) | |||
1712 | mddev->in_sync = 1; | 1714 | mddev->in_sync = 1; |
1713 | 1715 | ||
1714 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 1716 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
1717 | md_wakeup_thread(mddev->thread); | ||
1715 | 1718 | ||
1716 | if (mddev->sb_dirty) | 1719 | if (mddev->sb_dirty) |
1717 | md_update_sb(mddev); | 1720 | md_update_sb(mddev); |
@@ -1824,6 +1827,7 @@ static int do_md_stop(mddev_t * mddev, int ro) | |||
1824 | fput(mddev->bitmap_file); | 1827 | fput(mddev->bitmap_file); |
1825 | mddev->bitmap_file = NULL; | 1828 | mddev->bitmap_file = NULL; |
1826 | } | 1829 | } |
1830 | mddev->bitmap_offset = 0; | ||
1827 | 1831 | ||
1828 | /* | 1832 | /* |
1829 | * Free resources if final stop | 1833 | * Free resources if final stop |
@@ -2233,8 +2237,7 @@ static int add_new_disk(mddev_t * mddev, mdu_disk_info_t *info) | |||
2233 | export_rdev(rdev); | 2237 | export_rdev(rdev); |
2234 | 2238 | ||
2235 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); | 2239 | set_bit(MD_RECOVERY_NEEDED, &mddev->recovery); |
2236 | if (mddev->thread) | 2240 | md_wakeup_thread(mddev->thread); |
2237 | md_wakeup_thread(mddev->thread); | ||
2238 | return err; | 2241 | return err; |
2239 | } | 2242 | } |
2240 | 2243 | ||
@@ -4009,3 +4012,4 @@ EXPORT_SYMBOL(md_print_devices); | |||
4009 | EXPORT_SYMBOL(md_check_recovery); | 4012 | EXPORT_SYMBOL(md_check_recovery); |
4010 | MODULE_LICENSE("GPL"); | 4013 | MODULE_LICENSE("GPL"); |
4011 | MODULE_ALIAS("md"); | 4014 | MODULE_ALIAS("md"); |
4015 | MODULE_ALIAS_BLOCKDEV_MAJOR(MD_MAJOR); | ||
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c index 63b626f70c81..9b9d6f8ee74e 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-common.c +++ b/drivers/media/dvb/dvb-usb/dibusb-common.c | |||
@@ -70,13 +70,22 @@ EXPORT_SYMBOL(dibusb_power_ctrl); | |||
70 | 70 | ||
71 | int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff) | 71 | int dibusb2_0_streaming_ctrl(struct dvb_usb_device *d, int onoff) |
72 | { | 72 | { |
73 | u8 b[2]; | 73 | u8 b[3] = { 0 }; |
74 | b[0] = DIBUSB_REQ_SET_IOCTL; | 74 | int ret; |
75 | b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; | 75 | |
76 | if ((ret = dibusb_streaming_ctrl(d,onoff)) < 0) | ||
77 | return ret; | ||
76 | 78 | ||
77 | dvb_usb_generic_write(d,b,3); | 79 | if (onoff) { |
80 | b[0] = DIBUSB_REQ_SET_STREAMING_MODE; | ||
81 | b[1] = 0x00; | ||
82 | if ((ret = dvb_usb_generic_write(d,b,2)) < 0) | ||
83 | return ret; | ||
84 | } | ||
78 | 85 | ||
79 | return dibusb_streaming_ctrl(d,onoff); | 86 | b[0] = DIBUSB_REQ_SET_IOCTL; |
87 | b[1] = onoff ? DIBUSB_IOCTL_CMD_ENABLE_STREAM : DIBUSB_IOCTL_CMD_DISABLE_STREAM; | ||
88 | return dvb_usb_generic_write(d,b,3); | ||
80 | } | 89 | } |
81 | EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); | 90 | EXPORT_SYMBOL(dibusb2_0_streaming_ctrl); |
82 | 91 | ||
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c index 3491ff40885c..6fa92100248b 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c | |||
@@ -23,12 +23,12 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) | |||
23 | */ | 23 | */ |
24 | if (newfeedcount == 0) { | 24 | if (newfeedcount == 0) { |
25 | deb_ts("stop feeding\n"); | 25 | deb_ts("stop feeding\n"); |
26 | dvb_usb_urb_kill(d); | ||
26 | 27 | ||
27 | if (d->props.streaming_ctrl != NULL) | 28 | if (d->props.streaming_ctrl != NULL) |
28 | if ((ret = d->props.streaming_ctrl(d,0))) | 29 | if ((ret = d->props.streaming_ctrl(d,0))) |
29 | err("error while stopping stream."); | 30 | err("error while stopping stream."); |
30 | 31 | ||
31 | dvb_usb_urb_kill(d); | ||
32 | } | 32 | } |
33 | 33 | ||
34 | d->feedcount = newfeedcount; | 34 | d->feedcount = newfeedcount; |
@@ -44,6 +44,8 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) | |||
44 | * for reception. | 44 | * for reception. |
45 | */ | 45 | */ |
46 | if (d->feedcount == onoff && d->feedcount > 0) { | 46 | if (d->feedcount == onoff && d->feedcount > 0) { |
47 | deb_ts("submitting all URBs\n"); | ||
48 | dvb_usb_urb_submit(d); | ||
47 | 49 | ||
48 | deb_ts("controlling pid parser\n"); | 50 | deb_ts("controlling pid parser\n"); |
49 | if (d->props.caps & DVB_USB_HAS_PID_FILTER && | 51 | if (d->props.caps & DVB_USB_HAS_PID_FILTER && |
@@ -59,7 +61,6 @@ static int dvb_usb_ctrl_feed(struct dvb_demux_feed *dvbdmxfeed, int onoff) | |||
59 | return -ENODEV; | 61 | return -ENODEV; |
60 | } | 62 | } |
61 | 63 | ||
62 | dvb_usb_urb_submit(d); | ||
63 | } | 64 | } |
64 | return 0; | 65 | return 0; |
65 | } | 66 | } |
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index ac81e5e01a9a..3f5742396096 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig | |||
@@ -356,7 +356,7 @@ config VIDEO_M32R_AR | |||
356 | 356 | ||
357 | config VIDEO_M32R_AR_M64278 | 357 | config VIDEO_M32R_AR_M64278 |
358 | tristate "Use Colour AR module M64278(VGA)" | 358 | tristate "Use Colour AR module M64278(VGA)" |
359 | depends on VIDEO_M32R_AR | 359 | depends on VIDEO_M32R_AR && PLAT_M32700UT |
360 | ---help--- | 360 | ---help--- |
361 | Say Y here to use the Renesas M64278E-800 camera module, | 361 | Say Y here to use the Renesas M64278E-800 camera module, |
362 | which supports VGA(640x480 pixcels) size of images. | 362 | which supports VGA(640x480 pixcels) size of images. |
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c index 7b293f01c9ed..34b80de34fae 100644 --- a/drivers/net/8139cp.c +++ b/drivers/net/8139cp.c | |||
@@ -1897,6 +1897,7 @@ static int cp_resume (struct pci_dev *pdev) | |||
1897 | { | 1897 | { |
1898 | struct net_device *dev; | 1898 | struct net_device *dev; |
1899 | struct cp_private *cp; | 1899 | struct cp_private *cp; |
1900 | unsigned long flags; | ||
1900 | 1901 | ||
1901 | dev = pci_get_drvdata (pdev); | 1902 | dev = pci_get_drvdata (pdev); |
1902 | cp = netdev_priv(dev); | 1903 | cp = netdev_priv(dev); |
@@ -1910,6 +1911,12 @@ static int cp_resume (struct pci_dev *pdev) | |||
1910 | 1911 | ||
1911 | cp_init_hw (cp); | 1912 | cp_init_hw (cp); |
1912 | netif_start_queue (dev); | 1913 | netif_start_queue (dev); |
1914 | |||
1915 | spin_lock_irqsave (&cp->lock, flags); | ||
1916 | |||
1917 | mii_check_media(&cp->mii_if, netif_msg_link(cp), FALSE); | ||
1918 | |||
1919 | spin_unlock_irqrestore (&cp->lock, flags); | ||
1913 | 1920 | ||
1914 | return 0; | 1921 | return 0; |
1915 | } | 1922 | } |
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 8a835eb58808..79e8aa6f2b9e 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig | |||
@@ -131,6 +131,8 @@ config NET_SB1000 | |||
131 | 131 | ||
132 | source "drivers/net/arcnet/Kconfig" | 132 | source "drivers/net/arcnet/Kconfig" |
133 | 133 | ||
134 | source "drivers/net/phy/Kconfig" | ||
135 | |||
134 | # | 136 | # |
135 | # Ethernet | 137 | # Ethernet |
136 | # | 138 | # |
@@ -1145,7 +1147,7 @@ config IBMVETH | |||
1145 | be called ibmveth. | 1147 | be called ibmveth. |
1146 | 1148 | ||
1147 | config IBM_EMAC | 1149 | config IBM_EMAC |
1148 | tristate "IBM PPC4xx EMAC driver support" | 1150 | bool "IBM PPC4xx EMAC driver support" |
1149 | depends on 4xx | 1151 | depends on 4xx |
1150 | select CRC32 | 1152 | select CRC32 |
1151 | ---help--- | 1153 | ---help--- |
@@ -1154,7 +1156,7 @@ config IBM_EMAC | |||
1154 | 1156 | ||
1155 | config IBM_EMAC_ERRMSG | 1157 | config IBM_EMAC_ERRMSG |
1156 | bool "Verbose error messages" | 1158 | bool "Verbose error messages" |
1157 | depends on IBM_EMAC | 1159 | depends on IBM_EMAC && BROKEN |
1158 | 1160 | ||
1159 | config IBM_EMAC_RXB | 1161 | config IBM_EMAC_RXB |
1160 | int "Number of receive buffers" | 1162 | int "Number of receive buffers" |
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 63c6d1e6d4d9..a369ae284a9a 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile | |||
@@ -65,6 +65,7 @@ obj-$(CONFIG_ADAPTEC_STARFIRE) += starfire.o | |||
65 | # | 65 | # |
66 | 66 | ||
67 | obj-$(CONFIG_MII) += mii.o | 67 | obj-$(CONFIG_MII) += mii.o |
68 | obj-$(CONFIG_PHYLIB) += phy/ | ||
68 | 69 | ||
69 | obj-$(CONFIG_SUNDANCE) += sundance.o | 70 | obj-$(CONFIG_SUNDANCE) += sundance.o |
70 | obj-$(CONFIG_HAMACHI) += hamachi.o | 71 | obj-$(CONFIG_HAMACHI) += hamachi.o |
diff --git a/drivers/net/Space.c b/drivers/net/Space.c index 3707df6b0cfa..60304f7e7e5b 100644 --- a/drivers/net/Space.c +++ b/drivers/net/Space.c | |||
@@ -87,7 +87,6 @@ extern struct net_device *mvme147lance_probe(int unit); | |||
87 | extern struct net_device *tc515_probe(int unit); | 87 | extern struct net_device *tc515_probe(int unit); |
88 | extern struct net_device *lance_probe(int unit); | 88 | extern struct net_device *lance_probe(int unit); |
89 | extern struct net_device *mace_probe(int unit); | 89 | extern struct net_device *mace_probe(int unit); |
90 | extern struct net_device *macsonic_probe(int unit); | ||
91 | extern struct net_device *mac8390_probe(int unit); | 90 | extern struct net_device *mac8390_probe(int unit); |
92 | extern struct net_device *mac89x0_probe(int unit); | 91 | extern struct net_device *mac89x0_probe(int unit); |
93 | extern struct net_device *mc32_probe(int unit); | 92 | extern struct net_device *mc32_probe(int unit); |
@@ -284,9 +283,6 @@ static struct devprobe2 m68k_probes[] __initdata = { | |||
284 | #ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ | 283 | #ifdef CONFIG_MACMACE /* Mac 68k Quadra AV builtin Ethernet */ |
285 | {mace_probe, 0}, | 284 | {mace_probe, 0}, |
286 | #endif | 285 | #endif |
287 | #ifdef CONFIG_MACSONIC /* Mac SONIC-based Ethernet of all sorts */ | ||
288 | {macsonic_probe, 0}, | ||
289 | #endif | ||
290 | #ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ | 286 | #ifdef CONFIG_MAC8390 /* NuBus NS8390-based cards */ |
291 | {mac8390_probe, 0}, | 287 | {mac8390_probe, 0}, |
292 | #endif | 288 | #endif |
@@ -318,17 +314,9 @@ static void __init ethif_probe2(int unit) | |||
318 | #ifdef CONFIG_TR | 314 | #ifdef CONFIG_TR |
319 | /* Token-ring device probe */ | 315 | /* Token-ring device probe */ |
320 | extern int ibmtr_probe_card(struct net_device *); | 316 | extern int ibmtr_probe_card(struct net_device *); |
321 | extern struct net_device *sk_isa_probe(int unit); | ||
322 | extern struct net_device *proteon_probe(int unit); | ||
323 | extern struct net_device *smctr_probe(int unit); | 317 | extern struct net_device *smctr_probe(int unit); |
324 | 318 | ||
325 | static struct devprobe2 tr_probes2[] __initdata = { | 319 | static struct devprobe2 tr_probes2[] __initdata = { |
326 | #ifdef CONFIG_SKISA | ||
327 | {sk_isa_probe, 0}, | ||
328 | #endif | ||
329 | #ifdef CONFIG_PROTEON | ||
330 | {proteon_probe, 0}, | ||
331 | #endif | ||
332 | #ifdef CONFIG_SMCTR | 320 | #ifdef CONFIG_SMCTR |
333 | {smctr_probe, 0}, | 321 | {smctr_probe, 0}, |
334 | #endif | 322 | #endif |
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c index 5ce606d9dc03..19e829b567d0 100644 --- a/drivers/net/bonding/bond_alb.c +++ b/drivers/net/bonding/bond_alb.c | |||
@@ -1106,18 +1106,13 @@ static int alb_handle_addr_collision_on_attach(struct bonding *bond, struct slav | |||
1106 | } | 1106 | } |
1107 | } | 1107 | } |
1108 | 1108 | ||
1109 | if (found) { | 1109 | if (!found) |
1110 | /* a slave was found that is using the mac address | 1110 | return 0; |
1111 | * of the new slave | ||
1112 | */ | ||
1113 | printk(KERN_ERR DRV_NAME | ||
1114 | ": Error: the hw address of slave %s is not " | ||
1115 | "unique - cannot enslave it!", | ||
1116 | slave->dev->name); | ||
1117 | return -EINVAL; | ||
1118 | } | ||
1119 | 1111 | ||
1120 | return 0; | 1112 | /* Try setting slave mac to bond address and fall-through |
1113 | to code handling that situation below... */ | ||
1114 | alb_set_slave_mac_addr(slave, bond->dev->dev_addr, | ||
1115 | bond->alb_info.rlb_enabled); | ||
1121 | } | 1116 | } |
1122 | 1117 | ||
1123 | /* The slave's address is equal to the address of the bond. | 1118 | /* The slave's address is equal to the address of the bond. |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index 2c930da90a85..94c9f68dd16b 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -1604,6 +1604,44 @@ static int bond_sethwaddr(struct net_device *bond_dev, struct net_device *slave_ | |||
1604 | return 0; | 1604 | return 0; |
1605 | } | 1605 | } |
1606 | 1606 | ||
1607 | #define BOND_INTERSECT_FEATURES \ | ||
1608 | (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) | ||
1609 | |||
1610 | /* | ||
1611 | * Compute the features available to the bonding device by | ||
1612 | * intersection of all of the slave devices' BOND_INTERSECT_FEATURES. | ||
1613 | * Call this after attaching or detaching a slave to update the | ||
1614 | * bond's features. | ||
1615 | */ | ||
1616 | static int bond_compute_features(struct bonding *bond) | ||
1617 | { | ||
1618 | int i; | ||
1619 | struct slave *slave; | ||
1620 | struct net_device *bond_dev = bond->dev; | ||
1621 | int features = bond->bond_features; | ||
1622 | |||
1623 | bond_for_each_slave(bond, slave, i) { | ||
1624 | struct net_device * slave_dev = slave->dev; | ||
1625 | if (i == 0) { | ||
1626 | features |= BOND_INTERSECT_FEATURES; | ||
1627 | } | ||
1628 | features &= | ||
1629 | ~(~slave_dev->features & BOND_INTERSECT_FEATURES); | ||
1630 | } | ||
1631 | |||
1632 | /* turn off NETIF_F_SG if we need a csum and h/w can't do it */ | ||
1633 | if ((features & NETIF_F_SG) && | ||
1634 | !(features & (NETIF_F_IP_CSUM | | ||
1635 | NETIF_F_NO_CSUM | | ||
1636 | NETIF_F_HW_CSUM))) { | ||
1637 | features &= ~NETIF_F_SG; | ||
1638 | } | ||
1639 | |||
1640 | bond_dev->features = features; | ||
1641 | |||
1642 | return 0; | ||
1643 | } | ||
1644 | |||
1607 | /* enslave device <slave> to bond device <master> */ | 1645 | /* enslave device <slave> to bond device <master> */ |
1608 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) | 1646 | static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev) |
1609 | { | 1647 | { |
@@ -1811,6 +1849,8 @@ static int bond_enslave(struct net_device *bond_dev, struct net_device *slave_de | |||
1811 | new_slave->delay = 0; | 1849 | new_slave->delay = 0; |
1812 | new_slave->link_failure_count = 0; | 1850 | new_slave->link_failure_count = 0; |
1813 | 1851 | ||
1852 | bond_compute_features(bond); | ||
1853 | |||
1814 | if (bond->params.miimon && !bond->params.use_carrier) { | 1854 | if (bond->params.miimon && !bond->params.use_carrier) { |
1815 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); | 1855 | link_reporting = bond_check_dev_link(bond, slave_dev, 1); |
1816 | 1856 | ||
@@ -2015,7 +2055,7 @@ err_free: | |||
2015 | 2055 | ||
2016 | err_undo_flags: | 2056 | err_undo_flags: |
2017 | bond_dev->features = old_features; | 2057 | bond_dev->features = old_features; |
2018 | 2058 | ||
2019 | return res; | 2059 | return res; |
2020 | } | 2060 | } |
2021 | 2061 | ||
@@ -2100,6 +2140,8 @@ static int bond_release(struct net_device *bond_dev, struct net_device *slave_de | |||
2100 | /* release the slave from its bond */ | 2140 | /* release the slave from its bond */ |
2101 | bond_detach_slave(bond, slave); | 2141 | bond_detach_slave(bond, slave); |
2102 | 2142 | ||
2143 | bond_compute_features(bond); | ||
2144 | |||
2103 | if (bond->primary_slave == slave) { | 2145 | if (bond->primary_slave == slave) { |
2104 | bond->primary_slave = NULL; | 2146 | bond->primary_slave = NULL; |
2105 | } | 2147 | } |
@@ -2243,6 +2285,8 @@ static int bond_release_all(struct net_device *bond_dev) | |||
2243 | bond_alb_deinit_slave(bond, slave); | 2285 | bond_alb_deinit_slave(bond, slave); |
2244 | } | 2286 | } |
2245 | 2287 | ||
2288 | bond_compute_features(bond); | ||
2289 | |||
2246 | /* now that the slave is detached, unlock and perform | 2290 | /* now that the slave is detached, unlock and perform |
2247 | * all the undo steps that should not be called from | 2291 | * all the undo steps that should not be called from |
2248 | * within a lock. | 2292 | * within a lock. |
@@ -3588,6 +3632,7 @@ static int bond_master_netdev_event(unsigned long event, struct net_device *bond | |||
3588 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) | 3632 | static int bond_slave_netdev_event(unsigned long event, struct net_device *slave_dev) |
3589 | { | 3633 | { |
3590 | struct net_device *bond_dev = slave_dev->master; | 3634 | struct net_device *bond_dev = slave_dev->master; |
3635 | struct bonding *bond = bond_dev->priv; | ||
3591 | 3636 | ||
3592 | switch (event) { | 3637 | switch (event) { |
3593 | case NETDEV_UNREGISTER: | 3638 | case NETDEV_UNREGISTER: |
@@ -3626,6 +3671,9 @@ static int bond_slave_netdev_event(unsigned long event, struct net_device *slave | |||
3626 | * TODO: handle changing the primary's name | 3671 | * TODO: handle changing the primary's name |
3627 | */ | 3672 | */ |
3628 | break; | 3673 | break; |
3674 | case NETDEV_FEAT_CHANGE: | ||
3675 | bond_compute_features(bond); | ||
3676 | break; | ||
3629 | default: | 3677 | default: |
3630 | break; | 3678 | break; |
3631 | } | 3679 | } |
@@ -4526,6 +4574,11 @@ static inline void bond_set_mode_ops(struct bonding *bond, int mode) | |||
4526 | } | 4574 | } |
4527 | } | 4575 | } |
4528 | 4576 | ||
4577 | static struct ethtool_ops bond_ethtool_ops = { | ||
4578 | .get_tx_csum = ethtool_op_get_tx_csum, | ||
4579 | .get_sg = ethtool_op_get_sg, | ||
4580 | }; | ||
4581 | |||
4529 | /* | 4582 | /* |
4530 | * Does not allocate but creates a /proc entry. | 4583 | * Does not allocate but creates a /proc entry. |
4531 | * Allowed to fail. | 4584 | * Allowed to fail. |
@@ -4555,6 +4608,7 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4555 | bond_dev->stop = bond_close; | 4608 | bond_dev->stop = bond_close; |
4556 | bond_dev->get_stats = bond_get_stats; | 4609 | bond_dev->get_stats = bond_get_stats; |
4557 | bond_dev->do_ioctl = bond_do_ioctl; | 4610 | bond_dev->do_ioctl = bond_do_ioctl; |
4611 | bond_dev->ethtool_ops = &bond_ethtool_ops; | ||
4558 | bond_dev->set_multicast_list = bond_set_multicast_list; | 4612 | bond_dev->set_multicast_list = bond_set_multicast_list; |
4559 | bond_dev->change_mtu = bond_change_mtu; | 4613 | bond_dev->change_mtu = bond_change_mtu; |
4560 | bond_dev->set_mac_address = bond_set_mac_address; | 4614 | bond_dev->set_mac_address = bond_set_mac_address; |
@@ -4591,6 +4645,8 @@ static int __init bond_init(struct net_device *bond_dev, struct bond_params *par | |||
4591 | NETIF_F_HW_VLAN_RX | | 4645 | NETIF_F_HW_VLAN_RX | |
4592 | NETIF_F_HW_VLAN_FILTER); | 4646 | NETIF_F_HW_VLAN_FILTER); |
4593 | 4647 | ||
4648 | bond->bond_features = bond_dev->features; | ||
4649 | |||
4594 | #ifdef CONFIG_PROC_FS | 4650 | #ifdef CONFIG_PROC_FS |
4595 | bond_create_proc_entry(bond); | 4651 | bond_create_proc_entry(bond); |
4596 | #endif | 4652 | #endif |
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h index d27f377b3eeb..388196980862 100644 --- a/drivers/net/bonding/bonding.h +++ b/drivers/net/bonding/bonding.h | |||
@@ -211,6 +211,9 @@ struct bonding { | |||
211 | struct bond_params params; | 211 | struct bond_params params; |
212 | struct list_head vlan_list; | 212 | struct list_head vlan_list; |
213 | struct vlan_group *vlgrp; | 213 | struct vlan_group *vlgrp; |
214 | /* the features the bonding device supports, independently | ||
215 | * of any slaves */ | ||
216 | int bond_features; | ||
214 | }; | 217 | }; |
215 | 218 | ||
216 | /** | 219 | /** |
diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 5fddc0ff8878..6440a892bb81 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c | |||
@@ -48,6 +48,10 @@ | |||
48 | * net_device_stats | 48 | * net_device_stats |
49 | * * introduced tx_timeout function | 49 | * * introduced tx_timeout function |
50 | * * reworked locking | 50 | * * reworked locking |
51 | * | ||
52 | * 01-Jul-2005 Ben Dooks <ben@simtec.co.uk> | ||
53 | * * fixed spinlock call without pointer | ||
54 | * * ensure spinlock is initialised | ||
51 | */ | 55 | */ |
52 | 56 | ||
53 | #include <linux/module.h> | 57 | #include <linux/module.h> |
@@ -148,7 +152,6 @@ static int dm9000_probe(struct device *); | |||
148 | static int dm9000_open(struct net_device *); | 152 | static int dm9000_open(struct net_device *); |
149 | static int dm9000_start_xmit(struct sk_buff *, struct net_device *); | 153 | static int dm9000_start_xmit(struct sk_buff *, struct net_device *); |
150 | static int dm9000_stop(struct net_device *); | 154 | static int dm9000_stop(struct net_device *); |
151 | static int dm9000_do_ioctl(struct net_device *, struct ifreq *, int); | ||
152 | 155 | ||
153 | 156 | ||
154 | static void dm9000_timer(unsigned long); | 157 | static void dm9000_timer(unsigned long); |
@@ -322,7 +325,7 @@ static void dm9000_timeout(struct net_device *dev) | |||
322 | 325 | ||
323 | /* Save previous register address */ | 326 | /* Save previous register address */ |
324 | reg_save = readb(db->io_addr); | 327 | reg_save = readb(db->io_addr); |
325 | spin_lock_irqsave(db->lock,flags); | 328 | spin_lock_irqsave(&db->lock,flags); |
326 | 329 | ||
327 | netif_stop_queue(dev); | 330 | netif_stop_queue(dev); |
328 | dm9000_reset(db); | 331 | dm9000_reset(db); |
@@ -333,7 +336,7 @@ static void dm9000_timeout(struct net_device *dev) | |||
333 | 336 | ||
334 | /* Restore previous register address */ | 337 | /* Restore previous register address */ |
335 | writeb(reg_save, db->io_addr); | 338 | writeb(reg_save, db->io_addr); |
336 | spin_unlock_irqrestore(db->lock,flags); | 339 | spin_unlock_irqrestore(&db->lock,flags); |
337 | } | 340 | } |
338 | 341 | ||
339 | 342 | ||
@@ -387,8 +390,6 @@ dm9000_probe(struct device *dev) | |||
387 | int i; | 390 | int i; |
388 | u32 id_val; | 391 | u32 id_val; |
389 | 392 | ||
390 | printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); | ||
391 | |||
392 | /* Init network device */ | 393 | /* Init network device */ |
393 | ndev = alloc_etherdev(sizeof (struct board_info)); | 394 | ndev = alloc_etherdev(sizeof (struct board_info)); |
394 | if (!ndev) { | 395 | if (!ndev) { |
@@ -405,6 +406,8 @@ dm9000_probe(struct device *dev) | |||
405 | db = (struct board_info *) ndev->priv; | 406 | db = (struct board_info *) ndev->priv; |
406 | memset(db, 0, sizeof (*db)); | 407 | memset(db, 0, sizeof (*db)); |
407 | 408 | ||
409 | spin_lock_init(&db->lock); | ||
410 | |||
408 | if (pdev->num_resources < 2) { | 411 | if (pdev->num_resources < 2) { |
409 | ret = -ENODEV; | 412 | ret = -ENODEV; |
410 | goto out; | 413 | goto out; |
@@ -541,7 +544,6 @@ dm9000_probe(struct device *dev) | |||
541 | ndev->stop = &dm9000_stop; | 544 | ndev->stop = &dm9000_stop; |
542 | ndev->get_stats = &dm9000_get_stats; | 545 | ndev->get_stats = &dm9000_get_stats; |
543 | ndev->set_multicast_list = &dm9000_hash_table; | 546 | ndev->set_multicast_list = &dm9000_hash_table; |
544 | ndev->do_ioctl = &dm9000_do_ioctl; | ||
545 | 547 | ||
546 | #ifdef DM9000_PROGRAM_EEPROM | 548 | #ifdef DM9000_PROGRAM_EEPROM |
547 | program_eeprom(db); | 549 | program_eeprom(db); |
@@ -612,7 +614,7 @@ dm9000_open(struct net_device *dev) | |||
612 | 614 | ||
613 | /* set and active a timer process */ | 615 | /* set and active a timer process */ |
614 | init_timer(&db->timer); | 616 | init_timer(&db->timer); |
615 | db->timer.expires = DM9000_TIMER_WUT * 2; | 617 | db->timer.expires = DM9000_TIMER_WUT; |
616 | db->timer.data = (unsigned long) dev; | 618 | db->timer.data = (unsigned long) dev; |
617 | db->timer.function = &dm9000_timer; | 619 | db->timer.function = &dm9000_timer; |
618 | add_timer(&db->timer); | 620 | add_timer(&db->timer); |
@@ -845,15 +847,6 @@ dm9000_get_stats(struct net_device *dev) | |||
845 | return &db->stats; | 847 | return &db->stats; |
846 | } | 848 | } |
847 | 849 | ||
848 | /* | ||
849 | * Process the upper socket ioctl command | ||
850 | */ | ||
851 | static int | ||
852 | dm9000_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | ||
853 | { | ||
854 | PRINTK1("entering %s\n",__FUNCTION__); | ||
855 | return 0; | ||
856 | } | ||
857 | 850 | ||
858 | /* | 851 | /* |
859 | * A periodic timer routine | 852 | * A periodic timer routine |
@@ -864,21 +857,11 @@ dm9000_timer(unsigned long data) | |||
864 | { | 857 | { |
865 | struct net_device *dev = (struct net_device *) data; | 858 | struct net_device *dev = (struct net_device *) data; |
866 | board_info_t *db = (board_info_t *) dev->priv; | 859 | board_info_t *db = (board_info_t *) dev->priv; |
867 | u8 reg_save; | ||
868 | unsigned long flags; | ||
869 | 860 | ||
870 | PRINTK3("dm9000_timer()\n"); | 861 | PRINTK3("dm9000_timer()\n"); |
871 | 862 | ||
872 | spin_lock_irqsave(db->lock,flags); | ||
873 | /* Save previous register address */ | ||
874 | reg_save = readb(db->io_addr); | ||
875 | |||
876 | mii_check_media(&db->mii, netif_msg_link(db), 0); | 863 | mii_check_media(&db->mii, netif_msg_link(db), 0); |
877 | 864 | ||
878 | /* Restore previous register address */ | ||
879 | writeb(reg_save, db->io_addr); | ||
880 | spin_unlock_irqrestore(db->lock,flags); | ||
881 | |||
882 | /* Set timer again */ | 865 | /* Set timer again */ |
883 | db->timer.expires = DM9000_TIMER_WUT; | 866 | db->timer.expires = DM9000_TIMER_WUT; |
884 | add_timer(&db->timer); | 867 | add_timer(&db->timer); |
@@ -1098,9 +1081,14 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) | |||
1098 | { | 1081 | { |
1099 | board_info_t *db = (board_info_t *) dev->priv; | 1082 | board_info_t *db = (board_info_t *) dev->priv; |
1100 | unsigned long flags; | 1083 | unsigned long flags; |
1084 | unsigned int reg_save; | ||
1101 | int ret; | 1085 | int ret; |
1102 | 1086 | ||
1103 | spin_lock_irqsave(&db->lock,flags); | 1087 | spin_lock_irqsave(&db->lock,flags); |
1088 | |||
1089 | /* Save previous register address */ | ||
1090 | reg_save = readb(db->io_addr); | ||
1091 | |||
1104 | /* Fill the phyxcer register into REG_0C */ | 1092 | /* Fill the phyxcer register into REG_0C */ |
1105 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | 1093 | iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1106 | 1094 | ||
@@ -1111,6 +1099,9 @@ dm9000_phy_read(struct net_device *dev, int phy_reg_unused, int reg) | |||
1111 | /* The read data keeps on REG_0D & REG_0E */ | 1099 | /* The read data keeps on REG_0D & REG_0E */ |
1112 | ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); | 1100 | ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL); |
1113 | 1101 | ||
1102 | /* restore the previous address */ | ||
1103 | writeb(reg_save, db->io_addr); | ||
1104 | |||
1114 | spin_unlock_irqrestore(&db->lock,flags); | 1105 | spin_unlock_irqrestore(&db->lock,flags); |
1115 | 1106 | ||
1116 | return ret; | 1107 | return ret; |
@@ -1124,9 +1115,13 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | |||
1124 | { | 1115 | { |
1125 | board_info_t *db = (board_info_t *) dev->priv; | 1116 | board_info_t *db = (board_info_t *) dev->priv; |
1126 | unsigned long flags; | 1117 | unsigned long flags; |
1118 | unsigned long reg_save; | ||
1127 | 1119 | ||
1128 | spin_lock_irqsave(&db->lock,flags); | 1120 | spin_lock_irqsave(&db->lock,flags); |
1129 | 1121 | ||
1122 | /* Save previous register address */ | ||
1123 | reg_save = readb(db->io_addr); | ||
1124 | |||
1130 | /* Fill the phyxcer register into REG_0C */ | 1125 | /* Fill the phyxcer register into REG_0C */ |
1131 | iow(db, DM9000_EPAR, DM9000_PHY | reg); | 1126 | iow(db, DM9000_EPAR, DM9000_PHY | reg); |
1132 | 1127 | ||
@@ -1138,6 +1133,9 @@ dm9000_phy_write(struct net_device *dev, int phyaddr_unused, int reg, int value) | |||
1138 | udelay(500); /* Wait write complete */ | 1133 | udelay(500); /* Wait write complete */ |
1139 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ | 1134 | iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */ |
1140 | 1135 | ||
1136 | /* restore the previous address */ | ||
1137 | writeb(reg_save, db->io_addr); | ||
1138 | |||
1141 | spin_unlock_irqrestore(&db->lock,flags); | 1139 | spin_unlock_irqrestore(&db->lock,flags); |
1142 | } | 1140 | } |
1143 | 1141 | ||
@@ -1202,6 +1200,8 @@ static struct device_driver dm9000_driver = { | |||
1202 | static int __init | 1200 | static int __init |
1203 | dm9000_init(void) | 1201 | dm9000_init(void) |
1204 | { | 1202 | { |
1203 | printk(KERN_INFO "%s Ethernet Driver\n", CARDNAME); | ||
1204 | |||
1205 | return driver_register(&dm9000_driver); /* search board and register */ | 1205 | return driver_register(&dm9000_driver); /* search board and register */ |
1206 | } | 1206 | } |
1207 | 1207 | ||
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index b82fd15d0891..9b596e0bbf95 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -2767,7 +2767,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
2767 | " next_to_use <%x>\n" | 2767 | " next_to_use <%x>\n" |
2768 | " next_to_clean <%x>\n" | 2768 | " next_to_clean <%x>\n" |
2769 | "buffer_info[next_to_clean]\n" | 2769 | "buffer_info[next_to_clean]\n" |
2770 | " dma <%zx>\n" | 2770 | " dma <%llx>\n" |
2771 | " time_stamp <%lx>\n" | 2771 | " time_stamp <%lx>\n" |
2772 | " next_to_watch <%x>\n" | 2772 | " next_to_watch <%x>\n" |
2773 | " jiffies <%lx>\n" | 2773 | " jiffies <%lx>\n" |
@@ -2776,7 +2776,7 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter) | |||
2776 | E1000_READ_REG(&adapter->hw, TDT), | 2776 | E1000_READ_REG(&adapter->hw, TDT), |
2777 | tx_ring->next_to_use, | 2777 | tx_ring->next_to_use, |
2778 | i, | 2778 | i, |
2779 | tx_ring->buffer_info[i].dma, | 2779 | (unsigned long long)tx_ring->buffer_info[i].dma, |
2780 | tx_ring->buffer_info[i].time_stamp, | 2780 | tx_ring->buffer_info[i].time_stamp, |
2781 | eop, | 2781 | eop, |
2782 | jiffies, | 2782 | jiffies, |
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 1795425f512e..8c62ced2c9b2 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c | |||
@@ -1263,8 +1263,8 @@ speedo_init_rx_ring(struct net_device *dev) | |||
1263 | for (i = 0; i < RX_RING_SIZE; i++) { | 1263 | for (i = 0; i < RX_RING_SIZE; i++) { |
1264 | struct sk_buff *skb; | 1264 | struct sk_buff *skb; |
1265 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); | 1265 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); |
1266 | /* XXX: do we really want to call this before the NULL check? --hch */ | 1266 | if (skb) |
1267 | rx_align(skb); /* Align IP on 16 byte boundary */ | 1267 | rx_align(skb); /* Align IP on 16 byte boundary */ |
1268 | sp->rx_skbuff[i] = skb; | 1268 | sp->rx_skbuff[i] = skb; |
1269 | if (skb == NULL) | 1269 | if (skb == NULL) |
1270 | break; /* OK. Just initially short of Rx bufs. */ | 1270 | break; /* OK. Just initially short of Rx bufs. */ |
@@ -1654,8 +1654,8 @@ static inline struct RxFD *speedo_rx_alloc(struct net_device *dev, int entry) | |||
1654 | struct sk_buff *skb; | 1654 | struct sk_buff *skb; |
1655 | /* Get a fresh skbuff to replace the consumed one. */ | 1655 | /* Get a fresh skbuff to replace the consumed one. */ |
1656 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); | 1656 | skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD)); |
1657 | /* XXX: do we really want to call this before the NULL check? --hch */ | 1657 | if (skb) |
1658 | rx_align(skb); /* Align IP on 16 byte boundary */ | 1658 | rx_align(skb); /* Align IP on 16 byte boundary */ |
1659 | sp->rx_skbuff[entry] = skb; | 1659 | sp->rx_skbuff[entry] = skb; |
1660 | if (skb == NULL) { | 1660 | if (skb == NULL) { |
1661 | sp->rx_ringp[entry] = NULL; | 1661 | sp->rx_ringp[entry] = NULL; |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 64f0f697c958..7d93948aec83 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -85,6 +85,16 @@ | |||
85 | * 0.33: 16 May 2005: Support for MCP51 added. | 85 | * 0.33: 16 May 2005: Support for MCP51 added. |
86 | * 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics. | 86 | * 0.34: 18 Jun 2005: Add DEV_NEED_LINKTIMER to all nForce nics. |
87 | * 0.35: 26 Jun 2005: Support for MCP55 added. | 87 | * 0.35: 26 Jun 2005: Support for MCP55 added. |
88 | * 0.36: 28 Jun 2005: Add jumbo frame support. | ||
89 | * 0.37: 10 Jul 2005: Additional ethtool support, cleanup of pci id list | ||
90 | * 0.38: 16 Jul 2005: tx irq rewrite: Use global flags instead of | ||
91 | * per-packet flags. | ||
92 | * 0.39: 18 Jul 2005: Add 64bit descriptor support. | ||
93 | * 0.40: 19 Jul 2005: Add support for mac address change. | ||
94 | * 0.41: 30 Jul 2005: Write back original MAC in nv_close instead | ||
95 | * of nv_remove | ||
96 | * 0.42: 06 Aug 2005: Fix lack of link speed initialization | ||
97 | * in the second (and later) nv_open call | ||
88 | * | 98 | * |
89 | * Known bugs: | 99 | * Known bugs: |
90 | * We suspect that on some hardware no TX done interrupts are generated. | 100 | * We suspect that on some hardware no TX done interrupts are generated. |
@@ -96,7 +106,7 @@ | |||
96 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 106 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
97 | * superfluous timer interrupts from the nic. | 107 | * superfluous timer interrupts from the nic. |
98 | */ | 108 | */ |
99 | #define FORCEDETH_VERSION "0.35" | 109 | #define FORCEDETH_VERSION "0.41" |
100 | #define DRV_NAME "forcedeth" | 110 | #define DRV_NAME "forcedeth" |
101 | 111 | ||
102 | #include <linux/module.h> | 112 | #include <linux/module.h> |
@@ -131,11 +141,10 @@ | |||
131 | * Hardware access: | 141 | * Hardware access: |
132 | */ | 142 | */ |
133 | 143 | ||
134 | #define DEV_NEED_LASTPACKET1 0x0001 /* set LASTPACKET1 in tx flags */ | 144 | #define DEV_NEED_TIMERIRQ 0x0001 /* set the timer irq flag in the irq mask */ |
135 | #define DEV_IRQMASK_1 0x0002 /* use NVREG_IRQMASK_WANTED_1 for irq mask */ | 145 | #define DEV_NEED_LINKTIMER 0x0002 /* poll link settings. Relies on the timer irq */ |
136 | #define DEV_IRQMASK_2 0x0004 /* use NVREG_IRQMASK_WANTED_2 for irq mask */ | 146 | #define DEV_HAS_LARGEDESC 0x0004 /* device supports jumbo frames and needs packet format 2 */ |
137 | #define DEV_NEED_TIMERIRQ 0x0008 /* set the timer irq flag in the irq mask */ | 147 | #define DEV_HAS_HIGH_DMA 0x0008 /* device supports 64bit dma */ |
138 | #define DEV_NEED_LINKTIMER 0x0010 /* poll link settings. Relies on the timer irq */ | ||
139 | 148 | ||
140 | enum { | 149 | enum { |
141 | NvRegIrqStatus = 0x000, | 150 | NvRegIrqStatus = 0x000, |
@@ -146,13 +155,16 @@ enum { | |||
146 | #define NVREG_IRQ_RX 0x0002 | 155 | #define NVREG_IRQ_RX 0x0002 |
147 | #define NVREG_IRQ_RX_NOBUF 0x0004 | 156 | #define NVREG_IRQ_RX_NOBUF 0x0004 |
148 | #define NVREG_IRQ_TX_ERR 0x0008 | 157 | #define NVREG_IRQ_TX_ERR 0x0008 |
149 | #define NVREG_IRQ_TX2 0x0010 | 158 | #define NVREG_IRQ_TX_OK 0x0010 |
150 | #define NVREG_IRQ_TIMER 0x0020 | 159 | #define NVREG_IRQ_TIMER 0x0020 |
151 | #define NVREG_IRQ_LINK 0x0040 | 160 | #define NVREG_IRQ_LINK 0x0040 |
161 | #define NVREG_IRQ_TX_ERROR 0x0080 | ||
152 | #define NVREG_IRQ_TX1 0x0100 | 162 | #define NVREG_IRQ_TX1 0x0100 |
153 | #define NVREG_IRQMASK_WANTED_1 0x005f | 163 | #define NVREG_IRQMASK_WANTED 0x00df |
154 | #define NVREG_IRQMASK_WANTED_2 0x0147 | 164 | |
155 | #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR|NVREG_IRQ_TX2|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX1)) | 165 | #define NVREG_IRQ_UNKNOWN (~(NVREG_IRQ_RX_ERROR|NVREG_IRQ_RX|NVREG_IRQ_RX_NOBUF|NVREG_IRQ_TX_ERR| \ |
166 | NVREG_IRQ_TX_OK|NVREG_IRQ_TIMER|NVREG_IRQ_LINK|NVREG_IRQ_TX_ERROR| \ | ||
167 | NVREG_IRQ_TX1)) | ||
156 | 168 | ||
157 | NvRegUnknownSetupReg6 = 0x008, | 169 | NvRegUnknownSetupReg6 = 0x008, |
158 | #define NVREG_UNKSETUP6_VAL 3 | 170 | #define NVREG_UNKSETUP6_VAL 3 |
@@ -286,6 +298,18 @@ struct ring_desc { | |||
286 | u32 FlagLen; | 298 | u32 FlagLen; |
287 | }; | 299 | }; |
288 | 300 | ||
301 | struct ring_desc_ex { | ||
302 | u32 PacketBufferHigh; | ||
303 | u32 PacketBufferLow; | ||
304 | u32 Reserved; | ||
305 | u32 FlagLen; | ||
306 | }; | ||
307 | |||
308 | typedef union _ring_type { | ||
309 | struct ring_desc* orig; | ||
310 | struct ring_desc_ex* ex; | ||
311 | } ring_type; | ||
312 | |||
289 | #define FLAG_MASK_V1 0xffff0000 | 313 | #define FLAG_MASK_V1 0xffff0000 |
290 | #define FLAG_MASK_V2 0xffffc000 | 314 | #define FLAG_MASK_V2 0xffffc000 |
291 | #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) | 315 | #define LEN_MASK_V1 (0xffffffff ^ FLAG_MASK_V1) |
@@ -293,7 +317,7 @@ struct ring_desc { | |||
293 | 317 | ||
294 | #define NV_TX_LASTPACKET (1<<16) | 318 | #define NV_TX_LASTPACKET (1<<16) |
295 | #define NV_TX_RETRYERROR (1<<19) | 319 | #define NV_TX_RETRYERROR (1<<19) |
296 | #define NV_TX_LASTPACKET1 (1<<24) | 320 | #define NV_TX_FORCED_INTERRUPT (1<<24) |
297 | #define NV_TX_DEFERRED (1<<26) | 321 | #define NV_TX_DEFERRED (1<<26) |
298 | #define NV_TX_CARRIERLOST (1<<27) | 322 | #define NV_TX_CARRIERLOST (1<<27) |
299 | #define NV_TX_LATECOLLISION (1<<28) | 323 | #define NV_TX_LATECOLLISION (1<<28) |
@@ -303,7 +327,7 @@ struct ring_desc { | |||
303 | 327 | ||
304 | #define NV_TX2_LASTPACKET (1<<29) | 328 | #define NV_TX2_LASTPACKET (1<<29) |
305 | #define NV_TX2_RETRYERROR (1<<18) | 329 | #define NV_TX2_RETRYERROR (1<<18) |
306 | #define NV_TX2_LASTPACKET1 (1<<23) | 330 | #define NV_TX2_FORCED_INTERRUPT (1<<30) |
307 | #define NV_TX2_DEFERRED (1<<25) | 331 | #define NV_TX2_DEFERRED (1<<25) |
308 | #define NV_TX2_CARRIERLOST (1<<26) | 332 | #define NV_TX2_CARRIERLOST (1<<26) |
309 | #define NV_TX2_LATECOLLISION (1<<27) | 333 | #define NV_TX2_LATECOLLISION (1<<27) |
@@ -379,9 +403,13 @@ struct ring_desc { | |||
379 | #define TX_LIMIT_START 62 | 403 | #define TX_LIMIT_START 62 |
380 | 404 | ||
381 | /* rx/tx mac addr + type + vlan + align + slack*/ | 405 | /* rx/tx mac addr + type + vlan + align + slack*/ |
382 | #define RX_NIC_BUFSIZE (ETH_DATA_LEN + 64) | 406 | #define NV_RX_HEADERS (64) |
383 | /* even more slack */ | 407 | /* even more slack. */ |
384 | #define RX_ALLOC_BUFSIZE (ETH_DATA_LEN + 128) | 408 | #define NV_RX_ALLOC_PAD (64) |
409 | |||
410 | /* maximum mtu size */ | ||
411 | #define NV_PKTLIMIT_1 ETH_DATA_LEN /* hard limit not known */ | ||
412 | #define NV_PKTLIMIT_2 9100 /* Actual limit according to NVidia: 9202 */ | ||
385 | 413 | ||
386 | #define OOM_REFILL (1+HZ/20) | 414 | #define OOM_REFILL (1+HZ/20) |
387 | #define POLL_WAIT (1+HZ/100) | 415 | #define POLL_WAIT (1+HZ/100) |
@@ -396,6 +424,7 @@ struct ring_desc { | |||
396 | */ | 424 | */ |
397 | #define DESC_VER_1 0x0 | 425 | #define DESC_VER_1 0x0 |
398 | #define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) | 426 | #define DESC_VER_2 (0x02100|NVREG_TXRXCTL_RXCHECK) |
427 | #define DESC_VER_3 (0x02200|NVREG_TXRXCTL_RXCHECK) | ||
399 | 428 | ||
400 | /* PHY defines */ | 429 | /* PHY defines */ |
401 | #define PHY_OUI_MARVELL 0x5043 | 430 | #define PHY_OUI_MARVELL 0x5043 |
@@ -468,11 +497,12 @@ struct fe_priv { | |||
468 | /* rx specific fields. | 497 | /* rx specific fields. |
469 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); | 498 | * Locking: Within irq hander or disable_irq+spin_lock(&np->lock); |
470 | */ | 499 | */ |
471 | struct ring_desc *rx_ring; | 500 | ring_type rx_ring; |
472 | unsigned int cur_rx, refill_rx; | 501 | unsigned int cur_rx, refill_rx; |
473 | struct sk_buff *rx_skbuff[RX_RING]; | 502 | struct sk_buff *rx_skbuff[RX_RING]; |
474 | dma_addr_t rx_dma[RX_RING]; | 503 | dma_addr_t rx_dma[RX_RING]; |
475 | unsigned int rx_buf_sz; | 504 | unsigned int rx_buf_sz; |
505 | unsigned int pkt_limit; | ||
476 | struct timer_list oom_kick; | 506 | struct timer_list oom_kick; |
477 | struct timer_list nic_poll; | 507 | struct timer_list nic_poll; |
478 | 508 | ||
@@ -484,7 +514,7 @@ struct fe_priv { | |||
484 | /* | 514 | /* |
485 | * tx specific fields. | 515 | * tx specific fields. |
486 | */ | 516 | */ |
487 | struct ring_desc *tx_ring; | 517 | ring_type tx_ring; |
488 | unsigned int next_tx, nic_tx; | 518 | unsigned int next_tx, nic_tx; |
489 | struct sk_buff *tx_skbuff[TX_RING]; | 519 | struct sk_buff *tx_skbuff[TX_RING]; |
490 | dma_addr_t tx_dma[TX_RING]; | 520 | dma_addr_t tx_dma[TX_RING]; |
@@ -519,6 +549,11 @@ static inline u32 nv_descr_getlength(struct ring_desc *prd, u32 v) | |||
519 | & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); | 549 | & ((v == DESC_VER_1) ? LEN_MASK_V1 : LEN_MASK_V2); |
520 | } | 550 | } |
521 | 551 | ||
552 | static inline u32 nv_descr_getlength_ex(struct ring_desc_ex *prd, u32 v) | ||
553 | { | ||
554 | return le32_to_cpu(prd->FlagLen) & LEN_MASK_V2; | ||
555 | } | ||
556 | |||
522 | static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, | 557 | static int reg_delay(struct net_device *dev, int offset, u32 mask, u32 target, |
523 | int delay, int delaymax, const char *msg) | 558 | int delay, int delaymax, const char *msg) |
524 | { | 559 | { |
@@ -792,7 +827,7 @@ static int nv_alloc_rx(struct net_device *dev) | |||
792 | nr = refill_rx % RX_RING; | 827 | nr = refill_rx % RX_RING; |
793 | if (np->rx_skbuff[nr] == NULL) { | 828 | if (np->rx_skbuff[nr] == NULL) { |
794 | 829 | ||
795 | skb = dev_alloc_skb(RX_ALLOC_BUFSIZE); | 830 | skb = dev_alloc_skb(np->rx_buf_sz + NV_RX_ALLOC_PAD); |
796 | if (!skb) | 831 | if (!skb) |
797 | break; | 832 | break; |
798 | 833 | ||
@@ -803,9 +838,16 @@ static int nv_alloc_rx(struct net_device *dev) | |||
803 | } | 838 | } |
804 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, | 839 | np->rx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len, |
805 | PCI_DMA_FROMDEVICE); | 840 | PCI_DMA_FROMDEVICE); |
806 | np->rx_ring[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); | 841 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
807 | wmb(); | 842 | np->rx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->rx_dma[nr]); |
808 | np->rx_ring[nr].FlagLen = cpu_to_le32(RX_NIC_BUFSIZE | NV_RX_AVAIL); | 843 | wmb(); |
844 | np->rx_ring.orig[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX_AVAIL); | ||
845 | } else { | ||
846 | np->rx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->rx_dma[nr]) >> 32; | ||
847 | np->rx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->rx_dma[nr]) & 0x0FFFFFFFF; | ||
848 | wmb(); | ||
849 | np->rx_ring.ex[nr].FlagLen = cpu_to_le32(np->rx_buf_sz | NV_RX2_AVAIL); | ||
850 | } | ||
809 | dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", | 851 | dprintk(KERN_DEBUG "%s: nv_alloc_rx: Packet %d marked as Available\n", |
810 | dev->name, refill_rx); | 852 | dev->name, refill_rx); |
811 | refill_rx++; | 853 | refill_rx++; |
@@ -831,19 +873,37 @@ static void nv_do_rx_refill(unsigned long data) | |||
831 | enable_irq(dev->irq); | 873 | enable_irq(dev->irq); |
832 | } | 874 | } |
833 | 875 | ||
834 | static int nv_init_ring(struct net_device *dev) | 876 | static void nv_init_rx(struct net_device *dev) |
835 | { | 877 | { |
836 | struct fe_priv *np = get_nvpriv(dev); | 878 | struct fe_priv *np = get_nvpriv(dev); |
837 | int i; | 879 | int i; |
838 | 880 | ||
839 | np->next_tx = np->nic_tx = 0; | ||
840 | for (i = 0; i < TX_RING; i++) | ||
841 | np->tx_ring[i].FlagLen = 0; | ||
842 | |||
843 | np->cur_rx = RX_RING; | 881 | np->cur_rx = RX_RING; |
844 | np->refill_rx = 0; | 882 | np->refill_rx = 0; |
845 | for (i = 0; i < RX_RING; i++) | 883 | for (i = 0; i < RX_RING; i++) |
846 | np->rx_ring[i].FlagLen = 0; | 884 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
885 | np->rx_ring.orig[i].FlagLen = 0; | ||
886 | else | ||
887 | np->rx_ring.ex[i].FlagLen = 0; | ||
888 | } | ||
889 | |||
890 | static void nv_init_tx(struct net_device *dev) | ||
891 | { | ||
892 | struct fe_priv *np = get_nvpriv(dev); | ||
893 | int i; | ||
894 | |||
895 | np->next_tx = np->nic_tx = 0; | ||
896 | for (i = 0; i < TX_RING; i++) | ||
897 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) | ||
898 | np->tx_ring.orig[i].FlagLen = 0; | ||
899 | else | ||
900 | np->tx_ring.ex[i].FlagLen = 0; | ||
901 | } | ||
902 | |||
903 | static int nv_init_ring(struct net_device *dev) | ||
904 | { | ||
905 | nv_init_tx(dev); | ||
906 | nv_init_rx(dev); | ||
847 | return nv_alloc_rx(dev); | 907 | return nv_alloc_rx(dev); |
848 | } | 908 | } |
849 | 909 | ||
@@ -852,7 +912,10 @@ static void nv_drain_tx(struct net_device *dev) | |||
852 | struct fe_priv *np = get_nvpriv(dev); | 912 | struct fe_priv *np = get_nvpriv(dev); |
853 | int i; | 913 | int i; |
854 | for (i = 0; i < TX_RING; i++) { | 914 | for (i = 0; i < TX_RING; i++) { |
855 | np->tx_ring[i].FlagLen = 0; | 915 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
916 | np->tx_ring.orig[i].FlagLen = 0; | ||
917 | else | ||
918 | np->tx_ring.ex[i].FlagLen = 0; | ||
856 | if (np->tx_skbuff[i]) { | 919 | if (np->tx_skbuff[i]) { |
857 | pci_unmap_single(np->pci_dev, np->tx_dma[i], | 920 | pci_unmap_single(np->pci_dev, np->tx_dma[i], |
858 | np->tx_skbuff[i]->len, | 921 | np->tx_skbuff[i]->len, |
@@ -869,7 +932,10 @@ static void nv_drain_rx(struct net_device *dev) | |||
869 | struct fe_priv *np = get_nvpriv(dev); | 932 | struct fe_priv *np = get_nvpriv(dev); |
870 | int i; | 933 | int i; |
871 | for (i = 0; i < RX_RING; i++) { | 934 | for (i = 0; i < RX_RING; i++) { |
872 | np->rx_ring[i].FlagLen = 0; | 935 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
936 | np->rx_ring.orig[i].FlagLen = 0; | ||
937 | else | ||
938 | np->rx_ring.ex[i].FlagLen = 0; | ||
873 | wmb(); | 939 | wmb(); |
874 | if (np->rx_skbuff[i]) { | 940 | if (np->rx_skbuff[i]) { |
875 | pci_unmap_single(np->pci_dev, np->rx_dma[i], | 941 | pci_unmap_single(np->pci_dev, np->rx_dma[i], |
@@ -900,11 +966,19 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
900 | np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len, | 966 | np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len, |
901 | PCI_DMA_TODEVICE); | 967 | PCI_DMA_TODEVICE); |
902 | 968 | ||
903 | np->tx_ring[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); | 969 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
970 | np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]); | ||
971 | else { | ||
972 | np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32; | ||
973 | np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF; | ||
974 | } | ||
904 | 975 | ||
905 | spin_lock_irq(&np->lock); | 976 | spin_lock_irq(&np->lock); |
906 | wmb(); | 977 | wmb(); |
907 | np->tx_ring[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | 978 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
979 | np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | ||
980 | else | ||
981 | np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags ); | ||
908 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", | 982 | dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n", |
909 | dev->name, np->next_tx); | 983 | dev->name, np->next_tx); |
910 | { | 984 | { |
@@ -942,7 +1016,10 @@ static void nv_tx_done(struct net_device *dev) | |||
942 | while (np->nic_tx != np->next_tx) { | 1016 | while (np->nic_tx != np->next_tx) { |
943 | i = np->nic_tx % TX_RING; | 1017 | i = np->nic_tx % TX_RING; |
944 | 1018 | ||
945 | Flags = le32_to_cpu(np->tx_ring[i].FlagLen); | 1019 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
1020 | Flags = le32_to_cpu(np->tx_ring.orig[i].FlagLen); | ||
1021 | else | ||
1022 | Flags = le32_to_cpu(np->tx_ring.ex[i].FlagLen); | ||
946 | 1023 | ||
947 | dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", | 1024 | dprintk(KERN_DEBUG "%s: nv_tx_done: looking at packet %d, Flags 0x%x.\n", |
948 | dev->name, np->nic_tx, Flags); | 1025 | dev->name, np->nic_tx, Flags); |
@@ -993,9 +1070,56 @@ static void nv_tx_timeout(struct net_device *dev) | |||
993 | struct fe_priv *np = get_nvpriv(dev); | 1070 | struct fe_priv *np = get_nvpriv(dev); |
994 | u8 __iomem *base = get_hwbase(dev); | 1071 | u8 __iomem *base = get_hwbase(dev); |
995 | 1072 | ||
996 | dprintk(KERN_DEBUG "%s: Got tx_timeout. irq: %08x\n", dev->name, | 1073 | printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name, |
997 | readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); | 1074 | readl(base + NvRegIrqStatus) & NVREG_IRQSTAT_MASK); |
998 | 1075 | ||
1076 | { | ||
1077 | int i; | ||
1078 | |||
1079 | printk(KERN_INFO "%s: Ring at %lx: next %d nic %d\n", | ||
1080 | dev->name, (unsigned long)np->ring_addr, | ||
1081 | np->next_tx, np->nic_tx); | ||
1082 | printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); | ||
1083 | for (i=0;i<0x400;i+= 32) { | ||
1084 | printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | ||
1085 | i, | ||
1086 | readl(base + i + 0), readl(base + i + 4), | ||
1087 | readl(base + i + 8), readl(base + i + 12), | ||
1088 | readl(base + i + 16), readl(base + i + 20), | ||
1089 | readl(base + i + 24), readl(base + i + 28)); | ||
1090 | } | ||
1091 | printk(KERN_INFO "%s: Dumping tx ring\n", dev->name); | ||
1092 | for (i=0;i<TX_RING;i+= 4) { | ||
1093 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { | ||
1094 | printk(KERN_INFO "%03x: %08x %08x // %08x %08x // %08x %08x // %08x %08x\n", | ||
1095 | i, | ||
1096 | le32_to_cpu(np->tx_ring.orig[i].PacketBuffer), | ||
1097 | le32_to_cpu(np->tx_ring.orig[i].FlagLen), | ||
1098 | le32_to_cpu(np->tx_ring.orig[i+1].PacketBuffer), | ||
1099 | le32_to_cpu(np->tx_ring.orig[i+1].FlagLen), | ||
1100 | le32_to_cpu(np->tx_ring.orig[i+2].PacketBuffer), | ||
1101 | le32_to_cpu(np->tx_ring.orig[i+2].FlagLen), | ||
1102 | le32_to_cpu(np->tx_ring.orig[i+3].PacketBuffer), | ||
1103 | le32_to_cpu(np->tx_ring.orig[i+3].FlagLen)); | ||
1104 | } else { | ||
1105 | printk(KERN_INFO "%03x: %08x %08x %08x // %08x %08x %08x // %08x %08x %08x // %08x %08x %08x\n", | ||
1106 | i, | ||
1107 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferHigh), | ||
1108 | le32_to_cpu(np->tx_ring.ex[i].PacketBufferLow), | ||
1109 | le32_to_cpu(np->tx_ring.ex[i].FlagLen), | ||
1110 | le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferHigh), | ||
1111 | le32_to_cpu(np->tx_ring.ex[i+1].PacketBufferLow), | ||
1112 | le32_to_cpu(np->tx_ring.ex[i+1].FlagLen), | ||
1113 | le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferHigh), | ||
1114 | le32_to_cpu(np->tx_ring.ex[i+2].PacketBufferLow), | ||
1115 | le32_to_cpu(np->tx_ring.ex[i+2].FlagLen), | ||
1116 | le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferHigh), | ||
1117 | le32_to_cpu(np->tx_ring.ex[i+3].PacketBufferLow), | ||
1118 | le32_to_cpu(np->tx_ring.ex[i+3].FlagLen)); | ||
1119 | } | ||
1120 | } | ||
1121 | } | ||
1122 | |||
999 | spin_lock_irq(&np->lock); | 1123 | spin_lock_irq(&np->lock); |
1000 | 1124 | ||
1001 | /* 1) stop tx engine */ | 1125 | /* 1) stop tx engine */ |
@@ -1009,7 +1133,10 @@ static void nv_tx_timeout(struct net_device *dev) | |||
1009 | printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); | 1133 | printk(KERN_DEBUG "%s: tx_timeout: dead entries!\n", dev->name); |
1010 | nv_drain_tx(dev); | 1134 | nv_drain_tx(dev); |
1011 | np->next_tx = np->nic_tx = 0; | 1135 | np->next_tx = np->nic_tx = 0; |
1012 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | 1136 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
1137 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
1138 | else | ||
1139 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1013 | netif_wake_queue(dev); | 1140 | netif_wake_queue(dev); |
1014 | } | 1141 | } |
1015 | 1142 | ||
@@ -1084,8 +1211,13 @@ static void nv_rx_process(struct net_device *dev) | |||
1084 | break; /* we scanned the whole ring - do not continue */ | 1211 | break; /* we scanned the whole ring - do not continue */ |
1085 | 1212 | ||
1086 | i = np->cur_rx % RX_RING; | 1213 | i = np->cur_rx % RX_RING; |
1087 | Flags = le32_to_cpu(np->rx_ring[i].FlagLen); | 1214 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
1088 | len = nv_descr_getlength(&np->rx_ring[i], np->desc_ver); | 1215 | Flags = le32_to_cpu(np->rx_ring.orig[i].FlagLen); |
1216 | len = nv_descr_getlength(&np->rx_ring.orig[i], np->desc_ver); | ||
1217 | } else { | ||
1218 | Flags = le32_to_cpu(np->rx_ring.ex[i].FlagLen); | ||
1219 | len = nv_descr_getlength_ex(&np->rx_ring.ex[i], np->desc_ver); | ||
1220 | } | ||
1089 | 1221 | ||
1090 | dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", | 1222 | dprintk(KERN_DEBUG "%s: nv_rx_process: looking at packet %d, Flags 0x%x.\n", |
1091 | dev->name, np->cur_rx, Flags); | 1223 | dev->name, np->cur_rx, Flags); |
@@ -1207,15 +1339,133 @@ next_pkt: | |||
1207 | } | 1339 | } |
1208 | } | 1340 | } |
1209 | 1341 | ||
1342 | static void set_bufsize(struct net_device *dev) | ||
1343 | { | ||
1344 | struct fe_priv *np = netdev_priv(dev); | ||
1345 | |||
1346 | if (dev->mtu <= ETH_DATA_LEN) | ||
1347 | np->rx_buf_sz = ETH_DATA_LEN + NV_RX_HEADERS; | ||
1348 | else | ||
1349 | np->rx_buf_sz = dev->mtu + NV_RX_HEADERS; | ||
1350 | } | ||
1351 | |||
1210 | /* | 1352 | /* |
1211 | * nv_change_mtu: dev->change_mtu function | 1353 | * nv_change_mtu: dev->change_mtu function |
1212 | * Called with dev_base_lock held for read. | 1354 | * Called with dev_base_lock held for read. |
1213 | */ | 1355 | */ |
1214 | static int nv_change_mtu(struct net_device *dev, int new_mtu) | 1356 | static int nv_change_mtu(struct net_device *dev, int new_mtu) |
1215 | { | 1357 | { |
1216 | if (new_mtu > ETH_DATA_LEN) | 1358 | struct fe_priv *np = get_nvpriv(dev); |
1359 | int old_mtu; | ||
1360 | |||
1361 | if (new_mtu < 64 || new_mtu > np->pkt_limit) | ||
1217 | return -EINVAL; | 1362 | return -EINVAL; |
1363 | |||
1364 | old_mtu = dev->mtu; | ||
1218 | dev->mtu = new_mtu; | 1365 | dev->mtu = new_mtu; |
1366 | |||
1367 | /* return early if the buffer sizes will not change */ | ||
1368 | if (old_mtu <= ETH_DATA_LEN && new_mtu <= ETH_DATA_LEN) | ||
1369 | return 0; | ||
1370 | if (old_mtu == new_mtu) | ||
1371 | return 0; | ||
1372 | |||
1373 | /* synchronized against open : rtnl_lock() held by caller */ | ||
1374 | if (netif_running(dev)) { | ||
1375 | u8 *base = get_hwbase(dev); | ||
1376 | /* | ||
1377 | * It seems that the nic preloads valid ring entries into an | ||
1378 | * internal buffer. The procedure for flushing everything is | ||
1379 | * guessed, there is probably a simpler approach. | ||
1380 | * Changing the MTU is a rare event, it shouldn't matter. | ||
1381 | */ | ||
1382 | disable_irq(dev->irq); | ||
1383 | spin_lock_bh(&dev->xmit_lock); | ||
1384 | spin_lock(&np->lock); | ||
1385 | /* stop engines */ | ||
1386 | nv_stop_rx(dev); | ||
1387 | nv_stop_tx(dev); | ||
1388 | nv_txrx_reset(dev); | ||
1389 | /* drain rx queue */ | ||
1390 | nv_drain_rx(dev); | ||
1391 | nv_drain_tx(dev); | ||
1392 | /* reinit driver view of the rx queue */ | ||
1393 | nv_init_rx(dev); | ||
1394 | nv_init_tx(dev); | ||
1395 | /* alloc new rx buffers */ | ||
1396 | set_bufsize(dev); | ||
1397 | if (nv_alloc_rx(dev)) { | ||
1398 | if (!np->in_shutdown) | ||
1399 | mod_timer(&np->oom_kick, jiffies + OOM_REFILL); | ||
1400 | } | ||
1401 | /* reinit nic view of the rx queue */ | ||
1402 | writel(np->rx_buf_sz, base + NvRegOffloadConfig); | ||
1403 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); | ||
1404 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) | ||
1405 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
1406 | else | ||
1407 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1408 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), | ||
1409 | base + NvRegRingSizes); | ||
1410 | pci_push(base); | ||
1411 | writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl); | ||
1412 | pci_push(base); | ||
1413 | |||
1414 | /* restart rx engine */ | ||
1415 | nv_start_rx(dev); | ||
1416 | nv_start_tx(dev); | ||
1417 | spin_unlock(&np->lock); | ||
1418 | spin_unlock_bh(&dev->xmit_lock); | ||
1419 | enable_irq(dev->irq); | ||
1420 | } | ||
1421 | return 0; | ||
1422 | } | ||
1423 | |||
1424 | static void nv_copy_mac_to_hw(struct net_device *dev) | ||
1425 | { | ||
1426 | u8 *base = get_hwbase(dev); | ||
1427 | u32 mac[2]; | ||
1428 | |||
1429 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + | ||
1430 | (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); | ||
1431 | mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); | ||
1432 | |||
1433 | writel(mac[0], base + NvRegMacAddrA); | ||
1434 | writel(mac[1], base + NvRegMacAddrB); | ||
1435 | } | ||
1436 | |||
1437 | /* | ||
1438 | * nv_set_mac_address: dev->set_mac_address function | ||
1439 | * Called with rtnl_lock() held. | ||
1440 | */ | ||
1441 | static int nv_set_mac_address(struct net_device *dev, void *addr) | ||
1442 | { | ||
1443 | struct fe_priv *np = get_nvpriv(dev); | ||
1444 | struct sockaddr *macaddr = (struct sockaddr*)addr; | ||
1445 | |||
1446 | if(!is_valid_ether_addr(macaddr->sa_data)) | ||
1447 | return -EADDRNOTAVAIL; | ||
1448 | |||
1449 | /* synchronized against open : rtnl_lock() held by caller */ | ||
1450 | memcpy(dev->dev_addr, macaddr->sa_data, ETH_ALEN); | ||
1451 | |||
1452 | if (netif_running(dev)) { | ||
1453 | spin_lock_bh(&dev->xmit_lock); | ||
1454 | spin_lock_irq(&np->lock); | ||
1455 | |||
1456 | /* stop rx engine */ | ||
1457 | nv_stop_rx(dev); | ||
1458 | |||
1459 | /* set mac address */ | ||
1460 | nv_copy_mac_to_hw(dev); | ||
1461 | |||
1462 | /* restart rx engine */ | ||
1463 | nv_start_rx(dev); | ||
1464 | spin_unlock_irq(&np->lock); | ||
1465 | spin_unlock_bh(&dev->xmit_lock); | ||
1466 | } else { | ||
1467 | nv_copy_mac_to_hw(dev); | ||
1468 | } | ||
1219 | return 0; | 1469 | return 0; |
1220 | } | 1470 | } |
1221 | 1471 | ||
@@ -1470,7 +1720,7 @@ static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs) | |||
1470 | if (!(events & np->irqmask)) | 1720 | if (!(events & np->irqmask)) |
1471 | break; | 1721 | break; |
1472 | 1722 | ||
1473 | if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX2|NVREG_IRQ_TX_ERR)) { | 1723 | if (events & (NVREG_IRQ_TX1|NVREG_IRQ_TX_OK|NVREG_IRQ_TX_ERROR|NVREG_IRQ_TX_ERR)) { |
1474 | spin_lock(&np->lock); | 1724 | spin_lock(&np->lock); |
1475 | nv_tx_done(dev); | 1725 | nv_tx_done(dev); |
1476 | spin_unlock(&np->lock); | 1726 | spin_unlock(&np->lock); |
@@ -1761,6 +2011,50 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
1761 | return 0; | 2011 | return 0; |
1762 | } | 2012 | } |
1763 | 2013 | ||
2014 | #define FORCEDETH_REGS_VER 1 | ||
2015 | #define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ | ||
2016 | |||
2017 | static int nv_get_regs_len(struct net_device *dev) | ||
2018 | { | ||
2019 | return FORCEDETH_REGS_SIZE; | ||
2020 | } | ||
2021 | |||
2022 | static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) | ||
2023 | { | ||
2024 | struct fe_priv *np = get_nvpriv(dev); | ||
2025 | u8 __iomem *base = get_hwbase(dev); | ||
2026 | u32 *rbuf = buf; | ||
2027 | int i; | ||
2028 | |||
2029 | regs->version = FORCEDETH_REGS_VER; | ||
2030 | spin_lock_irq(&np->lock); | ||
2031 | for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) | ||
2032 | rbuf[i] = readl(base + i*sizeof(u32)); | ||
2033 | spin_unlock_irq(&np->lock); | ||
2034 | } | ||
2035 | |||
2036 | static int nv_nway_reset(struct net_device *dev) | ||
2037 | { | ||
2038 | struct fe_priv *np = get_nvpriv(dev); | ||
2039 | int ret; | ||
2040 | |||
2041 | spin_lock_irq(&np->lock); | ||
2042 | if (np->autoneg) { | ||
2043 | int bmcr; | ||
2044 | |||
2045 | bmcr = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ); | ||
2046 | bmcr |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
2047 | mii_rw(dev, np->phyaddr, MII_BMCR, bmcr); | ||
2048 | |||
2049 | ret = 0; | ||
2050 | } else { | ||
2051 | ret = -EINVAL; | ||
2052 | } | ||
2053 | spin_unlock_irq(&np->lock); | ||
2054 | |||
2055 | return ret; | ||
2056 | } | ||
2057 | |||
1764 | static struct ethtool_ops ops = { | 2058 | static struct ethtool_ops ops = { |
1765 | .get_drvinfo = nv_get_drvinfo, | 2059 | .get_drvinfo = nv_get_drvinfo, |
1766 | .get_link = ethtool_op_get_link, | 2060 | .get_link = ethtool_op_get_link, |
@@ -1768,6 +2062,9 @@ static struct ethtool_ops ops = { | |||
1768 | .set_wol = nv_set_wol, | 2062 | .set_wol = nv_set_wol, |
1769 | .get_settings = nv_get_settings, | 2063 | .get_settings = nv_get_settings, |
1770 | .set_settings = nv_set_settings, | 2064 | .set_settings = nv_set_settings, |
2065 | .get_regs_len = nv_get_regs_len, | ||
2066 | .get_regs = nv_get_regs, | ||
2067 | .nway_reset = nv_nway_reset, | ||
1771 | }; | 2068 | }; |
1772 | 2069 | ||
1773 | static int nv_open(struct net_device *dev) | 2070 | static int nv_open(struct net_device *dev) |
@@ -1792,6 +2089,7 @@ static int nv_open(struct net_device *dev) | |||
1792 | writel(0, base + NvRegAdapterControl); | 2089 | writel(0, base + NvRegAdapterControl); |
1793 | 2090 | ||
1794 | /* 2) initialize descriptor rings */ | 2091 | /* 2) initialize descriptor rings */ |
2092 | set_bufsize(dev); | ||
1795 | oom = nv_init_ring(dev); | 2093 | oom = nv_init_ring(dev); |
1796 | 2094 | ||
1797 | writel(0, base + NvRegLinkSpeed); | 2095 | writel(0, base + NvRegLinkSpeed); |
@@ -1802,20 +2100,14 @@ static int nv_open(struct net_device *dev) | |||
1802 | np->in_shutdown = 0; | 2100 | np->in_shutdown = 0; |
1803 | 2101 | ||
1804 | /* 3) set mac address */ | 2102 | /* 3) set mac address */ |
1805 | { | 2103 | nv_copy_mac_to_hw(dev); |
1806 | u32 mac[2]; | ||
1807 | |||
1808 | mac[0] = (dev->dev_addr[0] << 0) + (dev->dev_addr[1] << 8) + | ||
1809 | (dev->dev_addr[2] << 16) + (dev->dev_addr[3] << 24); | ||
1810 | mac[1] = (dev->dev_addr[4] << 0) + (dev->dev_addr[5] << 8); | ||
1811 | |||
1812 | writel(mac[0], base + NvRegMacAddrA); | ||
1813 | writel(mac[1], base + NvRegMacAddrB); | ||
1814 | } | ||
1815 | 2104 | ||
1816 | /* 4) give hw rings */ | 2105 | /* 4) give hw rings */ |
1817 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); | 2106 | writel((u32) np->ring_addr, base + NvRegRxRingPhysAddr); |
1818 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | 2107 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2108 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc)), base + NvRegTxRingPhysAddr); | ||
2109 | else | ||
2110 | writel((u32) (np->ring_addr + RX_RING*sizeof(struct ring_desc_ex)), base + NvRegTxRingPhysAddr); | ||
1819 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), | 2111 | writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT), |
1820 | base + NvRegRingSizes); | 2112 | base + NvRegRingSizes); |
1821 | 2113 | ||
@@ -1837,7 +2129,7 @@ static int nv_open(struct net_device *dev) | |||
1837 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); | 2129 | writel(NVREG_MISC1_FORCE | NVREG_MISC1_HD, base + NvRegMisc1); |
1838 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); | 2130 | writel(readl(base + NvRegTransmitterStatus), base + NvRegTransmitterStatus); |
1839 | writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); | 2131 | writel(NVREG_PFF_ALWAYS, base + NvRegPacketFilterFlags); |
1840 | writel(NVREG_OFFLOAD_NORMAL, base + NvRegOffloadConfig); | 2132 | writel(np->rx_buf_sz, base + NvRegOffloadConfig); |
1841 | 2133 | ||
1842 | writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); | 2134 | writel(readl(base + NvRegReceiverStatus), base + NvRegReceiverStatus); |
1843 | get_random_bytes(&i, sizeof(i)); | 2135 | get_random_bytes(&i, sizeof(i)); |
@@ -1888,6 +2180,9 @@ static int nv_open(struct net_device *dev) | |||
1888 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); | 2180 | writel(NVREG_MIISTAT_MASK, base + NvRegMIIStatus); |
1889 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); | 2181 | dprintk(KERN_INFO "startup: got 0x%08x.\n", miistat); |
1890 | } | 2182 | } |
2183 | /* set linkspeed to invalid value, thus force nv_update_linkspeed | ||
2184 | * to init hw */ | ||
2185 | np->linkspeed = 0; | ||
1891 | ret = nv_update_linkspeed(dev); | 2186 | ret = nv_update_linkspeed(dev); |
1892 | nv_start_rx(dev); | 2187 | nv_start_rx(dev); |
1893 | nv_start_tx(dev); | 2188 | nv_start_tx(dev); |
@@ -1942,6 +2237,12 @@ static int nv_close(struct net_device *dev) | |||
1942 | if (np->wolenabled) | 2237 | if (np->wolenabled) |
1943 | nv_start_rx(dev); | 2238 | nv_start_rx(dev); |
1944 | 2239 | ||
2240 | /* special op: write back the misordered MAC address - otherwise | ||
2241 | * the next nv_probe would see a wrong address. | ||
2242 | */ | ||
2243 | writel(np->orig_mac[0], base + NvRegMacAddrA); | ||
2244 | writel(np->orig_mac[1], base + NvRegMacAddrB); | ||
2245 | |||
1945 | /* FIXME: power down nic */ | 2246 | /* FIXME: power down nic */ |
1946 | 2247 | ||
1947 | return 0; | 2248 | return 0; |
@@ -2006,32 +2307,55 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2006 | } | 2307 | } |
2007 | 2308 | ||
2008 | /* handle different descriptor versions */ | 2309 | /* handle different descriptor versions */ |
2009 | if (pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_1 || | 2310 | if (id->driver_data & DEV_HAS_HIGH_DMA) { |
2010 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_2 || | 2311 | /* packet format 3: supports 40-bit addressing */ |
2011 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_3 || | 2312 | np->desc_ver = DESC_VER_3; |
2012 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || | 2313 | if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) { |
2013 | pci_dev->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) | 2314 | printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n", |
2014 | np->desc_ver = DESC_VER_1; | 2315 | pci_name(pci_dev)); |
2015 | else | 2316 | } |
2317 | } else if (id->driver_data & DEV_HAS_LARGEDESC) { | ||
2318 | /* packet format 2: supports jumbo frames */ | ||
2016 | np->desc_ver = DESC_VER_2; | 2319 | np->desc_ver = DESC_VER_2; |
2320 | } else { | ||
2321 | /* original packet format */ | ||
2322 | np->desc_ver = DESC_VER_1; | ||
2323 | } | ||
2324 | |||
2325 | np->pkt_limit = NV_PKTLIMIT_1; | ||
2326 | if (id->driver_data & DEV_HAS_LARGEDESC) | ||
2327 | np->pkt_limit = NV_PKTLIMIT_2; | ||
2017 | 2328 | ||
2018 | err = -ENOMEM; | 2329 | err = -ENOMEM; |
2019 | np->base = ioremap(addr, NV_PCI_REGSZ); | 2330 | np->base = ioremap(addr, NV_PCI_REGSZ); |
2020 | if (!np->base) | 2331 | if (!np->base) |
2021 | goto out_relreg; | 2332 | goto out_relreg; |
2022 | dev->base_addr = (unsigned long)np->base; | 2333 | dev->base_addr = (unsigned long)np->base; |
2334 | |||
2023 | dev->irq = pci_dev->irq; | 2335 | dev->irq = pci_dev->irq; |
2024 | np->rx_ring = pci_alloc_consistent(pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), | 2336 | |
2025 | &np->ring_addr); | 2337 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { |
2026 | if (!np->rx_ring) | 2338 | np->rx_ring.orig = pci_alloc_consistent(pci_dev, |
2027 | goto out_unmap; | 2339 | sizeof(struct ring_desc) * (RX_RING + TX_RING), |
2028 | np->tx_ring = &np->rx_ring[RX_RING]; | 2340 | &np->ring_addr); |
2341 | if (!np->rx_ring.orig) | ||
2342 | goto out_unmap; | ||
2343 | np->tx_ring.orig = &np->rx_ring.orig[RX_RING]; | ||
2344 | } else { | ||
2345 | np->rx_ring.ex = pci_alloc_consistent(pci_dev, | ||
2346 | sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), | ||
2347 | &np->ring_addr); | ||
2348 | if (!np->rx_ring.ex) | ||
2349 | goto out_unmap; | ||
2350 | np->tx_ring.ex = &np->rx_ring.ex[RX_RING]; | ||
2351 | } | ||
2029 | 2352 | ||
2030 | dev->open = nv_open; | 2353 | dev->open = nv_open; |
2031 | dev->stop = nv_close; | 2354 | dev->stop = nv_close; |
2032 | dev->hard_start_xmit = nv_start_xmit; | 2355 | dev->hard_start_xmit = nv_start_xmit; |
2033 | dev->get_stats = nv_get_stats; | 2356 | dev->get_stats = nv_get_stats; |
2034 | dev->change_mtu = nv_change_mtu; | 2357 | dev->change_mtu = nv_change_mtu; |
2358 | dev->set_mac_address = nv_set_mac_address; | ||
2035 | dev->set_multicast_list = nv_set_multicast; | 2359 | dev->set_multicast_list = nv_set_multicast; |
2036 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2360 | #ifdef CONFIG_NET_POLL_CONTROLLER |
2037 | dev->poll_controller = nv_poll_controller; | 2361 | dev->poll_controller = nv_poll_controller; |
@@ -2080,17 +2404,10 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2080 | 2404 | ||
2081 | if (np->desc_ver == DESC_VER_1) { | 2405 | if (np->desc_ver == DESC_VER_1) { |
2082 | np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; | 2406 | np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID; |
2083 | if (id->driver_data & DEV_NEED_LASTPACKET1) | ||
2084 | np->tx_flags |= NV_TX_LASTPACKET1; | ||
2085 | } else { | 2407 | } else { |
2086 | np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; | 2408 | np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID; |
2087 | if (id->driver_data & DEV_NEED_LASTPACKET1) | ||
2088 | np->tx_flags |= NV_TX2_LASTPACKET1; | ||
2089 | } | 2409 | } |
2090 | if (id->driver_data & DEV_IRQMASK_1) | 2410 | np->irqmask = NVREG_IRQMASK_WANTED; |
2091 | np->irqmask = NVREG_IRQMASK_WANTED_1; | ||
2092 | if (id->driver_data & DEV_IRQMASK_2) | ||
2093 | np->irqmask = NVREG_IRQMASK_WANTED_2; | ||
2094 | if (id->driver_data & DEV_NEED_TIMERIRQ) | 2411 | if (id->driver_data & DEV_NEED_TIMERIRQ) |
2095 | np->irqmask |= NVREG_IRQ_TIMER; | 2412 | np->irqmask |= NVREG_IRQ_TIMER; |
2096 | if (id->driver_data & DEV_NEED_LINKTIMER) { | 2413 | if (id->driver_data & DEV_NEED_LINKTIMER) { |
@@ -2155,8 +2472,12 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2155 | return 0; | 2472 | return 0; |
2156 | 2473 | ||
2157 | out_freering: | 2474 | out_freering: |
2158 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), | 2475 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2159 | np->rx_ring, np->ring_addr); | 2476 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), |
2477 | np->rx_ring.orig, np->ring_addr); | ||
2478 | else | ||
2479 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), | ||
2480 | np->rx_ring.ex, np->ring_addr); | ||
2160 | pci_set_drvdata(pci_dev, NULL); | 2481 | pci_set_drvdata(pci_dev, NULL); |
2161 | out_unmap: | 2482 | out_unmap: |
2162 | iounmap(get_hwbase(dev)); | 2483 | iounmap(get_hwbase(dev)); |
@@ -2174,18 +2495,14 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
2174 | { | 2495 | { |
2175 | struct net_device *dev = pci_get_drvdata(pci_dev); | 2496 | struct net_device *dev = pci_get_drvdata(pci_dev); |
2176 | struct fe_priv *np = get_nvpriv(dev); | 2497 | struct fe_priv *np = get_nvpriv(dev); |
2177 | u8 __iomem *base = get_hwbase(dev); | ||
2178 | 2498 | ||
2179 | unregister_netdev(dev); | 2499 | unregister_netdev(dev); |
2180 | 2500 | ||
2181 | /* special op: write back the misordered MAC address - otherwise | ||
2182 | * the next nv_probe would see a wrong address. | ||
2183 | */ | ||
2184 | writel(np->orig_mac[0], base + NvRegMacAddrA); | ||
2185 | writel(np->orig_mac[1], base + NvRegMacAddrB); | ||
2186 | |||
2187 | /* free all structures */ | 2501 | /* free all structures */ |
2188 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring, np->ring_addr); | 2502 | if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) |
2503 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc) * (RX_RING + TX_RING), np->rx_ring.orig, np->ring_addr); | ||
2504 | else | ||
2505 | pci_free_consistent(np->pci_dev, sizeof(struct ring_desc_ex) * (RX_RING + TX_RING), np->rx_ring.ex, np->ring_addr); | ||
2189 | iounmap(get_hwbase(dev)); | 2506 | iounmap(get_hwbase(dev)); |
2190 | pci_release_regions(pci_dev); | 2507 | pci_release_regions(pci_dev); |
2191 | pci_disable_device(pci_dev); | 2508 | pci_disable_device(pci_dev); |
@@ -2195,109 +2512,64 @@ static void __devexit nv_remove(struct pci_dev *pci_dev) | |||
2195 | 2512 | ||
2196 | static struct pci_device_id pci_tbl[] = { | 2513 | static struct pci_device_id pci_tbl[] = { |
2197 | { /* nForce Ethernet Controller */ | 2514 | { /* nForce Ethernet Controller */ |
2198 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2515 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_1), |
2199 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_1, | 2516 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2200 | .subvendor = PCI_ANY_ID, | ||
2201 | .subdevice = PCI_ANY_ID, | ||
2202 | .driver_data = DEV_IRQMASK_1|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2203 | }, | 2517 | }, |
2204 | { /* nForce2 Ethernet Controller */ | 2518 | { /* nForce2 Ethernet Controller */ |
2205 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2519 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_2), |
2206 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_2, | 2520 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2207 | .subvendor = PCI_ANY_ID, | ||
2208 | .subdevice = PCI_ANY_ID, | ||
2209 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2210 | }, | 2521 | }, |
2211 | { /* nForce3 Ethernet Controller */ | 2522 | { /* nForce3 Ethernet Controller */ |
2212 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2523 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_3), |
2213 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_3, | 2524 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, |
2214 | .subvendor = PCI_ANY_ID, | ||
2215 | .subdevice = PCI_ANY_ID, | ||
2216 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2217 | }, | 2525 | }, |
2218 | { /* nForce3 Ethernet Controller */ | 2526 | { /* nForce3 Ethernet Controller */ |
2219 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2527 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4), |
2220 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_4, | 2528 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2221 | .subvendor = PCI_ANY_ID, | ||
2222 | .subdevice = PCI_ANY_ID, | ||
2223 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2224 | }, | 2529 | }, |
2225 | { /* nForce3 Ethernet Controller */ | 2530 | { /* nForce3 Ethernet Controller */ |
2226 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2531 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5), |
2227 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_5, | 2532 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2228 | .subvendor = PCI_ANY_ID, | ||
2229 | .subdevice = PCI_ANY_ID, | ||
2230 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2231 | }, | 2533 | }, |
2232 | { /* nForce3 Ethernet Controller */ | 2534 | { /* nForce3 Ethernet Controller */ |
2233 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2535 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6), |
2234 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_6, | 2536 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2235 | .subvendor = PCI_ANY_ID, | ||
2236 | .subdevice = PCI_ANY_ID, | ||
2237 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2238 | }, | 2537 | }, |
2239 | { /* nForce3 Ethernet Controller */ | 2538 | { /* nForce3 Ethernet Controller */ |
2240 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2539 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7), |
2241 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_7, | 2540 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC, |
2242 | .subvendor = PCI_ANY_ID, | ||
2243 | .subdevice = PCI_ANY_ID, | ||
2244 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2245 | }, | 2541 | }, |
2246 | { /* CK804 Ethernet Controller */ | 2542 | { /* CK804 Ethernet Controller */ |
2247 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2543 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8), |
2248 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_8, | 2544 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2249 | .subvendor = PCI_ANY_ID, | ||
2250 | .subdevice = PCI_ANY_ID, | ||
2251 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2252 | }, | 2545 | }, |
2253 | { /* CK804 Ethernet Controller */ | 2546 | { /* CK804 Ethernet Controller */ |
2254 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2547 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9), |
2255 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_9, | 2548 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2256 | .subvendor = PCI_ANY_ID, | ||
2257 | .subdevice = PCI_ANY_ID, | ||
2258 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2259 | }, | 2549 | }, |
2260 | { /* MCP04 Ethernet Controller */ | 2550 | { /* MCP04 Ethernet Controller */ |
2261 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2551 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10), |
2262 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_10, | 2552 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2263 | .subvendor = PCI_ANY_ID, | ||
2264 | .subdevice = PCI_ANY_ID, | ||
2265 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2266 | }, | 2553 | }, |
2267 | { /* MCP04 Ethernet Controller */ | 2554 | { /* MCP04 Ethernet Controller */ |
2268 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2555 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11), |
2269 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_11, | 2556 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2270 | .subvendor = PCI_ANY_ID, | ||
2271 | .subdevice = PCI_ANY_ID, | ||
2272 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2273 | }, | 2557 | }, |
2274 | { /* MCP51 Ethernet Controller */ | 2558 | { /* MCP51 Ethernet Controller */ |
2275 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2559 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), |
2276 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_12, | 2560 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, |
2277 | .subvendor = PCI_ANY_ID, | ||
2278 | .subdevice = PCI_ANY_ID, | ||
2279 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2280 | }, | 2561 | }, |
2281 | { /* MCP51 Ethernet Controller */ | 2562 | { /* MCP51 Ethernet Controller */ |
2282 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2563 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), |
2283 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_13, | 2564 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, |
2284 | .subvendor = PCI_ANY_ID, | ||
2285 | .subdevice = PCI_ANY_ID, | ||
2286 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2287 | }, | 2565 | }, |
2288 | { /* MCP55 Ethernet Controller */ | 2566 | { /* MCP55 Ethernet Controller */ |
2289 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2567 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), |
2290 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_14, | 2568 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2291 | .subvendor = PCI_ANY_ID, | ||
2292 | .subdevice = PCI_ANY_ID, | ||
2293 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2294 | }, | 2569 | }, |
2295 | { /* MCP55 Ethernet Controller */ | 2570 | { /* MCP55 Ethernet Controller */ |
2296 | .vendor = PCI_VENDOR_ID_NVIDIA, | 2571 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), |
2297 | .device = PCI_DEVICE_ID_NVIDIA_NVENET_15, | 2572 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA, |
2298 | .subvendor = PCI_ANY_ID, | ||
2299 | .subdevice = PCI_ANY_ID, | ||
2300 | .driver_data = DEV_NEED_LASTPACKET1|DEV_IRQMASK_2|DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER, | ||
2301 | }, | 2573 | }, |
2302 | {0,}, | 2574 | {0,}, |
2303 | }; | 2575 | }; |
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c index f9e3be96963c..0b230222bfea 100644 --- a/drivers/net/hamradio/6pack.c +++ b/drivers/net/hamradio/6pack.c | |||
@@ -308,12 +308,6 @@ static int sp_set_mac_address(struct net_device *dev, void *addr) | |||
308 | { | 308 | { |
309 | struct sockaddr_ax25 *sa = addr; | 309 | struct sockaddr_ax25 *sa = addr; |
310 | 310 | ||
311 | if (sa->sax25_family != AF_AX25) | ||
312 | return -EINVAL; | ||
313 | |||
314 | if (!sa->sax25_ndigis) | ||
315 | return -EINVAL; | ||
316 | |||
317 | spin_lock_irq(&dev->xmit_lock); | 311 | spin_lock_irq(&dev->xmit_lock); |
318 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | 312 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); |
319 | spin_unlock_irq(&dev->xmit_lock); | 313 | spin_unlock_irq(&dev->xmit_lock); |
@@ -668,6 +662,9 @@ static int sixpack_open(struct tty_struct *tty) | |||
668 | netif_start_queue(dev); | 662 | netif_start_queue(dev); |
669 | 663 | ||
670 | init_timer(&sp->tx_t); | 664 | init_timer(&sp->tx_t); |
665 | sp->tx_t.function = sp_xmit_on_air; | ||
666 | sp->tx_t.data = (unsigned long) sp; | ||
667 | |||
671 | init_timer(&sp->resync_t); | 668 | init_timer(&sp->resync_t); |
672 | 669 | ||
673 | spin_unlock_bh(&sp->lock); | 670 | spin_unlock_bh(&sp->lock); |
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig index 0cd54306e636..de087cd609d9 100644 --- a/drivers/net/hamradio/Kconfig +++ b/drivers/net/hamradio/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config MKISS | 1 | config MKISS |
2 | tristate "Serial port KISS driver" | 2 | tristate "Serial port KISS driver" |
3 | depends on AX25 && BROKEN_ON_SMP | 3 | depends on AX25 |
4 | ---help--- | 4 | ---help--- |
5 | KISS is a protocol used for the exchange of data between a computer | 5 | KISS is a protocol used for the exchange of data between a computer |
6 | and a Terminal Node Controller (a small embedded system commonly | 6 | and a Terminal Node Controller (a small embedded system commonly |
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c index a7f15d9f13e5..5298096afbdb 100644 --- a/drivers/net/hamradio/baycom_epp.c +++ b/drivers/net/hamradio/baycom_epp.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <linux/kmod.h> | 54 | #include <linux/kmod.h> |
55 | #include <linux/hdlcdrv.h> | 55 | #include <linux/hdlcdrv.h> |
56 | #include <linux/baycom.h> | 56 | #include <linux/baycom.h> |
57 | #include <linux/jiffies.h> | ||
57 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | 58 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) |
58 | /* prototypes for ax25_encapsulate and ax25_rebuild_header */ | 59 | /* prototypes for ax25_encapsulate and ax25_rebuild_header */ |
59 | #include <net/ax25.h> | 60 | #include <net/ax25.h> |
@@ -287,7 +288,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
287 | * measure the interrupt frequency | 288 | * measure the interrupt frequency |
288 | */ | 289 | */ |
289 | bc->debug_vals.cur_intcnt++; | 290 | bc->debug_vals.cur_intcnt++; |
290 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 291 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
291 | bc->debug_vals.last_jiffies = cur_jiffies; | 292 | bc->debug_vals.last_jiffies = cur_jiffies; |
292 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 293 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
293 | bc->debug_vals.cur_intcnt = 0; | 294 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c index 612ad452bee0..3b1bef1ee215 100644 --- a/drivers/net/hamradio/baycom_par.c +++ b/drivers/net/hamradio/baycom_par.c | |||
@@ -84,6 +84,7 @@ | |||
84 | #include <linux/baycom.h> | 84 | #include <linux/baycom.h> |
85 | #include <linux/parport.h> | 85 | #include <linux/parport.h> |
86 | #include <linux/bitops.h> | 86 | #include <linux/bitops.h> |
87 | #include <linux/jiffies.h> | ||
87 | 88 | ||
88 | #include <asm/bug.h> | 89 | #include <asm/bug.h> |
89 | #include <asm/system.h> | 90 | #include <asm/system.h> |
@@ -165,7 +166,7 @@ static void __inline__ baycom_int_freq(struct baycom_state *bc) | |||
165 | * measure the interrupt frequency | 166 | * measure the interrupt frequency |
166 | */ | 167 | */ |
167 | bc->debug_vals.cur_intcnt++; | 168 | bc->debug_vals.cur_intcnt++; |
168 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 169 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
169 | bc->debug_vals.last_jiffies = cur_jiffies; | 170 | bc->debug_vals.last_jiffies = cur_jiffies; |
170 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 171 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
171 | bc->debug_vals.cur_intcnt = 0; | 172 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_ser_fdx.c b/drivers/net/hamradio/baycom_ser_fdx.c index 25f270b05378..232793d2ce6b 100644 --- a/drivers/net/hamradio/baycom_ser_fdx.c +++ b/drivers/net/hamradio/baycom_ser_fdx.c | |||
@@ -79,6 +79,7 @@ | |||
79 | #include <asm/io.h> | 79 | #include <asm/io.h> |
80 | #include <linux/hdlcdrv.h> | 80 | #include <linux/hdlcdrv.h> |
81 | #include <linux/baycom.h> | 81 | #include <linux/baycom.h> |
82 | #include <linux/jiffies.h> | ||
82 | 83 | ||
83 | /* --------------------------------------------------------------------- */ | 84 | /* --------------------------------------------------------------------- */ |
84 | 85 | ||
@@ -159,7 +160,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
159 | * measure the interrupt frequency | 160 | * measure the interrupt frequency |
160 | */ | 161 | */ |
161 | bc->debug_vals.cur_intcnt++; | 162 | bc->debug_vals.cur_intcnt++; |
162 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 163 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
163 | bc->debug_vals.last_jiffies = cur_jiffies; | 164 | bc->debug_vals.last_jiffies = cur_jiffies; |
164 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 165 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
165 | bc->debug_vals.cur_intcnt = 0; | 166 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/baycom_ser_hdx.c b/drivers/net/hamradio/baycom_ser_hdx.c index eead85d00962..be596a3eb3fd 100644 --- a/drivers/net/hamradio/baycom_ser_hdx.c +++ b/drivers/net/hamradio/baycom_ser_hdx.c | |||
@@ -69,6 +69,7 @@ | |||
69 | #include <asm/io.h> | 69 | #include <asm/io.h> |
70 | #include <linux/hdlcdrv.h> | 70 | #include <linux/hdlcdrv.h> |
71 | #include <linux/baycom.h> | 71 | #include <linux/baycom.h> |
72 | #include <linux/jiffies.h> | ||
72 | 73 | ||
73 | /* --------------------------------------------------------------------- */ | 74 | /* --------------------------------------------------------------------- */ |
74 | 75 | ||
@@ -150,7 +151,7 @@ static inline void baycom_int_freq(struct baycom_state *bc) | |||
150 | * measure the interrupt frequency | 151 | * measure the interrupt frequency |
151 | */ | 152 | */ |
152 | bc->debug_vals.cur_intcnt++; | 153 | bc->debug_vals.cur_intcnt++; |
153 | if ((cur_jiffies - bc->debug_vals.last_jiffies) >= HZ) { | 154 | if (time_after_eq(cur_jiffies, bc->debug_vals.last_jiffies + HZ)) { |
154 | bc->debug_vals.last_jiffies = cur_jiffies; | 155 | bc->debug_vals.last_jiffies = cur_jiffies; |
155 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; | 156 | bc->debug_vals.last_intcnt = bc->debug_vals.cur_intcnt; |
156 | bc->debug_vals.cur_intcnt = 0; | 157 | bc->debug_vals.cur_intcnt = 0; |
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c index 3035422f5ad8..63b1a2b86acb 100644 --- a/drivers/net/hamradio/mkiss.c +++ b/drivers/net/hamradio/mkiss.c | |||
@@ -1,30 +1,19 @@ | |||
1 | /* | 1 | /* |
2 | * MKISS Driver | 2 | * This program is free software; you can distribute it and/or modify it |
3 | * under the terms of the GNU General Public License (Version 2) as | ||
4 | * published by the Free Software Foundation. | ||
3 | * | 5 | * |
4 | * This module: | 6 | * This program is distributed in the hope it will be useful, but WITHOUT |
5 | * This module is free software; you can redistribute it and/or | 7 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
6 | * modify it under the terms of the GNU General Public License | 8 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
7 | * as published by the Free Software Foundation; either version | 9 | * for more details. |
8 | * 2 of the License, or (at your option) any later version. | ||
9 | * | 10 | * |
10 | * This module implements the AX.25 protocol for kernel-based | 11 | * You should have received a copy of the GNU General Public License along |
11 | * devices like TTYs. It interfaces between a raw TTY, and the | 12 | * with this program; if not, write to the Free Software Foundation, Inc., |
12 | * kernel's AX.25 protocol layers, just like slip.c. | 13 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
13 | * AX.25 needs to be separated from slip.c while slip.c is no | ||
14 | * longer a static kernel device since it is a module. | ||
15 | * This method clears the way to implement other kiss protocols | ||
16 | * like mkiss smack g8bpq ..... so far only mkiss is implemented. | ||
17 | * | 14 | * |
18 | * Hans Alblas <hans@esrac.ele.tue.nl> | 15 | * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl> |
19 | * | 16 | * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org> |
20 | * History | ||
21 | * Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15. | ||
22 | * Matthias (DG2FEF) Added support for FlexNet CRC (on special request) | ||
23 | * Fixed bug in ax25_close(): dev_lock_wait() was | ||
24 | * called twice, causing a deadlock. | ||
25 | * Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to | ||
26 | * MOD_*_USE_COUNT | ||
27 | * Remove cli() and fix rtnl lock usage. | ||
28 | */ | 17 | */ |
29 | 18 | ||
30 | #include <linux/config.h> | 19 | #include <linux/config.h> |
@@ -46,177 +35,300 @@ | |||
46 | #include <linux/etherdevice.h> | 35 | #include <linux/etherdevice.h> |
47 | #include <linux/skbuff.h> | 36 | #include <linux/skbuff.h> |
48 | #include <linux/if_arp.h> | 37 | #include <linux/if_arp.h> |
38 | #include <linux/jiffies.h> | ||
49 | 39 | ||
50 | #include <net/ax25.h> | 40 | #include <net/ax25.h> |
51 | 41 | ||
52 | #include "mkiss.h" | ||
53 | |||
54 | #ifdef CONFIG_INET | 42 | #ifdef CONFIG_INET |
55 | #include <linux/ip.h> | 43 | #include <linux/ip.h> |
56 | #include <linux/tcp.h> | 44 | #include <linux/tcp.h> |
57 | #endif | 45 | #endif |
58 | 46 | ||
59 | static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; | 47 | #define AX_MTU 236 |
60 | 48 | ||
61 | typedef struct ax25_ctrl { | 49 | /* SLIP/KISS protocol characters. */ |
62 | struct ax_disp ctrl; /* */ | 50 | #define END 0300 /* indicates end of frame */ |
63 | struct net_device dev; /* the device */ | 51 | #define ESC 0333 /* indicates byte stuffing */ |
64 | } ax25_ctrl_t; | 52 | #define ESC_END 0334 /* ESC ESC_END means END 'data' */ |
65 | 53 | #define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ | |
66 | static ax25_ctrl_t **ax25_ctrls; | 54 | |
67 | 55 | struct mkiss { | |
68 | int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */ | 56 | struct tty_struct *tty; /* ptr to TTY structure */ |
69 | 57 | struct net_device *dev; /* easy for intr handling */ | |
70 | static struct tty_ldisc ax_ldisc; | 58 | |
71 | 59 | /* These are pointers to the malloc()ed frame buffers. */ | |
72 | static int ax25_init(struct net_device *); | 60 | spinlock_t buflock;/* lock for rbuf and xbuf */ |
73 | static int kiss_esc(unsigned char *, unsigned char *, int); | 61 | unsigned char *rbuff; /* receiver buffer */ |
74 | static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int); | 62 | int rcount; /* received chars counter */ |
75 | static void kiss_unesc(struct ax_disp *, unsigned char); | 63 | unsigned char *xbuff; /* transmitter buffer */ |
64 | unsigned char *xhead; /* pointer to next byte to XMIT */ | ||
65 | int xleft; /* bytes left in XMIT queue */ | ||
66 | |||
67 | struct net_device_stats stats; | ||
68 | |||
69 | /* Detailed SLIP statistics. */ | ||
70 | int mtu; /* Our mtu (to spot changes!) */ | ||
71 | int buffsize; /* Max buffers sizes */ | ||
72 | |||
73 | unsigned long flags; /* Flag values/ mode etc */ | ||
74 | /* long req'd: used by set_bit --RR */ | ||
75 | #define AXF_INUSE 0 /* Channel in use */ | ||
76 | #define AXF_ESCAPE 1 /* ESC received */ | ||
77 | #define AXF_ERROR 2 /* Parity, etc. error */ | ||
78 | #define AXF_KEEPTEST 3 /* Keepalive test flag */ | ||
79 | #define AXF_OUTWAIT 4 /* is outpacket was flag */ | ||
80 | |||
81 | int mode; | ||
82 | int crcmode; /* MW: for FlexNet, SMACK etc. */ | ||
83 | #define CRC_MODE_NONE 0 | ||
84 | #define CRC_MODE_FLEX 1 | ||
85 | #define CRC_MODE_SMACK 2 | ||
86 | |||
87 | atomic_t refcnt; | ||
88 | struct semaphore dead_sem; | ||
89 | }; | ||
76 | 90 | ||
77 | /*---------------------------------------------------------------------------*/ | 91 | /*---------------------------------------------------------------------------*/ |
78 | 92 | ||
79 | static const unsigned short Crc_flex_table[] = { | 93 | static const unsigned short crc_flex_table[] = { |
80 | 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, | 94 | 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38, |
81 | 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, | 95 | 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770, |
82 | 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, | 96 | 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9, |
83 | 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, | 97 | 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1, |
84 | 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, | 98 | 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a, |
85 | 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, | 99 | 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672, |
86 | 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, | 100 | 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb, |
87 | 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, | 101 | 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3, |
88 | 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, | 102 | 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c, |
89 | 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, | 103 | 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574, |
90 | 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, | 104 | 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd, |
91 | 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, | 105 | 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5, |
92 | 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, | 106 | 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e, |
93 | 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, | 107 | 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476, |
94 | 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, | 108 | 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf, |
95 | 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, | 109 | 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7, |
96 | 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, | 110 | 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30, |
97 | 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, | 111 | 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378, |
98 | 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, | 112 | 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1, |
99 | 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, | 113 | 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9, |
100 | 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, | 114 | 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32, |
101 | 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, | 115 | 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a, |
102 | 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, | 116 | 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3, |
103 | 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, | 117 | 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb, |
104 | 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, | 118 | 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34, |
105 | 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, | 119 | 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c, |
106 | 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, | 120 | 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5, |
107 | 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, | 121 | 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd, |
108 | 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, | 122 | 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36, |
109 | 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, | 123 | 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e, |
110 | 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, | 124 | 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7, |
111 | 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff | 125 | 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff |
112 | }; | 126 | }; |
113 | 127 | ||
114 | /*---------------------------------------------------------------------------*/ | ||
115 | |||
116 | static unsigned short calc_crc_flex(unsigned char *cp, int size) | 128 | static unsigned short calc_crc_flex(unsigned char *cp, int size) |
117 | { | 129 | { |
118 | unsigned short crc = 0xffff; | 130 | unsigned short crc = 0xffff; |
119 | |||
120 | while (size--) | ||
121 | crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; | ||
122 | 131 | ||
123 | return crc; | 132 | while (size--) |
124 | } | 133 | crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; |
125 | 134 | ||
126 | /*---------------------------------------------------------------------------*/ | 135 | return crc; |
136 | } | ||
127 | 137 | ||
128 | static int check_crc_flex(unsigned char *cp, int size) | 138 | static int check_crc_flex(unsigned char *cp, int size) |
129 | { | 139 | { |
130 | unsigned short crc = 0xffff; | 140 | unsigned short crc = 0xffff; |
131 | 141 | ||
132 | if (size < 3) | 142 | if (size < 3) |
133 | return -1; | 143 | return -1; |
134 | 144 | ||
135 | while (size--) | 145 | while (size--) |
136 | crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; | 146 | crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff]; |
137 | 147 | ||
138 | if ((crc & 0xffff) != 0x7070) | 148 | if ((crc & 0xffff) != 0x7070) |
139 | return -1; | 149 | return -1; |
140 | 150 | ||
141 | return 0; | 151 | return 0; |
142 | } | 152 | } |
143 | 153 | ||
144 | /*---------------------------------------------------------------------------*/ | 154 | /* |
155 | * Standard encapsulation | ||
156 | */ | ||
145 | 157 | ||
146 | /* Find a free channel, and link in this `tty' line. */ | 158 | static int kiss_esc(unsigned char *s, unsigned char *d, int len) |
147 | static inline struct ax_disp *ax_alloc(void) | ||
148 | { | 159 | { |
149 | ax25_ctrl_t *axp=NULL; | 160 | unsigned char *ptr = d; |
150 | int i; | 161 | unsigned char c; |
151 | 162 | ||
152 | for (i = 0; i < ax25_maxdev; i++) { | 163 | /* |
153 | axp = ax25_ctrls[i]; | 164 | * Send an initial END character to flush out any data that may have |
165 | * accumulated in the receiver due to line noise. | ||
166 | */ | ||
154 | 167 | ||
155 | /* Not allocated ? */ | 168 | *ptr++ = END; |
156 | if (axp == NULL) | ||
157 | break; | ||
158 | 169 | ||
159 | /* Not in use ? */ | 170 | while (len-- > 0) { |
160 | if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags)) | 171 | switch (c = *s++) { |
172 | case END: | ||
173 | *ptr++ = ESC; | ||
174 | *ptr++ = ESC_END; | ||
161 | break; | 175 | break; |
176 | case ESC: | ||
177 | *ptr++ = ESC; | ||
178 | *ptr++ = ESC_ESC; | ||
179 | break; | ||
180 | default: | ||
181 | *ptr++ = c; | ||
182 | break; | ||
183 | } | ||
162 | } | 184 | } |
163 | 185 | ||
164 | /* Sorry, too many, all slots in use */ | 186 | *ptr++ = END; |
165 | if (i >= ax25_maxdev) | 187 | |
166 | return NULL; | 188 | return ptr - d; |
189 | } | ||
190 | |||
191 | /* | ||
192 | * MW: | ||
193 | * OK its ugly, but tell me a better solution without copying the | ||
194 | * packet to a temporary buffer :-) | ||
195 | */ | ||
196 | static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, | ||
197 | int len) | ||
198 | { | ||
199 | unsigned char *ptr = d; | ||
200 | unsigned char c=0; | ||
201 | |||
202 | *ptr++ = END; | ||
203 | while (len > 0) { | ||
204 | if (len > 2) | ||
205 | c = *s++; | ||
206 | else if (len > 1) | ||
207 | c = crc >> 8; | ||
208 | else if (len > 0) | ||
209 | c = crc & 0xff; | ||
210 | |||
211 | len--; | ||
167 | 212 | ||
168 | /* If no channels are available, allocate one */ | 213 | switch (c) { |
169 | if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) { | 214 | case END: |
170 | axp = ax25_ctrls[i]; | 215 | *ptr++ = ESC; |
216 | *ptr++ = ESC_END; | ||
217 | break; | ||
218 | case ESC: | ||
219 | *ptr++ = ESC; | ||
220 | *ptr++ = ESC_ESC; | ||
221 | break; | ||
222 | default: | ||
223 | *ptr++ = c; | ||
224 | break; | ||
225 | } | ||
171 | } | 226 | } |
172 | memset(axp, 0, sizeof(ax25_ctrl_t)); | 227 | *ptr++ = END; |
173 | 228 | ||
174 | /* Initialize channel control data */ | 229 | return ptr - d; |
175 | set_bit(AXF_INUSE, &axp->ctrl.flags); | 230 | } |
176 | sprintf(axp->dev.name, "ax%d", i++); | 231 | |
177 | axp->ctrl.tty = NULL; | 232 | /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ |
178 | axp->dev.base_addr = i; | 233 | static void ax_bump(struct mkiss *ax) |
179 | axp->dev.priv = (void *)&axp->ctrl; | 234 | { |
180 | axp->dev.next = NULL; | 235 | struct sk_buff *skb; |
181 | axp->dev.init = ax25_init; | 236 | int count; |
182 | 237 | ||
183 | if (axp != NULL) { | 238 | spin_lock_bh(&ax->buflock); |
184 | /* | 239 | if (ax->rbuff[0] > 0x0f) { |
185 | * register device so that it can be ifconfig'ed | 240 | if (ax->rbuff[0] & 0x20) { |
186 | * ax25_init() will be called as a side-effect | 241 | ax->crcmode = CRC_MODE_FLEX; |
187 | * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl ! | 242 | if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { |
188 | */ | 243 | ax->stats.rx_errors++; |
189 | if (register_netdev(&axp->dev) == 0) { | 244 | return; |
190 | /* (Re-)Set the INUSE bit. Very Important! */ | 245 | } |
191 | set_bit(AXF_INUSE, &axp->ctrl.flags); | 246 | ax->rcount -= 2; |
192 | axp->ctrl.dev = &axp->dev; | 247 | /* dl9sau bugfix: the trailling two bytes flexnet crc |
193 | axp->dev.priv = (void *) &axp->ctrl; | 248 | * will not be passed to the kernel. thus we have |
194 | 249 | * to correct the kissparm signature, because it | |
195 | return &axp->ctrl; | 250 | * indicates a crc but there's none |
196 | } else { | 251 | */ |
197 | clear_bit(AXF_INUSE,&axp->ctrl.flags); | 252 | *ax->rbuff &= ~0x20; |
198 | printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n"); | ||
199 | } | 253 | } |
254 | } | ||
255 | spin_unlock_bh(&ax->buflock); | ||
256 | |||
257 | count = ax->rcount; | ||
258 | |||
259 | if ((skb = dev_alloc_skb(count)) == NULL) { | ||
260 | printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", | ||
261 | ax->dev->name); | ||
262 | ax->stats.rx_dropped++; | ||
263 | return; | ||
200 | } | 264 | } |
201 | 265 | ||
202 | return NULL; | 266 | spin_lock_bh(&ax->buflock); |
267 | memcpy(skb_put(skb,count), ax->rbuff, count); | ||
268 | spin_unlock_bh(&ax->buflock); | ||
269 | skb->protocol = ax25_type_trans(skb, ax->dev); | ||
270 | netif_rx(skb); | ||
271 | ax->dev->last_rx = jiffies; | ||
272 | ax->stats.rx_packets++; | ||
273 | ax->stats.rx_bytes += count; | ||
203 | } | 274 | } |
204 | 275 | ||
205 | /* Free an AX25 channel. */ | 276 | static void kiss_unesc(struct mkiss *ax, unsigned char s) |
206 | static inline void ax_free(struct ax_disp *ax) | ||
207 | { | 277 | { |
208 | /* Free all AX25 frame buffers. */ | 278 | switch (s) { |
209 | if (ax->rbuff) | 279 | case END: |
210 | kfree(ax->rbuff); | 280 | /* drop keeptest bit = VSV */ |
211 | ax->rbuff = NULL; | 281 | if (test_bit(AXF_KEEPTEST, &ax->flags)) |
212 | if (ax->xbuff) | 282 | clear_bit(AXF_KEEPTEST, &ax->flags); |
213 | kfree(ax->xbuff); | 283 | |
214 | ax->xbuff = NULL; | 284 | if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) |
215 | if (!test_and_clear_bit(AXF_INUSE, &ax->flags)) | 285 | ax_bump(ax); |
216 | printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name); | 286 | |
287 | clear_bit(AXF_ESCAPE, &ax->flags); | ||
288 | ax->rcount = 0; | ||
289 | return; | ||
290 | |||
291 | case ESC: | ||
292 | set_bit(AXF_ESCAPE, &ax->flags); | ||
293 | return; | ||
294 | case ESC_ESC: | ||
295 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
296 | s = ESC; | ||
297 | break; | ||
298 | case ESC_END: | ||
299 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
300 | s = END; | ||
301 | break; | ||
302 | } | ||
303 | |||
304 | spin_lock_bh(&ax->buflock); | ||
305 | if (!test_bit(AXF_ERROR, &ax->flags)) { | ||
306 | if (ax->rcount < ax->buffsize) { | ||
307 | ax->rbuff[ax->rcount++] = s; | ||
308 | spin_unlock_bh(&ax->buflock); | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | ax->stats.rx_over_errors++; | ||
313 | set_bit(AXF_ERROR, &ax->flags); | ||
314 | } | ||
315 | spin_unlock_bh(&ax->buflock); | ||
316 | } | ||
317 | |||
318 | static int ax_set_mac_address(struct net_device *dev, void *addr) | ||
319 | { | ||
320 | struct sockaddr_ax25 *sa = addr; | ||
321 | |||
322 | spin_lock_irq(&dev->xmit_lock); | ||
323 | memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN); | ||
324 | spin_unlock_irq(&dev->xmit_lock); | ||
325 | |||
326 | return 0; | ||
217 | } | 327 | } |
218 | 328 | ||
219 | static void ax_changedmtu(struct ax_disp *ax) | 329 | /*---------------------------------------------------------------------------*/ |
330 | |||
331 | static void ax_changedmtu(struct mkiss *ax) | ||
220 | { | 332 | { |
221 | struct net_device *dev = ax->dev; | 333 | struct net_device *dev = ax->dev; |
222 | unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; | 334 | unsigned char *xbuff, *rbuff, *oxbuff, *orbuff; |
@@ -236,7 +348,8 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
236 | rbuff = kmalloc(len + 4, GFP_ATOMIC); | 348 | rbuff = kmalloc(len + 4, GFP_ATOMIC); |
237 | 349 | ||
238 | if (xbuff == NULL || rbuff == NULL) { | 350 | if (xbuff == NULL || rbuff == NULL) { |
239 | printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n", | 351 | printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, " |
352 | "MTU change cancelled.\n", | ||
240 | ax->dev->name); | 353 | ax->dev->name); |
241 | dev->mtu = ax->mtu; | 354 | dev->mtu = ax->mtu; |
242 | if (xbuff != NULL) | 355 | if (xbuff != NULL) |
@@ -258,7 +371,7 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
258 | memcpy(ax->xbuff, ax->xhead, ax->xleft); | 371 | memcpy(ax->xbuff, ax->xhead, ax->xleft); |
259 | } else { | 372 | } else { |
260 | ax->xleft = 0; | 373 | ax->xleft = 0; |
261 | ax->tx_dropped++; | 374 | ax->stats.tx_dropped++; |
262 | } | 375 | } |
263 | } | 376 | } |
264 | 377 | ||
@@ -269,7 +382,7 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
269 | memcpy(ax->rbuff, orbuff, ax->rcount); | 382 | memcpy(ax->rbuff, orbuff, ax->rcount); |
270 | } else { | 383 | } else { |
271 | ax->rcount = 0; | 384 | ax->rcount = 0; |
272 | ax->rx_over_errors++; | 385 | ax->stats.rx_over_errors++; |
273 | set_bit(AXF_ERROR, &ax->flags); | 386 | set_bit(AXF_ERROR, &ax->flags); |
274 | } | 387 | } |
275 | } | 388 | } |
@@ -279,72 +392,14 @@ static void ax_changedmtu(struct ax_disp *ax) | |||
279 | 392 | ||
280 | spin_unlock_bh(&ax->buflock); | 393 | spin_unlock_bh(&ax->buflock); |
281 | 394 | ||
282 | if (oxbuff != NULL) | 395 | kfree(oxbuff); |
283 | kfree(oxbuff); | 396 | kfree(orbuff); |
284 | if (orbuff != NULL) | ||
285 | kfree(orbuff); | ||
286 | } | ||
287 | |||
288 | |||
289 | /* Set the "sending" flag. This must be atomic. */ | ||
290 | static inline void ax_lock(struct ax_disp *ax) | ||
291 | { | ||
292 | netif_stop_queue(ax->dev); | ||
293 | } | ||
294 | |||
295 | |||
296 | /* Clear the "sending" flag. This must be atomic. */ | ||
297 | static inline void ax_unlock(struct ax_disp *ax) | ||
298 | { | ||
299 | netif_start_queue(ax->dev); | ||
300 | } | ||
301 | |||
302 | /* Send one completely decapsulated AX.25 packet to the AX.25 layer. */ | ||
303 | static void ax_bump(struct ax_disp *ax) | ||
304 | { | ||
305 | struct sk_buff *skb; | ||
306 | int count; | ||
307 | |||
308 | spin_lock_bh(&ax->buflock); | ||
309 | if (ax->rbuff[0] > 0x0f) { | ||
310 | if (ax->rbuff[0] & 0x20) { | ||
311 | ax->crcmode = CRC_MODE_FLEX; | ||
312 | if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { | ||
313 | ax->rx_errors++; | ||
314 | return; | ||
315 | } | ||
316 | ax->rcount -= 2; | ||
317 | /* dl9sau bugfix: the trailling two bytes flexnet crc | ||
318 | * will not be passed to the kernel. thus we have | ||
319 | * to correct the kissparm signature, because it | ||
320 | * indicates a crc but there's none | ||
321 | */ | ||
322 | *ax->rbuff &= ~0x20; | ||
323 | } | ||
324 | } | ||
325 | spin_unlock_bh(&ax->buflock); | ||
326 | |||
327 | count = ax->rcount; | ||
328 | |||
329 | if ((skb = dev_alloc_skb(count)) == NULL) { | ||
330 | printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name); | ||
331 | ax->rx_dropped++; | ||
332 | return; | ||
333 | } | ||
334 | |||
335 | spin_lock_bh(&ax->buflock); | ||
336 | memcpy(skb_put(skb,count), ax->rbuff, count); | ||
337 | spin_unlock_bh(&ax->buflock); | ||
338 | skb->protocol = ax25_type_trans(skb, ax->dev); | ||
339 | netif_rx(skb); | ||
340 | ax->dev->last_rx = jiffies; | ||
341 | ax->rx_packets++; | ||
342 | ax->rx_bytes+=count; | ||
343 | } | 397 | } |
344 | 398 | ||
345 | /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ | 399 | /* Encapsulate one AX.25 packet and stuff into a TTY queue. */ |
346 | static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | 400 | static void ax_encaps(struct net_device *dev, unsigned char *icp, int len) |
347 | { | 401 | { |
402 | struct mkiss *ax = netdev_priv(dev); | ||
348 | unsigned char *p; | 403 | unsigned char *p; |
349 | int actual, count; | 404 | int actual, count; |
350 | 405 | ||
@@ -354,8 +409,8 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
354 | if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ | 409 | if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */ |
355 | len = ax->mtu; | 410 | len = ax->mtu; |
356 | printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); | 411 | printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name); |
357 | ax->tx_dropped++; | 412 | ax->stats.tx_dropped++; |
358 | ax_unlock(ax); | 413 | netif_start_queue(dev); |
359 | return; | 414 | return; |
360 | } | 415 | } |
361 | 416 | ||
@@ -376,10 +431,11 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
376 | break; | 431 | break; |
377 | } | 432 | } |
378 | 433 | ||
379 | ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | 434 | set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
380 | actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); | 435 | actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); |
381 | ax->tx_packets++; | 436 | ax->stats.tx_packets++; |
382 | ax->tx_bytes+=actual; | 437 | ax->stats.tx_bytes += actual; |
438 | |||
383 | ax->dev->trans_start = jiffies; | 439 | ax->dev->trans_start = jiffies; |
384 | ax->xleft = count - actual; | 440 | ax->xleft = count - actual; |
385 | ax->xhead = ax->xbuff + actual; | 441 | ax->xhead = ax->xbuff + actual; |
@@ -387,37 +443,10 @@ static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len) | |||
387 | spin_unlock_bh(&ax->buflock); | 443 | spin_unlock_bh(&ax->buflock); |
388 | } | 444 | } |
389 | 445 | ||
390 | /* | ||
391 | * Called by the driver when there's room for more data. If we have | ||
392 | * more packets to send, we send them here. | ||
393 | */ | ||
394 | static void ax25_write_wakeup(struct tty_struct *tty) | ||
395 | { | ||
396 | int actual; | ||
397 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
398 | |||
399 | /* First make sure we're connected. */ | ||
400 | if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) | ||
401 | return; | ||
402 | if (ax->xleft <= 0) { | ||
403 | /* Now serial buffer is almost free & we can start | ||
404 | * transmission of another packet | ||
405 | */ | ||
406 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
407 | |||
408 | netif_wake_queue(ax->dev); | ||
409 | return; | ||
410 | } | ||
411 | |||
412 | actual = tty->driver->write(tty, ax->xhead, ax->xleft); | ||
413 | ax->xleft -= actual; | ||
414 | ax->xhead += actual; | ||
415 | } | ||
416 | |||
417 | /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ | 446 | /* Encapsulate an AX.25 packet and kick it into a TTY queue. */ |
418 | static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | 447 | static int ax_xmit(struct sk_buff *skb, struct net_device *dev) |
419 | { | 448 | { |
420 | struct ax_disp *ax = netdev_priv(dev); | 449 | struct mkiss *ax = netdev_priv(dev); |
421 | 450 | ||
422 | if (!netif_running(dev)) { | 451 | if (!netif_running(dev)) { |
423 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); | 452 | printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name); |
@@ -429,7 +458,7 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | |||
429 | * May be we must check transmitter timeout here ? | 458 | * May be we must check transmitter timeout here ? |
430 | * 14 Oct 1994 Dmitry Gorodchanin. | 459 | * 14 Oct 1994 Dmitry Gorodchanin. |
431 | */ | 460 | */ |
432 | if (jiffies - dev->trans_start < 20 * HZ) { | 461 | if (time_before(jiffies, dev->trans_start + 20 * HZ)) { |
433 | /* 20 sec timeout not reached */ | 462 | /* 20 sec timeout not reached */ |
434 | return 1; | 463 | return 1; |
435 | } | 464 | } |
@@ -439,20 +468,30 @@ static int ax_xmit(struct sk_buff *skb, struct net_device *dev) | |||
439 | "bad line quality" : "driver error"); | 468 | "bad line quality" : "driver error"); |
440 | 469 | ||
441 | ax->xleft = 0; | 470 | ax->xleft = 0; |
442 | ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | 471 | clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
443 | ax_unlock(ax); | 472 | netif_start_queue(dev); |
444 | } | 473 | } |
445 | 474 | ||
446 | /* We were not busy, so we are now... :-) */ | 475 | /* We were not busy, so we are now... :-) */ |
447 | if (skb != NULL) { | 476 | if (skb != NULL) { |
448 | ax_lock(ax); | 477 | netif_stop_queue(dev); |
449 | ax_encaps(ax, skb->data, skb->len); | 478 | ax_encaps(dev, skb->data, skb->len); |
450 | kfree_skb(skb); | 479 | kfree_skb(skb); |
451 | } | 480 | } |
452 | 481 | ||
453 | return 0; | 482 | return 0; |
454 | } | 483 | } |
455 | 484 | ||
485 | static int ax_open_dev(struct net_device *dev) | ||
486 | { | ||
487 | struct mkiss *ax = netdev_priv(dev); | ||
488 | |||
489 | if (ax->tty == NULL) | ||
490 | return -ENODEV; | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
456 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) | 495 | #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE) |
457 | 496 | ||
458 | /* Return the frame type ID */ | 497 | /* Return the frame type ID */ |
@@ -481,7 +520,7 @@ static int ax_rebuild_header(struct sk_buff *skb) | |||
481 | /* Open the low-level part of the AX25 channel. Easy! */ | 520 | /* Open the low-level part of the AX25 channel. Easy! */ |
482 | static int ax_open(struct net_device *dev) | 521 | static int ax_open(struct net_device *dev) |
483 | { | 522 | { |
484 | struct ax_disp *ax = netdev_priv(dev); | 523 | struct mkiss *ax = netdev_priv(dev); |
485 | unsigned long len; | 524 | unsigned long len; |
486 | 525 | ||
487 | if (ax->tty == NULL) | 526 | if (ax->tty == NULL) |
@@ -518,7 +557,6 @@ static int ax_open(struct net_device *dev) | |||
518 | 557 | ||
519 | spin_lock_init(&ax->buflock); | 558 | spin_lock_init(&ax->buflock); |
520 | 559 | ||
521 | netif_start_queue(dev); | ||
522 | return 0; | 560 | return 0; |
523 | 561 | ||
524 | noxbuff: | 562 | noxbuff: |
@@ -532,68 +570,100 @@ norbuff: | |||
532 | /* Close the low-level part of the AX25 channel. Easy! */ | 570 | /* Close the low-level part of the AX25 channel. Easy! */ |
533 | static int ax_close(struct net_device *dev) | 571 | static int ax_close(struct net_device *dev) |
534 | { | 572 | { |
535 | struct ax_disp *ax = netdev_priv(dev); | 573 | struct mkiss *ax = netdev_priv(dev); |
536 | 574 | ||
537 | if (ax->tty == NULL) | 575 | if (ax->tty) |
538 | return -EBUSY; | 576 | clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); |
539 | |||
540 | ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
541 | 577 | ||
542 | netif_stop_queue(dev); | 578 | netif_stop_queue(dev); |
543 | 579 | ||
544 | return 0; | 580 | return 0; |
545 | } | 581 | } |
546 | 582 | ||
547 | static int ax25_receive_room(struct tty_struct *tty) | 583 | static struct net_device_stats *ax_get_stats(struct net_device *dev) |
548 | { | 584 | { |
549 | return 65536; /* We can handle an infinite amount of data. :-) */ | 585 | struct mkiss *ax = netdev_priv(dev); |
586 | |||
587 | return &ax->stats; | ||
588 | } | ||
589 | |||
590 | static void ax_setup(struct net_device *dev) | ||
591 | { | ||
592 | static char ax25_bcast[AX25_ADDR_LEN] = | ||
593 | {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; | ||
594 | static char ax25_test[AX25_ADDR_LEN] = | ||
595 | {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; | ||
596 | |||
597 | /* Finish setting up the DEVICE info. */ | ||
598 | dev->mtu = AX_MTU; | ||
599 | dev->hard_start_xmit = ax_xmit; | ||
600 | dev->open = ax_open_dev; | ||
601 | dev->stop = ax_close; | ||
602 | dev->get_stats = ax_get_stats; | ||
603 | dev->set_mac_address = ax_set_mac_address; | ||
604 | dev->hard_header_len = 0; | ||
605 | dev->addr_len = 0; | ||
606 | dev->type = ARPHRD_AX25; | ||
607 | dev->tx_queue_len = 10; | ||
608 | dev->hard_header = ax_header; | ||
609 | dev->rebuild_header = ax_rebuild_header; | ||
610 | |||
611 | memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); | ||
612 | memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); | ||
613 | |||
614 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; | ||
550 | } | 615 | } |
551 | 616 | ||
552 | /* | 617 | /* |
553 | * Handle the 'receiver data ready' interrupt. | 618 | * We have a potential race on dereferencing tty->disc_data, because the tty |
554 | * This function is called by the 'tty_io' module in the kernel when | 619 | * layer provides no locking at all - thus one cpu could be running |
555 | * a block of data has been received, which can now be decapsulated | 620 | * sixpack_receive_buf while another calls sixpack_close, which zeroes |
556 | * and sent on to the AX.25 layer for further processing. | 621 | * tty->disc_data and frees the memory that sixpack_receive_buf is using. The |
622 | * best way to fix this is to use a rwlock in the tty struct, but for now we | ||
623 | * use a single global rwlock for all ttys in ppp line discipline. | ||
557 | */ | 624 | */ |
558 | static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count) | 625 | static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; |
626 | |||
627 | static struct mkiss *mkiss_get(struct tty_struct *tty) | ||
559 | { | 628 | { |
560 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | 629 | struct mkiss *ax; |
561 | 630 | ||
562 | if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev)) | 631 | read_lock(&disc_data_lock); |
563 | return; | 632 | ax = tty->disc_data; |
633 | if (ax) | ||
634 | atomic_inc(&ax->refcnt); | ||
635 | read_unlock(&disc_data_lock); | ||
564 | 636 | ||
565 | /* | 637 | return ax; |
566 | * Argh! mtu change time! - costs us the packet part received | 638 | } |
567 | * at the change | ||
568 | */ | ||
569 | if (ax->mtu != ax->dev->mtu + 73) | ||
570 | ax_changedmtu(ax); | ||
571 | |||
572 | /* Read the characters out of the buffer */ | ||
573 | while (count--) { | ||
574 | if (fp != NULL && *fp++) { | ||
575 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) | ||
576 | ax->rx_errors++; | ||
577 | cp++; | ||
578 | continue; | ||
579 | } | ||
580 | 639 | ||
581 | kiss_unesc(ax, *cp++); | 640 | static void mkiss_put(struct mkiss *ax) |
582 | } | 641 | { |
642 | if (atomic_dec_and_test(&ax->refcnt)) | ||
643 | up(&ax->dead_sem); | ||
583 | } | 644 | } |
584 | 645 | ||
585 | static int ax25_open(struct tty_struct *tty) | 646 | static int mkiss_open(struct tty_struct *tty) |
586 | { | 647 | { |
587 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | 648 | struct net_device *dev; |
649 | struct mkiss *ax; | ||
588 | int err; | 650 | int err; |
589 | 651 | ||
590 | /* First make sure we're not already connected. */ | 652 | if (!capable(CAP_NET_ADMIN)) |
591 | if (ax && ax->magic == AX25_MAGIC) | 653 | return -EPERM; |
592 | return -EEXIST; | ||
593 | 654 | ||
594 | /* OK. Find a free AX25 channel to use. */ | 655 | dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup); |
595 | if ((ax = ax_alloc()) == NULL) | 656 | if (!dev) { |
596 | return -ENFILE; | 657 | err = -ENOMEM; |
658 | goto out; | ||
659 | } | ||
660 | |||
661 | ax = netdev_priv(dev); | ||
662 | ax->dev = dev; | ||
663 | |||
664 | spin_lock_init(&ax->buflock); | ||
665 | atomic_set(&ax->refcnt, 1); | ||
666 | init_MUTEX_LOCKED(&ax->dead_sem); | ||
597 | 667 | ||
598 | ax->tty = tty; | 668 | ax->tty = tty; |
599 | tty->disc_data = ax; | 669 | tty->disc_data = ax; |
@@ -602,283 +672,212 @@ static int ax25_open(struct tty_struct *tty) | |||
602 | tty->driver->flush_buffer(tty); | 672 | tty->driver->flush_buffer(tty); |
603 | 673 | ||
604 | /* Restore default settings */ | 674 | /* Restore default settings */ |
605 | ax->dev->type = ARPHRD_AX25; | 675 | dev->type = ARPHRD_AX25; |
606 | 676 | ||
607 | /* Perform the low-level AX25 initialization. */ | 677 | /* Perform the low-level AX25 initialization. */ |
608 | if ((err = ax_open(ax->dev))) | 678 | if ((err = ax_open(ax->dev))) { |
609 | return err; | 679 | goto out_free_netdev; |
680 | } | ||
610 | 681 | ||
611 | /* Done. We have linked the TTY line to a channel. */ | 682 | if (register_netdev(dev)) |
612 | return ax->dev->base_addr; | 683 | goto out_free_buffers; |
613 | } | ||
614 | 684 | ||
615 | static void ax25_close(struct tty_struct *tty) | 685 | netif_start_queue(dev); |
616 | { | ||
617 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
618 | 686 | ||
619 | /* First make sure we're connected. */ | 687 | /* Done. We have linked the TTY line to a channel. */ |
620 | if (ax == NULL || ax->magic != AX25_MAGIC) | 688 | return 0; |
621 | return; | ||
622 | 689 | ||
623 | unregister_netdev(ax->dev); | 690 | out_free_buffers: |
691 | kfree(ax->rbuff); | ||
692 | kfree(ax->xbuff); | ||
624 | 693 | ||
625 | tty->disc_data = NULL; | 694 | out_free_netdev: |
626 | ax->tty = NULL; | 695 | free_netdev(dev); |
627 | 696 | ||
628 | ax_free(ax); | 697 | out: |
698 | return err; | ||
629 | } | 699 | } |
630 | 700 | ||
631 | 701 | static void mkiss_close(struct tty_struct *tty) | |
632 | static struct net_device_stats *ax_get_stats(struct net_device *dev) | ||
633 | { | 702 | { |
634 | static struct net_device_stats stats; | 703 | struct mkiss *ax; |
635 | struct ax_disp *ax = netdev_priv(dev); | ||
636 | |||
637 | memset(&stats, 0, sizeof(struct net_device_stats)); | ||
638 | |||
639 | stats.rx_packets = ax->rx_packets; | ||
640 | stats.tx_packets = ax->tx_packets; | ||
641 | stats.rx_bytes = ax->rx_bytes; | ||
642 | stats.tx_bytes = ax->tx_bytes; | ||
643 | stats.rx_dropped = ax->rx_dropped; | ||
644 | stats.tx_dropped = ax->tx_dropped; | ||
645 | stats.tx_errors = ax->tx_errors; | ||
646 | stats.rx_errors = ax->rx_errors; | ||
647 | stats.rx_over_errors = ax->rx_over_errors; | ||
648 | |||
649 | return &stats; | ||
650 | } | ||
651 | 704 | ||
705 | write_lock(&disc_data_lock); | ||
706 | ax = tty->disc_data; | ||
707 | tty->disc_data = NULL; | ||
708 | write_unlock(&disc_data_lock); | ||
652 | 709 | ||
653 | /************************************************************************ | 710 | if (ax == 0) |
654 | * STANDARD ENCAPSULATION * | 711 | return; |
655 | ************************************************************************/ | ||
656 | |||
657 | static int kiss_esc(unsigned char *s, unsigned char *d, int len) | ||
658 | { | ||
659 | unsigned char *ptr = d; | ||
660 | unsigned char c; | ||
661 | 712 | ||
662 | /* | 713 | /* |
663 | * Send an initial END character to flush out any | 714 | * We have now ensured that nobody can start using ap from now on, but |
664 | * data that may have accumulated in the receiver | 715 | * we have to wait for all existing users to finish. |
665 | * due to line noise. | ||
666 | */ | 716 | */ |
717 | if (!atomic_dec_and_test(&ax->refcnt)) | ||
718 | down(&ax->dead_sem); | ||
667 | 719 | ||
668 | *ptr++ = END; | 720 | unregister_netdev(ax->dev); |
669 | |||
670 | while (len-- > 0) { | ||
671 | switch (c = *s++) { | ||
672 | case END: | ||
673 | *ptr++ = ESC; | ||
674 | *ptr++ = ESC_END; | ||
675 | break; | ||
676 | case ESC: | ||
677 | *ptr++ = ESC; | ||
678 | *ptr++ = ESC_ESC; | ||
679 | break; | ||
680 | default: | ||
681 | *ptr++ = c; | ||
682 | break; | ||
683 | } | ||
684 | } | ||
685 | 721 | ||
686 | *ptr++ = END; | 722 | /* Free all AX25 frame buffers. */ |
723 | kfree(ax->rbuff); | ||
724 | kfree(ax->xbuff); | ||
687 | 725 | ||
688 | return ptr - d; | 726 | ax->tty = NULL; |
689 | } | 727 | } |
690 | 728 | ||
691 | /* | 729 | /* Perform I/O control on an active ax25 channel. */ |
692 | * MW: | 730 | static int mkiss_ioctl(struct tty_struct *tty, struct file *file, |
693 | * OK its ugly, but tell me a better solution without copying the | 731 | unsigned int cmd, unsigned long arg) |
694 | * packet to a temporary buffer :-) | ||
695 | */ | ||
696 | static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len) | ||
697 | { | 732 | { |
698 | unsigned char *ptr = d; | 733 | struct mkiss *ax = mkiss_get(tty); |
699 | unsigned char c=0; | 734 | struct net_device *dev = ax->dev; |
700 | 735 | unsigned int tmp, err; | |
701 | *ptr++ = END; | ||
702 | while (len > 0) { | ||
703 | if (len > 2) | ||
704 | c = *s++; | ||
705 | else if (len > 1) | ||
706 | c = crc >> 8; | ||
707 | else if (len > 0) | ||
708 | c = crc & 0xff; | ||
709 | 736 | ||
710 | len--; | 737 | /* First make sure we're connected. */ |
738 | if (ax == NULL) | ||
739 | return -ENXIO; | ||
711 | 740 | ||
712 | switch (c) { | 741 | switch (cmd) { |
713 | case END: | 742 | case SIOCGIFNAME: |
714 | *ptr++ = ESC; | 743 | err = copy_to_user((void __user *) arg, ax->dev->name, |
715 | *ptr++ = ESC_END; | 744 | strlen(ax->dev->name) + 1) ? -EFAULT : 0; |
716 | break; | 745 | break; |
717 | case ESC: | 746 | |
718 | *ptr++ = ESC; | 747 | case SIOCGIFENCAP: |
719 | *ptr++ = ESC_ESC; | 748 | err = put_user(4, (int __user *) arg); |
720 | break; | 749 | break; |
721 | default: | 750 | |
722 | *ptr++ = c; | 751 | case SIOCSIFENCAP: |
723 | break; | 752 | if (get_user(tmp, (int __user *) arg)) { |
753 | err = -EFAULT; | ||
754 | break; | ||
724 | } | 755 | } |
725 | } | ||
726 | *ptr++ = END; | ||
727 | return ptr - d; | ||
728 | } | ||
729 | 756 | ||
730 | static void kiss_unesc(struct ax_disp *ax, unsigned char s) | 757 | ax->mode = tmp; |
731 | { | 758 | dev->addr_len = AX25_ADDR_LEN; |
732 | switch (s) { | 759 | dev->hard_header_len = AX25_KISS_HEADER_LEN + |
733 | case END: | 760 | AX25_MAX_HEADER_LEN + 3; |
734 | /* drop keeptest bit = VSV */ | 761 | dev->type = ARPHRD_AX25; |
735 | if (test_bit(AXF_KEEPTEST, &ax->flags)) | ||
736 | clear_bit(AXF_KEEPTEST, &ax->flags); | ||
737 | 762 | ||
738 | if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2)) | 763 | err = 0; |
739 | ax_bump(ax); | 764 | break; |
740 | 765 | ||
741 | clear_bit(AXF_ESCAPE, &ax->flags); | 766 | case SIOCSIFHWADDR: { |
742 | ax->rcount = 0; | 767 | char addr[AX25_ADDR_LEN]; |
743 | return; | 768 | printk(KERN_INFO "In SIOCSIFHWADDR"); |
744 | 769 | ||
745 | case ESC: | 770 | if (copy_from_user(&addr, |
746 | set_bit(AXF_ESCAPE, &ax->flags); | 771 | (void __user *) arg, AX25_ADDR_LEN)) { |
747 | return; | 772 | err = -EFAULT; |
748 | case ESC_ESC: | ||
749 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
750 | s = ESC; | ||
751 | break; | 773 | break; |
752 | case ESC_END: | ||
753 | if (test_and_clear_bit(AXF_ESCAPE, &ax->flags)) | ||
754 | s = END; | ||
755 | break; | ||
756 | } | ||
757 | |||
758 | spin_lock_bh(&ax->buflock); | ||
759 | if (!test_bit(AXF_ERROR, &ax->flags)) { | ||
760 | if (ax->rcount < ax->buffsize) { | ||
761 | ax->rbuff[ax->rcount++] = s; | ||
762 | spin_unlock_bh(&ax->buflock); | ||
763 | return; | ||
764 | } | 774 | } |
765 | 775 | ||
766 | ax->rx_over_errors++; | 776 | spin_lock_irq(&dev->xmit_lock); |
767 | set_bit(AXF_ERROR, &ax->flags); | 777 | memcpy(dev->dev_addr, addr, AX25_ADDR_LEN); |
778 | spin_unlock_irq(&dev->xmit_lock); | ||
779 | |||
780 | err = 0; | ||
781 | break; | ||
782 | } | ||
783 | default: | ||
784 | err = -ENOIOCTLCMD; | ||
768 | } | 785 | } |
769 | spin_unlock_bh(&ax->buflock); | ||
770 | } | ||
771 | 786 | ||
787 | mkiss_put(ax); | ||
772 | 788 | ||
773 | static int ax_set_mac_address(struct net_device *dev, void __user *addr) | 789 | return err; |
774 | { | ||
775 | if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN)) | ||
776 | return -EFAULT; | ||
777 | return 0; | ||
778 | } | 790 | } |
779 | 791 | ||
780 | static int ax_set_dev_mac_address(struct net_device *dev, void *addr) | 792 | /* |
793 | * Handle the 'receiver data ready' interrupt. | ||
794 | * This function is called by the 'tty_io' module in the kernel when | ||
795 | * a block of data has been received, which can now be decapsulated | ||
796 | * and sent on to the AX.25 layer for further processing. | ||
797 | */ | ||
798 | static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp, | ||
799 | char *fp, int count) | ||
781 | { | 800 | { |
782 | struct sockaddr *sa = addr; | 801 | struct mkiss *ax = mkiss_get(tty); |
783 | |||
784 | memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN); | ||
785 | 802 | ||
786 | return 0; | 803 | if (!ax) |
787 | } | 804 | return; |
788 | |||
789 | |||
790 | /* Perform I/O control on an active ax25 channel. */ | ||
791 | static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg) | ||
792 | { | ||
793 | struct ax_disp *ax = (struct ax_disp *) tty->disc_data; | ||
794 | unsigned int tmp; | ||
795 | 805 | ||
796 | /* First make sure we're connected. */ | 806 | /* |
797 | if (ax == NULL || ax->magic != AX25_MAGIC) | 807 | * Argh! mtu change time! - costs us the packet part received |
798 | return -EINVAL; | 808 | * at the change |
809 | */ | ||
810 | if (ax->mtu != ax->dev->mtu + 73) | ||
811 | ax_changedmtu(ax); | ||
799 | 812 | ||
800 | switch (cmd) { | 813 | /* Read the characters out of the buffer */ |
801 | case SIOCGIFNAME: | 814 | while (count--) { |
802 | if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1)) | 815 | if (fp != NULL && *fp++) { |
803 | return -EFAULT; | 816 | if (!test_and_set_bit(AXF_ERROR, &ax->flags)) |
804 | return 0; | 817 | ax->stats.rx_errors++; |
805 | 818 | cp++; | |
806 | case SIOCGIFENCAP: | 819 | continue; |
807 | return put_user(4, (int __user *)arg); | 820 | } |
808 | |||
809 | case SIOCSIFENCAP: | ||
810 | if (get_user(tmp, (int __user *)arg)) | ||
811 | return -EFAULT; | ||
812 | ax->mode = tmp; | ||
813 | ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */ | ||
814 | ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3; | ||
815 | ax->dev->type = ARPHRD_AX25; | ||
816 | return 0; | ||
817 | |||
818 | case SIOCSIFHWADDR: | ||
819 | return ax_set_mac_address(ax->dev, arg); | ||
820 | 821 | ||
821 | default: | 822 | kiss_unesc(ax, *cp++); |
822 | return -ENOIOCTLCMD; | ||
823 | } | 823 | } |
824 | |||
825 | mkiss_put(ax); | ||
826 | if (test_and_clear_bit(TTY_THROTTLED, &tty->flags) | ||
827 | && tty->driver->unthrottle) | ||
828 | tty->driver->unthrottle(tty); | ||
824 | } | 829 | } |
825 | 830 | ||
826 | static int ax_open_dev(struct net_device *dev) | 831 | static int mkiss_receive_room(struct tty_struct *tty) |
827 | { | 832 | { |
828 | struct ax_disp *ax = netdev_priv(dev); | 833 | return 65536; /* We can handle an infinite amount of data. :-) */ |
829 | |||
830 | if (ax->tty == NULL) | ||
831 | return -ENODEV; | ||
832 | |||
833 | return 0; | ||
834 | } | 834 | } |
835 | 835 | ||
836 | 836 | /* | |
837 | /* Initialize the driver. Called by network startup. */ | 837 | * Called by the driver when there's room for more data. If we have |
838 | static int ax25_init(struct net_device *dev) | 838 | * more packets to send, we send them here. |
839 | */ | ||
840 | static void mkiss_write_wakeup(struct tty_struct *tty) | ||
839 | { | 841 | { |
840 | struct ax_disp *ax = netdev_priv(dev); | 842 | struct mkiss *ax = mkiss_get(tty); |
841 | 843 | int actual; | |
842 | static char ax25_bcast[AX25_ADDR_LEN] = | ||
843 | {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1}; | ||
844 | static char ax25_test[AX25_ADDR_LEN] = | ||
845 | {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1}; | ||
846 | |||
847 | if (ax == NULL) /* Allocation failed ?? */ | ||
848 | return -ENODEV; | ||
849 | 844 | ||
850 | /* Set up the "AX25 Control Block". (And clear statistics) */ | 845 | if (!ax) |
851 | memset(ax, 0, sizeof (struct ax_disp)); | 846 | return; |
852 | ax->magic = AX25_MAGIC; | ||
853 | ax->dev = dev; | ||
854 | 847 | ||
855 | /* Finish setting up the DEVICE info. */ | 848 | if (ax->xleft <= 0) { |
856 | dev->mtu = AX_MTU; | 849 | /* Now serial buffer is almost free & we can start |
857 | dev->hard_start_xmit = ax_xmit; | 850 | * transmission of another packet |
858 | dev->open = ax_open_dev; | 851 | */ |
859 | dev->stop = ax_close; | 852 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
860 | dev->get_stats = ax_get_stats; | ||
861 | dev->set_mac_address = ax_set_dev_mac_address; | ||
862 | dev->hard_header_len = 0; | ||
863 | dev->addr_len = 0; | ||
864 | dev->type = ARPHRD_AX25; | ||
865 | dev->tx_queue_len = 10; | ||
866 | dev->hard_header = ax_header; | ||
867 | dev->rebuild_header = ax_rebuild_header; | ||
868 | 853 | ||
869 | memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN); | 854 | netif_wake_queue(ax->dev); |
870 | memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN); | 855 | goto out; |
856 | } | ||
871 | 857 | ||
872 | /* New-style flags. */ | 858 | actual = tty->driver->write(tty, ax->xhead, ax->xleft); |
873 | dev->flags = IFF_BROADCAST | IFF_MULTICAST; | 859 | ax->xleft -= actual; |
860 | ax->xhead += actual; | ||
874 | 861 | ||
875 | return 0; | 862 | out: |
863 | mkiss_put(ax); | ||
876 | } | 864 | } |
877 | 865 | ||
866 | static struct tty_ldisc ax_ldisc = { | ||
867 | .magic = TTY_LDISC_MAGIC, | ||
868 | .name = "mkiss", | ||
869 | .open = mkiss_open, | ||
870 | .close = mkiss_close, | ||
871 | .ioctl = mkiss_ioctl, | ||
872 | .receive_buf = mkiss_receive_buf, | ||
873 | .receive_room = mkiss_receive_room, | ||
874 | .write_wakeup = mkiss_write_wakeup | ||
875 | }; | ||
878 | 876 | ||
879 | /* ******************************************************************** */ | 877 | static char banner[] __initdata = KERN_INFO \ |
880 | /* * Init MKISS driver * */ | 878 | "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n"; |
881 | /* ******************************************************************** */ | 879 | static char msg_regfail[] __initdata = KERN_ERR \ |
880 | "mkiss: can't register line discipline (err = %d)\n"; | ||
882 | 881 | ||
883 | static int __init mkiss_init_driver(void) | 882 | static int __init mkiss_init_driver(void) |
884 | { | 883 | { |
@@ -886,64 +885,27 @@ static int __init mkiss_init_driver(void) | |||
886 | 885 | ||
887 | printk(banner); | 886 | printk(banner); |
888 | 887 | ||
889 | if (ax25_maxdev < 4) | 888 | if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) |
890 | ax25_maxdev = 4; /* Sanity */ | 889 | printk(msg_regfail); |
891 | 890 | ||
892 | if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) { | ||
893 | printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n"); | ||
894 | return -ENOMEM; | ||
895 | } | ||
896 | |||
897 | /* Clear the pointer array, we allocate devices when we need them */ | ||
898 | memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */ | ||
899 | |||
900 | /* Fill in our line protocol discipline, and register it */ | ||
901 | ax_ldisc.magic = TTY_LDISC_MAGIC; | ||
902 | ax_ldisc.name = "mkiss"; | ||
903 | ax_ldisc.open = ax25_open; | ||
904 | ax_ldisc.close = ax25_close; | ||
905 | ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *, | ||
906 | unsigned int, unsigned long))ax25_disp_ioctl; | ||
907 | ax_ldisc.receive_buf = ax25_receive_buf; | ||
908 | ax_ldisc.receive_room = ax25_receive_room; | ||
909 | ax_ldisc.write_wakeup = ax25_write_wakeup; | ||
910 | |||
911 | if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) { | ||
912 | printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status); | ||
913 | kfree(ax25_ctrls); | ||
914 | } | ||
915 | return status; | 891 | return status; |
916 | } | 892 | } |
917 | 893 | ||
894 | static const char msg_unregfail[] __exitdata = KERN_ERR \ | ||
895 | "mkiss: can't unregister line discipline (err = %d)\n"; | ||
896 | |||
918 | static void __exit mkiss_exit_driver(void) | 897 | static void __exit mkiss_exit_driver(void) |
919 | { | 898 | { |
920 | int i; | 899 | int ret; |
921 | |||
922 | for (i = 0; i < ax25_maxdev; i++) { | ||
923 | if (ax25_ctrls[i]) { | ||
924 | /* | ||
925 | * VSV = if dev->start==0, then device | ||
926 | * unregistered while close proc. | ||
927 | */ | ||
928 | if (netif_running(&ax25_ctrls[i]->dev)) | ||
929 | unregister_netdev(&ax25_ctrls[i]->dev); | ||
930 | kfree(ax25_ctrls[i]); | ||
931 | } | ||
932 | } | ||
933 | 900 | ||
934 | kfree(ax25_ctrls); | 901 | if ((ret = tty_unregister_ldisc(N_AX25))) |
935 | ax25_ctrls = NULL; | 902 | printk(msg_unregfail, ret); |
936 | |||
937 | if ((i = tty_unregister_ldisc(N_AX25))) | ||
938 | printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i); | ||
939 | } | 903 | } |
940 | 904 | ||
941 | MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>"); | 905 | MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>"); |
942 | MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); | 906 | MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); |
943 | MODULE_PARM(ax25_maxdev, "i"); | ||
944 | MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices"); | ||
945 | MODULE_LICENSE("GPL"); | 907 | MODULE_LICENSE("GPL"); |
946 | MODULE_ALIAS_LDISC(N_AX25); | 908 | MODULE_ALIAS_LDISC(N_AX25); |
909 | |||
947 | module_init(mkiss_init_driver); | 910 | module_init(mkiss_init_driver); |
948 | module_exit(mkiss_exit_driver); | 911 | module_exit(mkiss_exit_driver); |
949 | |||
diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 6482d994d489..0de3bb906174 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c | |||
@@ -1253,7 +1253,7 @@ static int emac_init_tah(struct ocp_enet_private *fep) | |||
1253 | TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | | 1253 | TAH_MR_CVR | TAH_MR_ST_768 | TAH_MR_TFS_10KB | TAH_MR_DTFP | |
1254 | TAH_MR_DIG); | 1254 | TAH_MR_DIG); |
1255 | 1255 | ||
1256 | iounmap(&tahp); | 1256 | iounmap(tahp); |
1257 | 1257 | ||
1258 | return 0; | 1258 | return 0; |
1259 | } | 1259 | } |
@@ -1712,11 +1712,10 @@ struct mal_commac_ops emac_commac_ops = { | |||
1712 | }; | 1712 | }; |
1713 | 1713 | ||
1714 | #ifdef CONFIG_NET_POLL_CONTROLLER | 1714 | #ifdef CONFIG_NET_POLL_CONTROLLER |
1715 | static int emac_netpoll(struct net_device *ndev) | 1715 | static void emac_netpoll(struct net_device *ndev) |
1716 | { | 1716 | { |
1717 | emac_rxeob_dev((void *)ndev, 0); | 1717 | emac_rxeob_dev((void *)ndev, 0); |
1718 | emac_txeob_dev((void *)ndev, 0); | 1718 | emac_txeob_dev((void *)ndev, 0); |
1719 | return 0; | ||
1720 | } | 1719 | } |
1721 | #endif | 1720 | #endif |
1722 | 1721 | ||
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c index d520b5920d6c..49e5467bdd73 100644 --- a/drivers/net/ioc3-eth.c +++ b/drivers/net/ioc3-eth.c | |||
@@ -499,7 +499,7 @@ static int ioc3_mdio_read(struct net_device *dev, int phy, int reg) | |||
499 | ioc3_w_micr((phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG); | 499 | ioc3_w_micr((phy << MICR_PHYADDR_SHIFT) | reg | MICR_READTRIG); |
500 | while (ioc3_r_micr() & MICR_BUSY); | 500 | while (ioc3_r_micr() & MICR_BUSY); |
501 | 501 | ||
502 | return ioc3_r_micr() & MIDR_DATA_MASK; | 502 | return ioc3_r_midr_r() & MIDR_DATA_MASK; |
503 | } | 503 | } |
504 | 504 | ||
505 | static void ioc3_mdio_write(struct net_device *dev, int phy, int reg, int data) | 505 | static void ioc3_mdio_write(struct net_device *dev, int phy, int reg, int data) |
@@ -1291,7 +1291,6 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1291 | dev->features = NETIF_F_IP_CSUM; | 1291 | dev->features = NETIF_F_IP_CSUM; |
1292 | #endif | 1292 | #endif |
1293 | 1293 | ||
1294 | ioc3_setup_duplex(ip); | ||
1295 | sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); | 1294 | sw_physid1 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID1); |
1296 | sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); | 1295 | sw_physid2 = ioc3_mdio_read(dev, ip->mii.phy_id, MII_PHYSID2); |
1297 | 1296 | ||
@@ -1300,6 +1299,7 @@ static int ioc3_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1300 | goto out_stop; | 1299 | goto out_stop; |
1301 | 1300 | ||
1302 | mii_check_media(&ip->mii, 1, 1); | 1301 | mii_check_media(&ip->mii, 1, 1); |
1302 | ioc3_setup_duplex(ip); | ||
1303 | 1303 | ||
1304 | vendor = (sw_physid1 << 12) | (sw_physid2 >> 4); | 1304 | vendor = (sw_physid1 << 12) | (sw_physid2 >> 4); |
1305 | model = (sw_physid2 >> 4) & 0x3f; | 1305 | model = (sw_physid2 >> 4) & 0x3f; |
@@ -1524,7 +1524,7 @@ static void ioc3_get_drvinfo (struct net_device *dev, | |||
1524 | struct ethtool_drvinfo *info) | 1524 | struct ethtool_drvinfo *info) |
1525 | { | 1525 | { |
1526 | struct ioc3_private *ip = netdev_priv(dev); | 1526 | struct ioc3_private *ip = netdev_priv(dev); |
1527 | 1527 | ||
1528 | strcpy (info->driver, IOC3_NAME); | 1528 | strcpy (info->driver, IOC3_NAME); |
1529 | strcpy (info->version, IOC3_VERSION); | 1529 | strcpy (info->version, IOC3_VERSION); |
1530 | strcpy (info->bus_info, pci_name(ip->pdev)); | 1530 | strcpy (info->bus_info, pci_name(ip->pdev)); |
@@ -1550,7 +1550,7 @@ static int ioc3_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) | |||
1550 | spin_lock_irq(&ip->ioc3_lock); | 1550 | spin_lock_irq(&ip->ioc3_lock); |
1551 | rc = mii_ethtool_sset(&ip->mii, cmd); | 1551 | rc = mii_ethtool_sset(&ip->mii, cmd); |
1552 | spin_unlock_irq(&ip->ioc3_lock); | 1552 | spin_unlock_irq(&ip->ioc3_lock); |
1553 | 1553 | ||
1554 | return rc; | 1554 | return rc; |
1555 | } | 1555 | } |
1556 | 1556 | ||
diff --git a/drivers/net/ixgb/ixgb.h b/drivers/net/ixgb/ixgb.h index f8d3385c7842..c83271b38621 100644 --- a/drivers/net/ixgb/ixgb.h +++ b/drivers/net/ixgb/ixgb.h | |||
@@ -119,7 +119,7 @@ struct ixgb_adapter; | |||
119 | * so a DMA handle can be stored along with the buffer */ | 119 | * so a DMA handle can be stored along with the buffer */ |
120 | struct ixgb_buffer { | 120 | struct ixgb_buffer { |
121 | struct sk_buff *skb; | 121 | struct sk_buff *skb; |
122 | uint64_t dma; | 122 | dma_addr_t dma; |
123 | unsigned long time_stamp; | 123 | unsigned long time_stamp; |
124 | uint16_t length; | 124 | uint16_t length; |
125 | uint16_t next_to_watch; | 125 | uint16_t next_to_watch; |
diff --git a/drivers/net/ixgb/ixgb_ee.c b/drivers/net/ixgb/ixgb_ee.c index 3aae110c5560..661a46b95a61 100644 --- a/drivers/net/ixgb/ixgb_ee.c +++ b/drivers/net/ixgb/ixgb_ee.c | |||
@@ -565,24 +565,6 @@ ixgb_get_ee_mac_addr(struct ixgb_hw *hw, | |||
565 | } | 565 | } |
566 | } | 566 | } |
567 | 567 | ||
568 | /****************************************************************************** | ||
569 | * return the compatibility flags from EEPROM | ||
570 | * | ||
571 | * hw - Struct containing variables accessed by shared code | ||
572 | * | ||
573 | * Returns: | ||
574 | * compatibility flags if EEPROM contents are valid, 0 otherwise | ||
575 | ******************************************************************************/ | ||
576 | uint16_t | ||
577 | ixgb_get_ee_compatibility(struct ixgb_hw *hw) | ||
578 | { | ||
579 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
580 | |||
581 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
582 | return (le16_to_cpu(ee_map->compatibility)); | ||
583 | |||
584 | return(0); | ||
585 | } | ||
586 | 568 | ||
587 | /****************************************************************************** | 569 | /****************************************************************************** |
588 | * return the Printed Board Assembly number from EEPROM | 570 | * return the Printed Board Assembly number from EEPROM |
@@ -602,81 +584,6 @@ ixgb_get_ee_pba_number(struct ixgb_hw *hw) | |||
602 | return(0); | 584 | return(0); |
603 | } | 585 | } |
604 | 586 | ||
605 | /****************************************************************************** | ||
606 | * return the Initialization Control Word 1 from EEPROM | ||
607 | * | ||
608 | * hw - Struct containing variables accessed by shared code | ||
609 | * | ||
610 | * Returns: | ||
611 | * Initialization Control Word 1 if EEPROM contents are valid, 0 otherwise | ||
612 | ******************************************************************************/ | ||
613 | uint16_t | ||
614 | ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw) | ||
615 | { | ||
616 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
617 | |||
618 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
619 | return (le16_to_cpu(ee_map->init_ctrl_reg_1)); | ||
620 | |||
621 | return(0); | ||
622 | } | ||
623 | |||
624 | /****************************************************************************** | ||
625 | * return the Initialization Control Word 2 from EEPROM | ||
626 | * | ||
627 | * hw - Struct containing variables accessed by shared code | ||
628 | * | ||
629 | * Returns: | ||
630 | * Initialization Control Word 2 if EEPROM contents are valid, 0 otherwise | ||
631 | ******************************************************************************/ | ||
632 | uint16_t | ||
633 | ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw) | ||
634 | { | ||
635 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
636 | |||
637 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
638 | return (le16_to_cpu(ee_map->init_ctrl_reg_2)); | ||
639 | |||
640 | return(0); | ||
641 | } | ||
642 | |||
643 | /****************************************************************************** | ||
644 | * return the Subsystem Id from EEPROM | ||
645 | * | ||
646 | * hw - Struct containing variables accessed by shared code | ||
647 | * | ||
648 | * Returns: | ||
649 | * Subsystem Id if EEPROM contents are valid, 0 otherwise | ||
650 | ******************************************************************************/ | ||
651 | uint16_t | ||
652 | ixgb_get_ee_subsystem_id(struct ixgb_hw *hw) | ||
653 | { | ||
654 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
655 | |||
656 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
657 | return (le16_to_cpu(ee_map->subsystem_id)); | ||
658 | |||
659 | return(0); | ||
660 | } | ||
661 | |||
662 | /****************************************************************************** | ||
663 | * return the Sub Vendor Id from EEPROM | ||
664 | * | ||
665 | * hw - Struct containing variables accessed by shared code | ||
666 | * | ||
667 | * Returns: | ||
668 | * Sub Vendor Id if EEPROM contents are valid, 0 otherwise | ||
669 | ******************************************************************************/ | ||
670 | uint16_t | ||
671 | ixgb_get_ee_subvendor_id(struct ixgb_hw *hw) | ||
672 | { | ||
673 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
674 | |||
675 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
676 | return (le16_to_cpu(ee_map->subvendor_id)); | ||
677 | |||
678 | return(0); | ||
679 | } | ||
680 | 587 | ||
681 | /****************************************************************************** | 588 | /****************************************************************************** |
682 | * return the Device Id from EEPROM | 589 | * return the Device Id from EEPROM |
@@ -694,81 +601,6 @@ ixgb_get_ee_device_id(struct ixgb_hw *hw) | |||
694 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | 601 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) |
695 | return (le16_to_cpu(ee_map->device_id)); | 602 | return (le16_to_cpu(ee_map->device_id)); |
696 | 603 | ||
697 | return(0); | 604 | return (0); |
698 | } | ||
699 | |||
700 | /****************************************************************************** | ||
701 | * return the Vendor Id from EEPROM | ||
702 | * | ||
703 | * hw - Struct containing variables accessed by shared code | ||
704 | * | ||
705 | * Returns: | ||
706 | * Device Id if EEPROM contents are valid, 0 otherwise | ||
707 | ******************************************************************************/ | ||
708 | uint16_t | ||
709 | ixgb_get_ee_vendor_id(struct ixgb_hw *hw) | ||
710 | { | ||
711 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
712 | |||
713 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
714 | return (le16_to_cpu(ee_map->vendor_id)); | ||
715 | |||
716 | return(0); | ||
717 | } | ||
718 | |||
719 | /****************************************************************************** | ||
720 | * return the Software Defined Pins Register from EEPROM | ||
721 | * | ||
722 | * hw - Struct containing variables accessed by shared code | ||
723 | * | ||
724 | * Returns: | ||
725 | * SDP Register if EEPROM contents are valid, 0 otherwise | ||
726 | ******************************************************************************/ | ||
727 | uint16_t | ||
728 | ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw) | ||
729 | { | ||
730 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
731 | |||
732 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
733 | return (le16_to_cpu(ee_map->swdpins_reg)); | ||
734 | |||
735 | return(0); | ||
736 | } | 605 | } |
737 | 606 | ||
738 | /****************************************************************************** | ||
739 | * return the D3 Power Management Bits from EEPROM | ||
740 | * | ||
741 | * hw - Struct containing variables accessed by shared code | ||
742 | * | ||
743 | * Returns: | ||
744 | * D3 Power Management Bits if EEPROM contents are valid, 0 otherwise | ||
745 | ******************************************************************************/ | ||
746 | uint8_t | ||
747 | ixgb_get_ee_d3_power(struct ixgb_hw *hw) | ||
748 | { | ||
749 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
750 | |||
751 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
752 | return (le16_to_cpu(ee_map->d3_power)); | ||
753 | |||
754 | return(0); | ||
755 | } | ||
756 | |||
757 | /****************************************************************************** | ||
758 | * return the D0 Power Management Bits from EEPROM | ||
759 | * | ||
760 | * hw - Struct containing variables accessed by shared code | ||
761 | * | ||
762 | * Returns: | ||
763 | * D0 Power Management Bits if EEPROM contents are valid, 0 otherwise | ||
764 | ******************************************************************************/ | ||
765 | uint8_t | ||
766 | ixgb_get_ee_d0_power(struct ixgb_hw *hw) | ||
767 | { | ||
768 | struct ixgb_ee_map_type *ee_map = (struct ixgb_ee_map_type *)hw->eeprom; | ||
769 | |||
770 | if(ixgb_check_and_get_eeprom_data(hw) == TRUE) | ||
771 | return (le16_to_cpu(ee_map->d0_power)); | ||
772 | |||
773 | return(0); | ||
774 | } | ||
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c index 3fa113854eeb..9d026ed77ddd 100644 --- a/drivers/net/ixgb/ixgb_ethtool.c +++ b/drivers/net/ixgb/ixgb_ethtool.c | |||
@@ -98,10 +98,10 @@ static struct ixgb_stats ixgb_gstrings_stats[] = { | |||
98 | static int | 98 | static int |
99 | ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 99 | ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
100 | { | 100 | { |
101 | struct ixgb_adapter *adapter = netdev->priv; | 101 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
102 | 102 | ||
103 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | 103 | ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); |
104 | ecmd->advertising = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE); | 104 | ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE); |
105 | ecmd->port = PORT_FIBRE; | 105 | ecmd->port = PORT_FIBRE; |
106 | ecmd->transceiver = XCVR_EXTERNAL; | 106 | ecmd->transceiver = XCVR_EXTERNAL; |
107 | 107 | ||
@@ -120,7 +120,7 @@ ixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
120 | static int | 120 | static int |
121 | ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | 121 | ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) |
122 | { | 122 | { |
123 | struct ixgb_adapter *adapter = netdev->priv; | 123 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
124 | 124 | ||
125 | if(ecmd->autoneg == AUTONEG_ENABLE || | 125 | if(ecmd->autoneg == AUTONEG_ENABLE || |
126 | ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL) | 126 | ecmd->speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL) |
@@ -130,6 +130,12 @@ ixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
130 | ixgb_down(adapter, TRUE); | 130 | ixgb_down(adapter, TRUE); |
131 | ixgb_reset(adapter); | 131 | ixgb_reset(adapter); |
132 | ixgb_up(adapter); | 132 | ixgb_up(adapter); |
133 | /* be optimistic about our link, since we were up before */ | ||
134 | adapter->link_speed = 10000; | ||
135 | adapter->link_duplex = FULL_DUPLEX; | ||
136 | netif_carrier_on(netdev); | ||
137 | netif_wake_queue(netdev); | ||
138 | |||
133 | } else | 139 | } else |
134 | ixgb_reset(adapter); | 140 | ixgb_reset(adapter); |
135 | 141 | ||
@@ -140,7 +146,7 @@ static void | |||
140 | ixgb_get_pauseparam(struct net_device *netdev, | 146 | ixgb_get_pauseparam(struct net_device *netdev, |
141 | struct ethtool_pauseparam *pause) | 147 | struct ethtool_pauseparam *pause) |
142 | { | 148 | { |
143 | struct ixgb_adapter *adapter = netdev->priv; | 149 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
144 | struct ixgb_hw *hw = &adapter->hw; | 150 | struct ixgb_hw *hw = &adapter->hw; |
145 | 151 | ||
146 | pause->autoneg = AUTONEG_DISABLE; | 152 | pause->autoneg = AUTONEG_DISABLE; |
@@ -159,7 +165,7 @@ static int | |||
159 | ixgb_set_pauseparam(struct net_device *netdev, | 165 | ixgb_set_pauseparam(struct net_device *netdev, |
160 | struct ethtool_pauseparam *pause) | 166 | struct ethtool_pauseparam *pause) |
161 | { | 167 | { |
162 | struct ixgb_adapter *adapter = netdev->priv; | 168 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
163 | struct ixgb_hw *hw = &adapter->hw; | 169 | struct ixgb_hw *hw = &adapter->hw; |
164 | 170 | ||
165 | if(pause->autoneg == AUTONEG_ENABLE) | 171 | if(pause->autoneg == AUTONEG_ENABLE) |
@@ -177,6 +183,11 @@ ixgb_set_pauseparam(struct net_device *netdev, | |||
177 | if(netif_running(adapter->netdev)) { | 183 | if(netif_running(adapter->netdev)) { |
178 | ixgb_down(adapter, TRUE); | 184 | ixgb_down(adapter, TRUE); |
179 | ixgb_up(adapter); | 185 | ixgb_up(adapter); |
186 | /* be optimistic about our link, since we were up before */ | ||
187 | adapter->link_speed = 10000; | ||
188 | adapter->link_duplex = FULL_DUPLEX; | ||
189 | netif_carrier_on(netdev); | ||
190 | netif_wake_queue(netdev); | ||
180 | } else | 191 | } else |
181 | ixgb_reset(adapter); | 192 | ixgb_reset(adapter); |
182 | 193 | ||
@@ -186,19 +197,26 @@ ixgb_set_pauseparam(struct net_device *netdev, | |||
186 | static uint32_t | 197 | static uint32_t |
187 | ixgb_get_rx_csum(struct net_device *netdev) | 198 | ixgb_get_rx_csum(struct net_device *netdev) |
188 | { | 199 | { |
189 | struct ixgb_adapter *adapter = netdev->priv; | 200 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
201 | |||
190 | return adapter->rx_csum; | 202 | return adapter->rx_csum; |
191 | } | 203 | } |
192 | 204 | ||
193 | static int | 205 | static int |
194 | ixgb_set_rx_csum(struct net_device *netdev, uint32_t data) | 206 | ixgb_set_rx_csum(struct net_device *netdev, uint32_t data) |
195 | { | 207 | { |
196 | struct ixgb_adapter *adapter = netdev->priv; | 208 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
209 | |||
197 | adapter->rx_csum = data; | 210 | adapter->rx_csum = data; |
198 | 211 | ||
199 | if(netif_running(netdev)) { | 212 | if(netif_running(netdev)) { |
200 | ixgb_down(adapter,TRUE); | 213 | ixgb_down(adapter,TRUE); |
201 | ixgb_up(adapter); | 214 | ixgb_up(adapter); |
215 | /* be optimistic about our link, since we were up before */ | ||
216 | adapter->link_speed = 10000; | ||
217 | adapter->link_duplex = FULL_DUPLEX; | ||
218 | netif_carrier_on(netdev); | ||
219 | netif_wake_queue(netdev); | ||
202 | } else | 220 | } else |
203 | ixgb_reset(adapter); | 221 | ixgb_reset(adapter); |
204 | return 0; | 222 | return 0; |
@@ -246,14 +264,15 @@ static void | |||
246 | ixgb_get_regs(struct net_device *netdev, | 264 | ixgb_get_regs(struct net_device *netdev, |
247 | struct ethtool_regs *regs, void *p) | 265 | struct ethtool_regs *regs, void *p) |
248 | { | 266 | { |
249 | struct ixgb_adapter *adapter = netdev->priv; | 267 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
250 | struct ixgb_hw *hw = &adapter->hw; | 268 | struct ixgb_hw *hw = &adapter->hw; |
251 | uint32_t *reg = p; | 269 | uint32_t *reg = p; |
252 | uint32_t *reg_start = reg; | 270 | uint32_t *reg_start = reg; |
253 | uint8_t i; | 271 | uint8_t i; |
254 | 272 | ||
255 | /* the 1 (one) below indicates an attempt at versioning, if the | 273 | /* the 1 (one) below indicates an attempt at versioning, if the |
256 | * interface in ethtool or the driver this 1 should be incremented */ | 274 | * interface in ethtool or the driver changes, this 1 should be |
275 | * incremented */ | ||
257 | regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; | 276 | regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; |
258 | 277 | ||
259 | /* General Registers */ | 278 | /* General Registers */ |
@@ -283,7 +302,8 @@ ixgb_get_regs(struct net_device *netdev, | |||
283 | *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */ | 302 | *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */ |
284 | *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ | 303 | *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ |
285 | 304 | ||
286 | for (i = 0; i < IXGB_RAR_ENTRIES; i++) { | 305 | /* there are 16 RAR entries in hardware, we only use 3 */ |
306 | for(i = 0; i < 16; i++) { | ||
287 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ | 307 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ |
288 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ | 308 | *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ |
289 | } | 309 | } |
@@ -391,7 +411,7 @@ static int | |||
391 | ixgb_get_eeprom(struct net_device *netdev, | 411 | ixgb_get_eeprom(struct net_device *netdev, |
392 | struct ethtool_eeprom *eeprom, uint8_t *bytes) | 412 | struct ethtool_eeprom *eeprom, uint8_t *bytes) |
393 | { | 413 | { |
394 | struct ixgb_adapter *adapter = netdev->priv; | 414 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
395 | struct ixgb_hw *hw = &adapter->hw; | 415 | struct ixgb_hw *hw = &adapter->hw; |
396 | uint16_t *eeprom_buff; | 416 | uint16_t *eeprom_buff; |
397 | int i, max_len, first_word, last_word; | 417 | int i, max_len, first_word, last_word; |
@@ -439,7 +459,7 @@ static int | |||
439 | ixgb_set_eeprom(struct net_device *netdev, | 459 | ixgb_set_eeprom(struct net_device *netdev, |
440 | struct ethtool_eeprom *eeprom, uint8_t *bytes) | 460 | struct ethtool_eeprom *eeprom, uint8_t *bytes) |
441 | { | 461 | { |
442 | struct ixgb_adapter *adapter = netdev->priv; | 462 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
443 | struct ixgb_hw *hw = &adapter->hw; | 463 | struct ixgb_hw *hw = &adapter->hw; |
444 | uint16_t *eeprom_buff; | 464 | uint16_t *eeprom_buff; |
445 | void *ptr; | 465 | void *ptr; |
@@ -497,7 +517,7 @@ static void | |||
497 | ixgb_get_drvinfo(struct net_device *netdev, | 517 | ixgb_get_drvinfo(struct net_device *netdev, |
498 | struct ethtool_drvinfo *drvinfo) | 518 | struct ethtool_drvinfo *drvinfo) |
499 | { | 519 | { |
500 | struct ixgb_adapter *adapter = netdev->priv; | 520 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
501 | 521 | ||
502 | strncpy(drvinfo->driver, ixgb_driver_name, 32); | 522 | strncpy(drvinfo->driver, ixgb_driver_name, 32); |
503 | strncpy(drvinfo->version, ixgb_driver_version, 32); | 523 | strncpy(drvinfo->version, ixgb_driver_version, 32); |
@@ -512,7 +532,7 @@ static void | |||
512 | ixgb_get_ringparam(struct net_device *netdev, | 532 | ixgb_get_ringparam(struct net_device *netdev, |
513 | struct ethtool_ringparam *ring) | 533 | struct ethtool_ringparam *ring) |
514 | { | 534 | { |
515 | struct ixgb_adapter *adapter = netdev->priv; | 535 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
516 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; | 536 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; |
517 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; | 537 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; |
518 | 538 | ||
@@ -530,7 +550,7 @@ static int | |||
530 | ixgb_set_ringparam(struct net_device *netdev, | 550 | ixgb_set_ringparam(struct net_device *netdev, |
531 | struct ethtool_ringparam *ring) | 551 | struct ethtool_ringparam *ring) |
532 | { | 552 | { |
533 | struct ixgb_adapter *adapter = netdev->priv; | 553 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
534 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; | 554 | struct ixgb_desc_ring *txdr = &adapter->tx_ring; |
535 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; | 555 | struct ixgb_desc_ring *rxdr = &adapter->rx_ring; |
536 | struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; | 556 | struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; |
@@ -573,6 +593,11 @@ ixgb_set_ringparam(struct net_device *netdev, | |||
573 | adapter->tx_ring = tx_new; | 593 | adapter->tx_ring = tx_new; |
574 | if((err = ixgb_up(adapter))) | 594 | if((err = ixgb_up(adapter))) |
575 | return err; | 595 | return err; |
596 | /* be optimistic about our link, since we were up before */ | ||
597 | adapter->link_speed = 10000; | ||
598 | adapter->link_duplex = FULL_DUPLEX; | ||
599 | netif_carrier_on(netdev); | ||
600 | netif_wake_queue(netdev); | ||
576 | } | 601 | } |
577 | 602 | ||
578 | return 0; | 603 | return 0; |
@@ -607,7 +632,7 @@ ixgb_led_blink_callback(unsigned long data) | |||
607 | static int | 632 | static int |
608 | ixgb_phys_id(struct net_device *netdev, uint32_t data) | 633 | ixgb_phys_id(struct net_device *netdev, uint32_t data) |
609 | { | 634 | { |
610 | struct ixgb_adapter *adapter = netdev->priv; | 635 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
611 | 636 | ||
612 | if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) | 637 | if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ)) |
613 | data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); | 638 | data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ); |
@@ -643,7 +668,7 @@ static void | |||
643 | ixgb_get_ethtool_stats(struct net_device *netdev, | 668 | ixgb_get_ethtool_stats(struct net_device *netdev, |
644 | struct ethtool_stats *stats, uint64_t *data) | 669 | struct ethtool_stats *stats, uint64_t *data) |
645 | { | 670 | { |
646 | struct ixgb_adapter *adapter = netdev->priv; | 671 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
647 | int i; | 672 | int i; |
648 | 673 | ||
649 | ixgb_update_stats(adapter); | 674 | ixgb_update_stats(adapter); |
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h index 97898efe7cc8..8bcf31ed10c2 100644 --- a/drivers/net/ixgb/ixgb_hw.h +++ b/drivers/net/ixgb/ixgb_hw.h | |||
@@ -822,17 +822,8 @@ extern void ixgb_clear_vfta(struct ixgb_hw *hw); | |||
822 | 822 | ||
823 | /* Access functions to eeprom data */ | 823 | /* Access functions to eeprom data */ |
824 | void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr); | 824 | void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr); |
825 | uint16_t ixgb_get_ee_compatibility(struct ixgb_hw *hw); | ||
826 | uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw); | 825 | uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw); |
827 | uint16_t ixgb_get_ee_init_ctrl_reg_1(struct ixgb_hw *hw); | ||
828 | uint16_t ixgb_get_ee_init_ctrl_reg_2(struct ixgb_hw *hw); | ||
829 | uint16_t ixgb_get_ee_subsystem_id(struct ixgb_hw *hw); | ||
830 | uint16_t ixgb_get_ee_subvendor_id(struct ixgb_hw *hw); | ||
831 | uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw); | 826 | uint16_t ixgb_get_ee_device_id(struct ixgb_hw *hw); |
832 | uint16_t ixgb_get_ee_vendor_id(struct ixgb_hw *hw); | ||
833 | uint16_t ixgb_get_ee_swdpins_reg(struct ixgb_hw *hw); | ||
834 | uint8_t ixgb_get_ee_d3_power(struct ixgb_hw *hw); | ||
835 | uint8_t ixgb_get_ee_d0_power(struct ixgb_hw *hw); | ||
836 | boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw); | 827 | boolean_t ixgb_get_eeprom_data(struct ixgb_hw *hw); |
837 | uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index); | 828 | uint16_t ixgb_get_eeprom_word(struct ixgb_hw *hw, uint16_t index); |
838 | 829 | ||
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c index 097b90ccf575..5c555373adbe 100644 --- a/drivers/net/ixgb/ixgb_main.c +++ b/drivers/net/ixgb/ixgb_main.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #include "ixgb.h" | 29 | #include "ixgb.h" |
30 | 30 | ||
31 | /* Change Log | 31 | /* Change Log |
32 | * 1.0.96 04/19/05 | ||
33 | * - Make needlessly global code static -- bunk@stusta.de | ||
34 | * - ethtool cleanup -- shemminger@osdl.org | ||
35 | * - Support for MODULE_VERSION -- linville@tuxdriver.com | ||
36 | * - add skb_header_cloned check to the tso path -- herbert@apana.org.au | ||
32 | * 1.0.88 01/05/05 | 37 | * 1.0.88 01/05/05 |
33 | * - include fix to the condition that determines when to quit NAPI - Robert Olsson | 38 | * - include fix to the condition that determines when to quit NAPI - Robert Olsson |
34 | * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down | 39 | * - use netif_poll_{disable/enable} to synchronize between NAPI and i/f up/down |
@@ -47,10 +52,9 @@ char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver"; | |||
47 | #else | 52 | #else |
48 | #define DRIVERNAPI "-NAPI" | 53 | #define DRIVERNAPI "-NAPI" |
49 | #endif | 54 | #endif |
50 | 55 | #define DRV_VERSION "1.0.100-k2"DRIVERNAPI | |
51 | #define DRV_VERSION "1.0.95-k2"DRIVERNAPI | ||
52 | char ixgb_driver_version[] = DRV_VERSION; | 56 | char ixgb_driver_version[] = DRV_VERSION; |
53 | char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; | 57 | static char ixgb_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; |
54 | 58 | ||
55 | /* ixgb_pci_tbl - PCI Device ID Table | 59 | /* ixgb_pci_tbl - PCI Device ID Table |
56 | * | 60 | * |
@@ -145,10 +149,12 @@ MODULE_LICENSE("GPL"); | |||
145 | MODULE_VERSION(DRV_VERSION); | 149 | MODULE_VERSION(DRV_VERSION); |
146 | 150 | ||
147 | /* some defines for controlling descriptor fetches in h/w */ | 151 | /* some defines for controlling descriptor fetches in h/w */ |
148 | #define RXDCTL_PTHRESH_DEFAULT 128 /* chip considers prefech below this */ | ||
149 | #define RXDCTL_HTHRESH_DEFAULT 16 /* chip will only prefetch if tail is | ||
150 | pushed this many descriptors from head */ | ||
151 | #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ | 152 | #define RXDCTL_WTHRESH_DEFAULT 16 /* chip writes back at this many or RXT0 */ |
153 | #define RXDCTL_PTHRESH_DEFAULT 0 /* chip considers prefech below | ||
154 | * this */ | ||
155 | #define RXDCTL_HTHRESH_DEFAULT 0 /* chip will only prefetch if tail | ||
156 | * is pushed this many descriptors | ||
157 | * from head */ | ||
152 | 158 | ||
153 | /** | 159 | /** |
154 | * ixgb_init_module - Driver Registration Routine | 160 | * ixgb_init_module - Driver Registration Routine |
@@ -376,7 +382,7 @@ ixgb_probe(struct pci_dev *pdev, | |||
376 | SET_NETDEV_DEV(netdev, &pdev->dev); | 382 | SET_NETDEV_DEV(netdev, &pdev->dev); |
377 | 383 | ||
378 | pci_set_drvdata(pdev, netdev); | 384 | pci_set_drvdata(pdev, netdev); |
379 | adapter = netdev->priv; | 385 | adapter = netdev_priv(netdev); |
380 | adapter->netdev = netdev; | 386 | adapter->netdev = netdev; |
381 | adapter->pdev = pdev; | 387 | adapter->pdev = pdev; |
382 | adapter->hw.back = adapter; | 388 | adapter->hw.back = adapter; |
@@ -512,7 +518,7 @@ static void __devexit | |||
512 | ixgb_remove(struct pci_dev *pdev) | 518 | ixgb_remove(struct pci_dev *pdev) |
513 | { | 519 | { |
514 | struct net_device *netdev = pci_get_drvdata(pdev); | 520 | struct net_device *netdev = pci_get_drvdata(pdev); |
515 | struct ixgb_adapter *adapter = netdev->priv; | 521 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
516 | 522 | ||
517 | unregister_netdev(netdev); | 523 | unregister_netdev(netdev); |
518 | 524 | ||
@@ -583,7 +589,7 @@ ixgb_sw_init(struct ixgb_adapter *adapter) | |||
583 | static int | 589 | static int |
584 | ixgb_open(struct net_device *netdev) | 590 | ixgb_open(struct net_device *netdev) |
585 | { | 591 | { |
586 | struct ixgb_adapter *adapter = netdev->priv; | 592 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
587 | int err; | 593 | int err; |
588 | 594 | ||
589 | /* allocate transmit descriptors */ | 595 | /* allocate transmit descriptors */ |
@@ -626,7 +632,7 @@ err_setup_tx: | |||
626 | static int | 632 | static int |
627 | ixgb_close(struct net_device *netdev) | 633 | ixgb_close(struct net_device *netdev) |
628 | { | 634 | { |
629 | struct ixgb_adapter *adapter = netdev->priv; | 635 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
630 | 636 | ||
631 | ixgb_down(adapter, TRUE); | 637 | ixgb_down(adapter, TRUE); |
632 | 638 | ||
@@ -1017,7 +1023,7 @@ ixgb_clean_rx_ring(struct ixgb_adapter *adapter) | |||
1017 | static int | 1023 | static int |
1018 | ixgb_set_mac(struct net_device *netdev, void *p) | 1024 | ixgb_set_mac(struct net_device *netdev, void *p) |
1019 | { | 1025 | { |
1020 | struct ixgb_adapter *adapter = netdev->priv; | 1026 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1021 | struct sockaddr *addr = p; | 1027 | struct sockaddr *addr = p; |
1022 | 1028 | ||
1023 | if(!is_valid_ether_addr(addr->sa_data)) | 1029 | if(!is_valid_ether_addr(addr->sa_data)) |
@@ -1043,7 +1049,7 @@ ixgb_set_mac(struct net_device *netdev, void *p) | |||
1043 | static void | 1049 | static void |
1044 | ixgb_set_multi(struct net_device *netdev) | 1050 | ixgb_set_multi(struct net_device *netdev) |
1045 | { | 1051 | { |
1046 | struct ixgb_adapter *adapter = netdev->priv; | 1052 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1047 | struct ixgb_hw *hw = &adapter->hw; | 1053 | struct ixgb_hw *hw = &adapter->hw; |
1048 | struct dev_mc_list *mc_ptr; | 1054 | struct dev_mc_list *mc_ptr; |
1049 | uint32_t rctl; | 1055 | uint32_t rctl; |
@@ -1371,7 +1377,7 @@ ixgb_tx_queue(struct ixgb_adapter *adapter, int count, int vlan_id,int tx_flags) | |||
1371 | static int | 1377 | static int |
1372 | ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 1378 | ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
1373 | { | 1379 | { |
1374 | struct ixgb_adapter *adapter = netdev->priv; | 1380 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1375 | unsigned int first; | 1381 | unsigned int first; |
1376 | unsigned int tx_flags = 0; | 1382 | unsigned int tx_flags = 0; |
1377 | unsigned long flags; | 1383 | unsigned long flags; |
@@ -1425,7 +1431,7 @@ ixgb_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
1425 | static void | 1431 | static void |
1426 | ixgb_tx_timeout(struct net_device *netdev) | 1432 | ixgb_tx_timeout(struct net_device *netdev) |
1427 | { | 1433 | { |
1428 | struct ixgb_adapter *adapter = netdev->priv; | 1434 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1429 | 1435 | ||
1430 | /* Do the reset outside of interrupt context */ | 1436 | /* Do the reset outside of interrupt context */ |
1431 | schedule_work(&adapter->tx_timeout_task); | 1437 | schedule_work(&adapter->tx_timeout_task); |
@@ -1434,7 +1440,7 @@ ixgb_tx_timeout(struct net_device *netdev) | |||
1434 | static void | 1440 | static void |
1435 | ixgb_tx_timeout_task(struct net_device *netdev) | 1441 | ixgb_tx_timeout_task(struct net_device *netdev) |
1436 | { | 1442 | { |
1437 | struct ixgb_adapter *adapter = netdev->priv; | 1443 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1438 | 1444 | ||
1439 | ixgb_down(adapter, TRUE); | 1445 | ixgb_down(adapter, TRUE); |
1440 | ixgb_up(adapter); | 1446 | ixgb_up(adapter); |
@@ -1451,7 +1457,7 @@ ixgb_tx_timeout_task(struct net_device *netdev) | |||
1451 | static struct net_device_stats * | 1457 | static struct net_device_stats * |
1452 | ixgb_get_stats(struct net_device *netdev) | 1458 | ixgb_get_stats(struct net_device *netdev) |
1453 | { | 1459 | { |
1454 | struct ixgb_adapter *adapter = netdev->priv; | 1460 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1455 | 1461 | ||
1456 | return &adapter->net_stats; | 1462 | return &adapter->net_stats; |
1457 | } | 1463 | } |
@@ -1467,7 +1473,7 @@ ixgb_get_stats(struct net_device *netdev) | |||
1467 | static int | 1473 | static int |
1468 | ixgb_change_mtu(struct net_device *netdev, int new_mtu) | 1474 | ixgb_change_mtu(struct net_device *netdev, int new_mtu) |
1469 | { | 1475 | { |
1470 | struct ixgb_adapter *adapter = netdev->priv; | 1476 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1471 | int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; | 1477 | int max_frame = new_mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; |
1472 | int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; | 1478 | int old_max_frame = netdev->mtu + ENET_HEADER_SIZE + ENET_FCS_LENGTH; |
1473 | 1479 | ||
@@ -1522,7 +1528,8 @@ ixgb_update_stats(struct ixgb_adapter *adapter) | |||
1522 | 1528 | ||
1523 | multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); | 1529 | multi |= ((u64)IXGB_READ_REG(&adapter->hw, MPRCH) << 32); |
1524 | /* fix up multicast stats by removing broadcasts */ | 1530 | /* fix up multicast stats by removing broadcasts */ |
1525 | multi -= bcast; | 1531 | if(multi >= bcast) |
1532 | multi -= bcast; | ||
1526 | 1533 | ||
1527 | adapter->stats.mprcl += (multi & 0xFFFFFFFF); | 1534 | adapter->stats.mprcl += (multi & 0xFFFFFFFF); |
1528 | adapter->stats.mprch += (multi >> 32); | 1535 | adapter->stats.mprch += (multi >> 32); |
@@ -1641,7 +1648,7 @@ static irqreturn_t | |||
1641 | ixgb_intr(int irq, void *data, struct pt_regs *regs) | 1648 | ixgb_intr(int irq, void *data, struct pt_regs *regs) |
1642 | { | 1649 | { |
1643 | struct net_device *netdev = data; | 1650 | struct net_device *netdev = data; |
1644 | struct ixgb_adapter *adapter = netdev->priv; | 1651 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1645 | struct ixgb_hw *hw = &adapter->hw; | 1652 | struct ixgb_hw *hw = &adapter->hw; |
1646 | uint32_t icr = IXGB_READ_REG(hw, ICR); | 1653 | uint32_t icr = IXGB_READ_REG(hw, ICR); |
1647 | #ifndef CONFIG_IXGB_NAPI | 1654 | #ifndef CONFIG_IXGB_NAPI |
@@ -1688,7 +1695,7 @@ ixgb_intr(int irq, void *data, struct pt_regs *regs) | |||
1688 | static int | 1695 | static int |
1689 | ixgb_clean(struct net_device *netdev, int *budget) | 1696 | ixgb_clean(struct net_device *netdev, int *budget) |
1690 | { | 1697 | { |
1691 | struct ixgb_adapter *adapter = netdev->priv; | 1698 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
1692 | int work_to_do = min(*budget, netdev->quota); | 1699 | int work_to_do = min(*budget, netdev->quota); |
1693 | int tx_cleaned; | 1700 | int tx_cleaned; |
1694 | int work_done = 0; | 1701 | int work_done = 0; |
@@ -2017,7 +2024,7 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter) | |||
2017 | static void | 2024 | static void |
2018 | ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | 2025 | ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) |
2019 | { | 2026 | { |
2020 | struct ixgb_adapter *adapter = netdev->priv; | 2027 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2021 | uint32_t ctrl, rctl; | 2028 | uint32_t ctrl, rctl; |
2022 | 2029 | ||
2023 | ixgb_irq_disable(adapter); | 2030 | ixgb_irq_disable(adapter); |
@@ -2055,7 +2062,7 @@ ixgb_vlan_rx_register(struct net_device *netdev, struct vlan_group *grp) | |||
2055 | static void | 2062 | static void |
2056 | ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) | 2063 | ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) |
2057 | { | 2064 | { |
2058 | struct ixgb_adapter *adapter = netdev->priv; | 2065 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2059 | uint32_t vfta, index; | 2066 | uint32_t vfta, index; |
2060 | 2067 | ||
2061 | /* add VID to filter table */ | 2068 | /* add VID to filter table */ |
@@ -2069,7 +2076,7 @@ ixgb_vlan_rx_add_vid(struct net_device *netdev, uint16_t vid) | |||
2069 | static void | 2076 | static void |
2070 | ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) | 2077 | ixgb_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) |
2071 | { | 2078 | { |
2072 | struct ixgb_adapter *adapter = netdev->priv; | 2079 | struct ixgb_adapter *adapter = netdev_priv(netdev); |
2073 | uint32_t vfta, index; | 2080 | uint32_t vfta, index; |
2074 | 2081 | ||
2075 | ixgb_irq_disable(adapter); | 2082 | ixgb_irq_disable(adapter); |
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c index 7fec613e1675..8423cb6875f0 100644 --- a/drivers/net/jazzsonic.c +++ b/drivers/net/jazzsonic.c | |||
@@ -1,5 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * sonic.c | 2 | * jazzsonic.c |
3 | * | ||
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, and (from the mac68k project) introduced | ||
7 | * dhd's support for 16-bit cards. | ||
3 | * | 8 | * |
4 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
5 | * | 10 | * |
@@ -28,8 +33,8 @@ | |||
28 | #include <linux/netdevice.h> | 33 | #include <linux/netdevice.h> |
29 | #include <linux/etherdevice.h> | 34 | #include <linux/etherdevice.h> |
30 | #include <linux/skbuff.h> | 35 | #include <linux/skbuff.h> |
31 | #include <linux/bitops.h> | ||
32 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/dma-mapping.h> | ||
33 | 38 | ||
34 | #include <asm/bootinfo.h> | 39 | #include <asm/bootinfo.h> |
35 | #include <asm/system.h> | 40 | #include <asm/system.h> |
@@ -44,22 +49,20 @@ static struct platform_device *jazz_sonic_device; | |||
44 | 49 | ||
45 | #define SONIC_MEM_SIZE 0x100 | 50 | #define SONIC_MEM_SIZE 0x100 |
46 | 51 | ||
47 | #define SREGS_PAD(n) u16 n; | ||
48 | |||
49 | #include "sonic.h" | 52 | #include "sonic.h" |
50 | 53 | ||
51 | /* | 54 | /* |
52 | * Macros to access SONIC registers | 55 | * Macros to access SONIC registers |
53 | */ | 56 | */ |
54 | #define SONIC_READ(reg) (*((volatile unsigned int *)base_addr+reg)) | 57 | #define SONIC_READ(reg) (*((volatile unsigned int *)dev->base_addr+reg)) |
55 | 58 | ||
56 | #define SONIC_WRITE(reg,val) \ | 59 | #define SONIC_WRITE(reg,val) \ |
57 | do { \ | 60 | do { \ |
58 | *((volatile unsigned int *)base_addr+(reg)) = (val); \ | 61 | *((volatile unsigned int *)dev->base_addr+(reg)) = (val); \ |
59 | } while (0) | 62 | } while (0) |
60 | 63 | ||
61 | 64 | ||
62 | /* use 0 for production, 1 for verification, >2 for debug */ | 65 | /* use 0 for production, 1 for verification, >1 for debug */ |
63 | #ifdef SONIC_DEBUG | 66 | #ifdef SONIC_DEBUG |
64 | static unsigned int sonic_debug = SONIC_DEBUG; | 67 | static unsigned int sonic_debug = SONIC_DEBUG; |
65 | #else | 68 | #else |
@@ -85,18 +88,18 @@ static unsigned short known_revisions[] = | |||
85 | 0xffff /* end of list */ | 88 | 0xffff /* end of list */ |
86 | }; | 89 | }; |
87 | 90 | ||
88 | static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | 91 | static int __init sonic_probe1(struct net_device *dev) |
89 | unsigned int irq) | ||
90 | { | 92 | { |
91 | static unsigned version_printed; | 93 | static unsigned version_printed; |
92 | unsigned int silicon_revision; | 94 | unsigned int silicon_revision; |
93 | unsigned int val; | 95 | unsigned int val; |
94 | struct sonic_local *lp; | 96 | struct sonic_local *lp = netdev_priv(dev); |
95 | int err = -ENODEV; | 97 | int err = -ENODEV; |
96 | int i; | 98 | int i; |
97 | 99 | ||
98 | if (!request_mem_region(base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) | 100 | if (!request_mem_region(dev->base_addr, SONIC_MEM_SIZE, jazz_sonic_string)) |
99 | return -EBUSY; | 101 | return -EBUSY; |
102 | |||
100 | /* | 103 | /* |
101 | * get the Silicon Revision ID. If this is one of the known | 104 | * get the Silicon Revision ID. If this is one of the known |
102 | * one assume that we found a SONIC ethernet controller at | 105 | * one assume that we found a SONIC ethernet controller at |
@@ -120,11 +123,7 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
120 | if (sonic_debug && version_printed++ == 0) | 123 | if (sonic_debug && version_printed++ == 0) |
121 | printk(version); | 124 | printk(version); |
122 | 125 | ||
123 | printk("%s: Sonic ethernet found at 0x%08lx, ", dev->name, base_addr); | 126 | printk(KERN_INFO "%s: Sonic ethernet found at 0x%08lx, ", lp->device->bus_id, dev->base_addr); |
124 | |||
125 | /* Fill in the 'dev' fields. */ | ||
126 | dev->base_addr = base_addr; | ||
127 | dev->irq = irq; | ||
128 | 127 | ||
129 | /* | 128 | /* |
130 | * Put the sonic into software reset, then | 129 | * Put the sonic into software reset, then |
@@ -138,84 +137,44 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
138 | dev->dev_addr[i*2+1] = val >> 8; | 137 | dev->dev_addr[i*2+1] = val >> 8; |
139 | } | 138 | } |
140 | 139 | ||
141 | printk("HW Address "); | ||
142 | for (i = 0; i < 6; i++) { | ||
143 | printk("%2.2x", dev->dev_addr[i]); | ||
144 | if (i<5) | ||
145 | printk(":"); | ||
146 | } | ||
147 | |||
148 | printk(" IRQ %d\n", irq); | ||
149 | |||
150 | err = -ENOMEM; | 140 | err = -ENOMEM; |
151 | 141 | ||
152 | /* Initialize the device structure. */ | 142 | /* Initialize the device structure. */ |
153 | if (dev->priv == NULL) { | ||
154 | /* | ||
155 | * the memory be located in the same 64kb segment | ||
156 | */ | ||
157 | lp = NULL; | ||
158 | i = 0; | ||
159 | do { | ||
160 | lp = kmalloc(sizeof(*lp), GFP_KERNEL); | ||
161 | if ((unsigned long) lp >> 16 | ||
162 | != ((unsigned long)lp + sizeof(*lp) ) >> 16) { | ||
163 | /* FIXME, free the memory later */ | ||
164 | kfree(lp); | ||
165 | lp = NULL; | ||
166 | } | ||
167 | } while (lp == NULL && i++ < 20); | ||
168 | |||
169 | if (lp == NULL) { | ||
170 | printk("%s: couldn't allocate memory for descriptors\n", | ||
171 | dev->name); | ||
172 | goto out; | ||
173 | } | ||
174 | 143 | ||
175 | memset(lp, 0, sizeof(struct sonic_local)); | 144 | lp->dma_bitmode = SONIC_BITMODE32; |
176 | |||
177 | /* get the virtual dma address */ | ||
178 | lp->cda_laddr = vdma_alloc(CPHYSADDR(lp),sizeof(*lp)); | ||
179 | if (lp->cda_laddr == ~0UL) { | ||
180 | printk("%s: couldn't get DMA page entry for " | ||
181 | "descriptors\n", dev->name); | ||
182 | goto out1; | ||
183 | } | ||
184 | |||
185 | lp->tda_laddr = lp->cda_laddr + sizeof (lp->cda); | ||
186 | lp->rra_laddr = lp->tda_laddr + sizeof (lp->tda); | ||
187 | lp->rda_laddr = lp->rra_laddr + sizeof (lp->rra); | ||
188 | |||
189 | /* allocate receive buffer area */ | ||
190 | /* FIXME, maybe we should use skbs */ | ||
191 | lp->rba = kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL); | ||
192 | if (!lp->rba) { | ||
193 | printk("%s: couldn't allocate receive buffers\n", | ||
194 | dev->name); | ||
195 | goto out2; | ||
196 | } | ||
197 | 145 | ||
198 | /* get virtual dma address */ | 146 | /* Allocate the entire chunk of memory for the descriptors. |
199 | lp->rba_laddr = vdma_alloc(CPHYSADDR(lp->rba), | 147 | Note that this cannot cross a 64K boundary. */ |
200 | SONIC_NUM_RRS * SONIC_RBSIZE); | 148 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
201 | if (lp->rba_laddr == ~0UL) { | 149 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
202 | printk("%s: couldn't get DMA page entry for receive " | 150 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
203 | "buffers\n",dev->name); | 151 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); |
204 | goto out3; | 152 | goto out; |
205 | } | ||
206 | |||
207 | /* now convert pointer to KSEG1 pointer */ | ||
208 | lp->rba = (char *)KSEG1ADDR(lp->rba); | ||
209 | flush_cache_all(); | ||
210 | dev->priv = (struct sonic_local *)KSEG1ADDR(lp); | ||
211 | } | 153 | } |
212 | 154 | ||
213 | lp = (struct sonic_local *)dev->priv; | 155 | /* Now set up the pointers to point to the appropriate places */ |
156 | lp->cda = lp->descriptors; | ||
157 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA | ||
158 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
159 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
160 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
161 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
162 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
163 | |||
164 | lp->cda_laddr = lp->descriptors_laddr; | ||
165 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | ||
166 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
167 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | ||
168 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
169 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | ||
170 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
171 | |||
214 | dev->open = sonic_open; | 172 | dev->open = sonic_open; |
215 | dev->stop = sonic_close; | 173 | dev->stop = sonic_close; |
216 | dev->hard_start_xmit = sonic_send_packet; | 174 | dev->hard_start_xmit = sonic_send_packet; |
217 | dev->get_stats = sonic_get_stats; | 175 | dev->get_stats = sonic_get_stats; |
218 | dev->set_multicast_list = &sonic_multicast_list; | 176 | dev->set_multicast_list = &sonic_multicast_list; |
177 | dev->tx_timeout = sonic_tx_timeout; | ||
219 | dev->watchdog_timeo = TX_TIMEOUT; | 178 | dev->watchdog_timeo = TX_TIMEOUT; |
220 | 179 | ||
221 | /* | 180 | /* |
@@ -226,14 +185,8 @@ static int __init sonic_probe1(struct net_device *dev, unsigned long base_addr, | |||
226 | SONIC_WRITE(SONIC_MPT,0xffff); | 185 | SONIC_WRITE(SONIC_MPT,0xffff); |
227 | 186 | ||
228 | return 0; | 187 | return 0; |
229 | out3: | ||
230 | kfree(lp->rba); | ||
231 | out2: | ||
232 | vdma_free(lp->cda_laddr); | ||
233 | out1: | ||
234 | kfree(lp); | ||
235 | out: | 188 | out: |
236 | release_region(base_addr, SONIC_MEM_SIZE); | 189 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
237 | return err; | 190 | return err; |
238 | } | 191 | } |
239 | 192 | ||
@@ -245,7 +198,6 @@ static int __init jazz_sonic_probe(struct device *device) | |||
245 | { | 198 | { |
246 | struct net_device *dev; | 199 | struct net_device *dev; |
247 | struct sonic_local *lp; | 200 | struct sonic_local *lp; |
248 | unsigned long base_addr; | ||
249 | int err = 0; | 201 | int err = 0; |
250 | int i; | 202 | int i; |
251 | 203 | ||
@@ -255,21 +207,26 @@ static int __init jazz_sonic_probe(struct device *device) | |||
255 | if (mips_machgroup != MACH_GROUP_JAZZ) | 207 | if (mips_machgroup != MACH_GROUP_JAZZ) |
256 | return -ENODEV; | 208 | return -ENODEV; |
257 | 209 | ||
258 | dev = alloc_etherdev(0); | 210 | dev = alloc_etherdev(sizeof(struct sonic_local)); |
259 | if (!dev) | 211 | if (!dev) |
260 | return -ENOMEM; | 212 | return -ENOMEM; |
261 | 213 | ||
214 | lp = netdev_priv(dev); | ||
215 | lp->device = device; | ||
216 | SET_NETDEV_DEV(dev, device); | ||
217 | SET_MODULE_OWNER(dev); | ||
218 | |||
262 | netdev_boot_setup_check(dev); | 219 | netdev_boot_setup_check(dev); |
263 | base_addr = dev->base_addr; | ||
264 | 220 | ||
265 | if (base_addr >= KSEG0) { /* Check a single specified location. */ | 221 | if (dev->base_addr >= KSEG0) { /* Check a single specified location. */ |
266 | err = sonic_probe1(dev, base_addr, dev->irq); | 222 | err = sonic_probe1(dev); |
267 | } else if (base_addr != 0) { /* Don't probe at all. */ | 223 | } else if (dev->base_addr != 0) { /* Don't probe at all. */ |
268 | err = -ENXIO; | 224 | err = -ENXIO; |
269 | } else { | 225 | } else { |
270 | for (i = 0; sonic_portlist[i].port; i++) { | 226 | for (i = 0; sonic_portlist[i].port; i++) { |
271 | int io = sonic_portlist[i].port; | 227 | dev->base_addr = sonic_portlist[i].port; |
272 | if (sonic_probe1(dev, io, sonic_portlist[i].irq) == 0) | 228 | dev->irq = sonic_portlist[i].irq; |
229 | if (sonic_probe1(dev) == 0) | ||
273 | break; | 230 | break; |
274 | } | 231 | } |
275 | if (!sonic_portlist[i].port) | 232 | if (!sonic_portlist[i].port) |
@@ -281,14 +238,17 @@ static int __init jazz_sonic_probe(struct device *device) | |||
281 | if (err) | 238 | if (err) |
282 | goto out1; | 239 | goto out1; |
283 | 240 | ||
241 | printk("%s: MAC ", dev->name); | ||
242 | for (i = 0; i < 6; i++) { | ||
243 | printk("%2.2x", dev->dev_addr[i]); | ||
244 | if (i < 5) | ||
245 | printk(":"); | ||
246 | } | ||
247 | printk(" IRQ %d\n", dev->irq); | ||
248 | |||
284 | return 0; | 249 | return 0; |
285 | 250 | ||
286 | out1: | 251 | out1: |
287 | lp = dev->priv; | ||
288 | vdma_free(lp->rba_laddr); | ||
289 | kfree(lp->rba); | ||
290 | vdma_free(lp->cda_laddr); | ||
291 | kfree(lp); | ||
292 | release_region(dev->base_addr, SONIC_MEM_SIZE); | 252 | release_region(dev->base_addr, SONIC_MEM_SIZE); |
293 | out: | 253 | out: |
294 | free_netdev(dev); | 254 | free_netdev(dev); |
@@ -296,21 +256,22 @@ out: | |||
296 | return err; | 256 | return err; |
297 | } | 257 | } |
298 | 258 | ||
299 | /* | 259 | MODULE_DESCRIPTION("Jazz SONIC ethernet driver"); |
300 | * SONIC uses a normal IRQ | 260 | module_param(sonic_debug, int, 0); |
301 | */ | 261 | MODULE_PARM_DESC(sonic_debug, "jazzsonic debug level (1-4)"); |
302 | #define sonic_request_irq request_irq | ||
303 | #define sonic_free_irq free_irq | ||
304 | 262 | ||
305 | #define sonic_chiptomem(x) KSEG1ADDR(vdma_log2phys(x)) | 263 | #define SONIC_IRQ_FLAG SA_INTERRUPT |
306 | 264 | ||
307 | #include "sonic.c" | 265 | #include "sonic.c" |
308 | 266 | ||
309 | static int __devexit jazz_sonic_device_remove (struct device *device) | 267 | static int __devexit jazz_sonic_device_remove (struct device *device) |
310 | { | 268 | { |
311 | struct net_device *dev = device->driver_data; | 269 | struct net_device *dev = device->driver_data; |
270 | struct sonic_local* lp = netdev_priv(dev); | ||
312 | 271 | ||
313 | unregister_netdev (dev); | 272 | unregister_netdev (dev); |
273 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), | ||
274 | lp->descriptors, lp->descriptors_laddr); | ||
314 | release_region (dev->base_addr, SONIC_MEM_SIZE); | 275 | release_region (dev->base_addr, SONIC_MEM_SIZE); |
315 | free_netdev (dev); | 276 | free_netdev (dev); |
316 | 277 | ||
@@ -323,7 +284,7 @@ static struct device_driver jazz_sonic_driver = { | |||
323 | .probe = jazz_sonic_probe, | 284 | .probe = jazz_sonic_probe, |
324 | .remove = __devexit_p(jazz_sonic_device_remove), | 285 | .remove = __devexit_p(jazz_sonic_device_remove), |
325 | }; | 286 | }; |
326 | 287 | ||
327 | static void jazz_sonic_platform_release (struct device *device) | 288 | static void jazz_sonic_platform_release (struct device *device) |
328 | { | 289 | { |
329 | struct platform_device *pldev; | 290 | struct platform_device *pldev; |
@@ -336,10 +297,11 @@ static void jazz_sonic_platform_release (struct device *device) | |||
336 | static int __init jazz_sonic_init_module(void) | 297 | static int __init jazz_sonic_init_module(void) |
337 | { | 298 | { |
338 | struct platform_device *pldev; | 299 | struct platform_device *pldev; |
300 | int err; | ||
339 | 301 | ||
340 | if (driver_register(&jazz_sonic_driver)) { | 302 | if ((err = driver_register(&jazz_sonic_driver))) { |
341 | printk(KERN_ERR "Driver registration failed\n"); | 303 | printk(KERN_ERR "Driver registration failed\n"); |
342 | return -ENOMEM; | 304 | return err; |
343 | } | 305 | } |
344 | 306 | ||
345 | jazz_sonic_device = NULL; | 307 | jazz_sonic_device = NULL; |
diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index b33111e21313..690a1aae0b34 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c | |||
@@ -68,6 +68,7 @@ static DEFINE_PER_CPU(struct net_device_stats, loopback_stats); | |||
68 | * of largesending device modulo TCP checksum, which is ignored for loopback. | 68 | * of largesending device modulo TCP checksum, which is ignored for loopback. |
69 | */ | 69 | */ |
70 | 70 | ||
71 | #ifdef LOOPBACK_TSO | ||
71 | static void emulate_large_send_offload(struct sk_buff *skb) | 72 | static void emulate_large_send_offload(struct sk_buff *skb) |
72 | { | 73 | { |
73 | struct iphdr *iph = skb->nh.iph; | 74 | struct iphdr *iph = skb->nh.iph; |
@@ -119,6 +120,7 @@ static void emulate_large_send_offload(struct sk_buff *skb) | |||
119 | 120 | ||
120 | dev_kfree_skb(skb); | 121 | dev_kfree_skb(skb); |
121 | } | 122 | } |
123 | #endif /* LOOPBACK_TSO */ | ||
122 | 124 | ||
123 | /* | 125 | /* |
124 | * The higher levels take care of making this non-reentrant (it's | 126 | * The higher levels take care of making this non-reentrant (it's |
@@ -130,12 +132,13 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
130 | 132 | ||
131 | skb_orphan(skb); | 133 | skb_orphan(skb); |
132 | 134 | ||
133 | skb->protocol=eth_type_trans(skb,dev); | 135 | skb->protocol = eth_type_trans(skb,dev); |
134 | skb->dev=dev; | 136 | skb->dev = dev; |
135 | #ifndef LOOPBACK_MUST_CHECKSUM | 137 | #ifndef LOOPBACK_MUST_CHECKSUM |
136 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 138 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
137 | #endif | 139 | #endif |
138 | 140 | ||
141 | #ifdef LOOPBACK_TSO | ||
139 | if (skb_shinfo(skb)->tso_size) { | 142 | if (skb_shinfo(skb)->tso_size) { |
140 | BUG_ON(skb->protocol != htons(ETH_P_IP)); | 143 | BUG_ON(skb->protocol != htons(ETH_P_IP)); |
141 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); | 144 | BUG_ON(skb->nh.iph->protocol != IPPROTO_TCP); |
@@ -143,14 +146,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) | |||
143 | emulate_large_send_offload(skb); | 146 | emulate_large_send_offload(skb); |
144 | return 0; | 147 | return 0; |
145 | } | 148 | } |
146 | 149 | #endif | |
147 | dev->last_rx = jiffies; | 150 | dev->last_rx = jiffies; |
148 | 151 | ||
149 | lb_stats = &per_cpu(loopback_stats, get_cpu()); | 152 | lb_stats = &per_cpu(loopback_stats, get_cpu()); |
150 | lb_stats->rx_bytes += skb->len; | 153 | lb_stats->rx_bytes += skb->len; |
151 | lb_stats->tx_bytes += skb->len; | 154 | lb_stats->tx_bytes = lb_stats->rx_bytes; |
152 | lb_stats->rx_packets++; | 155 | lb_stats->rx_packets++; |
153 | lb_stats->tx_packets++; | 156 | lb_stats->tx_packets = lb_stats->rx_packets; |
154 | put_cpu(); | 157 | put_cpu(); |
155 | 158 | ||
156 | netif_rx(skb); | 159 | netif_rx(skb); |
@@ -208,13 +211,16 @@ struct net_device loopback_dev = { | |||
208 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ | 211 | .type = ARPHRD_LOOPBACK, /* 0x0001*/ |
209 | .rebuild_header = eth_rebuild_header, | 212 | .rebuild_header = eth_rebuild_header, |
210 | .flags = IFF_LOOPBACK, | 213 | .flags = IFF_LOOPBACK, |
211 | .features = NETIF_F_SG|NETIF_F_FRAGLIST | 214 | .features = NETIF_F_SG | NETIF_F_FRAGLIST |
212 | |NETIF_F_NO_CSUM|NETIF_F_HIGHDMA | 215 | #ifdef LOOPBACK_TSO |
213 | |NETIF_F_LLTX, | 216 | | NETIF_F_TSO |
217 | #endif | ||
218 | | NETIF_F_NO_CSUM | NETIF_F_HIGHDMA | ||
219 | | NETIF_F_LLTX, | ||
214 | .ethtool_ops = &loopback_ethtool_ops, | 220 | .ethtool_ops = &loopback_ethtool_ops, |
215 | }; | 221 | }; |
216 | 222 | ||
217 | /* Setup and register the of the LOOPBACK device. */ | 223 | /* Setup and register the loopback device. */ |
218 | int __init loopback_init(void) | 224 | int __init loopback_init(void) |
219 | { | 225 | { |
220 | struct net_device_stats *stats; | 226 | struct net_device_stats *stats; |
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c index be28c65de729..405e18365ede 100644 --- a/drivers/net/macsonic.c +++ b/drivers/net/macsonic.c | |||
@@ -1,6 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * macsonic.c | 2 | * macsonic.c |
3 | * | 3 | * |
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, converted to unified driver model, made it work as | ||
7 | * a module again, and from the mac68k project, introduced more 32-bit cards | ||
8 | * and dhd's support for 16-bit cards. | ||
9 | * | ||
4 | * (C) 1998 Alan Cox | 10 | * (C) 1998 Alan Cox |
5 | * | 11 | * |
6 | * Debugging Andreas Ehliar, Michael Schmitz | 12 | * Debugging Andreas Ehliar, Michael Schmitz |
@@ -26,8 +32,8 @@ | |||
26 | */ | 32 | */ |
27 | 33 | ||
28 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
35 | #include <linux/module.h> | ||
29 | #include <linux/types.h> | 36 | #include <linux/types.h> |
30 | #include <linux/ctype.h> | ||
31 | #include <linux/fcntl.h> | 37 | #include <linux/fcntl.h> |
32 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
33 | #include <linux/init.h> | 39 | #include <linux/init.h> |
@@ -41,8 +47,8 @@ | |||
41 | #include <linux/netdevice.h> | 47 | #include <linux/netdevice.h> |
42 | #include <linux/etherdevice.h> | 48 | #include <linux/etherdevice.h> |
43 | #include <linux/skbuff.h> | 49 | #include <linux/skbuff.h> |
44 | #include <linux/module.h> | 50 | #include <linux/device.h> |
45 | #include <linux/bitops.h> | 51 | #include <linux/dma-mapping.h> |
46 | 52 | ||
47 | #include <asm/bootinfo.h> | 53 | #include <asm/bootinfo.h> |
48 | #include <asm/system.h> | 54 | #include <asm/system.h> |
@@ -54,25 +60,28 @@ | |||
54 | #include <asm/macints.h> | 60 | #include <asm/macints.h> |
55 | #include <asm/mac_via.h> | 61 | #include <asm/mac_via.h> |
56 | 62 | ||
57 | #define SREGS_PAD(n) u16 n; | 63 | static char mac_sonic_string[] = "macsonic"; |
64 | static struct platform_device *mac_sonic_device; | ||
58 | 65 | ||
59 | #include "sonic.h" | 66 | #include "sonic.h" |
60 | 67 | ||
61 | #define SONIC_READ(reg) \ | 68 | /* These should basically be bus-size and endian independent (since |
62 | nubus_readl(base_addr+(reg)) | 69 | the SONIC is at least smart enough that it uses the same endianness |
63 | #define SONIC_WRITE(reg,val) \ | 70 | as the host, unlike certain less enlightened Macintosh NICs) */ |
64 | nubus_writel((val), base_addr+(reg)) | 71 | #define SONIC_READ(reg) (nubus_readw(dev->base_addr + (reg * 4) \ |
65 | #define sonic_read(dev, reg) \ | 72 | + lp->reg_offset)) |
66 | nubus_readl((dev)->base_addr+(reg)) | 73 | #define SONIC_WRITE(reg,val) (nubus_writew(val, dev->base_addr + (reg * 4) \ |
67 | #define sonic_write(dev, reg, val) \ | 74 | + lp->reg_offset)) |
68 | nubus_writel((val), (dev)->base_addr+(reg)) | 75 | |
69 | 76 | /* use 0 for production, 1 for verification, >1 for debug */ | |
77 | #ifdef SONIC_DEBUG | ||
78 | static unsigned int sonic_debug = SONIC_DEBUG; | ||
79 | #else | ||
80 | static unsigned int sonic_debug = 1; | ||
81 | #endif | ||
70 | 82 | ||
71 | static int sonic_debug; | ||
72 | static int sonic_version_printed; | 83 | static int sonic_version_printed; |
73 | 84 | ||
74 | static int reg_offset; | ||
75 | |||
76 | extern int mac_onboard_sonic_probe(struct net_device* dev); | 85 | extern int mac_onboard_sonic_probe(struct net_device* dev); |
77 | extern int mac_nubus_sonic_probe(struct net_device* dev); | 86 | extern int mac_nubus_sonic_probe(struct net_device* dev); |
78 | 87 | ||
@@ -108,40 +117,6 @@ enum macsonic_type { | |||
108 | 117 | ||
109 | #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr) | 118 | #define SONIC_READ_PROM(addr) nubus_readb(prom_addr+addr) |
110 | 119 | ||
111 | struct net_device * __init macsonic_probe(int unit) | ||
112 | { | ||
113 | struct net_device *dev = alloc_etherdev(0); | ||
114 | int err; | ||
115 | |||
116 | if (!dev) | ||
117 | return ERR_PTR(-ENOMEM); | ||
118 | |||
119 | if (unit >= 0) | ||
120 | sprintf(dev->name, "eth%d", unit); | ||
121 | |||
122 | SET_MODULE_OWNER(dev); | ||
123 | |||
124 | /* This will catch fatal stuff like -ENOMEM as well as success */ | ||
125 | err = mac_onboard_sonic_probe(dev); | ||
126 | if (err == 0) | ||
127 | goto found; | ||
128 | if (err != -ENODEV) | ||
129 | goto out; | ||
130 | err = mac_nubus_sonic_probe(dev); | ||
131 | if (err) | ||
132 | goto out; | ||
133 | found: | ||
134 | err = register_netdev(dev); | ||
135 | if (err) | ||
136 | goto out1; | ||
137 | return dev; | ||
138 | out1: | ||
139 | kfree(dev->priv); | ||
140 | out: | ||
141 | free_netdev(dev); | ||
142 | return ERR_PTR(err); | ||
143 | } | ||
144 | |||
145 | /* | 120 | /* |
146 | * For reversing the PROM address | 121 | * For reversing the PROM address |
147 | */ | 122 | */ |
@@ -160,103 +135,55 @@ static inline void bit_reverse_addr(unsigned char addr[6]) | |||
160 | 135 | ||
161 | int __init macsonic_init(struct net_device* dev) | 136 | int __init macsonic_init(struct net_device* dev) |
162 | { | 137 | { |
163 | struct sonic_local* lp = NULL; | 138 | struct sonic_local* lp = netdev_priv(dev); |
164 | int i; | ||
165 | 139 | ||
166 | /* Allocate the entire chunk of memory for the descriptors. | 140 | /* Allocate the entire chunk of memory for the descriptors. |
167 | Note that this cannot cross a 64K boundary. */ | 141 | Note that this cannot cross a 64K boundary. */ |
168 | for (i = 0; i < 20; i++) { | 142 | if ((lp->descriptors = dma_alloc_coherent(lp->device, |
169 | unsigned long desc_base, desc_top; | 143 | SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
170 | if((lp = kmalloc(sizeof(struct sonic_local), GFP_KERNEL | GFP_DMA)) == NULL) { | 144 | &lp->descriptors_laddr, GFP_KERNEL)) == NULL) { |
171 | printk(KERN_ERR "%s: couldn't allocate descriptor buffers\n", dev->name); | 145 | printk(KERN_ERR "%s: couldn't alloc DMA memory for descriptors.\n", lp->device->bus_id); |
172 | return -ENOMEM; | ||
173 | } | ||
174 | |||
175 | desc_base = (unsigned long) lp; | ||
176 | desc_top = desc_base + sizeof(struct sonic_local); | ||
177 | if ((desc_top & 0xffff) >= (desc_base & 0xffff)) | ||
178 | break; | ||
179 | /* Hmm. try again (FIXME: does this actually work?) */ | ||
180 | kfree(lp); | ||
181 | printk(KERN_DEBUG | ||
182 | "%s: didn't get continguous chunk [%08lx - %08lx], trying again\n", | ||
183 | dev->name, desc_base, desc_top); | ||
184 | } | ||
185 | |||
186 | if (lp == NULL) { | ||
187 | printk(KERN_ERR "%s: tried 20 times to allocate descriptor buffers, giving up.\n", | ||
188 | dev->name); | ||
189 | return -ENOMEM; | 146 | return -ENOMEM; |
190 | } | 147 | } |
191 | |||
192 | dev->priv = lp; | ||
193 | |||
194 | #if 0 | ||
195 | /* this code is only here as a curiousity... mainly, where the | ||
196 | fuck did SONIC_BUS_SCALE come from, and what was it supposed | ||
197 | to do? the normal allocation works great for 32 bit stuffs.. */ | ||
198 | 148 | ||
199 | /* Now set up the pointers to point to the appropriate places */ | 149 | /* Now set up the pointers to point to the appropriate places */ |
200 | lp->cda = lp->sonic_desc; | 150 | lp->cda = lp->descriptors; |
201 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA * SONIC_BUS_SCALE(lp->dma_bitmode)); | 151 | lp->tda = lp->cda + (SIZEOF_SONIC_CDA |
152 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | ||
202 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | 153 | lp->rda = lp->tda + (SIZEOF_SONIC_TD * SONIC_NUM_TDS |
203 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 154 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
204 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS | 155 | lp->rra = lp->rda + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
205 | * SONIC_BUS_SCALE(lp->dma_bitmode)); | 156 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
206 | 157 | ||
207 | #endif | 158 | lp->cda_laddr = lp->descriptors_laddr; |
208 | 159 | lp->tda_laddr = lp->cda_laddr + (SIZEOF_SONIC_CDA | |
209 | memset(lp, 0, sizeof(struct sonic_local)); | 160 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
210 | 161 | lp->rda_laddr = lp->tda_laddr + (SIZEOF_SONIC_TD * SONIC_NUM_TDS | |
211 | lp->cda_laddr = (unsigned int)&(lp->cda); | 162 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
212 | lp->tda_laddr = (unsigned int)lp->tda; | 163 | lp->rra_laddr = lp->rda_laddr + (SIZEOF_SONIC_RD * SONIC_NUM_RDS |
213 | lp->rra_laddr = (unsigned int)lp->rra; | 164 | * SONIC_BUS_SCALE(lp->dma_bitmode)); |
214 | lp->rda_laddr = (unsigned int)lp->rda; | ||
215 | |||
216 | /* FIXME, maybe we should use skbs */ | ||
217 | if ((lp->rba = (char *) | ||
218 | kmalloc(SONIC_NUM_RRS * SONIC_RBSIZE, GFP_KERNEL | GFP_DMA)) == NULL) { | ||
219 | printk(KERN_ERR "%s: couldn't allocate receive buffers\n", dev->name); | ||
220 | dev->priv = NULL; | ||
221 | kfree(lp); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | |||
225 | lp->rba_laddr = (unsigned int)lp->rba; | ||
226 | |||
227 | { | ||
228 | int rs, ds; | ||
229 | |||
230 | /* almost always 12*4096, but let's not take chances */ | ||
231 | rs = ((SONIC_NUM_RRS * SONIC_RBSIZE + 4095) / 4096) * 4096; | ||
232 | /* almost always under a page, but let's not take chances */ | ||
233 | ds = ((sizeof(struct sonic_local) + 4095) / 4096) * 4096; | ||
234 | kernel_set_cachemode(lp->rba, rs, IOMAP_NOCACHE_SER); | ||
235 | kernel_set_cachemode(lp, ds, IOMAP_NOCACHE_SER); | ||
236 | } | ||
237 | |||
238 | #if 0 | ||
239 | flush_cache_all(); | ||
240 | #endif | ||
241 | 165 | ||
242 | dev->open = sonic_open; | 166 | dev->open = sonic_open; |
243 | dev->stop = sonic_close; | 167 | dev->stop = sonic_close; |
244 | dev->hard_start_xmit = sonic_send_packet; | 168 | dev->hard_start_xmit = sonic_send_packet; |
245 | dev->get_stats = sonic_get_stats; | 169 | dev->get_stats = sonic_get_stats; |
246 | dev->set_multicast_list = &sonic_multicast_list; | 170 | dev->set_multicast_list = &sonic_multicast_list; |
171 | dev->tx_timeout = sonic_tx_timeout; | ||
172 | dev->watchdog_timeo = TX_TIMEOUT; | ||
247 | 173 | ||
248 | /* | 174 | /* |
249 | * clear tally counter | 175 | * clear tally counter |
250 | */ | 176 | */ |
251 | sonic_write(dev, SONIC_CRCT, 0xffff); | 177 | SONIC_WRITE(SONIC_CRCT, 0xffff); |
252 | sonic_write(dev, SONIC_FAET, 0xffff); | 178 | SONIC_WRITE(SONIC_FAET, 0xffff); |
253 | sonic_write(dev, SONIC_MPT, 0xffff); | 179 | SONIC_WRITE(SONIC_MPT, 0xffff); |
254 | 180 | ||
255 | return 0; | 181 | return 0; |
256 | } | 182 | } |
257 | 183 | ||
258 | int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | 184 | int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) |
259 | { | 185 | { |
186 | struct sonic_local *lp = netdev_priv(dev); | ||
260 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; | 187 | const int prom_addr = ONBOARD_SONIC_PROM_BASE; |
261 | int i; | 188 | int i; |
262 | 189 | ||
@@ -270,6 +197,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
270 | why this is so. */ | 197 | why this is so. */ |
271 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 198 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
272 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 199 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
200 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
273 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 201 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
274 | bit_reverse_addr(dev->dev_addr); | 202 | bit_reverse_addr(dev->dev_addr); |
275 | else | 203 | else |
@@ -281,22 +209,23 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
281 | the card... */ | 209 | the card... */ |
282 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 210 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
283 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 211 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
212 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
284 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 213 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
285 | { | 214 | { |
286 | unsigned short val; | 215 | unsigned short val; |
287 | 216 | ||
288 | printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n"); | 217 | printk(KERN_INFO "macsonic: PROM seems to be wrong, trying CAM entry 15\n"); |
289 | 218 | ||
290 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 219 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
291 | sonic_write(dev, SONIC_CEP, 15); | 220 | SONIC_WRITE(SONIC_CEP, 15); |
292 | 221 | ||
293 | val = sonic_read(dev, SONIC_CAP2); | 222 | val = SONIC_READ(SONIC_CAP2); |
294 | dev->dev_addr[5] = val >> 8; | 223 | dev->dev_addr[5] = val >> 8; |
295 | dev->dev_addr[4] = val & 0xff; | 224 | dev->dev_addr[4] = val & 0xff; |
296 | val = sonic_read(dev, SONIC_CAP1); | 225 | val = SONIC_READ(SONIC_CAP1); |
297 | dev->dev_addr[3] = val >> 8; | 226 | dev->dev_addr[3] = val >> 8; |
298 | dev->dev_addr[2] = val & 0xff; | 227 | dev->dev_addr[2] = val & 0xff; |
299 | val = sonic_read(dev, SONIC_CAP0); | 228 | val = SONIC_READ(SONIC_CAP0); |
300 | dev->dev_addr[1] = val >> 8; | 229 | dev->dev_addr[1] = val >> 8; |
301 | dev->dev_addr[0] = val & 0xff; | 230 | dev->dev_addr[0] = val & 0xff; |
302 | 231 | ||
@@ -311,6 +240,7 @@ int __init mac_onboard_sonic_ethernet_addr(struct net_device* dev) | |||
311 | 240 | ||
312 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && | 241 | if (memcmp(dev->dev_addr, "\x08\x00\x07", 3) && |
313 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && | 242 | memcmp(dev->dev_addr, "\x00\xA0\x40", 3) && |
243 | memcmp(dev->dev_addr, "\x00\x80\x19", 3) && | ||
314 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) | 244 | memcmp(dev->dev_addr, "\x00\x05\x02", 3)) |
315 | { | 245 | { |
316 | /* | 246 | /* |
@@ -325,8 +255,9 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
325 | { | 255 | { |
326 | /* Bwahahaha */ | 256 | /* Bwahahaha */ |
327 | static int once_is_more_than_enough; | 257 | static int once_is_more_than_enough; |
328 | int i; | 258 | struct sonic_local* lp = netdev_priv(dev); |
329 | int dma_bitmode; | 259 | int sr; |
260 | int commslot = 0; | ||
330 | 261 | ||
331 | if (once_is_more_than_enough) | 262 | if (once_is_more_than_enough) |
332 | return -ENODEV; | 263 | return -ENODEV; |
@@ -335,20 +266,18 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
335 | if (!MACH_IS_MAC) | 266 | if (!MACH_IS_MAC) |
336 | return -ENODEV; | 267 | return -ENODEV; |
337 | 268 | ||
338 | printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); | ||
339 | |||
340 | if (macintosh_config->ether_type != MAC_ETHER_SONIC) | 269 | if (macintosh_config->ether_type != MAC_ETHER_SONIC) |
341 | { | ||
342 | printk("none.\n"); | ||
343 | return -ENODEV; | 270 | return -ENODEV; |
344 | } | 271 | |
345 | 272 | printk(KERN_INFO "Checking for internal Macintosh ethernet (SONIC).. "); | |
273 | |||
346 | /* Bogus probing, on the models which may or may not have | 274 | /* Bogus probing, on the models which may or may not have |
347 | Ethernet (BTW, the Ethernet *is* always at the same | 275 | Ethernet (BTW, the Ethernet *is* always at the same |
348 | address, and nothing else lives there, at least if Apple's | 276 | address, and nothing else lives there, at least if Apple's |
349 | documentation is to be believed) */ | 277 | documentation is to be believed) */ |
350 | if (macintosh_config->ident == MAC_MODEL_Q630 || | 278 | if (macintosh_config->ident == MAC_MODEL_Q630 || |
351 | macintosh_config->ident == MAC_MODEL_P588 || | 279 | macintosh_config->ident == MAC_MODEL_P588 || |
280 | macintosh_config->ident == MAC_MODEL_P575 || | ||
352 | macintosh_config->ident == MAC_MODEL_C610) { | 281 | macintosh_config->ident == MAC_MODEL_C610) { |
353 | unsigned long flags; | 282 | unsigned long flags; |
354 | int card_present; | 283 | int card_present; |
@@ -361,13 +290,13 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
361 | printk("none.\n"); | 290 | printk("none.\n"); |
362 | return -ENODEV; | 291 | return -ENODEV; |
363 | } | 292 | } |
293 | commslot = 1; | ||
364 | } | 294 | } |
365 | 295 | ||
366 | printk("yes\n"); | 296 | printk("yes\n"); |
367 | 297 | ||
368 | /* Danger! My arms are flailing wildly! You *must* set this | 298 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset |
369 | before using sonic_read() */ | 299 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ |
370 | |||
371 | dev->base_addr = ONBOARD_SONIC_REGISTERS; | 300 | dev->base_addr = ONBOARD_SONIC_REGISTERS; |
372 | if (via_alt_mapping) | 301 | if (via_alt_mapping) |
373 | dev->irq = IRQ_AUTO_3; | 302 | dev->irq = IRQ_AUTO_3; |
@@ -379,84 +308,66 @@ int __init mac_onboard_sonic_probe(struct net_device* dev) | |||
379 | sonic_version_printed = 1; | 308 | sonic_version_printed = 1; |
380 | } | 309 | } |
381 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", | 310 | printk(KERN_INFO "%s: onboard / comm-slot SONIC at 0x%08lx\n", |
382 | dev->name, dev->base_addr); | 311 | lp->device->bus_id, dev->base_addr); |
383 | |||
384 | /* Now do a song and dance routine in an attempt to determine | ||
385 | the bus width */ | ||
386 | 312 | ||
387 | /* The PowerBook's SONIC is 16 bit always. */ | 313 | /* The PowerBook's SONIC is 16 bit always. */ |
388 | if (macintosh_config->ident == MAC_MODEL_PB520) { | 314 | if (macintosh_config->ident == MAC_MODEL_PB520) { |
389 | reg_offset = 0; | 315 | lp->reg_offset = 0; |
390 | dma_bitmode = 0; | 316 | lp->dma_bitmode = SONIC_BITMODE16; |
391 | } else if (macintosh_config->ident == MAC_MODEL_C610) { | 317 | sr = SONIC_READ(SONIC_SR); |
392 | reg_offset = 0; | 318 | } else if (commslot) { |
393 | dma_bitmode = 1; | ||
394 | } else { | ||
395 | /* Some of the comm-slot cards are 16 bit. But some | 319 | /* Some of the comm-slot cards are 16 bit. But some |
396 | of them are not. The 32-bit cards use offset 2 and | 320 | of them are not. The 32-bit cards use offset 2 and |
397 | pad with zeroes or sometimes ones (I think...) | 321 | have known revisions, we try reading the revision |
398 | Therefore, if we try offset 0 and get a silicon | 322 | register at offset 2, if we don't get a known revision |
399 | revision of 0, we assume 16 bit. */ | 323 | we assume 16 bit at offset 0. */ |
400 | int sr; | 324 | lp->reg_offset = 2; |
401 | 325 | lp->dma_bitmode = SONIC_BITMODE16; | |
402 | /* Technically this is not necessary since we zeroed | 326 | |
403 | it above */ | 327 | sr = SONIC_READ(SONIC_SR); |
404 | reg_offset = 0; | 328 | if (sr == 0x0004 || sr == 0x0006 || sr == 0x0100 || sr == 0x0101) |
405 | dma_bitmode = 0; | 329 | /* 83932 is 0x0004 or 0x0006, 83934 is 0x0100 or 0x0101 */ |
406 | sr = sonic_read(dev, SONIC_SR); | 330 | lp->dma_bitmode = SONIC_BITMODE32; |
407 | if (sr == 0 || sr == 0xffff) { | 331 | else { |
408 | reg_offset = 2; | 332 | lp->dma_bitmode = SONIC_BITMODE16; |
409 | /* 83932 is 0x0004, 83934 is 0x0100 or 0x0101 */ | 333 | lp->reg_offset = 0; |
410 | sr = sonic_read(dev, SONIC_SR); | 334 | sr = SONIC_READ(SONIC_SR); |
411 | dma_bitmode = 1; | ||
412 | |||
413 | } | 335 | } |
414 | printk(KERN_INFO | 336 | } else { |
415 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 337 | /* All onboard cards are at offset 2 with 32 bit DMA. */ |
416 | dev->name, sr, dma_bitmode?32:16, reg_offset); | 338 | lp->reg_offset = 2; |
339 | lp->dma_bitmode = SONIC_BITMODE32; | ||
340 | sr = SONIC_READ(SONIC_SR); | ||
417 | } | 341 | } |
418 | 342 | printk(KERN_INFO | |
343 | "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | ||
344 | lp->device->bus_id, sr, lp->dma_bitmode?32:16, lp->reg_offset); | ||
419 | 345 | ||
420 | /* this carries my sincere apologies -- by the time I got to updating | 346 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
421 | the driver, support for "reg_offsets" appeares nowhere in the sonic | 347 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, |
422 | code, going back for over a year. Fortunately, my Mac does't seem | 348 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
423 | to use whatever this was. | 349 | #endif |
424 | 350 | ||
425 | If you know how this is supposed to be implemented, either fix it, | ||
426 | or contact me (sammy@oh.verio.com) to explain what it is. --Sam */ | ||
427 | |||
428 | if(reg_offset) { | ||
429 | printk("%s: register offset unsupported. please fix this if you know what it is.\n", dev->name); | ||
430 | return -ENODEV; | ||
431 | } | ||
432 | |||
433 | /* Software reset, then initialize control registers. */ | 351 | /* Software reset, then initialize control registers. */ |
434 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 352 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
435 | sonic_write(dev, SONIC_DCR, SONIC_DCR_BMS | | 353 | |
436 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_EXBUS | | 354 | SONIC_WRITE(SONIC_DCR, SONIC_DCR_EXBUS | SONIC_DCR_BMS | |
437 | (dma_bitmode ? SONIC_DCR_DW : 0)); | 355 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
356 | (lp->dma_bitmode ? SONIC_DCR_DW : 0)); | ||
438 | 357 | ||
439 | /* This *must* be written back to in order to restore the | 358 | /* This *must* be written back to in order to restore the |
440 | extended programmable output bits */ | 359 | * extended programmable output bits, as it may not have been |
441 | sonic_write(dev, SONIC_DCR2, 0); | 360 | * initialised since the hardware reset. */ |
361 | SONIC_WRITE(SONIC_DCR2, 0); | ||
442 | 362 | ||
443 | /* Clear *and* disable interrupts to be on the safe side */ | 363 | /* Clear *and* disable interrupts to be on the safe side */ |
444 | sonic_write(dev, SONIC_ISR,0x7fff); | 364 | SONIC_WRITE(SONIC_IMR, 0); |
445 | sonic_write(dev, SONIC_IMR,0); | 365 | SONIC_WRITE(SONIC_ISR, 0x7fff); |
446 | 366 | ||
447 | /* Now look for the MAC address. */ | 367 | /* Now look for the MAC address. */ |
448 | if (mac_onboard_sonic_ethernet_addr(dev) != 0) | 368 | if (mac_onboard_sonic_ethernet_addr(dev) != 0) |
449 | return -ENODEV; | 369 | return -ENODEV; |
450 | 370 | ||
451 | printk(KERN_INFO "MAC "); | ||
452 | for (i = 0; i < 6; i++) { | ||
453 | printk("%2.2x", dev->dev_addr[i]); | ||
454 | if (i < 5) | ||
455 | printk(":"); | ||
456 | } | ||
457 | |||
458 | printk(" IRQ %d\n", dev->irq); | ||
459 | |||
460 | /* Shared init code */ | 371 | /* Shared init code */ |
461 | return macsonic_init(dev); | 372 | return macsonic_init(dev); |
462 | } | 373 | } |
@@ -468,8 +379,10 @@ int __init mac_nubus_sonic_ethernet_addr(struct net_device* dev, | |||
468 | int i; | 379 | int i; |
469 | for(i = 0; i < 6; i++) | 380 | for(i = 0; i < 6; i++) |
470 | dev->dev_addr[i] = SONIC_READ_PROM(i); | 381 | dev->dev_addr[i] = SONIC_READ_PROM(i); |
471 | /* For now we are going to assume that they're all bit-reversed */ | 382 | |
472 | bit_reverse_addr(dev->dev_addr); | 383 | /* Some of the addresses are bit-reversed */ |
384 | if (id != MACSONIC_DAYNA) | ||
385 | bit_reverse_addr(dev->dev_addr); | ||
473 | 386 | ||
474 | return 0; | 387 | return 0; |
475 | } | 388 | } |
@@ -487,6 +400,15 @@ int __init macsonic_ident(struct nubus_dev* ndev) | |||
487 | else | 400 | else |
488 | return MACSONIC_APPLE; | 401 | return MACSONIC_APPLE; |
489 | } | 402 | } |
403 | |||
404 | if (ndev->dr_hw == NUBUS_DRHW_SMC9194 && | ||
405 | ndev->dr_sw == NUBUS_DRSW_DAYNA) | ||
406 | return MACSONIC_DAYNA; | ||
407 | |||
408 | if (ndev->dr_hw == NUBUS_DRHW_SONIC_LC && | ||
409 | ndev->dr_sw == 0) { /* huh? */ | ||
410 | return MACSONIC_APPLE16; | ||
411 | } | ||
490 | return -1; | 412 | return -1; |
491 | } | 413 | } |
492 | 414 | ||
@@ -494,12 +416,12 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
494 | { | 416 | { |
495 | static int slots; | 417 | static int slots; |
496 | struct nubus_dev* ndev = NULL; | 418 | struct nubus_dev* ndev = NULL; |
419 | struct sonic_local* lp = netdev_priv(dev); | ||
497 | unsigned long base_addr, prom_addr; | 420 | unsigned long base_addr, prom_addr; |
498 | u16 sonic_dcr; | 421 | u16 sonic_dcr; |
499 | int id; | 422 | int id = -1; |
500 | int i; | 423 | int reg_offset, dma_bitmode; |
501 | int dma_bitmode; | 424 | |
502 | |||
503 | /* Find the first SONIC that hasn't been initialized already */ | 425 | /* Find the first SONIC that hasn't been initialized already */ |
504 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, | 426 | while ((ndev = nubus_find_type(NUBUS_CAT_NETWORK, |
505 | NUBUS_TYPE_ETHERNET, ndev)) != NULL) | 427 | NUBUS_TYPE_ETHERNET, ndev)) != NULL) |
@@ -521,51 +443,52 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
521 | case MACSONIC_DUODOCK: | 443 | case MACSONIC_DUODOCK: |
522 | base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; | 444 | base_addr = ndev->board->slot_addr + DUODOCK_SONIC_REGISTERS; |
523 | prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; | 445 | prom_addr = ndev->board->slot_addr + DUODOCK_SONIC_PROM_BASE; |
524 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | 446 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT0 | SONIC_DCR_RFT1 | |
525 | | SONIC_DCR_TFT0; | 447 | SONIC_DCR_TFT0; |
526 | reg_offset = 2; | 448 | reg_offset = 2; |
527 | dma_bitmode = 1; | 449 | dma_bitmode = SONIC_BITMODE32; |
528 | break; | 450 | break; |
529 | case MACSONIC_APPLE: | 451 | case MACSONIC_APPLE: |
530 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 452 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
531 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | 453 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; |
532 | sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; | 454 | sonic_dcr = SONIC_DCR_BMS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0; |
533 | reg_offset = 0; | 455 | reg_offset = 0; |
534 | dma_bitmode = 1; | 456 | dma_bitmode = SONIC_BITMODE32; |
535 | break; | 457 | break; |
536 | case MACSONIC_APPLE16: | 458 | case MACSONIC_APPLE16: |
537 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 459 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
538 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; | 460 | prom_addr = ndev->board->slot_addr + APPLE_SONIC_PROM_BASE; |
539 | sonic_dcr = SONIC_DCR_EXBUS | 461 | sonic_dcr = SONIC_DCR_EXBUS | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
540 | | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 462 | SONIC_DCR_PO1 | SONIC_DCR_BMS; |
541 | | SONIC_DCR_PO1 | SONIC_DCR_BMS; | ||
542 | reg_offset = 0; | 463 | reg_offset = 0; |
543 | dma_bitmode = 0; | 464 | dma_bitmode = SONIC_BITMODE16; |
544 | break; | 465 | break; |
545 | case MACSONIC_DAYNALINK: | 466 | case MACSONIC_DAYNALINK: |
546 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; | 467 | base_addr = ndev->board->slot_addr + APPLE_SONIC_REGISTERS; |
547 | prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; | 468 | prom_addr = ndev->board->slot_addr + DAYNALINK_PROM_BASE; |
548 | sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | 469 | sonic_dcr = SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | |
549 | | SONIC_DCR_PO1 | SONIC_DCR_BMS; | 470 | SONIC_DCR_PO1 | SONIC_DCR_BMS; |
550 | reg_offset = 0; | 471 | reg_offset = 0; |
551 | dma_bitmode = 0; | 472 | dma_bitmode = SONIC_BITMODE16; |
552 | break; | 473 | break; |
553 | case MACSONIC_DAYNA: | 474 | case MACSONIC_DAYNA: |
554 | base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; | 475 | base_addr = ndev->board->slot_addr + DAYNA_SONIC_REGISTERS; |
555 | prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; | 476 | prom_addr = ndev->board->slot_addr + DAYNA_SONIC_MAC_ADDR; |
556 | sonic_dcr = SONIC_DCR_BMS | 477 | sonic_dcr = SONIC_DCR_BMS | |
557 | | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; | 478 | SONIC_DCR_RFT1 | SONIC_DCR_TFT0 | SONIC_DCR_PO1; |
558 | reg_offset = 0; | 479 | reg_offset = 0; |
559 | dma_bitmode = 0; | 480 | dma_bitmode = SONIC_BITMODE16; |
560 | break; | 481 | break; |
561 | default: | 482 | default: |
562 | printk(KERN_ERR "macsonic: WTF, id is %d\n", id); | 483 | printk(KERN_ERR "macsonic: WTF, id is %d\n", id); |
563 | return -ENODEV; | 484 | return -ENODEV; |
564 | } | 485 | } |
565 | 486 | ||
566 | /* Danger! My arms are flailing wildly! You *must* set this | 487 | /* Danger! My arms are flailing wildly! You *must* set lp->reg_offset |
567 | before using sonic_read() */ | 488 | * and dev->base_addr before using SONIC_READ() or SONIC_WRITE() */ |
568 | dev->base_addr = base_addr; | 489 | dev->base_addr = base_addr; |
490 | lp->reg_offset = reg_offset; | ||
491 | lp->dma_bitmode = dma_bitmode; | ||
569 | dev->irq = SLOT2IRQ(ndev->board->slot); | 492 | dev->irq = SLOT2IRQ(ndev->board->slot); |
570 | 493 | ||
571 | if (!sonic_version_printed) { | 494 | if (!sonic_version_printed) { |
@@ -573,29 +496,66 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
573 | sonic_version_printed = 1; | 496 | sonic_version_printed = 1; |
574 | } | 497 | } |
575 | printk(KERN_INFO "%s: %s in slot %X\n", | 498 | printk(KERN_INFO "%s: %s in slot %X\n", |
576 | dev->name, ndev->board->name, ndev->board->slot); | 499 | lp->device->bus_id, ndev->board->name, ndev->board->slot); |
577 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", | 500 | printk(KERN_INFO "%s: revision 0x%04x, using %d bit DMA and register offset %d\n", |
578 | dev->name, sonic_read(dev, SONIC_SR), dma_bitmode?32:16, reg_offset); | 501 | lp->device->bus_id, SONIC_READ(SONIC_SR), dma_bitmode?32:16, reg_offset); |
579 | 502 | ||
580 | if(reg_offset) { | 503 | #if 0 /* This is sometimes useful to find out how MacOS configured the card. */ |
581 | printk("%s: register offset unsupported. please fix this if you know what it is.\n", dev->name); | 504 | printk(KERN_INFO "%s: DCR: 0x%04x, DCR2: 0x%04x\n", lp->device->bus_id, |
582 | return -ENODEV; | 505 | SONIC_READ(SONIC_DCR) & 0xffff, SONIC_READ(SONIC_DCR2) & 0xffff); |
583 | } | 506 | #endif |
584 | 507 | ||
585 | /* Software reset, then initialize control registers. */ | 508 | /* Software reset, then initialize control registers. */ |
586 | sonic_write(dev, SONIC_CMD, SONIC_CR_RST); | 509 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
587 | sonic_write(dev, SONIC_DCR, sonic_dcr | 510 | SONIC_WRITE(SONIC_DCR, sonic_dcr | (dma_bitmode ? SONIC_DCR_DW : 0)); |
588 | | (dma_bitmode ? SONIC_DCR_DW : 0)); | 511 | /* This *must* be written back to in order to restore the |
512 | * extended programmable output bits, since it may not have been | ||
513 | * initialised since the hardware reset. */ | ||
514 | SONIC_WRITE(SONIC_DCR2, 0); | ||
589 | 515 | ||
590 | /* Clear *and* disable interrupts to be on the safe side */ | 516 | /* Clear *and* disable interrupts to be on the safe side */ |
591 | sonic_write(dev, SONIC_ISR,0x7fff); | 517 | SONIC_WRITE(SONIC_IMR, 0); |
592 | sonic_write(dev, SONIC_IMR,0); | 518 | SONIC_WRITE(SONIC_ISR, 0x7fff); |
593 | 519 | ||
594 | /* Now look for the MAC address. */ | 520 | /* Now look for the MAC address. */ |
595 | if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) | 521 | if (mac_nubus_sonic_ethernet_addr(dev, prom_addr, id) != 0) |
596 | return -ENODEV; | 522 | return -ENODEV; |
597 | 523 | ||
598 | printk(KERN_INFO "MAC "); | 524 | /* Shared init code */ |
525 | return macsonic_init(dev); | ||
526 | } | ||
527 | |||
528 | static int __init mac_sonic_probe(struct device *device) | ||
529 | { | ||
530 | struct net_device *dev; | ||
531 | struct sonic_local *lp; | ||
532 | int err; | ||
533 | int i; | ||
534 | |||
535 | dev = alloc_etherdev(sizeof(struct sonic_local)); | ||
536 | if (!dev) | ||
537 | return -ENOMEM; | ||
538 | |||
539 | lp = netdev_priv(dev); | ||
540 | lp->device = device; | ||
541 | SET_NETDEV_DEV(dev, device); | ||
542 | SET_MODULE_OWNER(dev); | ||
543 | |||
544 | /* This will catch fatal stuff like -ENOMEM as well as success */ | ||
545 | err = mac_onboard_sonic_probe(dev); | ||
546 | if (err == 0) | ||
547 | goto found; | ||
548 | if (err != -ENODEV) | ||
549 | goto out; | ||
550 | err = mac_nubus_sonic_probe(dev); | ||
551 | if (err) | ||
552 | goto out; | ||
553 | found: | ||
554 | err = register_netdev(dev); | ||
555 | if (err) | ||
556 | goto out; | ||
557 | |||
558 | printk("%s: MAC ", dev->name); | ||
599 | for (i = 0; i < 6; i++) { | 559 | for (i = 0; i < 6; i++) { |
600 | printk("%2.2x", dev->dev_addr[i]); | 560 | printk("%2.2x", dev->dev_addr[i]); |
601 | if (i < 5) | 561 | if (i < 5) |
@@ -603,55 +563,95 @@ int __init mac_nubus_sonic_probe(struct net_device* dev) | |||
603 | } | 563 | } |
604 | printk(" IRQ %d\n", dev->irq); | 564 | printk(" IRQ %d\n", dev->irq); |
605 | 565 | ||
606 | /* Shared init code */ | 566 | return 0; |
607 | return macsonic_init(dev); | ||
608 | } | ||
609 | 567 | ||
610 | #ifdef MODULE | 568 | out: |
611 | static struct net_device *dev_macsonic; | 569 | free_netdev(dev); |
612 | 570 | ||
613 | MODULE_PARM(sonic_debug, "i"); | 571 | return err; |
572 | } | ||
573 | |||
574 | MODULE_DESCRIPTION("Macintosh SONIC ethernet driver"); | ||
575 | module_param(sonic_debug, int, 0); | ||
614 | MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); | 576 | MODULE_PARM_DESC(sonic_debug, "macsonic debug level (1-4)"); |
615 | 577 | ||
616 | int | 578 | #define SONIC_IRQ_FLAG IRQ_FLG_FAST |
617 | init_module(void) | 579 | |
580 | #include "sonic.c" | ||
581 | |||
582 | static int __devexit mac_sonic_device_remove (struct device *device) | ||
618 | { | 583 | { |
619 | dev_macsonic = macsonic_probe(-1); | 584 | struct net_device *dev = device->driver_data; |
620 | if (IS_ERR(dev_macsonic)) { | 585 | struct sonic_local* lp = netdev_priv(dev); |
621 | printk(KERN_WARNING "macsonic.c: No card found\n"); | 586 | |
622 | return PTR_ERR(dev_macsonic); | 587 | unregister_netdev (dev); |
623 | } | 588 | dma_free_coherent(lp->device, SIZEOF_SONIC_DESC * SONIC_BUS_SCALE(lp->dma_bitmode), |
589 | lp->descriptors, lp->descriptors_laddr); | ||
590 | free_netdev (dev); | ||
591 | |||
624 | return 0; | 592 | return 0; |
625 | } | 593 | } |
626 | 594 | ||
627 | void | 595 | static struct device_driver mac_sonic_driver = { |
628 | cleanup_module(void) | 596 | .name = mac_sonic_string, |
597 | .bus = &platform_bus_type, | ||
598 | .probe = mac_sonic_probe, | ||
599 | .remove = __devexit_p(mac_sonic_device_remove), | ||
600 | }; | ||
601 | |||
602 | static void mac_sonic_platform_release(struct device *device) | ||
629 | { | 603 | { |
630 | unregister_netdev(dev_macsonic); | 604 | struct platform_device *pldev; |
631 | kfree(dev_macsonic->priv); | 605 | |
632 | free_netdev(dev_macsonic); | 606 | /* free device */ |
607 | pldev = to_platform_device (device); | ||
608 | kfree (pldev); | ||
633 | } | 609 | } |
634 | #endif /* MODULE */ | ||
635 | 610 | ||
611 | static int __init mac_sonic_init_module(void) | ||
612 | { | ||
613 | struct platform_device *pldev; | ||
614 | int err; | ||
636 | 615 | ||
637 | #define vdma_alloc(foo, bar) ((u32)foo) | 616 | if ((err = driver_register(&mac_sonic_driver))) { |
638 | #define vdma_free(baz) | 617 | printk(KERN_ERR "Driver registration failed\n"); |
639 | #define sonic_chiptomem(bat) (bat) | 618 | return err; |
640 | #define PHYSADDR(quux) (quux) | 619 | } |
641 | #define CPHYSADDR(quux) (quux) | ||
642 | 620 | ||
643 | #define sonic_request_irq request_irq | 621 | mac_sonic_device = NULL; |
644 | #define sonic_free_irq free_irq | ||
645 | 622 | ||
646 | #include "sonic.c" | 623 | if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) { |
624 | goto out_unregister; | ||
625 | } | ||
647 | 626 | ||
648 | /* | 627 | memset(pldev, 0, sizeof (*pldev)); |
649 | * Local variables: | 628 | pldev->name = mac_sonic_string; |
650 | * compile-command: "m68k-linux-gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -ffixed-a2 -DMODULE -DMODVERSIONS -include ../../include/linux/modversions.h -c -o macsonic.o macsonic.c" | 629 | pldev->id = 0; |
651 | * version-control: t | 630 | pldev->dev.release = mac_sonic_platform_release; |
652 | * kept-new-versions: 5 | 631 | mac_sonic_device = pldev; |
653 | * c-indent-level: 8 | 632 | |
654 | * tab-width: 8 | 633 | if (platform_device_register (pldev)) { |
655 | * End: | 634 | kfree(pldev); |
656 | * | 635 | mac_sonic_device = NULL; |
657 | */ | 636 | } |
637 | |||
638 | return 0; | ||
639 | |||
640 | out_unregister: | ||
641 | platform_device_unregister(pldev); | ||
642 | |||
643 | return -ENOMEM; | ||
644 | } | ||
645 | |||
646 | static void __exit mac_sonic_cleanup_module(void) | ||
647 | { | ||
648 | driver_unregister(&mac_sonic_driver); | ||
649 | |||
650 | if (mac_sonic_device) { | ||
651 | platform_device_unregister(mac_sonic_device); | ||
652 | mac_sonic_device = NULL; | ||
653 | } | ||
654 | } | ||
655 | |||
656 | module_init(mac_sonic_init_module); | ||
657 | module_exit(mac_sonic_cleanup_module); | ||
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c index 0405e1f0d3df..fb6b232069d6 100644 --- a/drivers/net/mv643xx_eth.c +++ b/drivers/net/mv643xx_eth.c | |||
@@ -1157,16 +1157,20 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1157 | if (!skb_shinfo(skb)->nr_frags) { | 1157 | if (!skb_shinfo(skb)->nr_frags) { |
1158 | linear: | 1158 | linear: |
1159 | if (skb->ip_summed != CHECKSUM_HW) { | 1159 | if (skb->ip_summed != CHECKSUM_HW) { |
1160 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ | ||
1160 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1161 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1161 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; | 1162 | ETH_TX_FIRST_DESC | |
1163 | ETH_TX_LAST_DESC | | ||
1164 | 5 << ETH_TX_IHL_SHIFT; | ||
1162 | pkt_info.l4i_chk = 0; | 1165 | pkt_info.l4i_chk = 0; |
1163 | } else { | 1166 | } else { |
1164 | u32 ipheader = skb->nh.iph->ihl << 11; | ||
1165 | 1167 | ||
1166 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | | 1168 | pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | |
1167 | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC | | 1169 | ETH_TX_FIRST_DESC | |
1168 | ETH_GEN_TCP_UDP_CHECKSUM | | 1170 | ETH_TX_LAST_DESC | |
1169 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1171 | ETH_GEN_TCP_UDP_CHECKSUM | |
1172 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1173 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1170 | /* CPU already calculated pseudo header checksum. */ | 1174 | /* CPU already calculated pseudo header checksum. */ |
1171 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1175 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1172 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1176 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
@@ -1193,7 +1197,6 @@ linear: | |||
1193 | stats->tx_bytes += pkt_info.byte_cnt; | 1197 | stats->tx_bytes += pkt_info.byte_cnt; |
1194 | } else { | 1198 | } else { |
1195 | unsigned int frag; | 1199 | unsigned int frag; |
1196 | u32 ipheader; | ||
1197 | 1200 | ||
1198 | /* Since hardware can't handle unaligned fragments smaller | 1201 | /* Since hardware can't handle unaligned fragments smaller |
1199 | * than 9 bytes, if we find any, we linearize the skb | 1202 | * than 9 bytes, if we find any, we linearize the skb |
@@ -1222,12 +1225,16 @@ linear: | |||
1222 | DMA_TO_DEVICE); | 1225 | DMA_TO_DEVICE); |
1223 | pkt_info.l4i_chk = 0; | 1226 | pkt_info.l4i_chk = 0; |
1224 | pkt_info.return_info = 0; | 1227 | pkt_info.return_info = 0; |
1225 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC; | ||
1226 | 1228 | ||
1227 | if (skb->ip_summed == CHECKSUM_HW) { | 1229 | if (skb->ip_summed != CHECKSUM_HW) |
1228 | ipheader = skb->nh.iph->ihl << 11; | 1230 | /* Errata BTS #50, IHL must be 5 if no HW checksum */ |
1229 | pkt_info.cmd_sts |= ETH_GEN_TCP_UDP_CHECKSUM | | 1231 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | |
1230 | ETH_GEN_IP_V_4_CHECKSUM | ipheader; | 1232 | 5 << ETH_TX_IHL_SHIFT; |
1233 | else { | ||
1234 | pkt_info.cmd_sts = ETH_TX_FIRST_DESC | | ||
1235 | ETH_GEN_TCP_UDP_CHECKSUM | | ||
1236 | ETH_GEN_IP_V_4_CHECKSUM | | ||
1237 | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; | ||
1231 | /* CPU already calculated pseudo header checksum. */ | 1238 | /* CPU already calculated pseudo header checksum. */ |
1232 | if (skb->nh.iph->protocol == IPPROTO_UDP) { | 1239 | if (skb->nh.iph->protocol == IPPROTO_UDP) { |
1233 | pkt_info.cmd_sts |= ETH_UDP_FRAME; | 1240 | pkt_info.cmd_sts |= ETH_UDP_FRAME; |
diff --git a/drivers/net/mv643xx_eth.h b/drivers/net/mv643xx_eth.h index 57c4f8fbfdb6..7678b59c2952 100644 --- a/drivers/net/mv643xx_eth.h +++ b/drivers/net/mv643xx_eth.h | |||
@@ -49,7 +49,7 @@ | |||
49 | /* Checksum offload for Tx works for most packets, but | 49 | /* Checksum offload for Tx works for most packets, but |
50 | * fails if previous packet sent did not use hw csum | 50 | * fails if previous packet sent did not use hw csum |
51 | */ | 51 | */ |
52 | #undef MV643XX_CHECKSUM_OFFLOAD_TX | 52 | #define MV643XX_CHECKSUM_OFFLOAD_TX |
53 | #define MV643XX_NAPI | 53 | #define MV643XX_NAPI |
54 | #define MV643XX_TX_FAST_REFILL | 54 | #define MV643XX_TX_FAST_REFILL |
55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ | 55 | #undef MV643XX_RX_QUEUE_FILL_ON_TASK /* Does not work, yet */ |
@@ -217,6 +217,8 @@ | |||
217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) | 217 | #define ETH_TX_ENABLE_INTERRUPT (BIT23) |
218 | #define ETH_AUTO_MODE (BIT30) | 218 | #define ETH_AUTO_MODE (BIT30) |
219 | 219 | ||
220 | #define ETH_TX_IHL_SHIFT 11 | ||
221 | |||
220 | /* typedefs */ | 222 | /* typedefs */ |
221 | 223 | ||
222 | typedef enum _eth_func_ret_status { | 224 | typedef enum _eth_func_ret_status { |
diff --git a/drivers/net/pci-skeleton.c b/drivers/net/pci-skeleton.c index 4a391ea0f58a..a1ac4bd1696e 100644 --- a/drivers/net/pci-skeleton.c +++ b/drivers/net/pci-skeleton.c | |||
@@ -486,9 +486,9 @@ struct netdrv_private { | |||
486 | MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); | 486 | MODULE_AUTHOR ("Jeff Garzik <jgarzik@pobox.com>"); |
487 | MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver"); | 487 | MODULE_DESCRIPTION ("Skeleton for a PCI Fast Ethernet driver"); |
488 | MODULE_LICENSE("GPL"); | 488 | MODULE_LICENSE("GPL"); |
489 | MODULE_PARM (multicast_filter_limit, "i"); | 489 | module_param(multicast_filter_limit, int, 0); |
490 | MODULE_PARM (max_interrupt_work, "i"); | 490 | module_param(max_interrupt_work, int, 0); |
491 | MODULE_PARM (media, "1-" __MODULE_STRING(8) "i"); | 491 | module_param_array(media, int, NULL, 0); |
492 | MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses"); | 492 | MODULE_PARM_DESC (multicast_filter_limit, "pci-skeleton maximum number of filtered multicast addresses"); |
493 | MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt"); | 493 | MODULE_PARM_DESC (max_interrupt_work, "pci-skeleton maximum events handled per interrupt"); |
494 | MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex"); | 494 | MODULE_PARM_DESC (media, "pci-skeleton: Bits 0-3: media type, bit 17: full duplex"); |
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c index 9d8197bb293a..384a736a0d2f 100644 --- a/drivers/net/pcmcia/fmvj18x_cs.c +++ b/drivers/net/pcmcia/fmvj18x_cs.c | |||
@@ -134,7 +134,7 @@ typedef struct local_info_t { | |||
134 | u_char mc_filter[8]; | 134 | u_char mc_filter[8]; |
135 | } local_info_t; | 135 | } local_info_t; |
136 | 136 | ||
137 | #define MC_FILTERBREAK 64 | 137 | #define MC_FILTERBREAK 8 |
138 | 138 | ||
139 | /*====================================================================*/ | 139 | /*====================================================================*/ |
140 | /* | 140 | /* |
@@ -1012,7 +1012,7 @@ static void fjn_reset(struct net_device *dev) | |||
1012 | outb(BANK_1U, ioaddr + CONFIG_1); | 1012 | outb(BANK_1U, ioaddr + CONFIG_1); |
1013 | 1013 | ||
1014 | /* set the multicast table to accept none. */ | 1014 | /* set the multicast table to accept none. */ |
1015 | for (i = 0; i < 6; i++) | 1015 | for (i = 0; i < 8; i++) |
1016 | outb(0x00, ioaddr + MAR_ADR + i); | 1016 | outb(0x00, ioaddr + MAR_ADR + i); |
1017 | 1017 | ||
1018 | /* Switch to bank 2 (runtime mode) */ | 1018 | /* Switch to bank 2 (runtime mode) */ |
@@ -1269,6 +1269,16 @@ static void set_rx_mode(struct net_device *dev) | |||
1269 | u_long flags; | 1269 | u_long flags; |
1270 | int i; | 1270 | int i; |
1271 | 1271 | ||
1272 | int saved_config_0 = inb(ioaddr + CONFIG_0); | ||
1273 | |||
1274 | local_irq_save(flags); | ||
1275 | |||
1276 | /* Disable Tx and Rx */ | ||
1277 | if (sram_config == 0) | ||
1278 | outb(CONFIG0_RST, ioaddr + CONFIG_0); | ||
1279 | else | ||
1280 | outb(CONFIG0_RST_1, ioaddr + CONFIG_0); | ||
1281 | |||
1272 | if (dev->flags & IFF_PROMISC) { | 1282 | if (dev->flags & IFF_PROMISC) { |
1273 | /* Unconditionally log net taps. */ | 1283 | /* Unconditionally log net taps. */ |
1274 | printk("%s: Promiscuous mode enabled.\n", dev->name); | 1284 | printk("%s: Promiscuous mode enabled.\n", dev->name); |
@@ -1290,20 +1300,23 @@ static void set_rx_mode(struct net_device *dev) | |||
1290 | for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; | 1300 | for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count; |
1291 | i++, mclist = mclist->next) { | 1301 | i++, mclist = mclist->next) { |
1292 | unsigned int bit = | 1302 | unsigned int bit = |
1293 | ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f; | 1303 | ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26; |
1294 | mc_filter[bit >> 3] |= (1 << bit); | 1304 | mc_filter[bit >> 3] |= (1 << (bit & 7)); |
1295 | } | 1305 | } |
1306 | outb(2, ioaddr + RX_MODE); /* Use normal mode. */ | ||
1296 | } | 1307 | } |
1297 | 1308 | ||
1298 | local_irq_save(flags); | ||
1299 | if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { | 1309 | if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) { |
1300 | int saved_bank = inb(ioaddr + CONFIG_1); | 1310 | int saved_bank = inb(ioaddr + CONFIG_1); |
1301 | /* Switch to bank 1 and set the multicast table. */ | 1311 | /* Switch to bank 1 and set the multicast table. */ |
1302 | outb(0xe4, ioaddr + CONFIG_1); | 1312 | outb(0xe4, ioaddr + CONFIG_1); |
1303 | for (i = 0; i < 8; i++) | 1313 | for (i = 0; i < 8; i++) |
1304 | outb(mc_filter[i], ioaddr + 8 + i); | 1314 | outb(mc_filter[i], ioaddr + MAR_ADR + i); |
1305 | memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); | 1315 | memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter)); |
1306 | outb(saved_bank, ioaddr + CONFIG_1); | 1316 | outb(saved_bank, ioaddr + CONFIG_1); |
1307 | } | 1317 | } |
1318 | |||
1319 | outb(saved_config_0, ioaddr + CONFIG_0); | ||
1320 | |||
1308 | local_irq_restore(flags); | 1321 | local_irq_restore(flags); |
1309 | } | 1322 | } |
diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig new file mode 100644 index 000000000000..6a2fe3583478 --- /dev/null +++ b/drivers/net/phy/Kconfig | |||
@@ -0,0 +1,57 @@ | |||
1 | # | ||
2 | # PHY Layer Configuration | ||
3 | # | ||
4 | |||
5 | menu "PHY device support" | ||
6 | |||
7 | config PHYLIB | ||
8 | tristate "PHY Device support and infrastructure" | ||
9 | depends on NET_ETHERNET | ||
10 | help | ||
11 | Ethernet controllers are usually attached to PHY | ||
12 | devices. This option provides infrastructure for | ||
13 | managing PHY devices. | ||
14 | |||
15 | config PHYCONTROL | ||
16 | bool " Support for automatically handling PHY state changes" | ||
17 | depends on PHYLIB | ||
18 | help | ||
19 | Adds code to perform all the work for keeping PHY link | ||
20 | state (speed/duplex/etc) up-to-date. Also handles | ||
21 | interrupts. | ||
22 | |||
23 | comment "MII PHY device drivers" | ||
24 | depends on PHYLIB | ||
25 | |||
26 | config MARVELL_PHY | ||
27 | tristate "Drivers for Marvell PHYs" | ||
28 | depends on PHYLIB | ||
29 | ---help--- | ||
30 | Currently has a driver for the 88E1011S | ||
31 | |||
32 | config DAVICOM_PHY | ||
33 | tristate "Drivers for Davicom PHYs" | ||
34 | depends on PHYLIB | ||
35 | ---help--- | ||
36 | Currently supports dm9161e and dm9131 | ||
37 | |||
38 | config QSEMI_PHY | ||
39 | tristate "Drivers for Quality Semiconductor PHYs" | ||
40 | depends on PHYLIB | ||
41 | ---help--- | ||
42 | Currently supports the qs6612 | ||
43 | |||
44 | config LXT_PHY | ||
45 | tristate "Drivers for the Intel LXT PHYs" | ||
46 | depends on PHYLIB | ||
47 | ---help--- | ||
48 | Currently supports the lxt970, lxt971 | ||
49 | |||
50 | config CICADA_PHY | ||
51 | tristate "Drivers for the Cicada PHYs" | ||
52 | depends on PHYLIB | ||
53 | ---help--- | ||
54 | Currently supports the cis8204 | ||
55 | |||
56 | endmenu | ||
57 | |||
diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile new file mode 100644 index 000000000000..e4116a5fbb4c --- /dev/null +++ b/drivers/net/phy/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # Makefile for Linux PHY drivers | ||
2 | |||
3 | libphy-objs := phy.o phy_device.o mdio_bus.o | ||
4 | |||
5 | obj-$(CONFIG_PHYLIB) += libphy.o | ||
6 | obj-$(CONFIG_MARVELL_PHY) += marvell.o | ||
7 | obj-$(CONFIG_DAVICOM_PHY) += davicom.o | ||
8 | obj-$(CONFIG_CICADA_PHY) += cicada.o | ||
9 | obj-$(CONFIG_LXT_PHY) += lxt.o | ||
10 | obj-$(CONFIG_QSEMI_PHY) += qsemi.o | ||
diff --git a/drivers/net/phy/cicada.c b/drivers/net/phy/cicada.c new file mode 100644 index 000000000000..c47fb2ecd147 --- /dev/null +++ b/drivers/net/phy/cicada.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/cicada.c | ||
3 | * | ||
4 | * Driver for Cicada PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* Cicada Extended Control Register 1 */ | ||
42 | #define MII_CIS8201_EXT_CON1 0x17 | ||
43 | #define MII_CIS8201_EXTCON1_INIT 0x0000 | ||
44 | |||
45 | /* Cicada Interrupt Mask Register */ | ||
46 | #define MII_CIS8201_IMASK 0x19 | ||
47 | #define MII_CIS8201_IMASK_IEN 0x8000 | ||
48 | #define MII_CIS8201_IMASK_SPEED 0x4000 | ||
49 | #define MII_CIS8201_IMASK_LINK 0x2000 | ||
50 | #define MII_CIS8201_IMASK_DUPLEX 0x1000 | ||
51 | #define MII_CIS8201_IMASK_MASK 0xf000 | ||
52 | |||
53 | /* Cicada Interrupt Status Register */ | ||
54 | #define MII_CIS8201_ISTAT 0x1a | ||
55 | #define MII_CIS8201_ISTAT_STATUS 0x8000 | ||
56 | #define MII_CIS8201_ISTAT_SPEED 0x4000 | ||
57 | #define MII_CIS8201_ISTAT_LINK 0x2000 | ||
58 | #define MII_CIS8201_ISTAT_DUPLEX 0x1000 | ||
59 | |||
60 | /* Cicada Auxiliary Control/Status Register */ | ||
61 | #define MII_CIS8201_AUX_CONSTAT 0x1c | ||
62 | #define MII_CIS8201_AUXCONSTAT_INIT 0x0004 | ||
63 | #define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020 | ||
64 | #define MII_CIS8201_AUXCONSTAT_SPEED 0x0018 | ||
65 | #define MII_CIS8201_AUXCONSTAT_GBIT 0x0010 | ||
66 | #define MII_CIS8201_AUXCONSTAT_100 0x0008 | ||
67 | |||
68 | MODULE_DESCRIPTION("Cicadia PHY driver"); | ||
69 | MODULE_AUTHOR("Andy Fleming"); | ||
70 | MODULE_LICENSE("GPL"); | ||
71 | |||
72 | static int cis820x_config_init(struct phy_device *phydev) | ||
73 | { | ||
74 | int err; | ||
75 | |||
76 | err = phy_write(phydev, MII_CIS8201_AUX_CONSTAT, | ||
77 | MII_CIS8201_AUXCONSTAT_INIT); | ||
78 | |||
79 | if (err < 0) | ||
80 | return err; | ||
81 | |||
82 | err = phy_write(phydev, MII_CIS8201_EXT_CON1, | ||
83 | MII_CIS8201_EXTCON1_INIT); | ||
84 | |||
85 | return err; | ||
86 | } | ||
87 | |||
88 | static int cis820x_ack_interrupt(struct phy_device *phydev) | ||
89 | { | ||
90 | int err = phy_read(phydev, MII_CIS8201_ISTAT); | ||
91 | |||
92 | return (err < 0) ? err : 0; | ||
93 | } | ||
94 | |||
95 | static int cis820x_config_intr(struct phy_device *phydev) | ||
96 | { | ||
97 | int err; | ||
98 | |||
99 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
100 | err = phy_write(phydev, MII_CIS8201_IMASK, | ||
101 | MII_CIS8201_IMASK_MASK); | ||
102 | else | ||
103 | err = phy_write(phydev, MII_CIS8201_IMASK, 0); | ||
104 | |||
105 | return err; | ||
106 | } | ||
107 | |||
108 | /* Cicada 820x */ | ||
109 | static struct phy_driver cis8204_driver = { | ||
110 | .phy_id = 0x000fc440, | ||
111 | .name = "Cicada Cis8204", | ||
112 | .phy_id_mask = 0x000fffc0, | ||
113 | .features = PHY_GBIT_FEATURES, | ||
114 | .flags = PHY_HAS_INTERRUPT, | ||
115 | .config_init = &cis820x_config_init, | ||
116 | .config_aneg = &genphy_config_aneg, | ||
117 | .read_status = &genphy_read_status, | ||
118 | .ack_interrupt = &cis820x_ack_interrupt, | ||
119 | .config_intr = &cis820x_config_intr, | ||
120 | .driver = { .owner = THIS_MODULE,}, | ||
121 | }; | ||
122 | |||
123 | static int __init cis8204_init(void) | ||
124 | { | ||
125 | return phy_driver_register(&cis8204_driver); | ||
126 | } | ||
127 | |||
128 | static void __exit cis8204_exit(void) | ||
129 | { | ||
130 | phy_driver_unregister(&cis8204_driver); | ||
131 | } | ||
132 | |||
133 | module_init(cis8204_init); | ||
134 | module_exit(cis8204_exit); | ||
diff --git a/drivers/net/phy/davicom.c b/drivers/net/phy/davicom.c new file mode 100644 index 000000000000..6caf499fae32 --- /dev/null +++ b/drivers/net/phy/davicom.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/davicom.c | ||
3 | * | ||
4 | * Driver for Davicom PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #define MII_DM9161_SCR 0x10 | ||
42 | #define MII_DM9161_SCR_INIT 0x0610 | ||
43 | |||
44 | /* DM9161 Interrupt Register */ | ||
45 | #define MII_DM9161_INTR 0x15 | ||
46 | #define MII_DM9161_INTR_PEND 0x8000 | ||
47 | #define MII_DM9161_INTR_DPLX_MASK 0x0800 | ||
48 | #define MII_DM9161_INTR_SPD_MASK 0x0400 | ||
49 | #define MII_DM9161_INTR_LINK_MASK 0x0200 | ||
50 | #define MII_DM9161_INTR_MASK 0x0100 | ||
51 | #define MII_DM9161_INTR_DPLX_CHANGE 0x0010 | ||
52 | #define MII_DM9161_INTR_SPD_CHANGE 0x0008 | ||
53 | #define MII_DM9161_INTR_LINK_CHANGE 0x0004 | ||
54 | #define MII_DM9161_INTR_INIT 0x0000 | ||
55 | #define MII_DM9161_INTR_STOP \ | ||
56 | (MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \ | ||
57 | | MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK) | ||
58 | |||
59 | /* DM9161 10BT Configuration/Status */ | ||
60 | #define MII_DM9161_10BTCSR 0x12 | ||
61 | #define MII_DM9161_10BTCSR_INIT 0x7800 | ||
62 | |||
63 | MODULE_DESCRIPTION("Davicom PHY driver"); | ||
64 | MODULE_AUTHOR("Andy Fleming"); | ||
65 | MODULE_LICENSE("GPL"); | ||
66 | |||
67 | |||
68 | #define DM9161_DELAY 1 | ||
69 | static int dm9161_config_intr(struct phy_device *phydev) | ||
70 | { | ||
71 | int temp; | ||
72 | |||
73 | temp = phy_read(phydev, MII_DM9161_INTR); | ||
74 | |||
75 | if (temp < 0) | ||
76 | return temp; | ||
77 | |||
78 | if(PHY_INTERRUPT_ENABLED == phydev->interrupts ) | ||
79 | temp &= ~(MII_DM9161_INTR_STOP); | ||
80 | else | ||
81 | temp |= MII_DM9161_INTR_STOP; | ||
82 | |||
83 | temp = phy_write(phydev, MII_DM9161_INTR, temp); | ||
84 | |||
85 | return temp; | ||
86 | } | ||
87 | |||
88 | static int dm9161_config_aneg(struct phy_device *phydev) | ||
89 | { | ||
90 | int err; | ||
91 | |||
92 | /* Isolate the PHY */ | ||
93 | err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); | ||
94 | |||
95 | if (err < 0) | ||
96 | return err; | ||
97 | |||
98 | /* Configure the new settings */ | ||
99 | err = genphy_config_aneg(phydev); | ||
100 | |||
101 | if (err < 0) | ||
102 | return err; | ||
103 | |||
104 | return 0; | ||
105 | } | ||
106 | |||
107 | static int dm9161_config_init(struct phy_device *phydev) | ||
108 | { | ||
109 | int err; | ||
110 | |||
111 | /* Isolate the PHY */ | ||
112 | err = phy_write(phydev, MII_BMCR, BMCR_ISOLATE); | ||
113 | |||
114 | if (err < 0) | ||
115 | return err; | ||
116 | |||
117 | /* Do not bypass the scrambler/descrambler */ | ||
118 | err = phy_write(phydev, MII_DM9161_SCR, MII_DM9161_SCR_INIT); | ||
119 | |||
120 | if (err < 0) | ||
121 | return err; | ||
122 | |||
123 | /* Clear 10BTCSR to default */ | ||
124 | err = phy_write(phydev, MII_DM9161_10BTCSR, MII_DM9161_10BTCSR_INIT); | ||
125 | |||
126 | if (err < 0) | ||
127 | return err; | ||
128 | |||
129 | /* Reconnect the PHY, and enable Autonegotiation */ | ||
130 | err = phy_write(phydev, MII_BMCR, BMCR_ANENABLE); | ||
131 | |||
132 | if (err < 0) | ||
133 | return err; | ||
134 | |||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int dm9161_ack_interrupt(struct phy_device *phydev) | ||
139 | { | ||
140 | int err = phy_read(phydev, MII_DM9161_INTR); | ||
141 | |||
142 | return (err < 0) ? err : 0; | ||
143 | } | ||
144 | |||
145 | static struct phy_driver dm9161_driver = { | ||
146 | .phy_id = 0x0181b880, | ||
147 | .name = "Davicom DM9161E", | ||
148 | .phy_id_mask = 0x0ffffff0, | ||
149 | .features = PHY_BASIC_FEATURES, | ||
150 | .config_init = dm9161_config_init, | ||
151 | .config_aneg = dm9161_config_aneg, | ||
152 | .read_status = genphy_read_status, | ||
153 | .driver = { .owner = THIS_MODULE,}, | ||
154 | }; | ||
155 | |||
156 | static struct phy_driver dm9131_driver = { | ||
157 | .phy_id = 0x00181b80, | ||
158 | .name = "Davicom DM9131", | ||
159 | .phy_id_mask = 0x0ffffff0, | ||
160 | .features = PHY_BASIC_FEATURES, | ||
161 | .flags = PHY_HAS_INTERRUPT, | ||
162 | .config_aneg = genphy_config_aneg, | ||
163 | .read_status = genphy_read_status, | ||
164 | .ack_interrupt = dm9161_ack_interrupt, | ||
165 | .config_intr = dm9161_config_intr, | ||
166 | .driver = { .owner = THIS_MODULE,}, | ||
167 | }; | ||
168 | |||
169 | static int __init davicom_init(void) | ||
170 | { | ||
171 | int ret; | ||
172 | |||
173 | ret = phy_driver_register(&dm9161_driver); | ||
174 | if (ret) | ||
175 | goto err1; | ||
176 | |||
177 | ret = phy_driver_register(&dm9131_driver); | ||
178 | if (ret) | ||
179 | goto err2; | ||
180 | return 0; | ||
181 | |||
182 | err2: | ||
183 | phy_driver_unregister(&dm9161_driver); | ||
184 | err1: | ||
185 | return ret; | ||
186 | } | ||
187 | |||
188 | static void __exit davicom_exit(void) | ||
189 | { | ||
190 | phy_driver_unregister(&dm9161_driver); | ||
191 | phy_driver_unregister(&dm9131_driver); | ||
192 | } | ||
193 | |||
194 | module_init(davicom_init); | ||
195 | module_exit(davicom_exit); | ||
diff --git a/drivers/net/phy/lxt.c b/drivers/net/phy/lxt.c new file mode 100644 index 000000000000..4c840448ec86 --- /dev/null +++ b/drivers/net/phy/lxt.c | |||
@@ -0,0 +1,179 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/lxt.c | ||
3 | * | ||
4 | * Driver for Intel LXT PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* The Level one LXT970 is used by many boards */ | ||
42 | |||
43 | #define MII_LXT970_IER 17 /* Interrupt Enable Register */ | ||
44 | |||
45 | #define MII_LXT970_IER_IEN 0x0002 | ||
46 | |||
47 | #define MII_LXT970_ISR 18 /* Interrupt Status Register */ | ||
48 | |||
49 | #define MII_LXT970_CONFIG 19 /* Configuration Register */ | ||
50 | |||
51 | /* ------------------------------------------------------------------------- */ | ||
52 | /* The Level one LXT971 is used on some of my custom boards */ | ||
53 | |||
54 | /* register definitions for the 971 */ | ||
55 | #define MII_LXT971_IER 18 /* Interrupt Enable Register */ | ||
56 | #define MII_LXT971_IER_IEN 0x00f2 | ||
57 | |||
58 | #define MII_LXT971_ISR 19 /* Interrupt Status Register */ | ||
59 | |||
60 | |||
61 | MODULE_DESCRIPTION("Intel LXT PHY driver"); | ||
62 | MODULE_AUTHOR("Andy Fleming"); | ||
63 | MODULE_LICENSE("GPL"); | ||
64 | |||
65 | static int lxt970_ack_interrupt(struct phy_device *phydev) | ||
66 | { | ||
67 | int err; | ||
68 | |||
69 | err = phy_read(phydev, MII_BMSR); | ||
70 | |||
71 | if (err < 0) | ||
72 | return err; | ||
73 | |||
74 | err = phy_read(phydev, MII_LXT970_ISR); | ||
75 | |||
76 | if (err < 0) | ||
77 | return err; | ||
78 | |||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | static int lxt970_config_intr(struct phy_device *phydev) | ||
83 | { | ||
84 | int err; | ||
85 | |||
86 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
87 | err = phy_write(phydev, MII_LXT970_IER, MII_LXT970_IER_IEN); | ||
88 | else | ||
89 | err = phy_write(phydev, MII_LXT970_IER, 0); | ||
90 | |||
91 | return err; | ||
92 | } | ||
93 | |||
94 | static int lxt970_config_init(struct phy_device *phydev) | ||
95 | { | ||
96 | int err; | ||
97 | |||
98 | err = phy_write(phydev, MII_LXT970_CONFIG, 0); | ||
99 | |||
100 | return err; | ||
101 | } | ||
102 | |||
103 | |||
104 | static int lxt971_ack_interrupt(struct phy_device *phydev) | ||
105 | { | ||
106 | int err = phy_read(phydev, MII_LXT971_ISR); | ||
107 | |||
108 | if (err < 0) | ||
109 | return err; | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int lxt971_config_intr(struct phy_device *phydev) | ||
115 | { | ||
116 | int err; | ||
117 | |||
118 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
119 | err = phy_write(phydev, MII_LXT971_IER, MII_LXT971_IER_IEN); | ||
120 | else | ||
121 | err = phy_write(phydev, MII_LXT971_IER, 0); | ||
122 | |||
123 | return err; | ||
124 | } | ||
125 | |||
126 | static struct phy_driver lxt970_driver = { | ||
127 | .phy_id = 0x07810000, | ||
128 | .name = "LXT970", | ||
129 | .phy_id_mask = 0x0fffffff, | ||
130 | .features = PHY_BASIC_FEATURES, | ||
131 | .flags = PHY_HAS_INTERRUPT, | ||
132 | .config_init = lxt970_config_init, | ||
133 | .config_aneg = genphy_config_aneg, | ||
134 | .read_status = genphy_read_status, | ||
135 | .ack_interrupt = lxt970_ack_interrupt, | ||
136 | .config_intr = lxt970_config_intr, | ||
137 | .driver = { .owner = THIS_MODULE,}, | ||
138 | }; | ||
139 | |||
140 | static struct phy_driver lxt971_driver = { | ||
141 | .phy_id = 0x0001378e, | ||
142 | .name = "LXT971", | ||
143 | .phy_id_mask = 0x0fffffff, | ||
144 | .features = PHY_BASIC_FEATURES, | ||
145 | .flags = PHY_HAS_INTERRUPT, | ||
146 | .config_aneg = genphy_config_aneg, | ||
147 | .read_status = genphy_read_status, | ||
148 | .ack_interrupt = lxt971_ack_interrupt, | ||
149 | .config_intr = lxt971_config_intr, | ||
150 | .driver = { .owner = THIS_MODULE,}, | ||
151 | }; | ||
152 | |||
153 | static int __init lxt_init(void) | ||
154 | { | ||
155 | int ret; | ||
156 | |||
157 | ret = phy_driver_register(&lxt970_driver); | ||
158 | if (ret) | ||
159 | goto err1; | ||
160 | |||
161 | ret = phy_driver_register(&lxt971_driver); | ||
162 | if (ret) | ||
163 | goto err2; | ||
164 | return 0; | ||
165 | |||
166 | err2: | ||
167 | phy_driver_unregister(&lxt970_driver); | ||
168 | err1: | ||
169 | return ret; | ||
170 | } | ||
171 | |||
172 | static void __exit lxt_exit(void) | ||
173 | { | ||
174 | phy_driver_unregister(&lxt970_driver); | ||
175 | phy_driver_unregister(&lxt971_driver); | ||
176 | } | ||
177 | |||
178 | module_init(lxt_init); | ||
179 | module_exit(lxt_exit); | ||
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c new file mode 100644 index 000000000000..4a72b025006b --- /dev/null +++ b/drivers/net/phy/marvell.c | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/marvell.c | ||
3 | * | ||
4 | * Driver for Marvell PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | #define MII_M1011_IEVENT 0x13 | ||
42 | #define MII_M1011_IEVENT_CLEAR 0x0000 | ||
43 | |||
44 | #define MII_M1011_IMASK 0x12 | ||
45 | #define MII_M1011_IMASK_INIT 0x6400 | ||
46 | #define MII_M1011_IMASK_CLEAR 0x0000 | ||
47 | |||
48 | MODULE_DESCRIPTION("Marvell PHY driver"); | ||
49 | MODULE_AUTHOR("Andy Fleming"); | ||
50 | MODULE_LICENSE("GPL"); | ||
51 | |||
52 | static int marvell_ack_interrupt(struct phy_device *phydev) | ||
53 | { | ||
54 | int err; | ||
55 | |||
56 | /* Clear the interrupts by reading the reg */ | ||
57 | err = phy_read(phydev, MII_M1011_IEVENT); | ||
58 | |||
59 | if (err < 0) | ||
60 | return err; | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int marvell_config_intr(struct phy_device *phydev) | ||
66 | { | ||
67 | int err; | ||
68 | |||
69 | if(phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
70 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_INIT); | ||
71 | else | ||
72 | err = phy_write(phydev, MII_M1011_IMASK, MII_M1011_IMASK_CLEAR); | ||
73 | |||
74 | return err; | ||
75 | } | ||
76 | |||
77 | static int marvell_config_aneg(struct phy_device *phydev) | ||
78 | { | ||
79 | int err; | ||
80 | |||
81 | /* The Marvell PHY has an errata which requires | ||
82 | * that certain registers get written in order | ||
83 | * to restart autonegotiation */ | ||
84 | err = phy_write(phydev, MII_BMCR, BMCR_RESET); | ||
85 | |||
86 | if (err < 0) | ||
87 | return err; | ||
88 | |||
89 | err = phy_write(phydev, 0x1d, 0x1f); | ||
90 | if (err < 0) | ||
91 | return err; | ||
92 | |||
93 | err = phy_write(phydev, 0x1e, 0x200c); | ||
94 | if (err < 0) | ||
95 | return err; | ||
96 | |||
97 | err = phy_write(phydev, 0x1d, 0x5); | ||
98 | if (err < 0) | ||
99 | return err; | ||
100 | |||
101 | err = phy_write(phydev, 0x1e, 0); | ||
102 | if (err < 0) | ||
103 | return err; | ||
104 | |||
105 | err = phy_write(phydev, 0x1e, 0x100); | ||
106 | if (err < 0) | ||
107 | return err; | ||
108 | |||
109 | |||
110 | err = genphy_config_aneg(phydev); | ||
111 | |||
112 | return err; | ||
113 | } | ||
114 | |||
115 | |||
116 | static struct phy_driver m88e1101_driver = { | ||
117 | .phy_id = 0x01410c00, | ||
118 | .phy_id_mask = 0xffffff00, | ||
119 | .name = "Marvell 88E1101", | ||
120 | .features = PHY_GBIT_FEATURES, | ||
121 | .flags = PHY_HAS_INTERRUPT, | ||
122 | .config_aneg = &marvell_config_aneg, | ||
123 | .read_status = &genphy_read_status, | ||
124 | .ack_interrupt = &marvell_ack_interrupt, | ||
125 | .config_intr = &marvell_config_intr, | ||
126 | .driver = { .owner = THIS_MODULE,}, | ||
127 | }; | ||
128 | |||
129 | static int __init marvell_init(void) | ||
130 | { | ||
131 | return phy_driver_register(&m88e1101_driver); | ||
132 | } | ||
133 | |||
134 | static void __exit marvell_exit(void) | ||
135 | { | ||
136 | phy_driver_unregister(&m88e1101_driver); | ||
137 | } | ||
138 | |||
139 | module_init(marvell_init); | ||
140 | module_exit(marvell_exit); | ||
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c new file mode 100644 index 000000000000..41f62c0c5fcb --- /dev/null +++ b/drivers/net/phy/mdio_bus.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/mdio_bus.c | ||
3 | * | ||
4 | * MDIO Bus interface | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* mdiobus_register | ||
42 | * | ||
43 | * description: Called by a bus driver to bring up all the PHYs | ||
44 | * on a given bus, and attach them to the bus | ||
45 | */ | ||
46 | int mdiobus_register(struct mii_bus *bus) | ||
47 | { | ||
48 | int i; | ||
49 | int err = 0; | ||
50 | |||
51 | spin_lock_init(&bus->mdio_lock); | ||
52 | |||
53 | if (NULL == bus || NULL == bus->name || | ||
54 | NULL == bus->read || | ||
55 | NULL == bus->write) | ||
56 | return -EINVAL; | ||
57 | |||
58 | if (bus->reset) | ||
59 | bus->reset(bus); | ||
60 | |||
61 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
62 | struct phy_device *phydev; | ||
63 | |||
64 | phydev = get_phy_device(bus, i); | ||
65 | |||
66 | if (IS_ERR(phydev)) | ||
67 | return PTR_ERR(phydev); | ||
68 | |||
69 | /* There's a PHY at this address | ||
70 | * We need to set: | ||
71 | * 1) IRQ | ||
72 | * 2) bus_id | ||
73 | * 3) parent | ||
74 | * 4) bus | ||
75 | * 5) mii_bus | ||
76 | * And, we need to register it */ | ||
77 | if (phydev) { | ||
78 | phydev->irq = bus->irq[i]; | ||
79 | |||
80 | phydev->dev.parent = bus->dev; | ||
81 | phydev->dev.bus = &mdio_bus_type; | ||
82 | sprintf(phydev->dev.bus_id, "phy%d:%d", bus->id, i); | ||
83 | |||
84 | phydev->bus = bus; | ||
85 | |||
86 | err = device_register(&phydev->dev); | ||
87 | |||
88 | if (err) | ||
89 | printk(KERN_ERR "phy %d failed to register\n", | ||
90 | i); | ||
91 | } | ||
92 | |||
93 | bus->phy_map[i] = phydev; | ||
94 | } | ||
95 | |||
96 | pr_info("%s: probed\n", bus->name); | ||
97 | |||
98 | return err; | ||
99 | } | ||
100 | EXPORT_SYMBOL(mdiobus_register); | ||
101 | |||
102 | void mdiobus_unregister(struct mii_bus *bus) | ||
103 | { | ||
104 | int i; | ||
105 | |||
106 | for (i = 0; i < PHY_MAX_ADDR; i++) { | ||
107 | if (bus->phy_map[i]) { | ||
108 | device_unregister(&bus->phy_map[i]->dev); | ||
109 | kfree(bus->phy_map[i]); | ||
110 | } | ||
111 | } | ||
112 | } | ||
113 | EXPORT_SYMBOL(mdiobus_unregister); | ||
114 | |||
115 | /* mdio_bus_match | ||
116 | * | ||
117 | * description: Given a PHY device, and a PHY driver, return 1 if | ||
118 | * the driver supports the device. Otherwise, return 0 | ||
119 | */ | ||
120 | static int mdio_bus_match(struct device *dev, struct device_driver *drv) | ||
121 | { | ||
122 | struct phy_device *phydev = to_phy_device(dev); | ||
123 | struct phy_driver *phydrv = to_phy_driver(drv); | ||
124 | |||
125 | return (phydrv->phy_id == (phydev->phy_id & phydrv->phy_id_mask)); | ||
126 | } | ||
127 | |||
128 | /* Suspend and resume. Copied from platform_suspend and | ||
129 | * platform_resume | ||
130 | */ | ||
131 | static int mdio_bus_suspend(struct device * dev, u32 state) | ||
132 | { | ||
133 | int ret = 0; | ||
134 | struct device_driver *drv = dev->driver; | ||
135 | |||
136 | if (drv && drv->suspend) { | ||
137 | ret = drv->suspend(dev, state, SUSPEND_DISABLE); | ||
138 | if (ret == 0) | ||
139 | ret = drv->suspend(dev, state, SUSPEND_SAVE_STATE); | ||
140 | if (ret == 0) | ||
141 | ret = drv->suspend(dev, state, SUSPEND_POWER_DOWN); | ||
142 | } | ||
143 | return ret; | ||
144 | } | ||
145 | |||
146 | static int mdio_bus_resume(struct device * dev) | ||
147 | { | ||
148 | int ret = 0; | ||
149 | struct device_driver *drv = dev->driver; | ||
150 | |||
151 | if (drv && drv->resume) { | ||
152 | ret = drv->resume(dev, RESUME_POWER_ON); | ||
153 | if (ret == 0) | ||
154 | ret = drv->resume(dev, RESUME_RESTORE_STATE); | ||
155 | if (ret == 0) | ||
156 | ret = drv->resume(dev, RESUME_ENABLE); | ||
157 | } | ||
158 | return ret; | ||
159 | } | ||
160 | |||
161 | struct bus_type mdio_bus_type = { | ||
162 | .name = "mdio_bus", | ||
163 | .match = mdio_bus_match, | ||
164 | .suspend = mdio_bus_suspend, | ||
165 | .resume = mdio_bus_resume, | ||
166 | }; | ||
167 | |||
168 | int __init mdio_bus_init(void) | ||
169 | { | ||
170 | return bus_register(&mdio_bus_type); | ||
171 | } | ||
172 | |||
173 | void __exit mdio_bus_exit(void) | ||
174 | { | ||
175 | bus_unregister(&mdio_bus_type); | ||
176 | } | ||
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c new file mode 100644 index 000000000000..d9e11f93bf3a --- /dev/null +++ b/drivers/net/phy/phy.c | |||
@@ -0,0 +1,871 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/phy.c | ||
3 | * | ||
4 | * Framework for configuring and reading PHY devices | ||
5 | * Based on code in sungem_phy.c and gianfar_phy.c | ||
6 | * | ||
7 | * Author: Andy Fleming | ||
8 | * | ||
9 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/version.h> | ||
34 | #include <linux/mii.h> | ||
35 | #include <linux/ethtool.h> | ||
36 | #include <linux/phy.h> | ||
37 | |||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | /* Convenience function to print out the current phy status | ||
43 | */ | ||
44 | void phy_print_status(struct phy_device *phydev) | ||
45 | { | ||
46 | pr_info("%s: Link is %s", phydev->dev.bus_id, | ||
47 | phydev->link ? "Up" : "Down"); | ||
48 | if (phydev->link) | ||
49 | printk(" - %d/%s", phydev->speed, | ||
50 | DUPLEX_FULL == phydev->duplex ? | ||
51 | "Full" : "Half"); | ||
52 | |||
53 | printk("\n"); | ||
54 | } | ||
55 | EXPORT_SYMBOL(phy_print_status); | ||
56 | |||
57 | |||
58 | /* Convenience functions for reading/writing a given PHY | ||
59 | * register. They MUST NOT be called from interrupt context, | ||
60 | * because the bus read/write functions may wait for an interrupt | ||
61 | * to conclude the operation. */ | ||
62 | int phy_read(struct phy_device *phydev, u16 regnum) | ||
63 | { | ||
64 | int retval; | ||
65 | struct mii_bus *bus = phydev->bus; | ||
66 | |||
67 | spin_lock_bh(&bus->mdio_lock); | ||
68 | retval = bus->read(bus, phydev->addr, regnum); | ||
69 | spin_unlock_bh(&bus->mdio_lock); | ||
70 | |||
71 | return retval; | ||
72 | } | ||
73 | EXPORT_SYMBOL(phy_read); | ||
74 | |||
75 | int phy_write(struct phy_device *phydev, u16 regnum, u16 val) | ||
76 | { | ||
77 | int err; | ||
78 | struct mii_bus *bus = phydev->bus; | ||
79 | |||
80 | spin_lock_bh(&bus->mdio_lock); | ||
81 | err = bus->write(bus, phydev->addr, regnum, val); | ||
82 | spin_unlock_bh(&bus->mdio_lock); | ||
83 | |||
84 | return err; | ||
85 | } | ||
86 | EXPORT_SYMBOL(phy_write); | ||
87 | |||
88 | |||
89 | int phy_clear_interrupt(struct phy_device *phydev) | ||
90 | { | ||
91 | int err = 0; | ||
92 | |||
93 | if (phydev->drv->ack_interrupt) | ||
94 | err = phydev->drv->ack_interrupt(phydev); | ||
95 | |||
96 | return err; | ||
97 | } | ||
98 | |||
99 | |||
100 | int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) | ||
101 | { | ||
102 | int err = 0; | ||
103 | |||
104 | phydev->interrupts = interrupts; | ||
105 | if (phydev->drv->config_intr) | ||
106 | err = phydev->drv->config_intr(phydev); | ||
107 | |||
108 | return err; | ||
109 | } | ||
110 | |||
111 | |||
112 | /* phy_aneg_done | ||
113 | * | ||
114 | * description: Reads the status register and returns 0 either if | ||
115 | * auto-negotiation is incomplete, or if there was an error. | ||
116 | * Returns BMSR_ANEGCOMPLETE if auto-negotiation is done. | ||
117 | */ | ||
118 | static inline int phy_aneg_done(struct phy_device *phydev) | ||
119 | { | ||
120 | int retval; | ||
121 | |||
122 | retval = phy_read(phydev, MII_BMSR); | ||
123 | |||
124 | return (retval < 0) ? retval : (retval & BMSR_ANEGCOMPLETE); | ||
125 | } | ||
126 | |||
127 | /* A structure for mapping a particular speed and duplex | ||
128 | * combination to a particular SUPPORTED and ADVERTISED value */ | ||
129 | struct phy_setting { | ||
130 | int speed; | ||
131 | int duplex; | ||
132 | u32 setting; | ||
133 | }; | ||
134 | |||
135 | /* A mapping of all SUPPORTED settings to speed/duplex */ | ||
136 | static struct phy_setting settings[] = { | ||
137 | { | ||
138 | .speed = 10000, | ||
139 | .duplex = DUPLEX_FULL, | ||
140 | .setting = SUPPORTED_10000baseT_Full, | ||
141 | }, | ||
142 | { | ||
143 | .speed = SPEED_1000, | ||
144 | .duplex = DUPLEX_FULL, | ||
145 | .setting = SUPPORTED_1000baseT_Full, | ||
146 | }, | ||
147 | { | ||
148 | .speed = SPEED_1000, | ||
149 | .duplex = DUPLEX_HALF, | ||
150 | .setting = SUPPORTED_1000baseT_Half, | ||
151 | }, | ||
152 | { | ||
153 | .speed = SPEED_100, | ||
154 | .duplex = DUPLEX_FULL, | ||
155 | .setting = SUPPORTED_100baseT_Full, | ||
156 | }, | ||
157 | { | ||
158 | .speed = SPEED_100, | ||
159 | .duplex = DUPLEX_HALF, | ||
160 | .setting = SUPPORTED_100baseT_Half, | ||
161 | }, | ||
162 | { | ||
163 | .speed = SPEED_10, | ||
164 | .duplex = DUPLEX_FULL, | ||
165 | .setting = SUPPORTED_10baseT_Full, | ||
166 | }, | ||
167 | { | ||
168 | .speed = SPEED_10, | ||
169 | .duplex = DUPLEX_HALF, | ||
170 | .setting = SUPPORTED_10baseT_Half, | ||
171 | }, | ||
172 | }; | ||
173 | |||
174 | #define MAX_NUM_SETTINGS (sizeof(settings)/sizeof(struct phy_setting)) | ||
175 | |||
176 | /* phy_find_setting | ||
177 | * | ||
178 | * description: Searches the settings array for the setting which | ||
179 | * matches the desired speed and duplex, and returns the index | ||
180 | * of that setting. Returns the index of the last setting if | ||
181 | * none of the others match. | ||
182 | */ | ||
183 | static inline int phy_find_setting(int speed, int duplex) | ||
184 | { | ||
185 | int idx = 0; | ||
186 | |||
187 | while (idx < ARRAY_SIZE(settings) && | ||
188 | (settings[idx].speed != speed || | ||
189 | settings[idx].duplex != duplex)) | ||
190 | idx++; | ||
191 | |||
192 | return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; | ||
193 | } | ||
194 | |||
195 | /* phy_find_valid | ||
196 | * idx: The first index in settings[] to search | ||
197 | * features: A mask of the valid settings | ||
198 | * | ||
199 | * description: Returns the index of the first valid setting less | ||
200 | * than or equal to the one pointed to by idx, as determined by | ||
201 | * the mask in features. Returns the index of the last setting | ||
202 | * if nothing else matches. | ||
203 | */ | ||
204 | static inline int phy_find_valid(int idx, u32 features) | ||
205 | { | ||
206 | while (idx < MAX_NUM_SETTINGS && !(settings[idx].setting & features)) | ||
207 | idx++; | ||
208 | |||
209 | return idx < MAX_NUM_SETTINGS ? idx : MAX_NUM_SETTINGS - 1; | ||
210 | } | ||
211 | |||
212 | /* phy_sanitize_settings | ||
213 | * | ||
214 | * description: Make sure the PHY is set to supported speeds and | ||
215 | * duplexes. Drop down by one in this order: 1000/FULL, | ||
216 | * 1000/HALF, 100/FULL, 100/HALF, 10/FULL, 10/HALF | ||
217 | */ | ||
218 | void phy_sanitize_settings(struct phy_device *phydev) | ||
219 | { | ||
220 | u32 features = phydev->supported; | ||
221 | int idx; | ||
222 | |||
223 | /* Sanitize settings based on PHY capabilities */ | ||
224 | if ((features & SUPPORTED_Autoneg) == 0) | ||
225 | phydev->autoneg = 0; | ||
226 | |||
227 | idx = phy_find_valid(phy_find_setting(phydev->speed, phydev->duplex), | ||
228 | features); | ||
229 | |||
230 | phydev->speed = settings[idx].speed; | ||
231 | phydev->duplex = settings[idx].duplex; | ||
232 | } | ||
233 | EXPORT_SYMBOL(phy_sanitize_settings); | ||
234 | |||
235 | /* phy_ethtool_sset: | ||
236 | * A generic ethtool sset function. Handles all the details | ||
237 | * | ||
238 | * A few notes about parameter checking: | ||
239 | * - We don't set port or transceiver, so we don't care what they | ||
240 | * were set to. | ||
241 | * - phy_start_aneg() will make sure forced settings are sane, and | ||
242 | * choose the next best ones from the ones selected, so we don't | ||
243 | * care if ethtool tries to give us bad values | ||
244 | * | ||
245 | * A note about the PHYCONTROL Layer. If you turn off | ||
246 | * CONFIG_PHYCONTROL, you will need to read the PHY status | ||
247 | * registers after this function completes, and update your | ||
248 | * controller manually. | ||
249 | */ | ||
250 | int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||
251 | { | ||
252 | if (cmd->phy_address != phydev->addr) | ||
253 | return -EINVAL; | ||
254 | |||
255 | /* We make sure that we don't pass unsupported | ||
256 | * values in to the PHY */ | ||
257 | cmd->advertising &= phydev->supported; | ||
258 | |||
259 | /* Verify the settings we care about. */ | ||
260 | if (cmd->autoneg != AUTONEG_ENABLE && cmd->autoneg != AUTONEG_DISABLE) | ||
261 | return -EINVAL; | ||
262 | |||
263 | if (cmd->autoneg == AUTONEG_ENABLE && cmd->advertising == 0) | ||
264 | return -EINVAL; | ||
265 | |||
266 | if (cmd->autoneg == AUTONEG_DISABLE | ||
267 | && ((cmd->speed != SPEED_1000 | ||
268 | && cmd->speed != SPEED_100 | ||
269 | && cmd->speed != SPEED_10) | ||
270 | || (cmd->duplex != DUPLEX_HALF | ||
271 | && cmd->duplex != DUPLEX_FULL))) | ||
272 | return -EINVAL; | ||
273 | |||
274 | phydev->autoneg = cmd->autoneg; | ||
275 | |||
276 | phydev->speed = cmd->speed; | ||
277 | |||
278 | phydev->advertising = cmd->advertising; | ||
279 | |||
280 | if (AUTONEG_ENABLE == cmd->autoneg) | ||
281 | phydev->advertising |= ADVERTISED_Autoneg; | ||
282 | else | ||
283 | phydev->advertising &= ~ADVERTISED_Autoneg; | ||
284 | |||
285 | phydev->duplex = cmd->duplex; | ||
286 | |||
287 | /* Restart the PHY */ | ||
288 | phy_start_aneg(phydev); | ||
289 | |||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd) | ||
294 | { | ||
295 | cmd->supported = phydev->supported; | ||
296 | |||
297 | cmd->advertising = phydev->advertising; | ||
298 | |||
299 | cmd->speed = phydev->speed; | ||
300 | cmd->duplex = phydev->duplex; | ||
301 | cmd->port = PORT_MII; | ||
302 | cmd->phy_address = phydev->addr; | ||
303 | cmd->transceiver = XCVR_EXTERNAL; | ||
304 | cmd->autoneg = phydev->autoneg; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | |||
310 | /* Note that this function is currently incompatible with the | ||
311 | * PHYCONTROL layer. It changes registers without regard to | ||
312 | * current state. Use at own risk | ||
313 | */ | ||
314 | int phy_mii_ioctl(struct phy_device *phydev, | ||
315 | struct mii_ioctl_data *mii_data, int cmd) | ||
316 | { | ||
317 | u16 val = mii_data->val_in; | ||
318 | |||
319 | switch (cmd) { | ||
320 | case SIOCGMIIPHY: | ||
321 | mii_data->phy_id = phydev->addr; | ||
322 | break; | ||
323 | case SIOCGMIIREG: | ||
324 | mii_data->val_out = phy_read(phydev, mii_data->reg_num); | ||
325 | break; | ||
326 | |||
327 | case SIOCSMIIREG: | ||
328 | if (!capable(CAP_NET_ADMIN)) | ||
329 | return -EPERM; | ||
330 | |||
331 | if (mii_data->phy_id == phydev->addr) { | ||
332 | switch(mii_data->reg_num) { | ||
333 | case MII_BMCR: | ||
334 | if (val & (BMCR_RESET|BMCR_ANENABLE)) | ||
335 | phydev->autoneg = AUTONEG_DISABLE; | ||
336 | else | ||
337 | phydev->autoneg = AUTONEG_ENABLE; | ||
338 | if ((!phydev->autoneg) && (val & BMCR_FULLDPLX)) | ||
339 | phydev->duplex = DUPLEX_FULL; | ||
340 | else | ||
341 | phydev->duplex = DUPLEX_HALF; | ||
342 | break; | ||
343 | case MII_ADVERTISE: | ||
344 | phydev->advertising = val; | ||
345 | break; | ||
346 | default: | ||
347 | /* do nothing */ | ||
348 | break; | ||
349 | } | ||
350 | } | ||
351 | |||
352 | phy_write(phydev, mii_data->reg_num, val); | ||
353 | |||
354 | if (mii_data->reg_num == MII_BMCR | ||
355 | && val & BMCR_RESET | ||
356 | && phydev->drv->config_init) | ||
357 | phydev->drv->config_init(phydev); | ||
358 | break; | ||
359 | } | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | /* phy_start_aneg | ||
365 | * | ||
366 | * description: Sanitizes the settings (if we're not | ||
367 | * autonegotiating them), and then calls the driver's | ||
368 | * config_aneg function. If the PHYCONTROL Layer is operating, | ||
369 | * we change the state to reflect the beginning of | ||
370 | * Auto-negotiation or forcing. | ||
371 | */ | ||
372 | int phy_start_aneg(struct phy_device *phydev) | ||
373 | { | ||
374 | int err; | ||
375 | |||
376 | spin_lock(&phydev->lock); | ||
377 | |||
378 | if (AUTONEG_DISABLE == phydev->autoneg) | ||
379 | phy_sanitize_settings(phydev); | ||
380 | |||
381 | err = phydev->drv->config_aneg(phydev); | ||
382 | |||
383 | #ifdef CONFIG_PHYCONTROL | ||
384 | if (err < 0) | ||
385 | goto out_unlock; | ||
386 | |||
387 | if (phydev->state != PHY_HALTED) { | ||
388 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
389 | phydev->state = PHY_AN; | ||
390 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
391 | } else { | ||
392 | phydev->state = PHY_FORCING; | ||
393 | phydev->link_timeout = PHY_FORCE_TIMEOUT; | ||
394 | } | ||
395 | } | ||
396 | |||
397 | out_unlock: | ||
398 | #endif | ||
399 | spin_unlock(&phydev->lock); | ||
400 | return err; | ||
401 | } | ||
402 | EXPORT_SYMBOL(phy_start_aneg); | ||
403 | |||
404 | |||
405 | #ifdef CONFIG_PHYCONTROL | ||
406 | static void phy_change(void *data); | ||
407 | static void phy_timer(unsigned long data); | ||
408 | |||
409 | /* phy_start_machine: | ||
410 | * | ||
411 | * description: The PHY infrastructure can run a state machine | ||
412 | * which tracks whether the PHY is starting up, negotiating, | ||
413 | * etc. This function starts the timer which tracks the state | ||
414 | * of the PHY. If you want to be notified when the state | ||
415 | * changes, pass in the callback, otherwise, pass NULL. If you | ||
416 | * want to maintain your own state machine, do not call this | ||
417 | * function. */ | ||
418 | void phy_start_machine(struct phy_device *phydev, | ||
419 | void (*handler)(struct net_device *)) | ||
420 | { | ||
421 | phydev->adjust_state = handler; | ||
422 | |||
423 | init_timer(&phydev->phy_timer); | ||
424 | phydev->phy_timer.function = &phy_timer; | ||
425 | phydev->phy_timer.data = (unsigned long) phydev; | ||
426 | mod_timer(&phydev->phy_timer, jiffies + HZ); | ||
427 | } | ||
428 | |||
429 | /* phy_stop_machine | ||
430 | * | ||
431 | * description: Stops the state machine timer, sets the state to | ||
432 | * UP (unless it wasn't up yet), and then frees the interrupt, | ||
433 | * if it is in use. This function must be called BEFORE | ||
434 | * phy_detach. | ||
435 | */ | ||
436 | void phy_stop_machine(struct phy_device *phydev) | ||
437 | { | ||
438 | del_timer_sync(&phydev->phy_timer); | ||
439 | |||
440 | spin_lock(&phydev->lock); | ||
441 | if (phydev->state > PHY_UP) | ||
442 | phydev->state = PHY_UP; | ||
443 | spin_unlock(&phydev->lock); | ||
444 | |||
445 | if (phydev->irq != PHY_POLL) | ||
446 | phy_stop_interrupts(phydev); | ||
447 | |||
448 | phydev->adjust_state = NULL; | ||
449 | } | ||
450 | |||
451 | /* phy_force_reduction | ||
452 | * | ||
453 | * description: Reduces the speed/duplex settings by | ||
454 | * one notch. The order is so: | ||
455 | * 1000/FULL, 1000/HALF, 100/FULL, 100/HALF, | ||
456 | * 10/FULL, 10/HALF. The function bottoms out at 10/HALF. | ||
457 | */ | ||
458 | static void phy_force_reduction(struct phy_device *phydev) | ||
459 | { | ||
460 | int idx; | ||
461 | |||
462 | idx = phy_find_setting(phydev->speed, phydev->duplex); | ||
463 | |||
464 | idx++; | ||
465 | |||
466 | idx = phy_find_valid(idx, phydev->supported); | ||
467 | |||
468 | phydev->speed = settings[idx].speed; | ||
469 | phydev->duplex = settings[idx].duplex; | ||
470 | |||
471 | pr_info("Trying %d/%s\n", phydev->speed, | ||
472 | DUPLEX_FULL == phydev->duplex ? | ||
473 | "FULL" : "HALF"); | ||
474 | } | ||
475 | |||
476 | |||
477 | /* phy_error: | ||
478 | * | ||
479 | * Moves the PHY to the HALTED state in response to a read | ||
480 | * or write error, and tells the controller the link is down. | ||
481 | * Must not be called from interrupt context, or while the | ||
482 | * phydev->lock is held. | ||
483 | */ | ||
484 | void phy_error(struct phy_device *phydev) | ||
485 | { | ||
486 | spin_lock(&phydev->lock); | ||
487 | phydev->state = PHY_HALTED; | ||
488 | spin_unlock(&phydev->lock); | ||
489 | } | ||
490 | |||
491 | /* phy_interrupt | ||
492 | * | ||
493 | * description: When a PHY interrupt occurs, the handler disables | ||
494 | * interrupts, and schedules a work task to clear the interrupt. | ||
495 | */ | ||
496 | static irqreturn_t phy_interrupt(int irq, void *phy_dat, struct pt_regs *regs) | ||
497 | { | ||
498 | struct phy_device *phydev = phy_dat; | ||
499 | |||
500 | /* The MDIO bus is not allowed to be written in interrupt | ||
501 | * context, so we need to disable the irq here. A work | ||
502 | * queue will write the PHY to disable and clear the | ||
503 | * interrupt, and then reenable the irq line. */ | ||
504 | disable_irq_nosync(irq); | ||
505 | |||
506 | schedule_work(&phydev->phy_queue); | ||
507 | |||
508 | return IRQ_HANDLED; | ||
509 | } | ||
510 | |||
511 | /* Enable the interrupts from the PHY side */ | ||
512 | int phy_enable_interrupts(struct phy_device *phydev) | ||
513 | { | ||
514 | int err; | ||
515 | |||
516 | err = phy_clear_interrupt(phydev); | ||
517 | |||
518 | if (err < 0) | ||
519 | return err; | ||
520 | |||
521 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); | ||
522 | |||
523 | return err; | ||
524 | } | ||
525 | EXPORT_SYMBOL(phy_enable_interrupts); | ||
526 | |||
527 | /* Disable the PHY interrupts from the PHY side */ | ||
528 | int phy_disable_interrupts(struct phy_device *phydev) | ||
529 | { | ||
530 | int err; | ||
531 | |||
532 | /* Disable PHY interrupts */ | ||
533 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
534 | |||
535 | if (err) | ||
536 | goto phy_err; | ||
537 | |||
538 | /* Clear the interrupt */ | ||
539 | err = phy_clear_interrupt(phydev); | ||
540 | |||
541 | if (err) | ||
542 | goto phy_err; | ||
543 | |||
544 | return 0; | ||
545 | |||
546 | phy_err: | ||
547 | phy_error(phydev); | ||
548 | |||
549 | return err; | ||
550 | } | ||
551 | EXPORT_SYMBOL(phy_disable_interrupts); | ||
552 | |||
553 | /* phy_start_interrupts | ||
554 | * | ||
555 | * description: Request the interrupt for the given PHY. If | ||
556 | * this fails, then we set irq to PHY_POLL. | ||
557 | * Otherwise, we enable the interrupts in the PHY. | ||
558 | * Returns 0 on success. | ||
559 | * This should only be called with a valid IRQ number. | ||
560 | */ | ||
561 | int phy_start_interrupts(struct phy_device *phydev) | ||
562 | { | ||
563 | int err = 0; | ||
564 | |||
565 | INIT_WORK(&phydev->phy_queue, phy_change, phydev); | ||
566 | |||
567 | if (request_irq(phydev->irq, phy_interrupt, | ||
568 | SA_SHIRQ, | ||
569 | "phy_interrupt", | ||
570 | phydev) < 0) { | ||
571 | printk(KERN_WARNING "%s: Can't get IRQ %d (PHY)\n", | ||
572 | phydev->bus->name, | ||
573 | phydev->irq); | ||
574 | phydev->irq = PHY_POLL; | ||
575 | return 0; | ||
576 | } | ||
577 | |||
578 | err = phy_enable_interrupts(phydev); | ||
579 | |||
580 | return err; | ||
581 | } | ||
582 | EXPORT_SYMBOL(phy_start_interrupts); | ||
583 | |||
584 | int phy_stop_interrupts(struct phy_device *phydev) | ||
585 | { | ||
586 | int err; | ||
587 | |||
588 | err = phy_disable_interrupts(phydev); | ||
589 | |||
590 | if (err) | ||
591 | phy_error(phydev); | ||
592 | |||
593 | free_irq(phydev->irq, phydev); | ||
594 | |||
595 | return err; | ||
596 | } | ||
597 | EXPORT_SYMBOL(phy_stop_interrupts); | ||
598 | |||
599 | |||
600 | /* Scheduled by the phy_interrupt/timer to handle PHY changes */ | ||
601 | static void phy_change(void *data) | ||
602 | { | ||
603 | int err; | ||
604 | struct phy_device *phydev = data; | ||
605 | |||
606 | err = phy_disable_interrupts(phydev); | ||
607 | |||
608 | if (err) | ||
609 | goto phy_err; | ||
610 | |||
611 | spin_lock(&phydev->lock); | ||
612 | if ((PHY_RUNNING == phydev->state) || (PHY_NOLINK == phydev->state)) | ||
613 | phydev->state = PHY_CHANGELINK; | ||
614 | spin_unlock(&phydev->lock); | ||
615 | |||
616 | enable_irq(phydev->irq); | ||
617 | |||
618 | /* Reenable interrupts */ | ||
619 | err = phy_config_interrupt(phydev, PHY_INTERRUPT_ENABLED); | ||
620 | |||
621 | if (err) | ||
622 | goto irq_enable_err; | ||
623 | |||
624 | return; | ||
625 | |||
626 | irq_enable_err: | ||
627 | disable_irq(phydev->irq); | ||
628 | phy_err: | ||
629 | phy_error(phydev); | ||
630 | } | ||
631 | |||
632 | /* Bring down the PHY link, and stop checking the status. */ | ||
633 | void phy_stop(struct phy_device *phydev) | ||
634 | { | ||
635 | spin_lock(&phydev->lock); | ||
636 | |||
637 | if (PHY_HALTED == phydev->state) | ||
638 | goto out_unlock; | ||
639 | |||
640 | if (phydev->irq != PHY_POLL) { | ||
641 | /* Clear any pending interrupts */ | ||
642 | phy_clear_interrupt(phydev); | ||
643 | |||
644 | /* Disable PHY Interrupts */ | ||
645 | phy_config_interrupt(phydev, PHY_INTERRUPT_DISABLED); | ||
646 | } | ||
647 | |||
648 | phydev->state = PHY_HALTED; | ||
649 | |||
650 | out_unlock: | ||
651 | spin_unlock(&phydev->lock); | ||
652 | } | ||
653 | |||
654 | |||
655 | /* phy_start | ||
656 | * | ||
657 | * description: Indicates the attached device's readiness to | ||
658 | * handle PHY-related work. Used during startup to start the | ||
659 | * PHY, and after a call to phy_stop() to resume operation. | ||
660 | * Also used to indicate the MDIO bus has cleared an error | ||
661 | * condition. | ||
662 | */ | ||
663 | void phy_start(struct phy_device *phydev) | ||
664 | { | ||
665 | spin_lock(&phydev->lock); | ||
666 | |||
667 | switch (phydev->state) { | ||
668 | case PHY_STARTING: | ||
669 | phydev->state = PHY_PENDING; | ||
670 | break; | ||
671 | case PHY_READY: | ||
672 | phydev->state = PHY_UP; | ||
673 | break; | ||
674 | case PHY_HALTED: | ||
675 | phydev->state = PHY_RESUMING; | ||
676 | default: | ||
677 | break; | ||
678 | } | ||
679 | spin_unlock(&phydev->lock); | ||
680 | } | ||
681 | EXPORT_SYMBOL(phy_stop); | ||
682 | EXPORT_SYMBOL(phy_start); | ||
683 | |||
684 | /* PHY timer which handles the state machine */ | ||
685 | static void phy_timer(unsigned long data) | ||
686 | { | ||
687 | struct phy_device *phydev = (struct phy_device *)data; | ||
688 | int needs_aneg = 0; | ||
689 | int err = 0; | ||
690 | |||
691 | spin_lock(&phydev->lock); | ||
692 | |||
693 | if (phydev->adjust_state) | ||
694 | phydev->adjust_state(phydev->attached_dev); | ||
695 | |||
696 | switch(phydev->state) { | ||
697 | case PHY_DOWN: | ||
698 | case PHY_STARTING: | ||
699 | case PHY_READY: | ||
700 | case PHY_PENDING: | ||
701 | break; | ||
702 | case PHY_UP: | ||
703 | needs_aneg = 1; | ||
704 | |||
705 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
706 | |||
707 | break; | ||
708 | case PHY_AN: | ||
709 | /* Check if negotiation is done. Break | ||
710 | * if there's an error */ | ||
711 | err = phy_aneg_done(phydev); | ||
712 | if (err < 0) | ||
713 | break; | ||
714 | |||
715 | /* If auto-negotiation is done, we change to | ||
716 | * either RUNNING, or NOLINK */ | ||
717 | if (err > 0) { | ||
718 | err = phy_read_status(phydev); | ||
719 | |||
720 | if (err) | ||
721 | break; | ||
722 | |||
723 | if (phydev->link) { | ||
724 | phydev->state = PHY_RUNNING; | ||
725 | netif_carrier_on(phydev->attached_dev); | ||
726 | } else { | ||
727 | phydev->state = PHY_NOLINK; | ||
728 | netif_carrier_off(phydev->attached_dev); | ||
729 | } | ||
730 | |||
731 | phydev->adjust_link(phydev->attached_dev); | ||
732 | |||
733 | } else if (0 == phydev->link_timeout--) { | ||
734 | /* The counter expired, so either we | ||
735 | * switch to forced mode, or the | ||
736 | * magic_aneg bit exists, and we try aneg | ||
737 | * again */ | ||
738 | if (!(phydev->drv->flags & PHY_HAS_MAGICANEG)) { | ||
739 | int idx; | ||
740 | |||
741 | /* We'll start from the | ||
742 | * fastest speed, and work | ||
743 | * our way down */ | ||
744 | idx = phy_find_valid(0, | ||
745 | phydev->supported); | ||
746 | |||
747 | phydev->speed = settings[idx].speed; | ||
748 | phydev->duplex = settings[idx].duplex; | ||
749 | |||
750 | phydev->autoneg = AUTONEG_DISABLE; | ||
751 | phydev->state = PHY_FORCING; | ||
752 | phydev->link_timeout = | ||
753 | PHY_FORCE_TIMEOUT; | ||
754 | |||
755 | pr_info("Trying %d/%s\n", | ||
756 | phydev->speed, | ||
757 | DUPLEX_FULL == | ||
758 | phydev->duplex ? | ||
759 | "FULL" : "HALF"); | ||
760 | } | ||
761 | |||
762 | needs_aneg = 1; | ||
763 | } | ||
764 | break; | ||
765 | case PHY_NOLINK: | ||
766 | err = phy_read_status(phydev); | ||
767 | |||
768 | if (err) | ||
769 | break; | ||
770 | |||
771 | if (phydev->link) { | ||
772 | phydev->state = PHY_RUNNING; | ||
773 | netif_carrier_on(phydev->attached_dev); | ||
774 | phydev->adjust_link(phydev->attached_dev); | ||
775 | } | ||
776 | break; | ||
777 | case PHY_FORCING: | ||
778 | err = phy_read_status(phydev); | ||
779 | |||
780 | if (err) | ||
781 | break; | ||
782 | |||
783 | if (phydev->link) { | ||
784 | phydev->state = PHY_RUNNING; | ||
785 | netif_carrier_on(phydev->attached_dev); | ||
786 | } else { | ||
787 | if (0 == phydev->link_timeout--) { | ||
788 | phy_force_reduction(phydev); | ||
789 | needs_aneg = 1; | ||
790 | } | ||
791 | } | ||
792 | |||
793 | phydev->adjust_link(phydev->attached_dev); | ||
794 | break; | ||
795 | case PHY_RUNNING: | ||
796 | /* Only register a CHANGE if we are | ||
797 | * polling */ | ||
798 | if (PHY_POLL == phydev->irq) | ||
799 | phydev->state = PHY_CHANGELINK; | ||
800 | break; | ||
801 | case PHY_CHANGELINK: | ||
802 | err = phy_read_status(phydev); | ||
803 | |||
804 | if (err) | ||
805 | break; | ||
806 | |||
807 | if (phydev->link) { | ||
808 | phydev->state = PHY_RUNNING; | ||
809 | netif_carrier_on(phydev->attached_dev); | ||
810 | } else { | ||
811 | phydev->state = PHY_NOLINK; | ||
812 | netif_carrier_off(phydev->attached_dev); | ||
813 | } | ||
814 | |||
815 | phydev->adjust_link(phydev->attached_dev); | ||
816 | |||
817 | if (PHY_POLL != phydev->irq) | ||
818 | err = phy_config_interrupt(phydev, | ||
819 | PHY_INTERRUPT_ENABLED); | ||
820 | break; | ||
821 | case PHY_HALTED: | ||
822 | if (phydev->link) { | ||
823 | phydev->link = 0; | ||
824 | netif_carrier_off(phydev->attached_dev); | ||
825 | phydev->adjust_link(phydev->attached_dev); | ||
826 | } | ||
827 | break; | ||
828 | case PHY_RESUMING: | ||
829 | |||
830 | err = phy_clear_interrupt(phydev); | ||
831 | |||
832 | if (err) | ||
833 | break; | ||
834 | |||
835 | err = phy_config_interrupt(phydev, | ||
836 | PHY_INTERRUPT_ENABLED); | ||
837 | |||
838 | if (err) | ||
839 | break; | ||
840 | |||
841 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
842 | err = phy_aneg_done(phydev); | ||
843 | if (err < 0) | ||
844 | break; | ||
845 | |||
846 | /* err > 0 if AN is done. | ||
847 | * Otherwise, it's 0, and we're | ||
848 | * still waiting for AN */ | ||
849 | if (err > 0) { | ||
850 | phydev->state = PHY_RUNNING; | ||
851 | } else { | ||
852 | phydev->state = PHY_AN; | ||
853 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
854 | } | ||
855 | } else | ||
856 | phydev->state = PHY_RUNNING; | ||
857 | break; | ||
858 | } | ||
859 | |||
860 | spin_unlock(&phydev->lock); | ||
861 | |||
862 | if (needs_aneg) | ||
863 | err = phy_start_aneg(phydev); | ||
864 | |||
865 | if (err < 0) | ||
866 | phy_error(phydev); | ||
867 | |||
868 | mod_timer(&phydev->phy_timer, jiffies + PHY_STATE_TIME * HZ); | ||
869 | } | ||
870 | |||
871 | #endif /* CONFIG_PHYCONTROL */ | ||
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c new file mode 100644 index 000000000000..33f7bdb5857c --- /dev/null +++ b/drivers/net/phy/phy_device.c | |||
@@ -0,0 +1,696 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/phy_device.c | ||
3 | * | ||
4 | * Framework for finding and configuring PHYs. | ||
5 | * Also contains generic PHY driver | ||
6 | * | ||
7 | * Author: Andy Fleming | ||
8 | * | ||
9 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/config.h> | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/string.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/unistd.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/delay.h> | ||
27 | #include <linux/netdevice.h> | ||
28 | #include <linux/etherdevice.h> | ||
29 | #include <linux/skbuff.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <linux/mm.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/version.h> | ||
34 | #include <linux/mii.h> | ||
35 | #include <linux/ethtool.h> | ||
36 | #include <linux/phy.h> | ||
37 | |||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/uaccess.h> | ||
41 | |||
42 | static struct phy_driver genphy_driver; | ||
43 | extern int mdio_bus_init(void); | ||
44 | extern void mdio_bus_exit(void); | ||
45 | |||
46 | /* get_phy_device | ||
47 | * | ||
48 | * description: Reads the ID registers of the PHY at addr on the | ||
49 | * bus, then allocates and returns the phy_device to | ||
50 | * represent it. | ||
51 | */ | ||
52 | struct phy_device * get_phy_device(struct mii_bus *bus, int addr) | ||
53 | { | ||
54 | int phy_reg; | ||
55 | u32 phy_id; | ||
56 | struct phy_device *dev = NULL; | ||
57 | |||
58 | /* Grab the bits from PHYIR1, and put them | ||
59 | * in the upper half */ | ||
60 | phy_reg = bus->read(bus, addr, MII_PHYSID1); | ||
61 | |||
62 | if (phy_reg < 0) | ||
63 | return ERR_PTR(phy_reg); | ||
64 | |||
65 | phy_id = (phy_reg & 0xffff) << 16; | ||
66 | |||
67 | /* Grab the bits from PHYIR2, and put them in the lower half */ | ||
68 | phy_reg = bus->read(bus, addr, MII_PHYSID2); | ||
69 | |||
70 | if (phy_reg < 0) | ||
71 | return ERR_PTR(phy_reg); | ||
72 | |||
73 | phy_id |= (phy_reg & 0xffff); | ||
74 | |||
75 | /* If the phy_id is all Fs, there is no device there */ | ||
76 | if (0xffffffff == phy_id) | ||
77 | return NULL; | ||
78 | |||
79 | /* Otherwise, we allocate the device, and initialize the | ||
80 | * default values */ | ||
81 | dev = kcalloc(1, sizeof(*dev), GFP_KERNEL); | ||
82 | |||
83 | if (NULL == dev) | ||
84 | return ERR_PTR(-ENOMEM); | ||
85 | |||
86 | dev->speed = 0; | ||
87 | dev->duplex = -1; | ||
88 | dev->pause = dev->asym_pause = 0; | ||
89 | dev->link = 1; | ||
90 | |||
91 | dev->autoneg = AUTONEG_ENABLE; | ||
92 | |||
93 | dev->addr = addr; | ||
94 | dev->phy_id = phy_id; | ||
95 | dev->bus = bus; | ||
96 | |||
97 | dev->state = PHY_DOWN; | ||
98 | |||
99 | spin_lock_init(&dev->lock); | ||
100 | |||
101 | return dev; | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_PHYCONTROL | ||
105 | /* phy_prepare_link: | ||
106 | * | ||
107 | * description: Tells the PHY infrastructure to handle the | ||
108 | * gory details on monitoring link status (whether through | ||
109 | * polling or an interrupt), and to call back to the | ||
110 | * connected device driver when the link status changes. | ||
111 | * If you want to monitor your own link state, don't call | ||
112 | * this function */ | ||
113 | void phy_prepare_link(struct phy_device *phydev, | ||
114 | void (*handler)(struct net_device *)) | ||
115 | { | ||
116 | phydev->adjust_link = handler; | ||
117 | } | ||
118 | |||
119 | /* phy_connect: | ||
120 | * | ||
121 | * description: Convenience function for connecting ethernet | ||
122 | * devices to PHY devices. The default behavior is for | ||
123 | * the PHY infrastructure to handle everything, and only notify | ||
124 | * the connected driver when the link status changes. If you | ||
125 | * don't want, or can't use the provided functionality, you may | ||
126 | * choose to call only the subset of functions which provide | ||
127 | * the desired functionality. | ||
128 | */ | ||
129 | struct phy_device * phy_connect(struct net_device *dev, const char *phy_id, | ||
130 | void (*handler)(struct net_device *), u32 flags) | ||
131 | { | ||
132 | struct phy_device *phydev; | ||
133 | |||
134 | phydev = phy_attach(dev, phy_id, flags); | ||
135 | |||
136 | if (IS_ERR(phydev)) | ||
137 | return phydev; | ||
138 | |||
139 | phy_prepare_link(phydev, handler); | ||
140 | |||
141 | phy_start_machine(phydev, NULL); | ||
142 | |||
143 | if (phydev->irq > 0) | ||
144 | phy_start_interrupts(phydev); | ||
145 | |||
146 | return phydev; | ||
147 | } | ||
148 | EXPORT_SYMBOL(phy_connect); | ||
149 | |||
150 | void phy_disconnect(struct phy_device *phydev) | ||
151 | { | ||
152 | if (phydev->irq > 0) | ||
153 | phy_stop_interrupts(phydev); | ||
154 | |||
155 | phy_stop_machine(phydev); | ||
156 | |||
157 | phydev->adjust_link = NULL; | ||
158 | |||
159 | phy_detach(phydev); | ||
160 | } | ||
161 | EXPORT_SYMBOL(phy_disconnect); | ||
162 | |||
163 | #endif /* CONFIG_PHYCONTROL */ | ||
164 | |||
165 | /* phy_attach: | ||
166 | * | ||
167 | * description: Called by drivers to attach to a particular PHY | ||
168 | * device. The phy_device is found, and properly hooked up | ||
169 | * to the phy_driver. If no driver is attached, then the | ||
170 | * genphy_driver is used. The phy_device is given a ptr to | ||
171 | * the attaching device, and given a callback for link status | ||
172 | * change. The phy_device is returned to the attaching | ||
173 | * driver. | ||
174 | */ | ||
175 | static int phy_compare_id(struct device *dev, void *data) | ||
176 | { | ||
177 | return strcmp((char *)data, dev->bus_id) ? 0 : 1; | ||
178 | } | ||
179 | |||
180 | struct phy_device *phy_attach(struct net_device *dev, | ||
181 | const char *phy_id, u32 flags) | ||
182 | { | ||
183 | struct bus_type *bus = &mdio_bus_type; | ||
184 | struct phy_device *phydev; | ||
185 | struct device *d; | ||
186 | |||
187 | /* Search the list of PHY devices on the mdio bus for the | ||
188 | * PHY with the requested name */ | ||
189 | d = bus_find_device(bus, NULL, (void *)phy_id, phy_compare_id); | ||
190 | |||
191 | if (d) { | ||
192 | phydev = to_phy_device(d); | ||
193 | } else { | ||
194 | printk(KERN_ERR "%s not found\n", phy_id); | ||
195 | return ERR_PTR(-ENODEV); | ||
196 | } | ||
197 | |||
198 | /* Assume that if there is no driver, that it doesn't | ||
199 | * exist, and we should use the genphy driver. */ | ||
200 | if (NULL == d->driver) { | ||
201 | int err; | ||
202 | down_write(&d->bus->subsys.rwsem); | ||
203 | d->driver = &genphy_driver.driver; | ||
204 | |||
205 | err = d->driver->probe(d); | ||
206 | |||
207 | if (err < 0) | ||
208 | return ERR_PTR(err); | ||
209 | |||
210 | device_bind_driver(d); | ||
211 | up_write(&d->bus->subsys.rwsem); | ||
212 | } | ||
213 | |||
214 | if (phydev->attached_dev) { | ||
215 | printk(KERN_ERR "%s: %s already attached\n", | ||
216 | dev->name, phy_id); | ||
217 | return ERR_PTR(-EBUSY); | ||
218 | } | ||
219 | |||
220 | phydev->attached_dev = dev; | ||
221 | |||
222 | phydev->dev_flags = flags; | ||
223 | |||
224 | return phydev; | ||
225 | } | ||
226 | EXPORT_SYMBOL(phy_attach); | ||
227 | |||
228 | void phy_detach(struct phy_device *phydev) | ||
229 | { | ||
230 | phydev->attached_dev = NULL; | ||
231 | |||
232 | /* If the device had no specific driver before (i.e. - it | ||
233 | * was using the generic driver), we unbind the device | ||
234 | * from the generic driver so that there's a chance a | ||
235 | * real driver could be loaded */ | ||
236 | if (phydev->dev.driver == &genphy_driver.driver) { | ||
237 | down_write(&phydev->dev.bus->subsys.rwsem); | ||
238 | device_release_driver(&phydev->dev); | ||
239 | up_write(&phydev->dev.bus->subsys.rwsem); | ||
240 | } | ||
241 | } | ||
242 | EXPORT_SYMBOL(phy_detach); | ||
243 | |||
244 | |||
245 | /* Generic PHY support and helper functions */ | ||
246 | |||
247 | /* genphy_config_advert | ||
248 | * | ||
249 | * description: Writes MII_ADVERTISE with the appropriate values, | ||
250 | * after sanitizing the values to make sure we only advertise | ||
251 | * what is supported | ||
252 | */ | ||
253 | int genphy_config_advert(struct phy_device *phydev) | ||
254 | { | ||
255 | u32 advertise; | ||
256 | int adv; | ||
257 | int err; | ||
258 | |||
259 | /* Only allow advertising what | ||
260 | * this PHY supports */ | ||
261 | phydev->advertising &= phydev->supported; | ||
262 | advertise = phydev->advertising; | ||
263 | |||
264 | /* Setup standard advertisement */ | ||
265 | adv = phy_read(phydev, MII_ADVERTISE); | ||
266 | |||
267 | if (adv < 0) | ||
268 | return adv; | ||
269 | |||
270 | adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | | ||
271 | ADVERTISE_PAUSE_ASYM); | ||
272 | if (advertise & ADVERTISED_10baseT_Half) | ||
273 | adv |= ADVERTISE_10HALF; | ||
274 | if (advertise & ADVERTISED_10baseT_Full) | ||
275 | adv |= ADVERTISE_10FULL; | ||
276 | if (advertise & ADVERTISED_100baseT_Half) | ||
277 | adv |= ADVERTISE_100HALF; | ||
278 | if (advertise & ADVERTISED_100baseT_Full) | ||
279 | adv |= ADVERTISE_100FULL; | ||
280 | if (advertise & ADVERTISED_Pause) | ||
281 | adv |= ADVERTISE_PAUSE_CAP; | ||
282 | if (advertise & ADVERTISED_Asym_Pause) | ||
283 | adv |= ADVERTISE_PAUSE_ASYM; | ||
284 | |||
285 | err = phy_write(phydev, MII_ADVERTISE, adv); | ||
286 | |||
287 | if (err < 0) | ||
288 | return err; | ||
289 | |||
290 | /* Configure gigabit if it's supported */ | ||
291 | if (phydev->supported & (SUPPORTED_1000baseT_Half | | ||
292 | SUPPORTED_1000baseT_Full)) { | ||
293 | adv = phy_read(phydev, MII_CTRL1000); | ||
294 | |||
295 | if (adv < 0) | ||
296 | return adv; | ||
297 | |||
298 | adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF); | ||
299 | if (advertise & SUPPORTED_1000baseT_Half) | ||
300 | adv |= ADVERTISE_1000HALF; | ||
301 | if (advertise & SUPPORTED_1000baseT_Full) | ||
302 | adv |= ADVERTISE_1000FULL; | ||
303 | err = phy_write(phydev, MII_CTRL1000, adv); | ||
304 | |||
305 | if (err < 0) | ||
306 | return err; | ||
307 | } | ||
308 | |||
309 | return adv; | ||
310 | } | ||
311 | EXPORT_SYMBOL(genphy_config_advert); | ||
312 | |||
313 | /* genphy_setup_forced | ||
314 | * | ||
315 | * description: Configures MII_BMCR to force speed/duplex | ||
316 | * to the values in phydev. Assumes that the values are valid. | ||
317 | * Please see phy_sanitize_settings() */ | ||
318 | int genphy_setup_forced(struct phy_device *phydev) | ||
319 | { | ||
320 | int ctl = BMCR_RESET; | ||
321 | |||
322 | phydev->pause = phydev->asym_pause = 0; | ||
323 | |||
324 | if (SPEED_1000 == phydev->speed) | ||
325 | ctl |= BMCR_SPEED1000; | ||
326 | else if (SPEED_100 == phydev->speed) | ||
327 | ctl |= BMCR_SPEED100; | ||
328 | |||
329 | if (DUPLEX_FULL == phydev->duplex) | ||
330 | ctl |= BMCR_FULLDPLX; | ||
331 | |||
332 | ctl = phy_write(phydev, MII_BMCR, ctl); | ||
333 | |||
334 | if (ctl < 0) | ||
335 | return ctl; | ||
336 | |||
337 | /* We just reset the device, so we'd better configure any | ||
338 | * settings the PHY requires to operate */ | ||
339 | if (phydev->drv->config_init) | ||
340 | ctl = phydev->drv->config_init(phydev); | ||
341 | |||
342 | return ctl; | ||
343 | } | ||
344 | |||
345 | |||
346 | /* Enable and Restart Autonegotiation */ | ||
347 | int genphy_restart_aneg(struct phy_device *phydev) | ||
348 | { | ||
349 | int ctl; | ||
350 | |||
351 | ctl = phy_read(phydev, MII_BMCR); | ||
352 | |||
353 | if (ctl < 0) | ||
354 | return ctl; | ||
355 | |||
356 | ctl |= (BMCR_ANENABLE | BMCR_ANRESTART); | ||
357 | |||
358 | /* Don't isolate the PHY if we're negotiating */ | ||
359 | ctl &= ~(BMCR_ISOLATE); | ||
360 | |||
361 | ctl = phy_write(phydev, MII_BMCR, ctl); | ||
362 | |||
363 | return ctl; | ||
364 | } | ||
365 | |||
366 | |||
367 | /* genphy_config_aneg | ||
368 | * | ||
369 | * description: If auto-negotiation is enabled, we configure the | ||
370 | * advertising, and then restart auto-negotiation. If it is not | ||
371 | * enabled, then we write the BMCR | ||
372 | */ | ||
373 | int genphy_config_aneg(struct phy_device *phydev) | ||
374 | { | ||
375 | int err = 0; | ||
376 | |||
377 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
378 | err = genphy_config_advert(phydev); | ||
379 | |||
380 | if (err < 0) | ||
381 | return err; | ||
382 | |||
383 | err = genphy_restart_aneg(phydev); | ||
384 | } else | ||
385 | err = genphy_setup_forced(phydev); | ||
386 | |||
387 | return err; | ||
388 | } | ||
389 | EXPORT_SYMBOL(genphy_config_aneg); | ||
390 | |||
391 | /* genphy_update_link | ||
392 | * | ||
393 | * description: Update the value in phydev->link to reflect the | ||
394 | * current link value. In order to do this, we need to read | ||
395 | * the status register twice, keeping the second value | ||
396 | */ | ||
397 | int genphy_update_link(struct phy_device *phydev) | ||
398 | { | ||
399 | int status; | ||
400 | |||
401 | /* Do a fake read */ | ||
402 | status = phy_read(phydev, MII_BMSR); | ||
403 | |||
404 | if (status < 0) | ||
405 | return status; | ||
406 | |||
407 | /* Read link and autonegotiation status */ | ||
408 | status = phy_read(phydev, MII_BMSR); | ||
409 | |||
410 | if (status < 0) | ||
411 | return status; | ||
412 | |||
413 | if ((status & BMSR_LSTATUS) == 0) | ||
414 | phydev->link = 0; | ||
415 | else | ||
416 | phydev->link = 1; | ||
417 | |||
418 | return 0; | ||
419 | } | ||
420 | |||
421 | /* genphy_read_status | ||
422 | * | ||
423 | * description: Check the link, then figure out the current state | ||
424 | * by comparing what we advertise with what the link partner | ||
425 | * advertises. Start by checking the gigabit possibilities, | ||
426 | * then move on to 10/100. | ||
427 | */ | ||
428 | int genphy_read_status(struct phy_device *phydev) | ||
429 | { | ||
430 | int adv; | ||
431 | int err; | ||
432 | int lpa; | ||
433 | int lpagb = 0; | ||
434 | |||
435 | /* Update the link, but return if there | ||
436 | * was an error */ | ||
437 | err = genphy_update_link(phydev); | ||
438 | if (err) | ||
439 | return err; | ||
440 | |||
441 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
442 | if (phydev->supported & (SUPPORTED_1000baseT_Half | ||
443 | | SUPPORTED_1000baseT_Full)) { | ||
444 | lpagb = phy_read(phydev, MII_STAT1000); | ||
445 | |||
446 | if (lpagb < 0) | ||
447 | return lpagb; | ||
448 | |||
449 | adv = phy_read(phydev, MII_CTRL1000); | ||
450 | |||
451 | if (adv < 0) | ||
452 | return adv; | ||
453 | |||
454 | lpagb &= adv << 2; | ||
455 | } | ||
456 | |||
457 | lpa = phy_read(phydev, MII_LPA); | ||
458 | |||
459 | if (lpa < 0) | ||
460 | return lpa; | ||
461 | |||
462 | adv = phy_read(phydev, MII_ADVERTISE); | ||
463 | |||
464 | if (adv < 0) | ||
465 | return adv; | ||
466 | |||
467 | lpa &= adv; | ||
468 | |||
469 | phydev->speed = SPEED_10; | ||
470 | phydev->duplex = DUPLEX_HALF; | ||
471 | phydev->pause = phydev->asym_pause = 0; | ||
472 | |||
473 | if (lpagb & (LPA_1000FULL | LPA_1000HALF)) { | ||
474 | phydev->speed = SPEED_1000; | ||
475 | |||
476 | if (lpagb & LPA_1000FULL) | ||
477 | phydev->duplex = DUPLEX_FULL; | ||
478 | } else if (lpa & (LPA_100FULL | LPA_100HALF)) { | ||
479 | phydev->speed = SPEED_100; | ||
480 | |||
481 | if (lpa & LPA_100FULL) | ||
482 | phydev->duplex = DUPLEX_FULL; | ||
483 | } else | ||
484 | if (lpa & LPA_10FULL) | ||
485 | phydev->duplex = DUPLEX_FULL; | ||
486 | |||
487 | if (phydev->duplex == DUPLEX_FULL){ | ||
488 | phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0; | ||
489 | phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0; | ||
490 | } | ||
491 | } else { | ||
492 | int bmcr = phy_read(phydev, MII_BMCR); | ||
493 | if (bmcr < 0) | ||
494 | return bmcr; | ||
495 | |||
496 | if (bmcr & BMCR_FULLDPLX) | ||
497 | phydev->duplex = DUPLEX_FULL; | ||
498 | else | ||
499 | phydev->duplex = DUPLEX_HALF; | ||
500 | |||
501 | if (bmcr & BMCR_SPEED1000) | ||
502 | phydev->speed = SPEED_1000; | ||
503 | else if (bmcr & BMCR_SPEED100) | ||
504 | phydev->speed = SPEED_100; | ||
505 | else | ||
506 | phydev->speed = SPEED_10; | ||
507 | |||
508 | phydev->pause = phydev->asym_pause = 0; | ||
509 | } | ||
510 | |||
511 | return 0; | ||
512 | } | ||
513 | EXPORT_SYMBOL(genphy_read_status); | ||
514 | |||
515 | static int genphy_config_init(struct phy_device *phydev) | ||
516 | { | ||
517 | u32 val; | ||
518 | u32 features; | ||
519 | |||
520 | /* For now, I'll claim that the generic driver supports | ||
521 | * all possible port types */ | ||
522 | features = (SUPPORTED_TP | SUPPORTED_MII | ||
523 | | SUPPORTED_AUI | SUPPORTED_FIBRE | | ||
524 | SUPPORTED_BNC); | ||
525 | |||
526 | /* Do we support autonegotiation? */ | ||
527 | val = phy_read(phydev, MII_BMSR); | ||
528 | |||
529 | if (val < 0) | ||
530 | return val; | ||
531 | |||
532 | if (val & BMSR_ANEGCAPABLE) | ||
533 | features |= SUPPORTED_Autoneg; | ||
534 | |||
535 | if (val & BMSR_100FULL) | ||
536 | features |= SUPPORTED_100baseT_Full; | ||
537 | if (val & BMSR_100HALF) | ||
538 | features |= SUPPORTED_100baseT_Half; | ||
539 | if (val & BMSR_10FULL) | ||
540 | features |= SUPPORTED_10baseT_Full; | ||
541 | if (val & BMSR_10HALF) | ||
542 | features |= SUPPORTED_10baseT_Half; | ||
543 | |||
544 | if (val & BMSR_ESTATEN) { | ||
545 | val = phy_read(phydev, MII_ESTATUS); | ||
546 | |||
547 | if (val < 0) | ||
548 | return val; | ||
549 | |||
550 | if (val & ESTATUS_1000_TFULL) | ||
551 | features |= SUPPORTED_1000baseT_Full; | ||
552 | if (val & ESTATUS_1000_THALF) | ||
553 | features |= SUPPORTED_1000baseT_Half; | ||
554 | } | ||
555 | |||
556 | phydev->supported = features; | ||
557 | phydev->advertising = features; | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | |||
563 | /* phy_probe | ||
564 | * | ||
565 | * description: Take care of setting up the phy_device structure, | ||
566 | * set the state to READY (the driver's init function should | ||
567 | * set it to STARTING if needed). | ||
568 | */ | ||
569 | static int phy_probe(struct device *dev) | ||
570 | { | ||
571 | struct phy_device *phydev; | ||
572 | struct phy_driver *phydrv; | ||
573 | struct device_driver *drv; | ||
574 | int err = 0; | ||
575 | |||
576 | phydev = to_phy_device(dev); | ||
577 | |||
578 | /* Make sure the driver is held. | ||
579 | * XXX -- Is this correct? */ | ||
580 | drv = get_driver(phydev->dev.driver); | ||
581 | phydrv = to_phy_driver(drv); | ||
582 | phydev->drv = phydrv; | ||
583 | |||
584 | /* Disable the interrupt if the PHY doesn't support it */ | ||
585 | if (!(phydrv->flags & PHY_HAS_INTERRUPT)) | ||
586 | phydev->irq = PHY_POLL; | ||
587 | |||
588 | spin_lock(&phydev->lock); | ||
589 | |||
590 | /* Start out supporting everything. Eventually, | ||
591 | * a controller will attach, and may modify one | ||
592 | * or both of these values */ | ||
593 | phydev->supported = phydrv->features; | ||
594 | phydev->advertising = phydrv->features; | ||
595 | |||
596 | /* Set the state to READY by default */ | ||
597 | phydev->state = PHY_READY; | ||
598 | |||
599 | if (phydev->drv->probe) | ||
600 | err = phydev->drv->probe(phydev); | ||
601 | |||
602 | spin_unlock(&phydev->lock); | ||
603 | |||
604 | if (err < 0) | ||
605 | return err; | ||
606 | |||
607 | if (phydev->drv->config_init) | ||
608 | err = phydev->drv->config_init(phydev); | ||
609 | |||
610 | return err; | ||
611 | } | ||
612 | |||
613 | static int phy_remove(struct device *dev) | ||
614 | { | ||
615 | struct phy_device *phydev; | ||
616 | |||
617 | phydev = to_phy_device(dev); | ||
618 | |||
619 | spin_lock(&phydev->lock); | ||
620 | phydev->state = PHY_DOWN; | ||
621 | spin_unlock(&phydev->lock); | ||
622 | |||
623 | if (phydev->drv->remove) | ||
624 | phydev->drv->remove(phydev); | ||
625 | |||
626 | put_driver(dev->driver); | ||
627 | phydev->drv = NULL; | ||
628 | |||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | int phy_driver_register(struct phy_driver *new_driver) | ||
633 | { | ||
634 | int retval; | ||
635 | |||
636 | memset(&new_driver->driver, 0, sizeof(new_driver->driver)); | ||
637 | new_driver->driver.name = new_driver->name; | ||
638 | new_driver->driver.bus = &mdio_bus_type; | ||
639 | new_driver->driver.probe = phy_probe; | ||
640 | new_driver->driver.remove = phy_remove; | ||
641 | |||
642 | retval = driver_register(&new_driver->driver); | ||
643 | |||
644 | if (retval) { | ||
645 | printk(KERN_ERR "%s: Error %d in registering driver\n", | ||
646 | new_driver->name, retval); | ||
647 | |||
648 | return retval; | ||
649 | } | ||
650 | |||
651 | pr_info("%s: Registered new driver\n", new_driver->name); | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | EXPORT_SYMBOL(phy_driver_register); | ||
656 | |||
657 | void phy_driver_unregister(struct phy_driver *drv) | ||
658 | { | ||
659 | driver_unregister(&drv->driver); | ||
660 | } | ||
661 | EXPORT_SYMBOL(phy_driver_unregister); | ||
662 | |||
663 | static struct phy_driver genphy_driver = { | ||
664 | .phy_id = 0xffffffff, | ||
665 | .phy_id_mask = 0xffffffff, | ||
666 | .name = "Generic PHY", | ||
667 | .config_init = genphy_config_init, | ||
668 | .features = 0, | ||
669 | .config_aneg = genphy_config_aneg, | ||
670 | .read_status = genphy_read_status, | ||
671 | .driver = {.owner= THIS_MODULE, }, | ||
672 | }; | ||
673 | |||
674 | static int __init phy_init(void) | ||
675 | { | ||
676 | int rc; | ||
677 | |||
678 | rc = mdio_bus_init(); | ||
679 | if (rc) | ||
680 | return rc; | ||
681 | |||
682 | rc = phy_driver_register(&genphy_driver); | ||
683 | if (rc) | ||
684 | mdio_bus_exit(); | ||
685 | |||
686 | return rc; | ||
687 | } | ||
688 | |||
689 | static void __exit phy_exit(void) | ||
690 | { | ||
691 | phy_driver_unregister(&genphy_driver); | ||
692 | mdio_bus_exit(); | ||
693 | } | ||
694 | |||
695 | subsys_initcall(phy_init); | ||
696 | module_exit(phy_exit); | ||
diff --git a/drivers/net/phy/qsemi.c b/drivers/net/phy/qsemi.c new file mode 100644 index 000000000000..d461ba457631 --- /dev/null +++ b/drivers/net/phy/qsemi.c | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * drivers/net/phy/qsemi.c | ||
3 | * | ||
4 | * Driver for Quality Semiconductor PHYs | ||
5 | * | ||
6 | * Author: Andy Fleming | ||
7 | * | ||
8 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | #include <linux/config.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/sched.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/unistd.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/netdevice.h> | ||
27 | #include <linux/etherdevice.h> | ||
28 | #include <linux/skbuff.h> | ||
29 | #include <linux/spinlock.h> | ||
30 | #include <linux/mm.h> | ||
31 | #include <linux/module.h> | ||
32 | #include <linux/version.h> | ||
33 | #include <linux/mii.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | |||
37 | #include <asm/io.h> | ||
38 | #include <asm/irq.h> | ||
39 | #include <asm/uaccess.h> | ||
40 | |||
41 | /* ------------------------------------------------------------------------- */ | ||
42 | /* The Quality Semiconductor QS6612 is used on the RPX CLLF */ | ||
43 | |||
44 | /* register definitions */ | ||
45 | |||
46 | #define MII_QS6612_MCR 17 /* Mode Control Register */ | ||
47 | #define MII_QS6612_FTR 27 /* Factory Test Register */ | ||
48 | #define MII_QS6612_MCO 28 /* Misc. Control Register */ | ||
49 | #define MII_QS6612_ISR 29 /* Interrupt Source Register */ | ||
50 | #define MII_QS6612_IMR 30 /* Interrupt Mask Register */ | ||
51 | #define MII_QS6612_IMR_INIT 0x003a | ||
52 | #define MII_QS6612_PCR 31 /* 100BaseTx PHY Control Reg. */ | ||
53 | |||
54 | #define QS6612_PCR_AN_COMPLETE 0x1000 | ||
55 | #define QS6612_PCR_RLBEN 0x0200 | ||
56 | #define QS6612_PCR_DCREN 0x0100 | ||
57 | #define QS6612_PCR_4B5BEN 0x0040 | ||
58 | #define QS6612_PCR_TX_ISOLATE 0x0020 | ||
59 | #define QS6612_PCR_MLT3_DIS 0x0002 | ||
60 | #define QS6612_PCR_SCRM_DESCRM 0x0001 | ||
61 | |||
62 | MODULE_DESCRIPTION("Quality Semiconductor PHY driver"); | ||
63 | MODULE_AUTHOR("Andy Fleming"); | ||
64 | MODULE_LICENSE("GPL"); | ||
65 | |||
66 | /* Returns 0, unless there's a write error */ | ||
67 | static int qs6612_config_init(struct phy_device *phydev) | ||
68 | { | ||
69 | /* The PHY powers up isolated on the RPX, | ||
70 | * so send a command to allow operation. | ||
71 | * XXX - My docs indicate this should be 0x0940 | ||
72 | * ...or something. The current value sets three | ||
73 | * reserved bits, bit 11, which specifies it should be | ||
74 | * set to one, bit 10, which specifies it should be set | ||
75 | * to 0, and bit 7, which doesn't specify. However, my | ||
76 | * docs are preliminary, and I will leave it like this | ||
77 | * until someone more knowledgable corrects me or it. | ||
78 | * -- Andy Fleming | ||
79 | */ | ||
80 | return phy_write(phydev, MII_QS6612_PCR, 0x0dc0); | ||
81 | } | ||
82 | |||
83 | static int qs6612_ack_interrupt(struct phy_device *phydev) | ||
84 | { | ||
85 | int err; | ||
86 | |||
87 | err = phy_read(phydev, MII_QS6612_ISR); | ||
88 | |||
89 | if (err < 0) | ||
90 | return err; | ||
91 | |||
92 | err = phy_read(phydev, MII_BMSR); | ||
93 | |||
94 | if (err < 0) | ||
95 | return err; | ||
96 | |||
97 | err = phy_read(phydev, MII_EXPANSION); | ||
98 | |||
99 | if (err < 0) | ||
100 | return err; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static int qs6612_config_intr(struct phy_device *phydev) | ||
106 | { | ||
107 | int err; | ||
108 | if (phydev->interrupts == PHY_INTERRUPT_ENABLED) | ||
109 | err = phy_write(phydev, MII_QS6612_IMR, | ||
110 | MII_QS6612_IMR_INIT); | ||
111 | else | ||
112 | err = phy_write(phydev, MII_QS6612_IMR, 0); | ||
113 | |||
114 | return err; | ||
115 | |||
116 | } | ||
117 | |||
118 | static struct phy_driver qs6612_driver = { | ||
119 | .phy_id = 0x00181440, | ||
120 | .name = "QS6612", | ||
121 | .phy_id_mask = 0xfffffff0, | ||
122 | .features = PHY_BASIC_FEATURES, | ||
123 | .flags = PHY_HAS_INTERRUPT, | ||
124 | .config_init = qs6612_config_init, | ||
125 | .config_aneg = genphy_config_aneg, | ||
126 | .read_status = genphy_read_status, | ||
127 | .ack_interrupt = qs6612_ack_interrupt, | ||
128 | .config_intr = qs6612_config_intr, | ||
129 | .driver = { .owner = THIS_MODULE,}, | ||
130 | }; | ||
131 | |||
132 | static int __init qs6612_init(void) | ||
133 | { | ||
134 | return phy_driver_register(&qs6612_driver); | ||
135 | } | ||
136 | |||
137 | static void __exit qs6612_exit(void) | ||
138 | { | ||
139 | phy_driver_unregister(&qs6612_driver); | ||
140 | } | ||
141 | |||
142 | module_init(qs6612_init); | ||
143 | module_exit(qs6612_exit); | ||
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c index d5afe05cd826..f0471d102e3c 100644 --- a/drivers/net/r8169.c +++ b/drivers/net/r8169.c | |||
@@ -187,6 +187,7 @@ static struct pci_device_id rtl8169_pci_tbl[] = { | |||
187 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, | 187 | { PCI_DEVICE(PCI_VENDOR_ID_REALTEK, 0x8169), }, |
188 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, | 188 | { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4300), }, |
189 | { PCI_DEVICE(0x16ec, 0x0116), }, | 189 | { PCI_DEVICE(0x16ec, 0x0116), }, |
190 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0024, }, | ||
190 | {0,}, | 191 | {0,}, |
191 | }; | 192 | }; |
192 | 193 | ||
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 7092ca6b277e..2234a8f05eb2 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
@@ -62,6 +62,7 @@ typedef struct _XENA_dev_config { | |||
62 | #define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6) | 62 | #define ADAPTER_STATUS_RMAC_REMOTE_FAULT BIT(6) |
63 | #define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7) | 63 | #define ADAPTER_STATUS_RMAC_LOCAL_FAULT BIT(7) |
64 | #define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8) | 64 | #define ADAPTER_STATUS_RMAC_PCC_IDLE vBIT(0xFF,8,8) |
65 | #define ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE vBIT(0x0F,8,8) | ||
65 | #define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8) | 66 | #define ADAPTER_STATUS_RC_PRC_QUIESCENT vBIT(0xFF,16,8) |
66 | #define ADAPTER_STATUS_MC_DRAM_READY BIT(24) | 67 | #define ADAPTER_STATUS_MC_DRAM_READY BIT(24) |
67 | #define ADAPTER_STATUS_MC_QUEUES_READY BIT(25) | 68 | #define ADAPTER_STATUS_MC_QUEUES_READY BIT(25) |
@@ -77,21 +78,34 @@ typedef struct _XENA_dev_config { | |||
77 | #define ADAPTER_ECC_EN BIT(55) | 78 | #define ADAPTER_ECC_EN BIT(55) |
78 | 79 | ||
79 | u64 serr_source; | 80 | u64 serr_source; |
80 | #define SERR_SOURCE_PIC BIT(0) | 81 | #define SERR_SOURCE_PIC BIT(0) |
81 | #define SERR_SOURCE_TXDMA BIT(1) | 82 | #define SERR_SOURCE_TXDMA BIT(1) |
82 | #define SERR_SOURCE_RXDMA BIT(2) | 83 | #define SERR_SOURCE_RXDMA BIT(2) |
83 | #define SERR_SOURCE_MAC BIT(3) | 84 | #define SERR_SOURCE_MAC BIT(3) |
84 | #define SERR_SOURCE_MC BIT(4) | 85 | #define SERR_SOURCE_MC BIT(4) |
85 | #define SERR_SOURCE_XGXS BIT(5) | 86 | #define SERR_SOURCE_XGXS BIT(5) |
86 | #define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \ | 87 | #define SERR_SOURCE_ANY (SERR_SOURCE_PIC | \ |
87 | SERR_SOURCE_TXDMA | \ | 88 | SERR_SOURCE_TXDMA | \ |
88 | SERR_SOURCE_RXDMA | \ | 89 | SERR_SOURCE_RXDMA | \ |
89 | SERR_SOURCE_MAC | \ | 90 | SERR_SOURCE_MAC | \ |
90 | SERR_SOURCE_MC | \ | 91 | SERR_SOURCE_MC | \ |
91 | SERR_SOURCE_XGXS) | 92 | SERR_SOURCE_XGXS) |
92 | 93 | ||
93 | 94 | u64 pci_mode; | |
94 | u8 unused_0[0x800 - 0x120]; | 95 | #define GET_PCI_MODE(val) ((val & vBIT(0xF, 0, 4)) >> 60) |
96 | #define PCI_MODE_PCI_33 0 | ||
97 | #define PCI_MODE_PCI_66 0x1 | ||
98 | #define PCI_MODE_PCIX_M1_66 0x2 | ||
99 | #define PCI_MODE_PCIX_M1_100 0x3 | ||
100 | #define PCI_MODE_PCIX_M1_133 0x4 | ||
101 | #define PCI_MODE_PCIX_M2_66 0x5 | ||
102 | #define PCI_MODE_PCIX_M2_100 0x6 | ||
103 | #define PCI_MODE_PCIX_M2_133 0x7 | ||
104 | #define PCI_MODE_UNSUPPORTED BIT(0) | ||
105 | #define PCI_MODE_32_BITS BIT(8) | ||
106 | #define PCI_MODE_UNKNOWN_MODE BIT(9) | ||
107 | |||
108 | u8 unused_0[0x800 - 0x128]; | ||
95 | 109 | ||
96 | /* PCI-X Controller registers */ | 110 | /* PCI-X Controller registers */ |
97 | u64 pic_int_status; | 111 | u64 pic_int_status; |
@@ -153,7 +167,11 @@ typedef struct _XENA_dev_config { | |||
153 | u8 unused4[0x08]; | 167 | u8 unused4[0x08]; |
154 | 168 | ||
155 | u64 gpio_int_reg; | 169 | u64 gpio_int_reg; |
170 | #define GPIO_INT_REG_LINK_DOWN BIT(1) | ||
171 | #define GPIO_INT_REG_LINK_UP BIT(2) | ||
156 | u64 gpio_int_mask; | 172 | u64 gpio_int_mask; |
173 | #define GPIO_INT_MASK_LINK_DOWN BIT(1) | ||
174 | #define GPIO_INT_MASK_LINK_UP BIT(2) | ||
157 | u64 gpio_alarms; | 175 | u64 gpio_alarms; |
158 | 176 | ||
159 | u8 unused5[0x38]; | 177 | u8 unused5[0x38]; |
@@ -223,19 +241,16 @@ typedef struct _XENA_dev_config { | |||
223 | u64 xmsi_data; | 241 | u64 xmsi_data; |
224 | 242 | ||
225 | u64 rx_mat; | 243 | u64 rx_mat; |
244 | #define RX_MAT_SET(ring, msi) vBIT(msi, (8 * ring), 8) | ||
226 | 245 | ||
227 | u8 unused6[0x8]; | 246 | u8 unused6[0x8]; |
228 | 247 | ||
229 | u64 tx_mat0_7; | 248 | u64 tx_mat0_n[0x8]; |
230 | u64 tx_mat8_15; | 249 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) |
231 | u64 tx_mat16_23; | ||
232 | u64 tx_mat24_31; | ||
233 | u64 tx_mat32_39; | ||
234 | u64 tx_mat40_47; | ||
235 | u64 tx_mat48_55; | ||
236 | u64 tx_mat56_63; | ||
237 | 250 | ||
238 | u8 unused_1[0x10]; | 251 | u8 unused_1[0x8]; |
252 | u64 stat_byte_cnt; | ||
253 | #define STAT_BC(n) vBIT(n,4,12) | ||
239 | 254 | ||
240 | /* Automated statistics collection */ | 255 | /* Automated statistics collection */ |
241 | u64 stat_cfg; | 256 | u64 stat_cfg; |
@@ -246,6 +261,7 @@ typedef struct _XENA_dev_config { | |||
246 | #define STAT_TRSF_PER(n) TBD | 261 | #define STAT_TRSF_PER(n) TBD |
247 | #define PER_SEC 0x208d5 | 262 | #define PER_SEC 0x208d5 |
248 | #define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32) | 263 | #define SET_UPDT_PERIOD(n) vBIT((PER_SEC*n),32,32) |
264 | #define SET_UPDT_CLICKS(val) vBIT(val, 32, 32) | ||
249 | 265 | ||
250 | u64 stat_addr; | 266 | u64 stat_addr; |
251 | 267 | ||
@@ -267,8 +283,15 @@ typedef struct _XENA_dev_config { | |||
267 | 283 | ||
268 | u64 gpio_control; | 284 | u64 gpio_control; |
269 | #define GPIO_CTRL_GPIO_0 BIT(8) | 285 | #define GPIO_CTRL_GPIO_0 BIT(8) |
286 | u64 misc_control; | ||
287 | #define MISC_LINK_STABILITY_PRD(val) vBIT(val,29,3) | ||
288 | |||
289 | u8 unused7_1[0x240 - 0x208]; | ||
290 | |||
291 | u64 wreq_split_mask; | ||
292 | #define WREQ_SPLIT_MASK_SET_MASK(val) vBIT(val, 52, 12) | ||
270 | 293 | ||
271 | u8 unused7[0x600]; | 294 | u8 unused7_2[0x800 - 0x248]; |
272 | 295 | ||
273 | /* TxDMA registers */ | 296 | /* TxDMA registers */ |
274 | u64 txdma_int_status; | 297 | u64 txdma_int_status; |
@@ -290,6 +313,7 @@ typedef struct _XENA_dev_config { | |||
290 | 313 | ||
291 | u64 pcc_err_reg; | 314 | u64 pcc_err_reg; |
292 | #define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8) | 315 | #define PCC_FB_ECC_DB_ERR vBIT(0xFF, 16, 8) |
316 | #define PCC_ENABLE_FOUR vBIT(0x0F,0,8) | ||
293 | 317 | ||
294 | u64 pcc_err_mask; | 318 | u64 pcc_err_mask; |
295 | u64 pcc_err_alarm; | 319 | u64 pcc_err_alarm; |
@@ -468,6 +492,7 @@ typedef struct _XENA_dev_config { | |||
468 | #define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23)) | 492 | #define PRC_CTRL_NO_SNOOP (BIT(22)|BIT(23)) |
469 | #define PRC_CTRL_NO_SNOOP_DESC BIT(22) | 493 | #define PRC_CTRL_NO_SNOOP_DESC BIT(22) |
470 | #define PRC_CTRL_NO_SNOOP_BUFF BIT(23) | 494 | #define PRC_CTRL_NO_SNOOP_BUFF BIT(23) |
495 | #define PRC_CTRL_BIMODAL_INTERRUPT BIT(37) | ||
471 | #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) | 496 | #define PRC_CTRL_RXD_BACKOFF_INTERVAL(val) vBIT(val,40,24) |
472 | 497 | ||
473 | u64 prc_alarm_action; | 498 | u64 prc_alarm_action; |
@@ -691,6 +716,10 @@ typedef struct _XENA_dev_config { | |||
691 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) | 716 | #define MC_ERR_REG_MIRI_CRI_ERR_0 BIT(22) |
692 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) | 717 | #define MC_ERR_REG_MIRI_CRI_ERR_1 BIT(23) |
693 | #define MC_ERR_REG_SM_ERR BIT(31) | 718 | #define MC_ERR_REG_SM_ERR BIT(31) |
719 | #define MC_ERR_REG_ECC_ALL_SNG (BIT(6) | \ | ||
720 | BIT(7) | BIT(17) | BIT(19)) | ||
721 | #define MC_ERR_REG_ECC_ALL_DBL (BIT(14) | \ | ||
722 | BIT(15) | BIT(18) | BIT(20)) | ||
694 | u64 mc_err_mask; | 723 | u64 mc_err_mask; |
695 | u64 mc_err_alarm; | 724 | u64 mc_err_alarm; |
696 | 725 | ||
@@ -736,7 +765,19 @@ typedef struct _XENA_dev_config { | |||
736 | u64 mc_rldram_test_d1; | 765 | u64 mc_rldram_test_d1; |
737 | u8 unused24[0x300 - 0x288]; | 766 | u8 unused24[0x300 - 0x288]; |
738 | u64 mc_rldram_test_d2; | 767 | u64 mc_rldram_test_d2; |
739 | u8 unused25[0x700 - 0x308]; | 768 | |
769 | u8 unused24_1[0x360 - 0x308]; | ||
770 | u64 mc_rldram_ctrl; | ||
771 | #define MC_RLDRAM_ENABLE_ODT BIT(7) | ||
772 | |||
773 | u8 unused24_2[0x640 - 0x368]; | ||
774 | u64 mc_rldram_ref_per_herc; | ||
775 | #define MC_RLDRAM_SET_REF_PERIOD(val) vBIT(val, 0, 16) | ||
776 | |||
777 | u8 unused24_3[0x660 - 0x648]; | ||
778 | u64 mc_rldram_mrs_herc; | ||
779 | |||
780 | u8 unused25[0x700 - 0x668]; | ||
740 | u64 mc_debug_ctrl; | 781 | u64 mc_debug_ctrl; |
741 | 782 | ||
742 | u8 unused26[0x3000 - 0x2f08]; | 783 | u8 unused26[0x3000 - 0x2f08]; |
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index ea638b162d3f..7ca78228b104 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -11,29 +11,28 @@ | |||
11 | * See the file COPYING in this distribution for more information. | 11 | * See the file COPYING in this distribution for more information. |
12 | * | 12 | * |
13 | * Credits: | 13 | * Credits: |
14 | * Jeff Garzik : For pointing out the improper error condition | 14 | * Jeff Garzik : For pointing out the improper error condition |
15 | * check in the s2io_xmit routine and also some | 15 | * check in the s2io_xmit routine and also some |
16 | * issues in the Tx watch dog function. Also for | 16 | * issues in the Tx watch dog function. Also for |
17 | * patiently answering all those innumerable | 17 | * patiently answering all those innumerable |
18 | * questions regaring the 2.6 porting issues. | 18 | * questions regaring the 2.6 porting issues. |
19 | * Stephen Hemminger : Providing proper 2.6 porting mechanism for some | 19 | * Stephen Hemminger : Providing proper 2.6 porting mechanism for some |
20 | * macros available only in 2.6 Kernel. | 20 | * macros available only in 2.6 Kernel. |
21 | * Francois Romieu : For pointing out all code part that were | 21 | * Francois Romieu : For pointing out all code part that were |
22 | * deprecated and also styling related comments. | 22 | * deprecated and also styling related comments. |
23 | * Grant Grundler : For helping me get rid of some Architecture | 23 | * Grant Grundler : For helping me get rid of some Architecture |
24 | * dependent code. | 24 | * dependent code. |
25 | * Christopher Hellwig : Some more 2.6 specific issues in the driver. | 25 | * Christopher Hellwig : Some more 2.6 specific issues in the driver. |
26 | * | 26 | * |
27 | * The module loadable parameters that are supported by the driver and a brief | 27 | * The module loadable parameters that are supported by the driver and a brief |
28 | * explaination of all the variables. | 28 | * explaination of all the variables. |
29 | * rx_ring_num : This can be used to program the number of receive rings used | 29 | * rx_ring_num : This can be used to program the number of receive rings used |
30 | * in the driver. | 30 | * in the driver. |
31 | * rx_ring_len: This defines the number of descriptors each ring can have. This | 31 | * rx_ring_len: This defines the number of descriptors each ring can have. This |
32 | * is also an array of size 8. | 32 | * is also an array of size 8. |
33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. | 33 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. |
34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of | 34 | * tx_fifo_len: This too is an array of 8. Each element defines the number of |
35 | * Tx descriptors that can be associated with each corresponding FIFO. | 35 | * Tx descriptors that can be associated with each corresponding FIFO. |
36 | * in PCI Configuration space. | ||
37 | ************************************************************************/ | 36 | ************************************************************************/ |
38 | 37 | ||
39 | #include <linux/config.h> | 38 | #include <linux/config.h> |
@@ -56,27 +55,39 @@ | |||
56 | #include <linux/ethtool.h> | 55 | #include <linux/ethtool.h> |
57 | #include <linux/version.h> | 56 | #include <linux/version.h> |
58 | #include <linux/workqueue.h> | 57 | #include <linux/workqueue.h> |
58 | #include <linux/if_vlan.h> | ||
59 | 59 | ||
60 | #include <asm/io.h> | ||
61 | #include <asm/system.h> | 60 | #include <asm/system.h> |
62 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
62 | #include <asm/io.h> | ||
63 | 63 | ||
64 | /* local include */ | 64 | /* local include */ |
65 | #include "s2io.h" | 65 | #include "s2io.h" |
66 | #include "s2io-regs.h" | 66 | #include "s2io-regs.h" |
67 | 67 | ||
68 | /* S2io Driver name & version. */ | 68 | /* S2io Driver name & version. */ |
69 | static char s2io_driver_name[] = "s2io"; | 69 | static char s2io_driver_name[] = "Neterion"; |
70 | static char s2io_driver_version[] = "Version 1.7.7.1"; | 70 | static char s2io_driver_version[] = "Version 2.0.3.1"; |
71 | |||
72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) | ||
73 | { | ||
74 | int ret; | ||
75 | |||
76 | ret = ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
77 | (GET_RXD_MARKER(rxdp->Control_2) != THE_RXD_MARK)); | ||
71 | 78 | ||
72 | /* | 79 | return ret; |
80 | } | ||
81 | |||
82 | /* | ||
73 | * Cards with following subsystem_id have a link state indication | 83 | * Cards with following subsystem_id have a link state indication |
74 | * problem, 600B, 600C, 600D, 640B, 640C and 640D. | 84 | * problem, 600B, 600C, 600D, 640B, 640C and 640D. |
75 | * macro below identifies these cards given the subsystem_id. | 85 | * macro below identifies these cards given the subsystem_id. |
76 | */ | 86 | */ |
77 | #define CARDS_WITH_FAULTY_LINK_INDICATORS(subid) \ | 87 | #define CARDS_WITH_FAULTY_LINK_INDICATORS(dev_type, subid) \ |
78 | (((subid >= 0x600B) && (subid <= 0x600D)) || \ | 88 | (dev_type == XFRAME_I_DEVICE) ? \ |
79 | ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0 | 89 | ((((subid >= 0x600B) && (subid <= 0x600D)) || \ |
90 | ((subid >= 0x640B) && (subid <= 0x640D))) ? 1 : 0) : 0 | ||
80 | 91 | ||
81 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ | 92 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ |
82 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) | 93 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) |
@@ -86,9 +97,12 @@ static char s2io_driver_version[] = "Version 1.7.7.1"; | |||
86 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) | 97 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) |
87 | { | 98 | { |
88 | int level = 0; | 99 | int level = 0; |
89 | if ((sp->pkt_cnt[ring] - rxb_size) > 16) { | 100 | mac_info_t *mac_control; |
101 | |||
102 | mac_control = &sp->mac_control; | ||
103 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { | ||
90 | level = LOW; | 104 | level = LOW; |
91 | if ((sp->pkt_cnt[ring] - rxb_size) < MAX_RXDS_PER_BLOCK) { | 105 | if (rxb_size <= MAX_RXDS_PER_BLOCK) { |
92 | level = PANIC; | 106 | level = PANIC; |
93 | } | 107 | } |
94 | } | 108 | } |
@@ -145,6 +159,9 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
145 | {"rmac_pause_cnt"}, | 159 | {"rmac_pause_cnt"}, |
146 | {"rmac_accepted_ip"}, | 160 | {"rmac_accepted_ip"}, |
147 | {"rmac_err_tcp"}, | 161 | {"rmac_err_tcp"}, |
162 | {"\n DRIVER STATISTICS"}, | ||
163 | {"single_bit_ecc_errs"}, | ||
164 | {"double_bit_ecc_errs"}, | ||
148 | }; | 165 | }; |
149 | 166 | ||
150 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN | 167 | #define S2IO_STAT_LEN sizeof(ethtool_stats_keys)/ ETH_GSTRING_LEN |
@@ -153,8 +170,37 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
153 | #define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN | 170 | #define S2IO_TEST_LEN sizeof(s2io_gstrings) / ETH_GSTRING_LEN |
154 | #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN | 171 | #define S2IO_STRINGS_LEN S2IO_TEST_LEN * ETH_GSTRING_LEN |
155 | 172 | ||
173 | #define S2IO_TIMER_CONF(timer, handle, arg, exp) \ | ||
174 | init_timer(&timer); \ | ||
175 | timer.function = handle; \ | ||
176 | timer.data = (unsigned long) arg; \ | ||
177 | mod_timer(&timer, (jiffies + exp)) \ | ||
178 | |||
179 | /* Add the vlan */ | ||
180 | static void s2io_vlan_rx_register(struct net_device *dev, | ||
181 | struct vlan_group *grp) | ||
182 | { | ||
183 | nic_t *nic = dev->priv; | ||
184 | unsigned long flags; | ||
185 | |||
186 | spin_lock_irqsave(&nic->tx_lock, flags); | ||
187 | nic->vlgrp = grp; | ||
188 | spin_unlock_irqrestore(&nic->tx_lock, flags); | ||
189 | } | ||
190 | |||
191 | /* Unregister the vlan */ | ||
192 | static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) | ||
193 | { | ||
194 | nic_t *nic = dev->priv; | ||
195 | unsigned long flags; | ||
196 | |||
197 | spin_lock_irqsave(&nic->tx_lock, flags); | ||
198 | if (nic->vlgrp) | ||
199 | nic->vlgrp->vlan_devices[vid] = NULL; | ||
200 | spin_unlock_irqrestore(&nic->tx_lock, flags); | ||
201 | } | ||
156 | 202 | ||
157 | /* | 203 | /* |
158 | * Constants to be programmed into the Xena's registers, to configure | 204 | * Constants to be programmed into the Xena's registers, to configure |
159 | * the XAUI. | 205 | * the XAUI. |
160 | */ | 206 | */ |
@@ -162,7 +208,28 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
162 | #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL | 208 | #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL |
163 | #define END_SIGN 0x0 | 209 | #define END_SIGN 0x0 |
164 | 210 | ||
165 | static u64 default_mdio_cfg[] = { | 211 | static u64 herc_act_dtx_cfg[] = { |
212 | /* Set address */ | ||
213 | 0x8000051536750000ULL, 0x80000515367500E0ULL, | ||
214 | /* Write data */ | ||
215 | 0x8000051536750004ULL, 0x80000515367500E4ULL, | ||
216 | /* Set address */ | ||
217 | 0x80010515003F0000ULL, 0x80010515003F00E0ULL, | ||
218 | /* Write data */ | ||
219 | 0x80010515003F0004ULL, 0x80010515003F00E4ULL, | ||
220 | /* Set address */ | ||
221 | 0x801205150D440000ULL, 0x801205150D4400E0ULL, | ||
222 | /* Write data */ | ||
223 | 0x801205150D440004ULL, 0x801205150D4400E4ULL, | ||
224 | /* Set address */ | ||
225 | 0x80020515F2100000ULL, 0x80020515F21000E0ULL, | ||
226 | /* Write data */ | ||
227 | 0x80020515F2100004ULL, 0x80020515F21000E4ULL, | ||
228 | /* Done */ | ||
229 | END_SIGN | ||
230 | }; | ||
231 | |||
232 | static u64 xena_mdio_cfg[] = { | ||
166 | /* Reset PMA PLL */ | 233 | /* Reset PMA PLL */ |
167 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, | 234 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, |
168 | 0xC0010100008000E4ULL, | 235 | 0xC0010100008000E4ULL, |
@@ -172,7 +239,7 @@ static u64 default_mdio_cfg[] = { | |||
172 | END_SIGN | 239 | END_SIGN |
173 | }; | 240 | }; |
174 | 241 | ||
175 | static u64 default_dtx_cfg[] = { | 242 | static u64 xena_dtx_cfg[] = { |
176 | 0x8000051500000000ULL, 0x80000515000000E0ULL, | 243 | 0x8000051500000000ULL, 0x80000515000000E0ULL, |
177 | 0x80000515D93500E4ULL, 0x8001051500000000ULL, | 244 | 0x80000515D93500E4ULL, 0x8001051500000000ULL, |
178 | 0x80010515000000E0ULL, 0x80010515001E00E4ULL, | 245 | 0x80010515000000E0ULL, 0x80010515001E00E4ULL, |
@@ -196,8 +263,7 @@ static u64 default_dtx_cfg[] = { | |||
196 | END_SIGN | 263 | END_SIGN |
197 | }; | 264 | }; |
198 | 265 | ||
199 | 266 | /* | |
200 | /* | ||
201 | * Constants for Fixing the MacAddress problem seen mostly on | 267 | * Constants for Fixing the MacAddress problem seen mostly on |
202 | * Alpha machines. | 268 | * Alpha machines. |
203 | */ | 269 | */ |
@@ -226,20 +292,25 @@ static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | |||
226 | static unsigned int rx_ring_num = 1; | 292 | static unsigned int rx_ring_num = 1; |
227 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 293 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = |
228 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 294 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; |
229 | static unsigned int Stats_refresh_time = 4; | 295 | static unsigned int rts_frm_len[MAX_RX_RINGS] = |
296 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | ||
297 | static unsigned int use_continuous_tx_intrs = 1; | ||
230 | static unsigned int rmac_pause_time = 65535; | 298 | static unsigned int rmac_pause_time = 65535; |
231 | static unsigned int mc_pause_threshold_q0q3 = 187; | 299 | static unsigned int mc_pause_threshold_q0q3 = 187; |
232 | static unsigned int mc_pause_threshold_q4q7 = 187; | 300 | static unsigned int mc_pause_threshold_q4q7 = 187; |
233 | static unsigned int shared_splits; | 301 | static unsigned int shared_splits; |
234 | static unsigned int tmac_util_period = 5; | 302 | static unsigned int tmac_util_period = 5; |
235 | static unsigned int rmac_util_period = 5; | 303 | static unsigned int rmac_util_period = 5; |
304 | static unsigned int bimodal = 0; | ||
236 | #ifndef CONFIG_S2IO_NAPI | 305 | #ifndef CONFIG_S2IO_NAPI |
237 | static unsigned int indicate_max_pkts; | 306 | static unsigned int indicate_max_pkts; |
238 | #endif | 307 | #endif |
308 | /* Frequency of Rx desc syncs expressed as power of 2 */ | ||
309 | static unsigned int rxsync_frequency = 3; | ||
239 | 310 | ||
240 | /* | 311 | /* |
241 | * S2IO device table. | 312 | * S2IO device table. |
242 | * This table lists all the devices that this driver supports. | 313 | * This table lists all the devices that this driver supports. |
243 | */ | 314 | */ |
244 | static struct pci_device_id s2io_tbl[] __devinitdata = { | 315 | static struct pci_device_id s2io_tbl[] __devinitdata = { |
245 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN, | 316 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_WIN, |
@@ -247,9 +318,9 @@ static struct pci_device_id s2io_tbl[] __devinitdata = { | |||
247 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI, | 318 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_S2IO_UNI, |
248 | PCI_ANY_ID, PCI_ANY_ID}, | 319 | PCI_ANY_ID, PCI_ANY_ID}, |
249 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN, | 320 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_WIN, |
250 | PCI_ANY_ID, PCI_ANY_ID}, | 321 | PCI_ANY_ID, PCI_ANY_ID}, |
251 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI, | 322 | {PCI_VENDOR_ID_S2IO, PCI_DEVICE_ID_HERC_UNI, |
252 | PCI_ANY_ID, PCI_ANY_ID}, | 323 | PCI_ANY_ID, PCI_ANY_ID}, |
253 | {0,} | 324 | {0,} |
254 | }; | 325 | }; |
255 | 326 | ||
@@ -268,8 +339,8 @@ static struct pci_driver s2io_driver = { | |||
268 | /** | 339 | /** |
269 | * init_shared_mem - Allocation and Initialization of Memory | 340 | * init_shared_mem - Allocation and Initialization of Memory |
270 | * @nic: Device private variable. | 341 | * @nic: Device private variable. |
271 | * Description: The function allocates all the memory areas shared | 342 | * Description: The function allocates all the memory areas shared |
272 | * between the NIC and the driver. This includes Tx descriptors, | 343 | * between the NIC and the driver. This includes Tx descriptors, |
273 | * Rx descriptors and the statistics block. | 344 | * Rx descriptors and the statistics block. |
274 | */ | 345 | */ |
275 | 346 | ||
@@ -279,11 +350,11 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
279 | void *tmp_v_addr, *tmp_v_addr_next; | 350 | void *tmp_v_addr, *tmp_v_addr_next; |
280 | dma_addr_t tmp_p_addr, tmp_p_addr_next; | 351 | dma_addr_t tmp_p_addr, tmp_p_addr_next; |
281 | RxD_block_t *pre_rxd_blk = NULL; | 352 | RxD_block_t *pre_rxd_blk = NULL; |
282 | int i, j, blk_cnt; | 353 | int i, j, blk_cnt, rx_sz, tx_sz; |
283 | int lst_size, lst_per_page; | 354 | int lst_size, lst_per_page; |
284 | struct net_device *dev = nic->dev; | 355 | struct net_device *dev = nic->dev; |
285 | #ifdef CONFIG_2BUFF_MODE | 356 | #ifdef CONFIG_2BUFF_MODE |
286 | unsigned long tmp; | 357 | u64 tmp; |
287 | buffAdd_t *ba; | 358 | buffAdd_t *ba; |
288 | #endif | 359 | #endif |
289 | 360 | ||
@@ -300,36 +371,41 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
300 | size += config->tx_cfg[i].fifo_len; | 371 | size += config->tx_cfg[i].fifo_len; |
301 | } | 372 | } |
302 | if (size > MAX_AVAILABLE_TXDS) { | 373 | if (size > MAX_AVAILABLE_TXDS) { |
303 | DBG_PRINT(ERR_DBG, "%s: Total number of Tx FIFOs ", | 374 | DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", |
304 | dev->name); | 375 | __FUNCTION__); |
305 | DBG_PRINT(ERR_DBG, "exceeds the maximum value "); | 376 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); |
306 | DBG_PRINT(ERR_DBG, "that can be used\n"); | ||
307 | return FAILURE; | 377 | return FAILURE; |
308 | } | 378 | } |
309 | 379 | ||
310 | lst_size = (sizeof(TxD_t) * config->max_txds); | 380 | lst_size = (sizeof(TxD_t) * config->max_txds); |
381 | tx_sz = lst_size * size; | ||
311 | lst_per_page = PAGE_SIZE / lst_size; | 382 | lst_per_page = PAGE_SIZE / lst_size; |
312 | 383 | ||
313 | for (i = 0; i < config->tx_fifo_num; i++) { | 384 | for (i = 0; i < config->tx_fifo_num; i++) { |
314 | int fifo_len = config->tx_cfg[i].fifo_len; | 385 | int fifo_len = config->tx_cfg[i].fifo_len; |
315 | int list_holder_size = fifo_len * sizeof(list_info_hold_t); | 386 | int list_holder_size = fifo_len * sizeof(list_info_hold_t); |
316 | nic->list_info[i] = kmalloc(list_holder_size, GFP_KERNEL); | 387 | mac_control->fifos[i].list_info = kmalloc(list_holder_size, |
317 | if (!nic->list_info[i]) { | 388 | GFP_KERNEL); |
389 | if (!mac_control->fifos[i].list_info) { | ||
318 | DBG_PRINT(ERR_DBG, | 390 | DBG_PRINT(ERR_DBG, |
319 | "Malloc failed for list_info\n"); | 391 | "Malloc failed for list_info\n"); |
320 | return -ENOMEM; | 392 | return -ENOMEM; |
321 | } | 393 | } |
322 | memset(nic->list_info[i], 0, list_holder_size); | 394 | memset(mac_control->fifos[i].list_info, 0, list_holder_size); |
323 | } | 395 | } |
324 | for (i = 0; i < config->tx_fifo_num; i++) { | 396 | for (i = 0; i < config->tx_fifo_num; i++) { |
325 | int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, | 397 | int page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, |
326 | lst_per_page); | 398 | lst_per_page); |
327 | mac_control->tx_curr_put_info[i].offset = 0; | 399 | mac_control->fifos[i].tx_curr_put_info.offset = 0; |
328 | mac_control->tx_curr_put_info[i].fifo_len = | 400 | mac_control->fifos[i].tx_curr_put_info.fifo_len = |
329 | config->tx_cfg[i].fifo_len - 1; | 401 | config->tx_cfg[i].fifo_len - 1; |
330 | mac_control->tx_curr_get_info[i].offset = 0; | 402 | mac_control->fifos[i].tx_curr_get_info.offset = 0; |
331 | mac_control->tx_curr_get_info[i].fifo_len = | 403 | mac_control->fifos[i].tx_curr_get_info.fifo_len = |
332 | config->tx_cfg[i].fifo_len - 1; | 404 | config->tx_cfg[i].fifo_len - 1; |
405 | mac_control->fifos[i].fifo_no = i; | ||
406 | mac_control->fifos[i].nic = nic; | ||
407 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS; | ||
408 | |||
333 | for (j = 0; j < page_num; j++) { | 409 | for (j = 0; j < page_num; j++) { |
334 | int k = 0; | 410 | int k = 0; |
335 | dma_addr_t tmp_p; | 411 | dma_addr_t tmp_p; |
@@ -345,16 +421,15 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
345 | while (k < lst_per_page) { | 421 | while (k < lst_per_page) { |
346 | int l = (j * lst_per_page) + k; | 422 | int l = (j * lst_per_page) + k; |
347 | if (l == config->tx_cfg[i].fifo_len) | 423 | if (l == config->tx_cfg[i].fifo_len) |
348 | goto end_txd_alloc; | 424 | break; |
349 | nic->list_info[i][l].list_virt_addr = | 425 | mac_control->fifos[i].list_info[l].list_virt_addr = |
350 | tmp_v + (k * lst_size); | 426 | tmp_v + (k * lst_size); |
351 | nic->list_info[i][l].list_phy_addr = | 427 | mac_control->fifos[i].list_info[l].list_phy_addr = |
352 | tmp_p + (k * lst_size); | 428 | tmp_p + (k * lst_size); |
353 | k++; | 429 | k++; |
354 | } | 430 | } |
355 | } | 431 | } |
356 | } | 432 | } |
357 | end_txd_alloc: | ||
358 | 433 | ||
359 | /* Allocation and initialization of RXDs in Rings */ | 434 | /* Allocation and initialization of RXDs in Rings */ |
360 | size = 0; | 435 | size = 0; |
@@ -367,21 +442,26 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
367 | return FAILURE; | 442 | return FAILURE; |
368 | } | 443 | } |
369 | size += config->rx_cfg[i].num_rxd; | 444 | size += config->rx_cfg[i].num_rxd; |
370 | nic->block_count[i] = | 445 | mac_control->rings[i].block_count = |
371 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 446 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
372 | nic->pkt_cnt[i] = | 447 | mac_control->rings[i].pkt_cnt = |
373 | config->rx_cfg[i].num_rxd - nic->block_count[i]; | 448 | config->rx_cfg[i].num_rxd - mac_control->rings[i].block_count; |
374 | } | 449 | } |
450 | size = (size * (sizeof(RxD_t))); | ||
451 | rx_sz = size; | ||
375 | 452 | ||
376 | for (i = 0; i < config->rx_ring_num; i++) { | 453 | for (i = 0; i < config->rx_ring_num; i++) { |
377 | mac_control->rx_curr_get_info[i].block_index = 0; | 454 | mac_control->rings[i].rx_curr_get_info.block_index = 0; |
378 | mac_control->rx_curr_get_info[i].offset = 0; | 455 | mac_control->rings[i].rx_curr_get_info.offset = 0; |
379 | mac_control->rx_curr_get_info[i].ring_len = | 456 | mac_control->rings[i].rx_curr_get_info.ring_len = |
380 | config->rx_cfg[i].num_rxd - 1; | 457 | config->rx_cfg[i].num_rxd - 1; |
381 | mac_control->rx_curr_put_info[i].block_index = 0; | 458 | mac_control->rings[i].rx_curr_put_info.block_index = 0; |
382 | mac_control->rx_curr_put_info[i].offset = 0; | 459 | mac_control->rings[i].rx_curr_put_info.offset = 0; |
383 | mac_control->rx_curr_put_info[i].ring_len = | 460 | mac_control->rings[i].rx_curr_put_info.ring_len = |
384 | config->rx_cfg[i].num_rxd - 1; | 461 | config->rx_cfg[i].num_rxd - 1; |
462 | mac_control->rings[i].nic = nic; | ||
463 | mac_control->rings[i].ring_no = i; | ||
464 | |||
385 | blk_cnt = | 465 | blk_cnt = |
386 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 466 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
387 | /* Allocating all the Rx blocks */ | 467 | /* Allocating all the Rx blocks */ |
@@ -395,32 +475,36 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
395 | &tmp_p_addr); | 475 | &tmp_p_addr); |
396 | if (tmp_v_addr == NULL) { | 476 | if (tmp_v_addr == NULL) { |
397 | /* | 477 | /* |
398 | * In case of failure, free_shared_mem() | 478 | * In case of failure, free_shared_mem() |
399 | * is called, which should free any | 479 | * is called, which should free any |
400 | * memory that was alloced till the | 480 | * memory that was alloced till the |
401 | * failure happened. | 481 | * failure happened. |
402 | */ | 482 | */ |
403 | nic->rx_blocks[i][j].block_virt_addr = | 483 | mac_control->rings[i].rx_blocks[j].block_virt_addr = |
404 | tmp_v_addr; | 484 | tmp_v_addr; |
405 | return -ENOMEM; | 485 | return -ENOMEM; |
406 | } | 486 | } |
407 | memset(tmp_v_addr, 0, size); | 487 | memset(tmp_v_addr, 0, size); |
408 | nic->rx_blocks[i][j].block_virt_addr = tmp_v_addr; | 488 | mac_control->rings[i].rx_blocks[j].block_virt_addr = |
409 | nic->rx_blocks[i][j].block_dma_addr = tmp_p_addr; | 489 | tmp_v_addr; |
490 | mac_control->rings[i].rx_blocks[j].block_dma_addr = | ||
491 | tmp_p_addr; | ||
410 | } | 492 | } |
411 | /* Interlinking all Rx Blocks */ | 493 | /* Interlinking all Rx Blocks */ |
412 | for (j = 0; j < blk_cnt; j++) { | 494 | for (j = 0; j < blk_cnt; j++) { |
413 | tmp_v_addr = nic->rx_blocks[i][j].block_virt_addr; | 495 | tmp_v_addr = |
496 | mac_control->rings[i].rx_blocks[j].block_virt_addr; | ||
414 | tmp_v_addr_next = | 497 | tmp_v_addr_next = |
415 | nic->rx_blocks[i][(j + 1) % | 498 | mac_control->rings[i].rx_blocks[(j + 1) % |
416 | blk_cnt].block_virt_addr; | 499 | blk_cnt].block_virt_addr; |
417 | tmp_p_addr = nic->rx_blocks[i][j].block_dma_addr; | 500 | tmp_p_addr = |
501 | mac_control->rings[i].rx_blocks[j].block_dma_addr; | ||
418 | tmp_p_addr_next = | 502 | tmp_p_addr_next = |
419 | nic->rx_blocks[i][(j + 1) % | 503 | mac_control->rings[i].rx_blocks[(j + 1) % |
420 | blk_cnt].block_dma_addr; | 504 | blk_cnt].block_dma_addr; |
421 | 505 | ||
422 | pre_rxd_blk = (RxD_block_t *) tmp_v_addr; | 506 | pre_rxd_blk = (RxD_block_t *) tmp_v_addr; |
423 | pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD | 507 | pre_rxd_blk->reserved_1 = END_OF_BLOCK; /* last RxD |
424 | * marker. | 508 | * marker. |
425 | */ | 509 | */ |
426 | #ifndef CONFIG_2BUFF_MODE | 510 | #ifndef CONFIG_2BUFF_MODE |
@@ -433,43 +517,43 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
433 | } | 517 | } |
434 | 518 | ||
435 | #ifdef CONFIG_2BUFF_MODE | 519 | #ifdef CONFIG_2BUFF_MODE |
436 | /* | 520 | /* |
437 | * Allocation of Storages for buffer addresses in 2BUFF mode | 521 | * Allocation of Storages for buffer addresses in 2BUFF mode |
438 | * and the buffers as well. | 522 | * and the buffers as well. |
439 | */ | 523 | */ |
440 | for (i = 0; i < config->rx_ring_num; i++) { | 524 | for (i = 0; i < config->rx_ring_num; i++) { |
441 | blk_cnt = | 525 | blk_cnt = |
442 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 526 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
443 | nic->ba[i] = kmalloc((sizeof(buffAdd_t *) * blk_cnt), | 527 | mac_control->rings[i].ba = kmalloc((sizeof(buffAdd_t *) * blk_cnt), |
444 | GFP_KERNEL); | 528 | GFP_KERNEL); |
445 | if (!nic->ba[i]) | 529 | if (!mac_control->rings[i].ba) |
446 | return -ENOMEM; | 530 | return -ENOMEM; |
447 | for (j = 0; j < blk_cnt; j++) { | 531 | for (j = 0; j < blk_cnt; j++) { |
448 | int k = 0; | 532 | int k = 0; |
449 | nic->ba[i][j] = kmalloc((sizeof(buffAdd_t) * | 533 | mac_control->rings[i].ba[j] = kmalloc((sizeof(buffAdd_t) * |
450 | (MAX_RXDS_PER_BLOCK + 1)), | 534 | (MAX_RXDS_PER_BLOCK + 1)), |
451 | GFP_KERNEL); | 535 | GFP_KERNEL); |
452 | if (!nic->ba[i][j]) | 536 | if (!mac_control->rings[i].ba[j]) |
453 | return -ENOMEM; | 537 | return -ENOMEM; |
454 | while (k != MAX_RXDS_PER_BLOCK) { | 538 | while (k != MAX_RXDS_PER_BLOCK) { |
455 | ba = &nic->ba[i][j][k]; | 539 | ba = &mac_control->rings[i].ba[j][k]; |
456 | 540 | ||
457 | ba->ba_0_org = kmalloc | 541 | ba->ba_0_org = (void *) kmalloc |
458 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); | 542 | (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL); |
459 | if (!ba->ba_0_org) | 543 | if (!ba->ba_0_org) |
460 | return -ENOMEM; | 544 | return -ENOMEM; |
461 | tmp = (unsigned long) ba->ba_0_org; | 545 | tmp = (u64) ba->ba_0_org; |
462 | tmp += ALIGN_SIZE; | 546 | tmp += ALIGN_SIZE; |
463 | tmp &= ~((unsigned long) ALIGN_SIZE); | 547 | tmp &= ~((u64) ALIGN_SIZE); |
464 | ba->ba_0 = (void *) tmp; | 548 | ba->ba_0 = (void *) tmp; |
465 | 549 | ||
466 | ba->ba_1_org = kmalloc | 550 | ba->ba_1_org = (void *) kmalloc |
467 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); | 551 | (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL); |
468 | if (!ba->ba_1_org) | 552 | if (!ba->ba_1_org) |
469 | return -ENOMEM; | 553 | return -ENOMEM; |
470 | tmp = (unsigned long) ba->ba_1_org; | 554 | tmp = (u64) ba->ba_1_org; |
471 | tmp += ALIGN_SIZE; | 555 | tmp += ALIGN_SIZE; |
472 | tmp &= ~((unsigned long) ALIGN_SIZE); | 556 | tmp &= ~((u64) ALIGN_SIZE); |
473 | ba->ba_1 = (void *) tmp; | 557 | ba->ba_1 = (void *) tmp; |
474 | k++; | 558 | k++; |
475 | } | 559 | } |
@@ -483,9 +567,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
483 | (nic->pdev, size, &mac_control->stats_mem_phy); | 567 | (nic->pdev, size, &mac_control->stats_mem_phy); |
484 | 568 | ||
485 | if (!mac_control->stats_mem) { | 569 | if (!mac_control->stats_mem) { |
486 | /* | 570 | /* |
487 | * In case of failure, free_shared_mem() is called, which | 571 | * In case of failure, free_shared_mem() is called, which |
488 | * should free any memory that was alloced till the | 572 | * should free any memory that was alloced till the |
489 | * failure happened. | 573 | * failure happened. |
490 | */ | 574 | */ |
491 | return -ENOMEM; | 575 | return -ENOMEM; |
@@ -495,15 +579,14 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
495 | tmp_v_addr = mac_control->stats_mem; | 579 | tmp_v_addr = mac_control->stats_mem; |
496 | mac_control->stats_info = (StatInfo_t *) tmp_v_addr; | 580 | mac_control->stats_info = (StatInfo_t *) tmp_v_addr; |
497 | memset(tmp_v_addr, 0, size); | 581 | memset(tmp_v_addr, 0, size); |
498 | |||
499 | DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, | 582 | DBG_PRINT(INIT_DBG, "%s:Ring Mem PHY: 0x%llx\n", dev->name, |
500 | (unsigned long long) tmp_p_addr); | 583 | (unsigned long long) tmp_p_addr); |
501 | 584 | ||
502 | return SUCCESS; | 585 | return SUCCESS; |
503 | } | 586 | } |
504 | 587 | ||
505 | /** | 588 | /** |
506 | * free_shared_mem - Free the allocated Memory | 589 | * free_shared_mem - Free the allocated Memory |
507 | * @nic: Device private variable. | 590 | * @nic: Device private variable. |
508 | * Description: This function is to free all memory locations allocated by | 591 | * Description: This function is to free all memory locations allocated by |
509 | * the init_shared_mem() function and return it to the kernel. | 592 | * the init_shared_mem() function and return it to the kernel. |
@@ -533,15 +616,19 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
533 | lst_per_page); | 616 | lst_per_page); |
534 | for (j = 0; j < page_num; j++) { | 617 | for (j = 0; j < page_num; j++) { |
535 | int mem_blks = (j * lst_per_page); | 618 | int mem_blks = (j * lst_per_page); |
536 | if (!nic->list_info[i][mem_blks].list_virt_addr) | 619 | if ((!mac_control->fifos[i].list_info) || |
620 | (!mac_control->fifos[i].list_info[mem_blks]. | ||
621 | list_virt_addr)) | ||
537 | break; | 622 | break; |
538 | pci_free_consistent(nic->pdev, PAGE_SIZE, | 623 | pci_free_consistent(nic->pdev, PAGE_SIZE, |
539 | nic->list_info[i][mem_blks]. | 624 | mac_control->fifos[i]. |
625 | list_info[mem_blks]. | ||
540 | list_virt_addr, | 626 | list_virt_addr, |
541 | nic->list_info[i][mem_blks]. | 627 | mac_control->fifos[i]. |
628 | list_info[mem_blks]. | ||
542 | list_phy_addr); | 629 | list_phy_addr); |
543 | } | 630 | } |
544 | kfree(nic->list_info[i]); | 631 | kfree(mac_control->fifos[i].list_info); |
545 | } | 632 | } |
546 | 633 | ||
547 | #ifndef CONFIG_2BUFF_MODE | 634 | #ifndef CONFIG_2BUFF_MODE |
@@ -550,10 +637,12 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
550 | size = SIZE_OF_BLOCK; | 637 | size = SIZE_OF_BLOCK; |
551 | #endif | 638 | #endif |
552 | for (i = 0; i < config->rx_ring_num; i++) { | 639 | for (i = 0; i < config->rx_ring_num; i++) { |
553 | blk_cnt = nic->block_count[i]; | 640 | blk_cnt = mac_control->rings[i].block_count; |
554 | for (j = 0; j < blk_cnt; j++) { | 641 | for (j = 0; j < blk_cnt; j++) { |
555 | tmp_v_addr = nic->rx_blocks[i][j].block_virt_addr; | 642 | tmp_v_addr = mac_control->rings[i].rx_blocks[j]. |
556 | tmp_p_addr = nic->rx_blocks[i][j].block_dma_addr; | 643 | block_virt_addr; |
644 | tmp_p_addr = mac_control->rings[i].rx_blocks[j]. | ||
645 | block_dma_addr; | ||
557 | if (tmp_v_addr == NULL) | 646 | if (tmp_v_addr == NULL) |
558 | break; | 647 | break; |
559 | pci_free_consistent(nic->pdev, size, | 648 | pci_free_consistent(nic->pdev, size, |
@@ -566,35 +655,21 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
566 | for (i = 0; i < config->rx_ring_num; i++) { | 655 | for (i = 0; i < config->rx_ring_num; i++) { |
567 | blk_cnt = | 656 | blk_cnt = |
568 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); | 657 | config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1); |
569 | if (!nic->ba[i]) | ||
570 | goto end_free; | ||
571 | for (j = 0; j < blk_cnt; j++) { | 658 | for (j = 0; j < blk_cnt; j++) { |
572 | int k = 0; | 659 | int k = 0; |
573 | if (!nic->ba[i][j]) { | 660 | if (!mac_control->rings[i].ba[j]) |
574 | kfree(nic->ba[i]); | 661 | continue; |
575 | goto end_free; | ||
576 | } | ||
577 | while (k != MAX_RXDS_PER_BLOCK) { | 662 | while (k != MAX_RXDS_PER_BLOCK) { |
578 | buffAdd_t *ba = &nic->ba[i][j][k]; | 663 | buffAdd_t *ba = &mac_control->rings[i].ba[j][k]; |
579 | if (!ba || !ba->ba_0_org || !ba->ba_1_org) | ||
580 | { | ||
581 | kfree(nic->ba[i]); | ||
582 | kfree(nic->ba[i][j]); | ||
583 | if(ba->ba_0_org) | ||
584 | kfree(ba->ba_0_org); | ||
585 | if(ba->ba_1_org) | ||
586 | kfree(ba->ba_1_org); | ||
587 | goto end_free; | ||
588 | } | ||
589 | kfree(ba->ba_0_org); | 664 | kfree(ba->ba_0_org); |
590 | kfree(ba->ba_1_org); | 665 | kfree(ba->ba_1_org); |
591 | k++; | 666 | k++; |
592 | } | 667 | } |
593 | kfree(nic->ba[i][j]); | 668 | kfree(mac_control->rings[i].ba[j]); |
594 | } | 669 | } |
595 | kfree(nic->ba[i]); | 670 | if (mac_control->rings[i].ba) |
671 | kfree(mac_control->rings[i].ba); | ||
596 | } | 672 | } |
597 | end_free: | ||
598 | #endif | 673 | #endif |
599 | 674 | ||
600 | if (mac_control->stats_mem) { | 675 | if (mac_control->stats_mem) { |
@@ -605,12 +680,93 @@ end_free: | |||
605 | } | 680 | } |
606 | } | 681 | } |
607 | 682 | ||
608 | /** | 683 | /** |
609 | * init_nic - Initialization of hardware | 684 | * s2io_verify_pci_mode - |
685 | */ | ||
686 | |||
687 | static int s2io_verify_pci_mode(nic_t *nic) | ||
688 | { | ||
689 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
690 | register u64 val64 = 0; | ||
691 | int mode; | ||
692 | |||
693 | val64 = readq(&bar0->pci_mode); | ||
694 | mode = (u8)GET_PCI_MODE(val64); | ||
695 | |||
696 | if ( val64 & PCI_MODE_UNKNOWN_MODE) | ||
697 | return -1; /* Unknown PCI mode */ | ||
698 | return mode; | ||
699 | } | ||
700 | |||
701 | |||
702 | /** | ||
703 | * s2io_print_pci_mode - | ||
704 | */ | ||
705 | static int s2io_print_pci_mode(nic_t *nic) | ||
706 | { | ||
707 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
708 | register u64 val64 = 0; | ||
709 | int mode; | ||
710 | struct config_param *config = &nic->config; | ||
711 | |||
712 | val64 = readq(&bar0->pci_mode); | ||
713 | mode = (u8)GET_PCI_MODE(val64); | ||
714 | |||
715 | if ( val64 & PCI_MODE_UNKNOWN_MODE) | ||
716 | return -1; /* Unknown PCI mode */ | ||
717 | |||
718 | if (val64 & PCI_MODE_32_BITS) { | ||
719 | DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name); | ||
720 | } else { | ||
721 | DBG_PRINT(ERR_DBG, "%s: Device is on 64 bit ", nic->dev->name); | ||
722 | } | ||
723 | |||
724 | switch(mode) { | ||
725 | case PCI_MODE_PCI_33: | ||
726 | DBG_PRINT(ERR_DBG, "33MHz PCI bus\n"); | ||
727 | config->bus_speed = 33; | ||
728 | break; | ||
729 | case PCI_MODE_PCI_66: | ||
730 | DBG_PRINT(ERR_DBG, "66MHz PCI bus\n"); | ||
731 | config->bus_speed = 133; | ||
732 | break; | ||
733 | case PCI_MODE_PCIX_M1_66: | ||
734 | DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n"); | ||
735 | config->bus_speed = 133; /* Herc doubles the clock rate */ | ||
736 | break; | ||
737 | case PCI_MODE_PCIX_M1_100: | ||
738 | DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n"); | ||
739 | config->bus_speed = 200; | ||
740 | break; | ||
741 | case PCI_MODE_PCIX_M1_133: | ||
742 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n"); | ||
743 | config->bus_speed = 266; | ||
744 | break; | ||
745 | case PCI_MODE_PCIX_M2_66: | ||
746 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n"); | ||
747 | config->bus_speed = 133; | ||
748 | break; | ||
749 | case PCI_MODE_PCIX_M2_100: | ||
750 | DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n"); | ||
751 | config->bus_speed = 200; | ||
752 | break; | ||
753 | case PCI_MODE_PCIX_M2_133: | ||
754 | DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n"); | ||
755 | config->bus_speed = 266; | ||
756 | break; | ||
757 | default: | ||
758 | return -1; /* Unsupported bus speed */ | ||
759 | } | ||
760 | |||
761 | return mode; | ||
762 | } | ||
763 | |||
764 | /** | ||
765 | * init_nic - Initialization of hardware | ||
610 | * @nic: device peivate variable | 766 | * @nic: device peivate variable |
611 | * Description: The function sequentially configures every block | 767 | * Description: The function sequentially configures every block |
612 | * of the H/W from their reset values. | 768 | * of the H/W from their reset values. |
613 | * Return Value: SUCCESS on success and | 769 | * Return Value: SUCCESS on success and |
614 | * '-1' on failure (endian settings incorrect). | 770 | * '-1' on failure (endian settings incorrect). |
615 | */ | 771 | */ |
616 | 772 | ||
@@ -626,21 +782,32 @@ static int init_nic(struct s2io_nic *nic) | |||
626 | struct config_param *config; | 782 | struct config_param *config; |
627 | int mdio_cnt = 0, dtx_cnt = 0; | 783 | int mdio_cnt = 0, dtx_cnt = 0; |
628 | unsigned long long mem_share; | 784 | unsigned long long mem_share; |
785 | int mem_size; | ||
629 | 786 | ||
630 | mac_control = &nic->mac_control; | 787 | mac_control = &nic->mac_control; |
631 | config = &nic->config; | 788 | config = &nic->config; |
632 | 789 | ||
633 | /* Initialize swapper control register */ | 790 | /* to set the swapper controle on the card */ |
634 | if (s2io_set_swapper(nic)) { | 791 | if(s2io_set_swapper(nic)) { |
635 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); | 792 | DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n"); |
636 | return -1; | 793 | return -1; |
637 | } | 794 | } |
638 | 795 | ||
796 | /* | ||
797 | * Herc requires EOI to be removed from reset before XGXS, so.. | ||
798 | */ | ||
799 | if (nic->device_type & XFRAME_II_DEVICE) { | ||
800 | val64 = 0xA500000000ULL; | ||
801 | writeq(val64, &bar0->sw_reset); | ||
802 | msleep(500); | ||
803 | val64 = readq(&bar0->sw_reset); | ||
804 | } | ||
805 | |||
639 | /* Remove XGXS from reset state */ | 806 | /* Remove XGXS from reset state */ |
640 | val64 = 0; | 807 | val64 = 0; |
641 | writeq(val64, &bar0->sw_reset); | 808 | writeq(val64, &bar0->sw_reset); |
642 | val64 = readq(&bar0->sw_reset); | ||
643 | msleep(500); | 809 | msleep(500); |
810 | val64 = readq(&bar0->sw_reset); | ||
644 | 811 | ||
645 | /* Enable Receiving broadcasts */ | 812 | /* Enable Receiving broadcasts */ |
646 | add = &bar0->mac_cfg; | 813 | add = &bar0->mac_cfg; |
@@ -660,48 +827,58 @@ static int init_nic(struct s2io_nic *nic) | |||
660 | val64 = dev->mtu; | 827 | val64 = dev->mtu; |
661 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | 828 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); |
662 | 829 | ||
663 | /* | 830 | /* |
664 | * Configuring the XAUI Interface of Xena. | 831 | * Configuring the XAUI Interface of Xena. |
665 | * *************************************** | 832 | * *************************************** |
666 | * To Configure the Xena's XAUI, one has to write a series | 833 | * To Configure the Xena's XAUI, one has to write a series |
667 | * of 64 bit values into two registers in a particular | 834 | * of 64 bit values into two registers in a particular |
668 | * sequence. Hence a macro 'SWITCH_SIGN' has been defined | 835 | * sequence. Hence a macro 'SWITCH_SIGN' has been defined |
669 | * which will be defined in the array of configuration values | 836 | * which will be defined in the array of configuration values |
670 | * (default_dtx_cfg & default_mdio_cfg) at appropriate places | 837 | * (xena_dtx_cfg & xena_mdio_cfg) at appropriate places |
671 | * to switch writing from one regsiter to another. We continue | 838 | * to switch writing from one regsiter to another. We continue |
672 | * writing these values until we encounter the 'END_SIGN' macro. | 839 | * writing these values until we encounter the 'END_SIGN' macro. |
673 | * For example, After making a series of 21 writes into | 840 | * For example, After making a series of 21 writes into |
674 | * dtx_control register the 'SWITCH_SIGN' appears and hence we | 841 | * dtx_control register the 'SWITCH_SIGN' appears and hence we |
675 | * start writing into mdio_control until we encounter END_SIGN. | 842 | * start writing into mdio_control until we encounter END_SIGN. |
676 | */ | 843 | */ |
677 | while (1) { | 844 | if (nic->device_type & XFRAME_II_DEVICE) { |
678 | dtx_cfg: | 845 | while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) { |
679 | while (default_dtx_cfg[dtx_cnt] != END_SIGN) { | 846 | SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt], |
680 | if (default_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { | ||
681 | dtx_cnt++; | ||
682 | goto mdio_cfg; | ||
683 | } | ||
684 | SPECIAL_REG_WRITE(default_dtx_cfg[dtx_cnt], | ||
685 | &bar0->dtx_control, UF); | 847 | &bar0->dtx_control, UF); |
686 | val64 = readq(&bar0->dtx_control); | 848 | if (dtx_cnt & 0x1) |
849 | msleep(1); /* Necessary!! */ | ||
687 | dtx_cnt++; | 850 | dtx_cnt++; |
688 | } | 851 | } |
689 | mdio_cfg: | 852 | } else { |
690 | while (default_mdio_cfg[mdio_cnt] != END_SIGN) { | 853 | while (1) { |
691 | if (default_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { | 854 | dtx_cfg: |
855 | while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { | ||
856 | if (xena_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { | ||
857 | dtx_cnt++; | ||
858 | goto mdio_cfg; | ||
859 | } | ||
860 | SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], | ||
861 | &bar0->dtx_control, UF); | ||
862 | val64 = readq(&bar0->dtx_control); | ||
863 | dtx_cnt++; | ||
864 | } | ||
865 | mdio_cfg: | ||
866 | while (xena_mdio_cfg[mdio_cnt] != END_SIGN) { | ||
867 | if (xena_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { | ||
868 | mdio_cnt++; | ||
869 | goto dtx_cfg; | ||
870 | } | ||
871 | SPECIAL_REG_WRITE(xena_mdio_cfg[mdio_cnt], | ||
872 | &bar0->mdio_control, UF); | ||
873 | val64 = readq(&bar0->mdio_control); | ||
692 | mdio_cnt++; | 874 | mdio_cnt++; |
875 | } | ||
876 | if ((xena_dtx_cfg[dtx_cnt] == END_SIGN) && | ||
877 | (xena_mdio_cfg[mdio_cnt] == END_SIGN)) { | ||
878 | break; | ||
879 | } else { | ||
693 | goto dtx_cfg; | 880 | goto dtx_cfg; |
694 | } | 881 | } |
695 | SPECIAL_REG_WRITE(default_mdio_cfg[mdio_cnt], | ||
696 | &bar0->mdio_control, UF); | ||
697 | val64 = readq(&bar0->mdio_control); | ||
698 | mdio_cnt++; | ||
699 | } | ||
700 | if ((default_dtx_cfg[dtx_cnt] == END_SIGN) && | ||
701 | (default_mdio_cfg[mdio_cnt] == END_SIGN)) { | ||
702 | break; | ||
703 | } else { | ||
704 | goto dtx_cfg; | ||
705 | } | 882 | } |
706 | } | 883 | } |
707 | 884 | ||
@@ -748,12 +925,20 @@ static int init_nic(struct s2io_nic *nic) | |||
748 | val64 |= BIT(0); /* To enable the FIFO partition. */ | 925 | val64 |= BIT(0); /* To enable the FIFO partition. */ |
749 | writeq(val64, &bar0->tx_fifo_partition_0); | 926 | writeq(val64, &bar0->tx_fifo_partition_0); |
750 | 927 | ||
928 | /* | ||
929 | * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug | ||
930 | * SXE-008 TRANSMIT DMA ARBITRATION ISSUE. | ||
931 | */ | ||
932 | if ((nic->device_type == XFRAME_I_DEVICE) && | ||
933 | (get_xena_rev_id(nic->pdev) < 4)) | ||
934 | writeq(PCC_ENABLE_FOUR, &bar0->pcc_enable); | ||
935 | |||
751 | val64 = readq(&bar0->tx_fifo_partition_0); | 936 | val64 = readq(&bar0->tx_fifo_partition_0); |
752 | DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n", | 937 | DBG_PRINT(INIT_DBG, "Fifo partition at: 0x%p is: 0x%llx\n", |
753 | &bar0->tx_fifo_partition_0, (unsigned long long) val64); | 938 | &bar0->tx_fifo_partition_0, (unsigned long long) val64); |
754 | 939 | ||
755 | /* | 940 | /* |
756 | * Initialization of Tx_PA_CONFIG register to ignore packet | 941 | * Initialization of Tx_PA_CONFIG register to ignore packet |
757 | * integrity checking. | 942 | * integrity checking. |
758 | */ | 943 | */ |
759 | val64 = readq(&bar0->tx_pa_cfg); | 944 | val64 = readq(&bar0->tx_pa_cfg); |
@@ -770,85 +955,304 @@ static int init_nic(struct s2io_nic *nic) | |||
770 | } | 955 | } |
771 | writeq(val64, &bar0->rx_queue_priority); | 956 | writeq(val64, &bar0->rx_queue_priority); |
772 | 957 | ||
773 | /* | 958 | /* |
774 | * Allocating equal share of memory to all the | 959 | * Allocating equal share of memory to all the |
775 | * configured Rings. | 960 | * configured Rings. |
776 | */ | 961 | */ |
777 | val64 = 0; | 962 | val64 = 0; |
963 | if (nic->device_type & XFRAME_II_DEVICE) | ||
964 | mem_size = 32; | ||
965 | else | ||
966 | mem_size = 64; | ||
967 | |||
778 | for (i = 0; i < config->rx_ring_num; i++) { | 968 | for (i = 0; i < config->rx_ring_num; i++) { |
779 | switch (i) { | 969 | switch (i) { |
780 | case 0: | 970 | case 0: |
781 | mem_share = (64 / config->rx_ring_num + | 971 | mem_share = (mem_size / config->rx_ring_num + |
782 | 64 % config->rx_ring_num); | 972 | mem_size % config->rx_ring_num); |
783 | val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share); | 973 | val64 |= RX_QUEUE_CFG_Q0_SZ(mem_share); |
784 | continue; | 974 | continue; |
785 | case 1: | 975 | case 1: |
786 | mem_share = (64 / config->rx_ring_num); | 976 | mem_share = (mem_size / config->rx_ring_num); |
787 | val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share); | 977 | val64 |= RX_QUEUE_CFG_Q1_SZ(mem_share); |
788 | continue; | 978 | continue; |
789 | case 2: | 979 | case 2: |
790 | mem_share = (64 / config->rx_ring_num); | 980 | mem_share = (mem_size / config->rx_ring_num); |
791 | val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share); | 981 | val64 |= RX_QUEUE_CFG_Q2_SZ(mem_share); |
792 | continue; | 982 | continue; |
793 | case 3: | 983 | case 3: |
794 | mem_share = (64 / config->rx_ring_num); | 984 | mem_share = (mem_size / config->rx_ring_num); |
795 | val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share); | 985 | val64 |= RX_QUEUE_CFG_Q3_SZ(mem_share); |
796 | continue; | 986 | continue; |
797 | case 4: | 987 | case 4: |
798 | mem_share = (64 / config->rx_ring_num); | 988 | mem_share = (mem_size / config->rx_ring_num); |
799 | val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share); | 989 | val64 |= RX_QUEUE_CFG_Q4_SZ(mem_share); |
800 | continue; | 990 | continue; |
801 | case 5: | 991 | case 5: |
802 | mem_share = (64 / config->rx_ring_num); | 992 | mem_share = (mem_size / config->rx_ring_num); |
803 | val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share); | 993 | val64 |= RX_QUEUE_CFG_Q5_SZ(mem_share); |
804 | continue; | 994 | continue; |
805 | case 6: | 995 | case 6: |
806 | mem_share = (64 / config->rx_ring_num); | 996 | mem_share = (mem_size / config->rx_ring_num); |
807 | val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share); | 997 | val64 |= RX_QUEUE_CFG_Q6_SZ(mem_share); |
808 | continue; | 998 | continue; |
809 | case 7: | 999 | case 7: |
810 | mem_share = (64 / config->rx_ring_num); | 1000 | mem_share = (mem_size / config->rx_ring_num); |
811 | val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share); | 1001 | val64 |= RX_QUEUE_CFG_Q7_SZ(mem_share); |
812 | continue; | 1002 | continue; |
813 | } | 1003 | } |
814 | } | 1004 | } |
815 | writeq(val64, &bar0->rx_queue_cfg); | 1005 | writeq(val64, &bar0->rx_queue_cfg); |
816 | 1006 | ||
817 | /* | 1007 | /* |
818 | * Initializing the Tx round robin registers to 0. | 1008 | * Filling Tx round robin registers |
819 | * Filling Tx and Rx round robin registers as per the | 1009 | * as per the number of FIFOs |
820 | * number of FIFOs and Rings is still TODO. | ||
821 | */ | ||
822 | writeq(0, &bar0->tx_w_round_robin_0); | ||
823 | writeq(0, &bar0->tx_w_round_robin_1); | ||
824 | writeq(0, &bar0->tx_w_round_robin_2); | ||
825 | writeq(0, &bar0->tx_w_round_robin_3); | ||
826 | writeq(0, &bar0->tx_w_round_robin_4); | ||
827 | |||
828 | /* | ||
829 | * TODO | ||
830 | * Disable Rx steering. Hard coding all packets be steered to | ||
831 | * Queue 0 for now. | ||
832 | */ | 1010 | */ |
833 | val64 = 0x8080808080808080ULL; | 1011 | switch (config->tx_fifo_num) { |
834 | writeq(val64, &bar0->rts_qos_steering); | 1012 | case 1: |
1013 | val64 = 0x0000000000000000ULL; | ||
1014 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1015 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1016 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1017 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1018 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1019 | break; | ||
1020 | case 2: | ||
1021 | val64 = 0x0000010000010000ULL; | ||
1022 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1023 | val64 = 0x0100000100000100ULL; | ||
1024 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1025 | val64 = 0x0001000001000001ULL; | ||
1026 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1027 | val64 = 0x0000010000010000ULL; | ||
1028 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1029 | val64 = 0x0100000000000000ULL; | ||
1030 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1031 | break; | ||
1032 | case 3: | ||
1033 | val64 = 0x0001000102000001ULL; | ||
1034 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1035 | val64 = 0x0001020000010001ULL; | ||
1036 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1037 | val64 = 0x0200000100010200ULL; | ||
1038 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1039 | val64 = 0x0001000102000001ULL; | ||
1040 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1041 | val64 = 0x0001020000000000ULL; | ||
1042 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1043 | break; | ||
1044 | case 4: | ||
1045 | val64 = 0x0001020300010200ULL; | ||
1046 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1047 | val64 = 0x0100000102030001ULL; | ||
1048 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1049 | val64 = 0x0200010000010203ULL; | ||
1050 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1051 | val64 = 0x0001020001000001ULL; | ||
1052 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1053 | val64 = 0x0203000100000000ULL; | ||
1054 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1055 | break; | ||
1056 | case 5: | ||
1057 | val64 = 0x0001000203000102ULL; | ||
1058 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1059 | val64 = 0x0001020001030004ULL; | ||
1060 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1061 | val64 = 0x0001000203000102ULL; | ||
1062 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1063 | val64 = 0x0001020001030004ULL; | ||
1064 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1065 | val64 = 0x0001000000000000ULL; | ||
1066 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1067 | break; | ||
1068 | case 6: | ||
1069 | val64 = 0x0001020304000102ULL; | ||
1070 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1071 | val64 = 0x0304050001020001ULL; | ||
1072 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1073 | val64 = 0x0203000100000102ULL; | ||
1074 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1075 | val64 = 0x0304000102030405ULL; | ||
1076 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1077 | val64 = 0x0001000200000000ULL; | ||
1078 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1079 | break; | ||
1080 | case 7: | ||
1081 | val64 = 0x0001020001020300ULL; | ||
1082 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1083 | val64 = 0x0102030400010203ULL; | ||
1084 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1085 | val64 = 0x0405060001020001ULL; | ||
1086 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1087 | val64 = 0x0304050000010200ULL; | ||
1088 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1089 | val64 = 0x0102030000000000ULL; | ||
1090 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1091 | break; | ||
1092 | case 8: | ||
1093 | val64 = 0x0001020300040105ULL; | ||
1094 | writeq(val64, &bar0->tx_w_round_robin_0); | ||
1095 | val64 = 0x0200030106000204ULL; | ||
1096 | writeq(val64, &bar0->tx_w_round_robin_1); | ||
1097 | val64 = 0x0103000502010007ULL; | ||
1098 | writeq(val64, &bar0->tx_w_round_robin_2); | ||
1099 | val64 = 0x0304010002060500ULL; | ||
1100 | writeq(val64, &bar0->tx_w_round_robin_3); | ||
1101 | val64 = 0x0103020400000000ULL; | ||
1102 | writeq(val64, &bar0->tx_w_round_robin_4); | ||
1103 | break; | ||
1104 | } | ||
1105 | |||
1106 | /* Filling the Rx round robin registers as per the | ||
1107 | * number of Rings and steering based on QoS. | ||
1108 | */ | ||
1109 | switch (config->rx_ring_num) { | ||
1110 | case 1: | ||
1111 | val64 = 0x8080808080808080ULL; | ||
1112 | writeq(val64, &bar0->rts_qos_steering); | ||
1113 | break; | ||
1114 | case 2: | ||
1115 | val64 = 0x0000010000010000ULL; | ||
1116 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1117 | val64 = 0x0100000100000100ULL; | ||
1118 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1119 | val64 = 0x0001000001000001ULL; | ||
1120 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1121 | val64 = 0x0000010000010000ULL; | ||
1122 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1123 | val64 = 0x0100000000000000ULL; | ||
1124 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1125 | |||
1126 | val64 = 0x8080808040404040ULL; | ||
1127 | writeq(val64, &bar0->rts_qos_steering); | ||
1128 | break; | ||
1129 | case 3: | ||
1130 | val64 = 0x0001000102000001ULL; | ||
1131 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1132 | val64 = 0x0001020000010001ULL; | ||
1133 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1134 | val64 = 0x0200000100010200ULL; | ||
1135 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1136 | val64 = 0x0001000102000001ULL; | ||
1137 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1138 | val64 = 0x0001020000000000ULL; | ||
1139 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1140 | |||
1141 | val64 = 0x8080804040402020ULL; | ||
1142 | writeq(val64, &bar0->rts_qos_steering); | ||
1143 | break; | ||
1144 | case 4: | ||
1145 | val64 = 0x0001020300010200ULL; | ||
1146 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1147 | val64 = 0x0100000102030001ULL; | ||
1148 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1149 | val64 = 0x0200010000010203ULL; | ||
1150 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1151 | val64 = 0x0001020001000001ULL; | ||
1152 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1153 | val64 = 0x0203000100000000ULL; | ||
1154 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1155 | |||
1156 | val64 = 0x8080404020201010ULL; | ||
1157 | writeq(val64, &bar0->rts_qos_steering); | ||
1158 | break; | ||
1159 | case 5: | ||
1160 | val64 = 0x0001000203000102ULL; | ||
1161 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1162 | val64 = 0x0001020001030004ULL; | ||
1163 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1164 | val64 = 0x0001000203000102ULL; | ||
1165 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1166 | val64 = 0x0001020001030004ULL; | ||
1167 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1168 | val64 = 0x0001000000000000ULL; | ||
1169 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1170 | |||
1171 | val64 = 0x8080404020201008ULL; | ||
1172 | writeq(val64, &bar0->rts_qos_steering); | ||
1173 | break; | ||
1174 | case 6: | ||
1175 | val64 = 0x0001020304000102ULL; | ||
1176 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1177 | val64 = 0x0304050001020001ULL; | ||
1178 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1179 | val64 = 0x0203000100000102ULL; | ||
1180 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1181 | val64 = 0x0304000102030405ULL; | ||
1182 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1183 | val64 = 0x0001000200000000ULL; | ||
1184 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1185 | |||
1186 | val64 = 0x8080404020100804ULL; | ||
1187 | writeq(val64, &bar0->rts_qos_steering); | ||
1188 | break; | ||
1189 | case 7: | ||
1190 | val64 = 0x0001020001020300ULL; | ||
1191 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1192 | val64 = 0x0102030400010203ULL; | ||
1193 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1194 | val64 = 0x0405060001020001ULL; | ||
1195 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1196 | val64 = 0x0304050000010200ULL; | ||
1197 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1198 | val64 = 0x0102030000000000ULL; | ||
1199 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1200 | |||
1201 | val64 = 0x8080402010080402ULL; | ||
1202 | writeq(val64, &bar0->rts_qos_steering); | ||
1203 | break; | ||
1204 | case 8: | ||
1205 | val64 = 0x0001020300040105ULL; | ||
1206 | writeq(val64, &bar0->rx_w_round_robin_0); | ||
1207 | val64 = 0x0200030106000204ULL; | ||
1208 | writeq(val64, &bar0->rx_w_round_robin_1); | ||
1209 | val64 = 0x0103000502010007ULL; | ||
1210 | writeq(val64, &bar0->rx_w_round_robin_2); | ||
1211 | val64 = 0x0304010002060500ULL; | ||
1212 | writeq(val64, &bar0->rx_w_round_robin_3); | ||
1213 | val64 = 0x0103020400000000ULL; | ||
1214 | writeq(val64, &bar0->rx_w_round_robin_4); | ||
1215 | |||
1216 | val64 = 0x8040201008040201ULL; | ||
1217 | writeq(val64, &bar0->rts_qos_steering); | ||
1218 | break; | ||
1219 | } | ||
835 | 1220 | ||
836 | /* UDP Fix */ | 1221 | /* UDP Fix */ |
837 | val64 = 0; | 1222 | val64 = 0; |
838 | for (i = 1; i < 8; i++) | 1223 | for (i = 0; i < 8; i++) |
1224 | writeq(val64, &bar0->rts_frm_len_n[i]); | ||
1225 | |||
1226 | /* Set the default rts frame length for the rings configured */ | ||
1227 | val64 = MAC_RTS_FRM_LEN_SET(dev->mtu+22); | ||
1228 | for (i = 0 ; i < config->rx_ring_num ; i++) | ||
839 | writeq(val64, &bar0->rts_frm_len_n[i]); | 1229 | writeq(val64, &bar0->rts_frm_len_n[i]); |
840 | 1230 | ||
841 | /* Set rts_frm_len register for fifo 0 */ | 1231 | /* Set the frame length for the configured rings |
842 | writeq(MAC_RTS_FRM_LEN_SET(dev->mtu + 22), | 1232 | * desired by the user |
843 | &bar0->rts_frm_len_n[0]); | 1233 | */ |
1234 | for (i = 0; i < config->rx_ring_num; i++) { | ||
1235 | /* If rts_frm_len[i] == 0 then it is assumed that user not | ||
1236 | * specified frame length steering. | ||
1237 | * If the user provides the frame length then program | ||
1238 | * the rts_frm_len register for those values or else | ||
1239 | * leave it as it is. | ||
1240 | */ | ||
1241 | if (rts_frm_len[i] != 0) { | ||
1242 | writeq(MAC_RTS_FRM_LEN_SET(rts_frm_len[i]), | ||
1243 | &bar0->rts_frm_len_n[i]); | ||
1244 | } | ||
1245 | } | ||
844 | 1246 | ||
845 | /* Enable statistics */ | 1247 | /* Program statistics memory */ |
846 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); | 1248 | writeq(mac_control->stats_mem_phy, &bar0->stat_addr); |
847 | val64 = SET_UPDT_PERIOD(Stats_refresh_time) | | ||
848 | STAT_CFG_STAT_RO | STAT_CFG_STAT_EN; | ||
849 | writeq(val64, &bar0->stat_cfg); | ||
850 | 1249 | ||
851 | /* | 1250 | if (nic->device_type == XFRAME_II_DEVICE) { |
1251 | val64 = STAT_BC(0x320); | ||
1252 | writeq(val64, &bar0->stat_byte_cnt); | ||
1253 | } | ||
1254 | |||
1255 | /* | ||
852 | * Initializing the sampling rate for the device to calculate the | 1256 | * Initializing the sampling rate for the device to calculate the |
853 | * bandwidth utilization. | 1257 | * bandwidth utilization. |
854 | */ | 1258 | */ |
@@ -857,30 +1261,38 @@ static int init_nic(struct s2io_nic *nic) | |||
857 | writeq(val64, &bar0->mac_link_util); | 1261 | writeq(val64, &bar0->mac_link_util); |
858 | 1262 | ||
859 | 1263 | ||
860 | /* | 1264 | /* |
861 | * Initializing the Transmit and Receive Traffic Interrupt | 1265 | * Initializing the Transmit and Receive Traffic Interrupt |
862 | * Scheme. | 1266 | * Scheme. |
863 | */ | 1267 | */ |
864 | /* TTI Initialization. Default Tx timer gets us about | 1268 | /* |
1269 | * TTI Initialization. Default Tx timer gets us about | ||
865 | * 250 interrupts per sec. Continuous interrupts are enabled | 1270 | * 250 interrupts per sec. Continuous interrupts are enabled |
866 | * by default. | 1271 | * by default. |
867 | */ | 1272 | */ |
868 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078) | | 1273 | if (nic->device_type == XFRAME_II_DEVICE) { |
869 | TTI_DATA1_MEM_TX_URNG_A(0xA) | | 1274 | int count = (nic->config.bus_speed * 125)/2; |
1275 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(count); | ||
1276 | } else { | ||
1277 | |||
1278 | val64 = TTI_DATA1_MEM_TX_TIMER_VAL(0x2078); | ||
1279 | } | ||
1280 | val64 |= TTI_DATA1_MEM_TX_URNG_A(0xA) | | ||
870 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1281 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
871 | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN | | 1282 | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
872 | TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1283 | if (use_continuous_tx_intrs) |
1284 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | ||
873 | writeq(val64, &bar0->tti_data1_mem); | 1285 | writeq(val64, &bar0->tti_data1_mem); |
874 | 1286 | ||
875 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1287 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
876 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1288 | TTI_DATA2_MEM_TX_UFC_B(0x20) | |
877 | TTI_DATA2_MEM_TX_UFC_C(0x40) | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1289 | TTI_DATA2_MEM_TX_UFC_C(0x70) | TTI_DATA2_MEM_TX_UFC_D(0x80); |
878 | writeq(val64, &bar0->tti_data2_mem); | 1290 | writeq(val64, &bar0->tti_data2_mem); |
879 | 1291 | ||
880 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; | 1292 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; |
881 | writeq(val64, &bar0->tti_command_mem); | 1293 | writeq(val64, &bar0->tti_command_mem); |
882 | 1294 | ||
883 | /* | 1295 | /* |
884 | * Once the operation completes, the Strobe bit of the command | 1296 | * Once the operation completes, the Strobe bit of the command |
885 | * register will be reset. We poll for this particular condition | 1297 | * register will be reset. We poll for this particular condition |
886 | * We wait for a maximum of 500ms for the operation to complete, | 1298 | * We wait for a maximum of 500ms for the operation to complete, |
@@ -901,52 +1313,97 @@ static int init_nic(struct s2io_nic *nic) | |||
901 | time++; | 1313 | time++; |
902 | } | 1314 | } |
903 | 1315 | ||
904 | /* RTI Initialization */ | 1316 | if (nic->config.bimodal) { |
905 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF) | | 1317 | int k = 0; |
906 | RTI_DATA1_MEM_RX_URNG_A(0xA) | | 1318 | for (k = 0; k < config->rx_ring_num; k++) { |
907 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | 1319 | val64 = TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE_NEW_CMD; |
908 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | 1320 | val64 |= TTI_CMD_MEM_OFFSET(0x38+k); |
1321 | writeq(val64, &bar0->tti_command_mem); | ||
1322 | |||
1323 | /* | ||
1324 | * Once the operation completes, the Strobe bit of the command | ||
1325 | * register will be reset. We poll for this particular condition | ||
1326 | * We wait for a maximum of 500ms for the operation to complete, | ||
1327 | * if it's not complete by then we return error. | ||
1328 | */ | ||
1329 | time = 0; | ||
1330 | while (TRUE) { | ||
1331 | val64 = readq(&bar0->tti_command_mem); | ||
1332 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | ||
1333 | break; | ||
1334 | } | ||
1335 | if (time > 10) { | ||
1336 | DBG_PRINT(ERR_DBG, | ||
1337 | "%s: TTI init Failed\n", | ||
1338 | dev->name); | ||
1339 | return -1; | ||
1340 | } | ||
1341 | time++; | ||
1342 | msleep(50); | ||
1343 | } | ||
1344 | } | ||
1345 | } else { | ||
909 | 1346 | ||
910 | writeq(val64, &bar0->rti_data1_mem); | 1347 | /* RTI Initialization */ |
1348 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1349 | /* | ||
1350 | * Programmed to generate Apprx 500 Intrs per | ||
1351 | * second | ||
1352 | */ | ||
1353 | int count = (nic->config.bus_speed * 125)/4; | ||
1354 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(count); | ||
1355 | } else { | ||
1356 | val64 = RTI_DATA1_MEM_RX_TIMER_VAL(0xFFF); | ||
1357 | } | ||
1358 | val64 |= RTI_DATA1_MEM_RX_URNG_A(0xA) | | ||
1359 | RTI_DATA1_MEM_RX_URNG_B(0x10) | | ||
1360 | RTI_DATA1_MEM_RX_URNG_C(0x30) | RTI_DATA1_MEM_RX_TIMER_AC_EN; | ||
911 | 1361 | ||
912 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | | 1362 | writeq(val64, &bar0->rti_data1_mem); |
913 | RTI_DATA2_MEM_RX_UFC_B(0x2) | | ||
914 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
915 | writeq(val64, &bar0->rti_data2_mem); | ||
916 | 1363 | ||
917 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD; | 1364 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | |
918 | writeq(val64, &bar0->rti_command_mem); | 1365 | RTI_DATA2_MEM_RX_UFC_B(0x2) | |
1366 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | ||
1367 | writeq(val64, &bar0->rti_data2_mem); | ||
919 | 1368 | ||
920 | /* | 1369 | for (i = 0; i < config->rx_ring_num; i++) { |
921 | * Once the operation completes, the Strobe bit of the command | 1370 | val64 = RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE_NEW_CMD |
922 | * register will be reset. We poll for this particular condition | 1371 | | RTI_CMD_MEM_OFFSET(i); |
923 | * We wait for a maximum of 500ms for the operation to complete, | 1372 | writeq(val64, &bar0->rti_command_mem); |
924 | * if it's not complete by then we return error. | 1373 | |
925 | */ | 1374 | /* |
926 | time = 0; | 1375 | * Once the operation completes, the Strobe bit of the |
927 | while (TRUE) { | 1376 | * command register will be reset. We poll for this |
928 | val64 = readq(&bar0->rti_command_mem); | 1377 | * particular condition. We wait for a maximum of 500ms |
929 | if (!(val64 & TTI_CMD_MEM_STROBE_NEW_CMD)) { | 1378 | * for the operation to complete, if it's not complete |
930 | break; | 1379 | * by then we return error. |
931 | } | 1380 | */ |
932 | if (time > 10) { | 1381 | time = 0; |
933 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | 1382 | while (TRUE) { |
934 | dev->name); | 1383 | val64 = readq(&bar0->rti_command_mem); |
935 | return -1; | 1384 | if (!(val64 & RTI_CMD_MEM_STROBE_NEW_CMD)) { |
1385 | break; | ||
1386 | } | ||
1387 | if (time > 10) { | ||
1388 | DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n", | ||
1389 | dev->name); | ||
1390 | return -1; | ||
1391 | } | ||
1392 | time++; | ||
1393 | msleep(50); | ||
1394 | } | ||
936 | } | 1395 | } |
937 | time++; | ||
938 | msleep(50); | ||
939 | } | 1396 | } |
940 | 1397 | ||
941 | /* | 1398 | /* |
942 | * Initializing proper values as Pause threshold into all | 1399 | * Initializing proper values as Pause threshold into all |
943 | * the 8 Queues on Rx side. | 1400 | * the 8 Queues on Rx side. |
944 | */ | 1401 | */ |
945 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3); | 1402 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q0q3); |
946 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); | 1403 | writeq(0xffbbffbbffbbffbbULL, &bar0->mc_pause_thresh_q4q7); |
947 | 1404 | ||
948 | /* Disable RMAC PAD STRIPPING */ | 1405 | /* Disable RMAC PAD STRIPPING */ |
949 | add = &bar0->mac_cfg; | 1406 | add = (void *) &bar0->mac_cfg; |
950 | val64 = readq(&bar0->mac_cfg); | 1407 | val64 = readq(&bar0->mac_cfg); |
951 | val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); | 1408 | val64 &= ~(MAC_CFG_RMAC_STRIP_PAD); |
952 | writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); | 1409 | writeq(RMAC_CFG_KEY(0x4C0D), &bar0->rmac_cfg_key); |
@@ -955,8 +1412,8 @@ static int init_nic(struct s2io_nic *nic) | |||
955 | writel((u32) (val64 >> 32), (add + 4)); | 1412 | writel((u32) (val64 >> 32), (add + 4)); |
956 | val64 = readq(&bar0->mac_cfg); | 1413 | val64 = readq(&bar0->mac_cfg); |
957 | 1414 | ||
958 | /* | 1415 | /* |
959 | * Set the time value to be inserted in the pause frame | 1416 | * Set the time value to be inserted in the pause frame |
960 | * generated by xena. | 1417 | * generated by xena. |
961 | */ | 1418 | */ |
962 | val64 = readq(&bar0->rmac_pause_cfg); | 1419 | val64 = readq(&bar0->rmac_pause_cfg); |
@@ -964,7 +1421,7 @@ static int init_nic(struct s2io_nic *nic) | |||
964 | val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); | 1421 | val64 |= RMAC_PAUSE_HG_PTIME(nic->mac_control.rmac_pause_time); |
965 | writeq(val64, &bar0->rmac_pause_cfg); | 1422 | writeq(val64, &bar0->rmac_pause_cfg); |
966 | 1423 | ||
967 | /* | 1424 | /* |
968 | * Set the Threshold Limit for Generating the pause frame | 1425 | * Set the Threshold Limit for Generating the pause frame |
969 | * If the amount of data in any Queue exceeds ratio of | 1426 | * If the amount of data in any Queue exceeds ratio of |
970 | * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 | 1427 | * (mac_control.mc_pause_threshold_q0q3 or q4q7)/256 |
@@ -988,25 +1445,54 @@ static int init_nic(struct s2io_nic *nic) | |||
988 | } | 1445 | } |
989 | writeq(val64, &bar0->mc_pause_thresh_q4q7); | 1446 | writeq(val64, &bar0->mc_pause_thresh_q4q7); |
990 | 1447 | ||
991 | /* | 1448 | /* |
992 | * TxDMA will stop Read request if the number of read split has | 1449 | * TxDMA will stop Read request if the number of read split has |
993 | * exceeded the limit pointed by shared_splits | 1450 | * exceeded the limit pointed by shared_splits |
994 | */ | 1451 | */ |
995 | val64 = readq(&bar0->pic_control); | 1452 | val64 = readq(&bar0->pic_control); |
996 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); | 1453 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); |
997 | writeq(val64, &bar0->pic_control); | 1454 | writeq(val64, &bar0->pic_control); |
998 | 1455 | ||
1456 | /* | ||
1457 | * Programming the Herc to split every write transaction | ||
1458 | * that does not start on an ADB to reduce disconnects. | ||
1459 | */ | ||
1460 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1461 | val64 = WREQ_SPLIT_MASK_SET_MASK(255); | ||
1462 | writeq(val64, &bar0->wreq_split_mask); | ||
1463 | } | ||
1464 | |||
1465 | /* Setting Link stability period to 64 ms */ | ||
1466 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
1467 | val64 = MISC_LINK_STABILITY_PRD(3); | ||
1468 | writeq(val64, &bar0->misc_control); | ||
1469 | } | ||
1470 | |||
999 | return SUCCESS; | 1471 | return SUCCESS; |
1000 | } | 1472 | } |
1473 | #define LINK_UP_DOWN_INTERRUPT 1 | ||
1474 | #define MAC_RMAC_ERR_TIMER 2 | ||
1001 | 1475 | ||
1002 | /** | 1476 | #if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE) |
1003 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | 1477 | #define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER |
1478 | #else | ||
1479 | int s2io_link_fault_indication(nic_t *nic) | ||
1480 | { | ||
1481 | if (nic->device_type == XFRAME_II_DEVICE) | ||
1482 | return LINK_UP_DOWN_INTERRUPT; | ||
1483 | else | ||
1484 | return MAC_RMAC_ERR_TIMER; | ||
1485 | } | ||
1486 | #endif | ||
1487 | |||
1488 | /** | ||
1489 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | ||
1004 | * @nic: device private variable, | 1490 | * @nic: device private variable, |
1005 | * @mask: A mask indicating which Intr block must be modified and, | 1491 | * @mask: A mask indicating which Intr block must be modified and, |
1006 | * @flag: A flag indicating whether to enable or disable the Intrs. | 1492 | * @flag: A flag indicating whether to enable or disable the Intrs. |
1007 | * Description: This function will either disable or enable the interrupts | 1493 | * Description: This function will either disable or enable the interrupts |
1008 | * depending on the flag argument. The mask argument can be used to | 1494 | * depending on the flag argument. The mask argument can be used to |
1009 | * enable/disable any Intr block. | 1495 | * enable/disable any Intr block. |
1010 | * Return Value: NONE. | 1496 | * Return Value: NONE. |
1011 | */ | 1497 | */ |
1012 | 1498 | ||
@@ -1024,20 +1510,31 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1024 | temp64 = readq(&bar0->general_int_mask); | 1510 | temp64 = readq(&bar0->general_int_mask); |
1025 | temp64 &= ~((u64) val64); | 1511 | temp64 &= ~((u64) val64); |
1026 | writeq(temp64, &bar0->general_int_mask); | 1512 | writeq(temp64, &bar0->general_int_mask); |
1027 | /* | 1513 | /* |
1028 | * Disabled all PCIX, Flash, MDIO, IIC and GPIO | 1514 | * If Hercules adapter enable GPIO otherwise |
1029 | * interrupts for now. | 1515 | * disabled all PCIX, Flash, MDIO, IIC and GPIO |
1030 | * TODO | 1516 | * interrupts for now. |
1517 | * TODO | ||
1031 | */ | 1518 | */ |
1032 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | 1519 | if (s2io_link_fault_indication(nic) == |
1033 | /* | 1520 | LINK_UP_DOWN_INTERRUPT ) { |
1521 | temp64 = readq(&bar0->pic_int_mask); | ||
1522 | temp64 &= ~((u64) PIC_INT_GPIO); | ||
1523 | writeq(temp64, &bar0->pic_int_mask); | ||
1524 | temp64 = readq(&bar0->gpio_int_mask); | ||
1525 | temp64 &= ~((u64) GPIO_INT_MASK_LINK_UP); | ||
1526 | writeq(temp64, &bar0->gpio_int_mask); | ||
1527 | } else { | ||
1528 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | ||
1529 | } | ||
1530 | /* | ||
1034 | * No MSI Support is available presently, so TTI and | 1531 | * No MSI Support is available presently, so TTI and |
1035 | * RTI interrupts are also disabled. | 1532 | * RTI interrupts are also disabled. |
1036 | */ | 1533 | */ |
1037 | } else if (flag == DISABLE_INTRS) { | 1534 | } else if (flag == DISABLE_INTRS) { |
1038 | /* | 1535 | /* |
1039 | * Disable PIC Intrs in the general | 1536 | * Disable PIC Intrs in the general |
1040 | * intr mask register | 1537 | * intr mask register |
1041 | */ | 1538 | */ |
1042 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); | 1539 | writeq(DISABLE_ALL_INTRS, &bar0->pic_int_mask); |
1043 | temp64 = readq(&bar0->general_int_mask); | 1540 | temp64 = readq(&bar0->general_int_mask); |
@@ -1055,27 +1552,27 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1055 | temp64 = readq(&bar0->general_int_mask); | 1552 | temp64 = readq(&bar0->general_int_mask); |
1056 | temp64 &= ~((u64) val64); | 1553 | temp64 &= ~((u64) val64); |
1057 | writeq(temp64, &bar0->general_int_mask); | 1554 | writeq(temp64, &bar0->general_int_mask); |
1058 | /* | 1555 | /* |
1059 | * Keep all interrupts other than PFC interrupt | 1556 | * Keep all interrupts other than PFC interrupt |
1060 | * and PCC interrupt disabled in DMA level. | 1557 | * and PCC interrupt disabled in DMA level. |
1061 | */ | 1558 | */ |
1062 | val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | | 1559 | val64 = DISABLE_ALL_INTRS & ~(TXDMA_PFC_INT_M | |
1063 | TXDMA_PCC_INT_M); | 1560 | TXDMA_PCC_INT_M); |
1064 | writeq(val64, &bar0->txdma_int_mask); | 1561 | writeq(val64, &bar0->txdma_int_mask); |
1065 | /* | 1562 | /* |
1066 | * Enable only the MISC error 1 interrupt in PFC block | 1563 | * Enable only the MISC error 1 interrupt in PFC block |
1067 | */ | 1564 | */ |
1068 | val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); | 1565 | val64 = DISABLE_ALL_INTRS & (~PFC_MISC_ERR_1); |
1069 | writeq(val64, &bar0->pfc_err_mask); | 1566 | writeq(val64, &bar0->pfc_err_mask); |
1070 | /* | 1567 | /* |
1071 | * Enable only the FB_ECC error interrupt in PCC block | 1568 | * Enable only the FB_ECC error interrupt in PCC block |
1072 | */ | 1569 | */ |
1073 | val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); | 1570 | val64 = DISABLE_ALL_INTRS & (~PCC_FB_ECC_ERR); |
1074 | writeq(val64, &bar0->pcc_err_mask); | 1571 | writeq(val64, &bar0->pcc_err_mask); |
1075 | } else if (flag == DISABLE_INTRS) { | 1572 | } else if (flag == DISABLE_INTRS) { |
1076 | /* | 1573 | /* |
1077 | * Disable TxDMA Intrs in the general intr mask | 1574 | * Disable TxDMA Intrs in the general intr mask |
1078 | * register | 1575 | * register |
1079 | */ | 1576 | */ |
1080 | writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); | 1577 | writeq(DISABLE_ALL_INTRS, &bar0->txdma_int_mask); |
1081 | writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); | 1578 | writeq(DISABLE_ALL_INTRS, &bar0->pfc_err_mask); |
@@ -1093,15 +1590,15 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1093 | temp64 = readq(&bar0->general_int_mask); | 1590 | temp64 = readq(&bar0->general_int_mask); |
1094 | temp64 &= ~((u64) val64); | 1591 | temp64 &= ~((u64) val64); |
1095 | writeq(temp64, &bar0->general_int_mask); | 1592 | writeq(temp64, &bar0->general_int_mask); |
1096 | /* | 1593 | /* |
1097 | * All RxDMA block interrupts are disabled for now | 1594 | * All RxDMA block interrupts are disabled for now |
1098 | * TODO | 1595 | * TODO |
1099 | */ | 1596 | */ |
1100 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); | 1597 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); |
1101 | } else if (flag == DISABLE_INTRS) { | 1598 | } else if (flag == DISABLE_INTRS) { |
1102 | /* | 1599 | /* |
1103 | * Disable RxDMA Intrs in the general intr mask | 1600 | * Disable RxDMA Intrs in the general intr mask |
1104 | * register | 1601 | * register |
1105 | */ | 1602 | */ |
1106 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); | 1603 | writeq(DISABLE_ALL_INTRS, &bar0->rxdma_int_mask); |
1107 | temp64 = readq(&bar0->general_int_mask); | 1604 | temp64 = readq(&bar0->general_int_mask); |
@@ -1118,22 +1615,13 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1118 | temp64 = readq(&bar0->general_int_mask); | 1615 | temp64 = readq(&bar0->general_int_mask); |
1119 | temp64 &= ~((u64) val64); | 1616 | temp64 &= ~((u64) val64); |
1120 | writeq(temp64, &bar0->general_int_mask); | 1617 | writeq(temp64, &bar0->general_int_mask); |
1121 | /* | 1618 | /* |
1122 | * All MAC block error interrupts are disabled for now | 1619 | * All MAC block error interrupts are disabled for now |
1123 | * except the link status change interrupt. | ||
1124 | * TODO | 1620 | * TODO |
1125 | */ | 1621 | */ |
1126 | val64 = MAC_INT_STATUS_RMAC_INT; | ||
1127 | temp64 = readq(&bar0->mac_int_mask); | ||
1128 | temp64 &= ~((u64) val64); | ||
1129 | writeq(temp64, &bar0->mac_int_mask); | ||
1130 | |||
1131 | val64 = readq(&bar0->mac_rmac_err_mask); | ||
1132 | val64 &= ~((u64) RMAC_LINK_STATE_CHANGE_INT); | ||
1133 | writeq(val64, &bar0->mac_rmac_err_mask); | ||
1134 | } else if (flag == DISABLE_INTRS) { | 1622 | } else if (flag == DISABLE_INTRS) { |
1135 | /* | 1623 | /* |
1136 | * Disable MAC Intrs in the general intr mask register | 1624 | * Disable MAC Intrs in the general intr mask register |
1137 | */ | 1625 | */ |
1138 | writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask); | 1626 | writeq(DISABLE_ALL_INTRS, &bar0->mac_int_mask); |
1139 | writeq(DISABLE_ALL_INTRS, | 1627 | writeq(DISABLE_ALL_INTRS, |
@@ -1152,14 +1640,14 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1152 | temp64 = readq(&bar0->general_int_mask); | 1640 | temp64 = readq(&bar0->general_int_mask); |
1153 | temp64 &= ~((u64) val64); | 1641 | temp64 &= ~((u64) val64); |
1154 | writeq(temp64, &bar0->general_int_mask); | 1642 | writeq(temp64, &bar0->general_int_mask); |
1155 | /* | 1643 | /* |
1156 | * All XGXS block error interrupts are disabled for now | 1644 | * All XGXS block error interrupts are disabled for now |
1157 | * TODO | 1645 | * TODO |
1158 | */ | 1646 | */ |
1159 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); | 1647 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); |
1160 | } else if (flag == DISABLE_INTRS) { | 1648 | } else if (flag == DISABLE_INTRS) { |
1161 | /* | 1649 | /* |
1162 | * Disable MC Intrs in the general intr mask register | 1650 | * Disable MC Intrs in the general intr mask register |
1163 | */ | 1651 | */ |
1164 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); | 1652 | writeq(DISABLE_ALL_INTRS, &bar0->xgxs_int_mask); |
1165 | temp64 = readq(&bar0->general_int_mask); | 1653 | temp64 = readq(&bar0->general_int_mask); |
@@ -1175,11 +1663,11 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1175 | temp64 = readq(&bar0->general_int_mask); | 1663 | temp64 = readq(&bar0->general_int_mask); |
1176 | temp64 &= ~((u64) val64); | 1664 | temp64 &= ~((u64) val64); |
1177 | writeq(temp64, &bar0->general_int_mask); | 1665 | writeq(temp64, &bar0->general_int_mask); |
1178 | /* | 1666 | /* |
1179 | * All MC block error interrupts are disabled for now | 1667 | * Enable all MC Intrs. |
1180 | * TODO | ||
1181 | */ | 1668 | */ |
1182 | writeq(DISABLE_ALL_INTRS, &bar0->mc_int_mask); | 1669 | writeq(0x0, &bar0->mc_int_mask); |
1670 | writeq(0x0, &bar0->mc_err_mask); | ||
1183 | } else if (flag == DISABLE_INTRS) { | 1671 | } else if (flag == DISABLE_INTRS) { |
1184 | /* | 1672 | /* |
1185 | * Disable MC Intrs in the general intr mask register | 1673 | * Disable MC Intrs in the general intr mask register |
@@ -1199,14 +1687,14 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1199 | temp64 = readq(&bar0->general_int_mask); | 1687 | temp64 = readq(&bar0->general_int_mask); |
1200 | temp64 &= ~((u64) val64); | 1688 | temp64 &= ~((u64) val64); |
1201 | writeq(temp64, &bar0->general_int_mask); | 1689 | writeq(temp64, &bar0->general_int_mask); |
1202 | /* | 1690 | /* |
1203 | * Enable all the Tx side interrupts | 1691 | * Enable all the Tx side interrupts |
1204 | * writing 0 Enables all 64 TX interrupt levels | 1692 | * writing 0 Enables all 64 TX interrupt levels |
1205 | */ | 1693 | */ |
1206 | writeq(0x0, &bar0->tx_traffic_mask); | 1694 | writeq(0x0, &bar0->tx_traffic_mask); |
1207 | } else if (flag == DISABLE_INTRS) { | 1695 | } else if (flag == DISABLE_INTRS) { |
1208 | /* | 1696 | /* |
1209 | * Disable Tx Traffic Intrs in the general intr mask | 1697 | * Disable Tx Traffic Intrs in the general intr mask |
1210 | * register. | 1698 | * register. |
1211 | */ | 1699 | */ |
1212 | writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask); | 1700 | writeq(DISABLE_ALL_INTRS, &bar0->tx_traffic_mask); |
@@ -1226,8 +1714,8 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1226 | /* writing 0 Enables all 8 RX interrupt levels */ | 1714 | /* writing 0 Enables all 8 RX interrupt levels */ |
1227 | writeq(0x0, &bar0->rx_traffic_mask); | 1715 | writeq(0x0, &bar0->rx_traffic_mask); |
1228 | } else if (flag == DISABLE_INTRS) { | 1716 | } else if (flag == DISABLE_INTRS) { |
1229 | /* | 1717 | /* |
1230 | * Disable Rx Traffic Intrs in the general intr mask | 1718 | * Disable Rx Traffic Intrs in the general intr mask |
1231 | * register. | 1719 | * register. |
1232 | */ | 1720 | */ |
1233 | writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask); | 1721 | writeq(DISABLE_ALL_INTRS, &bar0->rx_traffic_mask); |
@@ -1238,24 +1726,66 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1238 | } | 1726 | } |
1239 | } | 1727 | } |
1240 | 1728 | ||
1241 | /** | 1729 | static int check_prc_pcc_state(u64 val64, int flag, int rev_id, int herc) |
1242 | * verify_xena_quiescence - Checks whether the H/W is ready | 1730 | { |
1731 | int ret = 0; | ||
1732 | |||
1733 | if (flag == FALSE) { | ||
1734 | if ((!herc && (rev_id >= 4)) || herc) { | ||
1735 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1736 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1737 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1738 | ret = 1; | ||
1739 | } | ||
1740 | }else { | ||
1741 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && | ||
1742 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1743 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1744 | ret = 1; | ||
1745 | } | ||
1746 | } | ||
1747 | } else { | ||
1748 | if ((!herc && (rev_id >= 4)) || herc) { | ||
1749 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == | ||
1750 | ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1751 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1752 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1753 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1754 | ret = 1; | ||
1755 | } | ||
1756 | } else { | ||
1757 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) == | ||
1758 | ADAPTER_STATUS_RMAC_PCC_FOUR_IDLE) && | ||
1759 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1760 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1761 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1762 | ret = 1; | ||
1763 | } | ||
1764 | } | ||
1765 | } | ||
1766 | |||
1767 | return ret; | ||
1768 | } | ||
1769 | /** | ||
1770 | * verify_xena_quiescence - Checks whether the H/W is ready | ||
1243 | * @val64 : Value read from adapter status register. | 1771 | * @val64 : Value read from adapter status register. |
1244 | * @flag : indicates if the adapter enable bit was ever written once | 1772 | * @flag : indicates if the adapter enable bit was ever written once |
1245 | * before. | 1773 | * before. |
1246 | * Description: Returns whether the H/W is ready to go or not. Depending | 1774 | * Description: Returns whether the H/W is ready to go or not. Depending |
1247 | * on whether adapter enable bit was written or not the comparison | 1775 | * on whether adapter enable bit was written or not the comparison |
1248 | * differs and the calling function passes the input argument flag to | 1776 | * differs and the calling function passes the input argument flag to |
1249 | * indicate this. | 1777 | * indicate this. |
1250 | * Return: 1 If xena is quiescence | 1778 | * Return: 1 If xena is quiescence |
1251 | * 0 If Xena is not quiescence | 1779 | * 0 If Xena is not quiescence |
1252 | */ | 1780 | */ |
1253 | 1781 | ||
1254 | static int verify_xena_quiescence(u64 val64, int flag) | 1782 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag) |
1255 | { | 1783 | { |
1256 | int ret = 0; | 1784 | int ret = 0, herc; |
1257 | u64 tmp64 = ~((u64) val64); | 1785 | u64 tmp64 = ~((u64) val64); |
1786 | int rev_id = get_xena_rev_id(sp->pdev); | ||
1258 | 1787 | ||
1788 | herc = (sp->device_type == XFRAME_II_DEVICE); | ||
1259 | if (! | 1789 | if (! |
1260 | (tmp64 & | 1790 | (tmp64 & |
1261 | (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | | 1791 | (ADAPTER_STATUS_TDMA_READY | ADAPTER_STATUS_RDMA_READY | |
@@ -1263,25 +1793,7 @@ static int verify_xena_quiescence(u64 val64, int flag) | |||
1263 | ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | | 1793 | ADAPTER_STATUS_PIC_QUIESCENT | ADAPTER_STATUS_MC_DRAM_READY | |
1264 | ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | | 1794 | ADAPTER_STATUS_MC_QUEUES_READY | ADAPTER_STATUS_M_PLL_LOCK | |
1265 | ADAPTER_STATUS_P_PLL_LOCK))) { | 1795 | ADAPTER_STATUS_P_PLL_LOCK))) { |
1266 | if (flag == FALSE) { | 1796 | ret = check_prc_pcc_state(val64, flag, rev_id, herc); |
1267 | if (!(val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1268 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1269 | ADAPTER_STATUS_RC_PRC_QUIESCENT)) { | ||
1270 | |||
1271 | ret = 1; | ||
1272 | |||
1273 | } | ||
1274 | } else { | ||
1275 | if (((val64 & ADAPTER_STATUS_RMAC_PCC_IDLE) == | ||
1276 | ADAPTER_STATUS_RMAC_PCC_IDLE) && | ||
1277 | (!(val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) || | ||
1278 | ((val64 & ADAPTER_STATUS_RC_PRC_QUIESCENT) == | ||
1279 | ADAPTER_STATUS_RC_PRC_QUIESCENT))) { | ||
1280 | |||
1281 | ret = 1; | ||
1282 | |||
1283 | } | ||
1284 | } | ||
1285 | } | 1797 | } |
1286 | 1798 | ||
1287 | return ret; | 1799 | return ret; |
@@ -1290,12 +1802,12 @@ static int verify_xena_quiescence(u64 val64, int flag) | |||
1290 | /** | 1802 | /** |
1291 | * fix_mac_address - Fix for Mac addr problem on Alpha platforms | 1803 | * fix_mac_address - Fix for Mac addr problem on Alpha platforms |
1292 | * @sp: Pointer to device specifc structure | 1804 | * @sp: Pointer to device specifc structure |
1293 | * Description : | 1805 | * Description : |
1294 | * New procedure to clear mac address reading problems on Alpha platforms | 1806 | * New procedure to clear mac address reading problems on Alpha platforms |
1295 | * | 1807 | * |
1296 | */ | 1808 | */ |
1297 | 1809 | ||
1298 | static void fix_mac_address(nic_t * sp) | 1810 | void fix_mac_address(nic_t * sp) |
1299 | { | 1811 | { |
1300 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 1812 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
1301 | u64 val64; | 1813 | u64 val64; |
@@ -1303,20 +1815,21 @@ static void fix_mac_address(nic_t * sp) | |||
1303 | 1815 | ||
1304 | while (fix_mac[i] != END_SIGN) { | 1816 | while (fix_mac[i] != END_SIGN) { |
1305 | writeq(fix_mac[i++], &bar0->gpio_control); | 1817 | writeq(fix_mac[i++], &bar0->gpio_control); |
1818 | udelay(10); | ||
1306 | val64 = readq(&bar0->gpio_control); | 1819 | val64 = readq(&bar0->gpio_control); |
1307 | } | 1820 | } |
1308 | } | 1821 | } |
1309 | 1822 | ||
1310 | /** | 1823 | /** |
1311 | * start_nic - Turns the device on | 1824 | * start_nic - Turns the device on |
1312 | * @nic : device private variable. | 1825 | * @nic : device private variable. |
1313 | * Description: | 1826 | * Description: |
1314 | * This function actually turns the device on. Before this function is | 1827 | * This function actually turns the device on. Before this function is |
1315 | * called,all Registers are configured from their reset states | 1828 | * called,all Registers are configured from their reset states |
1316 | * and shared memory is allocated but the NIC is still quiescent. On | 1829 | * and shared memory is allocated but the NIC is still quiescent. On |
1317 | * calling this function, the device interrupts are cleared and the NIC is | 1830 | * calling this function, the device interrupts are cleared and the NIC is |
1318 | * literally switched on by writing into the adapter control register. | 1831 | * literally switched on by writing into the adapter control register. |
1319 | * Return Value: | 1832 | * Return Value: |
1320 | * SUCCESS on success and -1 on failure. | 1833 | * SUCCESS on success and -1 on failure. |
1321 | */ | 1834 | */ |
1322 | 1835 | ||
@@ -1325,8 +1838,8 @@ static int start_nic(struct s2io_nic *nic) | |||
1325 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 1838 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
1326 | struct net_device *dev = nic->dev; | 1839 | struct net_device *dev = nic->dev; |
1327 | register u64 val64 = 0; | 1840 | register u64 val64 = 0; |
1328 | u16 interruptible, i; | 1841 | u16 interruptible; |
1329 | u16 subid; | 1842 | u16 subid, i; |
1330 | mac_info_t *mac_control; | 1843 | mac_info_t *mac_control; |
1331 | struct config_param *config; | 1844 | struct config_param *config; |
1332 | 1845 | ||
@@ -1335,10 +1848,12 @@ static int start_nic(struct s2io_nic *nic) | |||
1335 | 1848 | ||
1336 | /* PRC Initialization and configuration */ | 1849 | /* PRC Initialization and configuration */ |
1337 | for (i = 0; i < config->rx_ring_num; i++) { | 1850 | for (i = 0; i < config->rx_ring_num; i++) { |
1338 | writeq((u64) nic->rx_blocks[i][0].block_dma_addr, | 1851 | writeq((u64) mac_control->rings[i].rx_blocks[0].block_dma_addr, |
1339 | &bar0->prc_rxd0_n[i]); | 1852 | &bar0->prc_rxd0_n[i]); |
1340 | 1853 | ||
1341 | val64 = readq(&bar0->prc_ctrl_n[i]); | 1854 | val64 = readq(&bar0->prc_ctrl_n[i]); |
1855 | if (nic->config.bimodal) | ||
1856 | val64 |= PRC_CTRL_BIMODAL_INTERRUPT; | ||
1342 | #ifndef CONFIG_2BUFF_MODE | 1857 | #ifndef CONFIG_2BUFF_MODE |
1343 | val64 |= PRC_CTRL_RC_ENABLED; | 1858 | val64 |= PRC_CTRL_RC_ENABLED; |
1344 | #else | 1859 | #else |
@@ -1354,7 +1869,7 @@ static int start_nic(struct s2io_nic *nic) | |||
1354 | writeq(val64, &bar0->rx_pa_cfg); | 1869 | writeq(val64, &bar0->rx_pa_cfg); |
1355 | #endif | 1870 | #endif |
1356 | 1871 | ||
1357 | /* | 1872 | /* |
1358 | * Enabling MC-RLDRAM. After enabling the device, we timeout | 1873 | * Enabling MC-RLDRAM. After enabling the device, we timeout |
1359 | * for around 100ms, which is approximately the time required | 1874 | * for around 100ms, which is approximately the time required |
1360 | * for the device to be ready for operation. | 1875 | * for the device to be ready for operation. |
@@ -1364,27 +1879,27 @@ static int start_nic(struct s2io_nic *nic) | |||
1364 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF); | 1879 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_mrs, UF); |
1365 | val64 = readq(&bar0->mc_rldram_mrs); | 1880 | val64 = readq(&bar0->mc_rldram_mrs); |
1366 | 1881 | ||
1367 | msleep(100); /* Delay by around 100 ms. */ | 1882 | msleep(100); /* Delay by around 100 ms. */ |
1368 | 1883 | ||
1369 | /* Enabling ECC Protection. */ | 1884 | /* Enabling ECC Protection. */ |
1370 | val64 = readq(&bar0->adapter_control); | 1885 | val64 = readq(&bar0->adapter_control); |
1371 | val64 &= ~ADAPTER_ECC_EN; | 1886 | val64 &= ~ADAPTER_ECC_EN; |
1372 | writeq(val64, &bar0->adapter_control); | 1887 | writeq(val64, &bar0->adapter_control); |
1373 | 1888 | ||
1374 | /* | 1889 | /* |
1375 | * Clearing any possible Link state change interrupts that | 1890 | * Clearing any possible Link state change interrupts that |
1376 | * could have popped up just before Enabling the card. | 1891 | * could have popped up just before Enabling the card. |
1377 | */ | 1892 | */ |
1378 | val64 = readq(&bar0->mac_rmac_err_reg); | 1893 | val64 = readq(&bar0->mac_rmac_err_reg); |
1379 | if (val64) | 1894 | if (val64) |
1380 | writeq(val64, &bar0->mac_rmac_err_reg); | 1895 | writeq(val64, &bar0->mac_rmac_err_reg); |
1381 | 1896 | ||
1382 | /* | 1897 | /* |
1383 | * Verify if the device is ready to be enabled, if so enable | 1898 | * Verify if the device is ready to be enabled, if so enable |
1384 | * it. | 1899 | * it. |
1385 | */ | 1900 | */ |
1386 | val64 = readq(&bar0->adapter_status); | 1901 | val64 = readq(&bar0->adapter_status); |
1387 | if (!verify_xena_quiescence(val64, nic->device_enabled_once)) { | 1902 | if (!verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { |
1388 | DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); | 1903 | DBG_PRINT(ERR_DBG, "%s: device is not ready, ", dev->name); |
1389 | DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", | 1904 | DBG_PRINT(ERR_DBG, "Adapter status reads: 0x%llx\n", |
1390 | (unsigned long long) val64); | 1905 | (unsigned long long) val64); |
@@ -1392,16 +1907,18 @@ static int start_nic(struct s2io_nic *nic) | |||
1392 | } | 1907 | } |
1393 | 1908 | ||
1394 | /* Enable select interrupts */ | 1909 | /* Enable select interrupts */ |
1395 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 1910 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
1396 | RX_MAC_INTR; | 1911 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
1912 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1913 | |||
1397 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | 1914 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); |
1398 | 1915 | ||
1399 | /* | 1916 | /* |
1400 | * With some switches, link might be already up at this point. | 1917 | * With some switches, link might be already up at this point. |
1401 | * Because of this weird behavior, when we enable laser, | 1918 | * Because of this weird behavior, when we enable laser, |
1402 | * we may not get link. We need to handle this. We cannot | 1919 | * we may not get link. We need to handle this. We cannot |
1403 | * figure out which switch is misbehaving. So we are forced to | 1920 | * figure out which switch is misbehaving. So we are forced to |
1404 | * make a global change. | 1921 | * make a global change. |
1405 | */ | 1922 | */ |
1406 | 1923 | ||
1407 | /* Enabling Laser. */ | 1924 | /* Enabling Laser. */ |
@@ -1411,44 +1928,30 @@ static int start_nic(struct s2io_nic *nic) | |||
1411 | 1928 | ||
1412 | /* SXE-002: Initialize link and activity LED */ | 1929 | /* SXE-002: Initialize link and activity LED */ |
1413 | subid = nic->pdev->subsystem_device; | 1930 | subid = nic->pdev->subsystem_device; |
1414 | if ((subid & 0xFF) >= 0x07) { | 1931 | if (((subid & 0xFF) >= 0x07) && |
1932 | (nic->device_type == XFRAME_I_DEVICE)) { | ||
1415 | val64 = readq(&bar0->gpio_control); | 1933 | val64 = readq(&bar0->gpio_control); |
1416 | val64 |= 0x0000800000000000ULL; | 1934 | val64 |= 0x0000800000000000ULL; |
1417 | writeq(val64, &bar0->gpio_control); | 1935 | writeq(val64, &bar0->gpio_control); |
1418 | val64 = 0x0411040400000000ULL; | 1936 | val64 = 0x0411040400000000ULL; |
1419 | writeq(val64, (void __iomem *) bar0 + 0x2700); | 1937 | writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); |
1420 | } | 1938 | } |
1421 | 1939 | ||
1422 | /* | 1940 | /* |
1423 | * Don't see link state interrupts on certain switches, so | 1941 | * Don't see link state interrupts on certain switches, so |
1424 | * directly scheduling a link state task from here. | 1942 | * directly scheduling a link state task from here. |
1425 | */ | 1943 | */ |
1426 | schedule_work(&nic->set_link_task); | 1944 | schedule_work(&nic->set_link_task); |
1427 | 1945 | ||
1428 | /* | ||
1429 | * Here we are performing soft reset on XGXS to | ||
1430 | * force link down. Since link is already up, we will get | ||
1431 | * link state change interrupt after this reset | ||
1432 | */ | ||
1433 | SPECIAL_REG_WRITE(0x80010515001E0000ULL, &bar0->dtx_control, UF); | ||
1434 | val64 = readq(&bar0->dtx_control); | ||
1435 | udelay(50); | ||
1436 | SPECIAL_REG_WRITE(0x80010515001E00E0ULL, &bar0->dtx_control, UF); | ||
1437 | val64 = readq(&bar0->dtx_control); | ||
1438 | udelay(50); | ||
1439 | SPECIAL_REG_WRITE(0x80070515001F00E4ULL, &bar0->dtx_control, UF); | ||
1440 | val64 = readq(&bar0->dtx_control); | ||
1441 | udelay(50); | ||
1442 | |||
1443 | return SUCCESS; | 1946 | return SUCCESS; |
1444 | } | 1947 | } |
1445 | 1948 | ||
1446 | /** | 1949 | /** |
1447 | * free_tx_buffers - Free all queued Tx buffers | 1950 | * free_tx_buffers - Free all queued Tx buffers |
1448 | * @nic : device private variable. | 1951 | * @nic : device private variable. |
1449 | * Description: | 1952 | * Description: |
1450 | * Free all queued Tx buffers. | 1953 | * Free all queued Tx buffers. |
1451 | * Return Value: void | 1954 | * Return Value: void |
1452 | */ | 1955 | */ |
1453 | 1956 | ||
1454 | static void free_tx_buffers(struct s2io_nic *nic) | 1957 | static void free_tx_buffers(struct s2io_nic *nic) |
@@ -1459,39 +1962,61 @@ static void free_tx_buffers(struct s2io_nic *nic) | |||
1459 | int i, j; | 1962 | int i, j; |
1460 | mac_info_t *mac_control; | 1963 | mac_info_t *mac_control; |
1461 | struct config_param *config; | 1964 | struct config_param *config; |
1462 | int cnt = 0; | 1965 | int cnt = 0, frg_cnt; |
1463 | 1966 | ||
1464 | mac_control = &nic->mac_control; | 1967 | mac_control = &nic->mac_control; |
1465 | config = &nic->config; | 1968 | config = &nic->config; |
1466 | 1969 | ||
1467 | for (i = 0; i < config->tx_fifo_num; i++) { | 1970 | for (i = 0; i < config->tx_fifo_num; i++) { |
1468 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { | 1971 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { |
1469 | txdp = (TxD_t *) nic->list_info[i][j]. | 1972 | txdp = (TxD_t *) mac_control->fifos[i].list_info[j]. |
1470 | list_virt_addr; | 1973 | list_virt_addr; |
1471 | skb = | 1974 | skb = |
1472 | (struct sk_buff *) ((unsigned long) txdp-> | 1975 | (struct sk_buff *) ((unsigned long) txdp-> |
1473 | Host_Control); | 1976 | Host_Control); |
1474 | if (skb == NULL) { | 1977 | if (skb == NULL) { |
1475 | memset(txdp, 0, sizeof(TxD_t)); | 1978 | memset(txdp, 0, sizeof(TxD_t) * |
1979 | config->max_txds); | ||
1476 | continue; | 1980 | continue; |
1477 | } | 1981 | } |
1982 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
1983 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1984 | txdp->Buffer_Pointer, | ||
1985 | skb->len - skb->data_len, | ||
1986 | PCI_DMA_TODEVICE); | ||
1987 | if (frg_cnt) { | ||
1988 | TxD_t *temp; | ||
1989 | temp = txdp; | ||
1990 | txdp++; | ||
1991 | for (j = 0; j < frg_cnt; j++, txdp++) { | ||
1992 | skb_frag_t *frag = | ||
1993 | &skb_shinfo(skb)->frags[j]; | ||
1994 | pci_unmap_page(nic->pdev, | ||
1995 | (dma_addr_t) | ||
1996 | txdp-> | ||
1997 | Buffer_Pointer, | ||
1998 | frag->size, | ||
1999 | PCI_DMA_TODEVICE); | ||
2000 | } | ||
2001 | txdp = temp; | ||
2002 | } | ||
1478 | dev_kfree_skb(skb); | 2003 | dev_kfree_skb(skb); |
1479 | memset(txdp, 0, sizeof(TxD_t)); | 2004 | memset(txdp, 0, sizeof(TxD_t) * config->max_txds); |
1480 | cnt++; | 2005 | cnt++; |
1481 | } | 2006 | } |
1482 | DBG_PRINT(INTR_DBG, | 2007 | DBG_PRINT(INTR_DBG, |
1483 | "%s:forcibly freeing %d skbs on FIFO%d\n", | 2008 | "%s:forcibly freeing %d skbs on FIFO%d\n", |
1484 | dev->name, cnt, i); | 2009 | dev->name, cnt, i); |
1485 | mac_control->tx_curr_get_info[i].offset = 0; | 2010 | mac_control->fifos[i].tx_curr_get_info.offset = 0; |
1486 | mac_control->tx_curr_put_info[i].offset = 0; | 2011 | mac_control->fifos[i].tx_curr_put_info.offset = 0; |
1487 | } | 2012 | } |
1488 | } | 2013 | } |
1489 | 2014 | ||
1490 | /** | 2015 | /** |
1491 | * stop_nic - To stop the nic | 2016 | * stop_nic - To stop the nic |
1492 | * @nic ; device private variable. | 2017 | * @nic ; device private variable. |
1493 | * Description: | 2018 | * Description: |
1494 | * This function does exactly the opposite of what the start_nic() | 2019 | * This function does exactly the opposite of what the start_nic() |
1495 | * function does. This function is called to stop the device. | 2020 | * function does. This function is called to stop the device. |
1496 | * Return Value: | 2021 | * Return Value: |
1497 | * void. | 2022 | * void. |
@@ -1509,8 +2034,9 @@ static void stop_nic(struct s2io_nic *nic) | |||
1509 | config = &nic->config; | 2034 | config = &nic->config; |
1510 | 2035 | ||
1511 | /* Disable all interrupts */ | 2036 | /* Disable all interrupts */ |
1512 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR | TX_MAC_INTR | | 2037 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
1513 | RX_MAC_INTR; | 2038 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
2039 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1514 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); | 2040 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); |
1515 | 2041 | ||
1516 | /* Disable PRCs */ | 2042 | /* Disable PRCs */ |
@@ -1521,11 +2047,11 @@ static void stop_nic(struct s2io_nic *nic) | |||
1521 | } | 2047 | } |
1522 | } | 2048 | } |
1523 | 2049 | ||
1524 | /** | 2050 | /** |
1525 | * fill_rx_buffers - Allocates the Rx side skbs | 2051 | * fill_rx_buffers - Allocates the Rx side skbs |
1526 | * @nic: device private variable | 2052 | * @nic: device private variable |
1527 | * @ring_no: ring number | 2053 | * @ring_no: ring number |
1528 | * Description: | 2054 | * Description: |
1529 | * The function allocates Rx side skbs and puts the physical | 2055 | * The function allocates Rx side skbs and puts the physical |
1530 | * address of these buffers into the RxD buffer pointers, so that the NIC | 2056 | * address of these buffers into the RxD buffer pointers, so that the NIC |
1531 | * can DMA the received frame into these locations. | 2057 | * can DMA the received frame into these locations. |
@@ -1533,8 +2059,8 @@ static void stop_nic(struct s2io_nic *nic) | |||
1533 | * 1. single buffer, | 2059 | * 1. single buffer, |
1534 | * 2. three buffer and | 2060 | * 2. three buffer and |
1535 | * 3. Five buffer modes. | 2061 | * 3. Five buffer modes. |
1536 | * Each mode defines how many fragments the received frame will be split | 2062 | * Each mode defines how many fragments the received frame will be split |
1537 | * up into by the NIC. The frame is split into L3 header, L4 Header, | 2063 | * up into by the NIC. The frame is split into L3 header, L4 Header, |
1538 | * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself | 2064 | * L4 payload in three buffer mode and in 5 buffer mode, L4 payload itself |
1539 | * is split into 3 fragments. As of now only single buffer mode is | 2065 | * is split into 3 fragments. As of now only single buffer mode is |
1540 | * supported. | 2066 | * supported. |
@@ -1542,7 +2068,7 @@ static void stop_nic(struct s2io_nic *nic) | |||
1542 | * SUCCESS on success or an appropriate -ve value on failure. | 2068 | * SUCCESS on success or an appropriate -ve value on failure. |
1543 | */ | 2069 | */ |
1544 | 2070 | ||
1545 | static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | 2071 | int fill_rx_buffers(struct s2io_nic *nic, int ring_no) |
1546 | { | 2072 | { |
1547 | struct net_device *dev = nic->dev; | 2073 | struct net_device *dev = nic->dev; |
1548 | struct sk_buff *skb; | 2074 | struct sk_buff *skb; |
@@ -1550,34 +2076,35 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1550 | int off, off1, size, block_no, block_no1; | 2076 | int off, off1, size, block_no, block_no1; |
1551 | int offset, offset1; | 2077 | int offset, offset1; |
1552 | u32 alloc_tab = 0; | 2078 | u32 alloc_tab = 0; |
1553 | u32 alloc_cnt = nic->pkt_cnt[ring_no] - | 2079 | u32 alloc_cnt; |
1554 | atomic_read(&nic->rx_bufs_left[ring_no]); | ||
1555 | mac_info_t *mac_control; | 2080 | mac_info_t *mac_control; |
1556 | struct config_param *config; | 2081 | struct config_param *config; |
1557 | #ifdef CONFIG_2BUFF_MODE | 2082 | #ifdef CONFIG_2BUFF_MODE |
1558 | RxD_t *rxdpnext; | 2083 | RxD_t *rxdpnext; |
1559 | int nextblk; | 2084 | int nextblk; |
1560 | unsigned long tmp; | 2085 | u64 tmp; |
1561 | buffAdd_t *ba; | 2086 | buffAdd_t *ba; |
1562 | dma_addr_t rxdpphys; | 2087 | dma_addr_t rxdpphys; |
1563 | #endif | 2088 | #endif |
1564 | #ifndef CONFIG_S2IO_NAPI | 2089 | #ifndef CONFIG_S2IO_NAPI |
1565 | unsigned long flags; | 2090 | unsigned long flags; |
1566 | #endif | 2091 | #endif |
2092 | RxD_t *first_rxdp = NULL; | ||
1567 | 2093 | ||
1568 | mac_control = &nic->mac_control; | 2094 | mac_control = &nic->mac_control; |
1569 | config = &nic->config; | 2095 | config = &nic->config; |
1570 | 2096 | alloc_cnt = mac_control->rings[ring_no].pkt_cnt - | |
2097 | atomic_read(&nic->rx_bufs_left[ring_no]); | ||
1571 | size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + | 2098 | size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + |
1572 | HEADER_802_2_SIZE + HEADER_SNAP_SIZE; | 2099 | HEADER_802_2_SIZE + HEADER_SNAP_SIZE; |
1573 | 2100 | ||
1574 | while (alloc_tab < alloc_cnt) { | 2101 | while (alloc_tab < alloc_cnt) { |
1575 | block_no = mac_control->rx_curr_put_info[ring_no]. | 2102 | block_no = mac_control->rings[ring_no].rx_curr_put_info. |
1576 | block_index; | 2103 | block_index; |
1577 | block_no1 = mac_control->rx_curr_get_info[ring_no]. | 2104 | block_no1 = mac_control->rings[ring_no].rx_curr_get_info. |
1578 | block_index; | 2105 | block_index; |
1579 | off = mac_control->rx_curr_put_info[ring_no].offset; | 2106 | off = mac_control->rings[ring_no].rx_curr_put_info.offset; |
1580 | off1 = mac_control->rx_curr_get_info[ring_no].offset; | 2107 | off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; |
1581 | #ifndef CONFIG_2BUFF_MODE | 2108 | #ifndef CONFIG_2BUFF_MODE |
1582 | offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off; | 2109 | offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off; |
1583 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1; | 2110 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1; |
@@ -1586,7 +2113,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1586 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1; | 2113 | offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1; |
1587 | #endif | 2114 | #endif |
1588 | 2115 | ||
1589 | rxdp = nic->rx_blocks[ring_no][block_no]. | 2116 | rxdp = mac_control->rings[ring_no].rx_blocks[block_no]. |
1590 | block_virt_addr + off; | 2117 | block_virt_addr + off; |
1591 | if ((offset == offset1) && (rxdp->Host_Control)) { | 2118 | if ((offset == offset1) && (rxdp->Host_Control)) { |
1592 | DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name); | 2119 | DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name); |
@@ -1595,15 +2122,15 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1595 | } | 2122 | } |
1596 | #ifndef CONFIG_2BUFF_MODE | 2123 | #ifndef CONFIG_2BUFF_MODE |
1597 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2124 | if (rxdp->Control_1 == END_OF_BLOCK) { |
1598 | mac_control->rx_curr_put_info[ring_no]. | 2125 | mac_control->rings[ring_no].rx_curr_put_info. |
1599 | block_index++; | 2126 | block_index++; |
1600 | mac_control->rx_curr_put_info[ring_no]. | 2127 | mac_control->rings[ring_no].rx_curr_put_info. |
1601 | block_index %= nic->block_count[ring_no]; | 2128 | block_index %= mac_control->rings[ring_no].block_count; |
1602 | block_no = mac_control->rx_curr_put_info | 2129 | block_no = mac_control->rings[ring_no].rx_curr_put_info. |
1603 | [ring_no].block_index; | 2130 | block_index; |
1604 | off++; | 2131 | off++; |
1605 | off %= (MAX_RXDS_PER_BLOCK + 1); | 2132 | off %= (MAX_RXDS_PER_BLOCK + 1); |
1606 | mac_control->rx_curr_put_info[ring_no].offset = | 2133 | mac_control->rings[ring_no].rx_curr_put_info.offset = |
1607 | off; | 2134 | off; |
1608 | rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2); | 2135 | rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2); |
1609 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", | 2136 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", |
@@ -1611,30 +2138,30 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1611 | } | 2138 | } |
1612 | #ifndef CONFIG_S2IO_NAPI | 2139 | #ifndef CONFIG_S2IO_NAPI |
1613 | spin_lock_irqsave(&nic->put_lock, flags); | 2140 | spin_lock_irqsave(&nic->put_lock, flags); |
1614 | nic->put_pos[ring_no] = | 2141 | mac_control->rings[ring_no].put_pos = |
1615 | (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off; | 2142 | (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off; |
1616 | spin_unlock_irqrestore(&nic->put_lock, flags); | 2143 | spin_unlock_irqrestore(&nic->put_lock, flags); |
1617 | #endif | 2144 | #endif |
1618 | #else | 2145 | #else |
1619 | if (rxdp->Host_Control == END_OF_BLOCK) { | 2146 | if (rxdp->Host_Control == END_OF_BLOCK) { |
1620 | mac_control->rx_curr_put_info[ring_no]. | 2147 | mac_control->rings[ring_no].rx_curr_put_info. |
1621 | block_index++; | 2148 | block_index++; |
1622 | mac_control->rx_curr_put_info[ring_no]. | 2149 | mac_control->rings[ring_no].rx_curr_put_info.block_index |
1623 | block_index %= nic->block_count[ring_no]; | 2150 | %= mac_control->rings[ring_no].block_count; |
1624 | block_no = mac_control->rx_curr_put_info | 2151 | block_no = mac_control->rings[ring_no].rx_curr_put_info |
1625 | [ring_no].block_index; | 2152 | .block_index; |
1626 | off = 0; | 2153 | off = 0; |
1627 | DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n", | 2154 | DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n", |
1628 | dev->name, block_no, | 2155 | dev->name, block_no, |
1629 | (unsigned long long) rxdp->Control_1); | 2156 | (unsigned long long) rxdp->Control_1); |
1630 | mac_control->rx_curr_put_info[ring_no].offset = | 2157 | mac_control->rings[ring_no].rx_curr_put_info.offset = |
1631 | off; | 2158 | off; |
1632 | rxdp = nic->rx_blocks[ring_no][block_no]. | 2159 | rxdp = mac_control->rings[ring_no].rx_blocks[block_no]. |
1633 | block_virt_addr; | 2160 | block_virt_addr; |
1634 | } | 2161 | } |
1635 | #ifndef CONFIG_S2IO_NAPI | 2162 | #ifndef CONFIG_S2IO_NAPI |
1636 | spin_lock_irqsave(&nic->put_lock, flags); | 2163 | spin_lock_irqsave(&nic->put_lock, flags); |
1637 | nic->put_pos[ring_no] = (block_no * | 2164 | mac_control->rings[ring_no].put_pos = (block_no * |
1638 | (MAX_RXDS_PER_BLOCK + 1)) + off; | 2165 | (MAX_RXDS_PER_BLOCK + 1)) + off; |
1639 | spin_unlock_irqrestore(&nic->put_lock, flags); | 2166 | spin_unlock_irqrestore(&nic->put_lock, flags); |
1640 | #endif | 2167 | #endif |
@@ -1646,27 +2173,27 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1646 | if (rxdp->Control_2 & BIT(0)) | 2173 | if (rxdp->Control_2 & BIT(0)) |
1647 | #endif | 2174 | #endif |
1648 | { | 2175 | { |
1649 | mac_control->rx_curr_put_info[ring_no]. | 2176 | mac_control->rings[ring_no].rx_curr_put_info. |
1650 | offset = off; | 2177 | offset = off; |
1651 | goto end; | 2178 | goto end; |
1652 | } | 2179 | } |
1653 | #ifdef CONFIG_2BUFF_MODE | 2180 | #ifdef CONFIG_2BUFF_MODE |
1654 | /* | 2181 | /* |
1655 | * RxDs Spanning cache lines will be replenished only | 2182 | * RxDs Spanning cache lines will be replenished only |
1656 | * if the succeeding RxD is also owned by Host. It | 2183 | * if the succeeding RxD is also owned by Host. It |
1657 | * will always be the ((8*i)+3) and ((8*i)+6) | 2184 | * will always be the ((8*i)+3) and ((8*i)+6) |
1658 | * descriptors for the 48 byte descriptor. The offending | 2185 | * descriptors for the 48 byte descriptor. The offending |
1659 | * decsriptor is of-course the 3rd descriptor. | 2186 | * decsriptor is of-course the 3rd descriptor. |
1660 | */ | 2187 | */ |
1661 | rxdpphys = nic->rx_blocks[ring_no][block_no]. | 2188 | rxdpphys = mac_control->rings[ring_no].rx_blocks[block_no]. |
1662 | block_dma_addr + (off * sizeof(RxD_t)); | 2189 | block_dma_addr + (off * sizeof(RxD_t)); |
1663 | if (((u64) (rxdpphys)) % 128 > 80) { | 2190 | if (((u64) (rxdpphys)) % 128 > 80) { |
1664 | rxdpnext = nic->rx_blocks[ring_no][block_no]. | 2191 | rxdpnext = mac_control->rings[ring_no].rx_blocks[block_no]. |
1665 | block_virt_addr + (off + 1); | 2192 | block_virt_addr + (off + 1); |
1666 | if (rxdpnext->Host_Control == END_OF_BLOCK) { | 2193 | if (rxdpnext->Host_Control == END_OF_BLOCK) { |
1667 | nextblk = (block_no + 1) % | 2194 | nextblk = (block_no + 1) % |
1668 | (nic->block_count[ring_no]); | 2195 | (mac_control->rings[ring_no].block_count); |
1669 | rxdpnext = nic->rx_blocks[ring_no] | 2196 | rxdpnext = mac_control->rings[ring_no].rx_blocks |
1670 | [nextblk].block_virt_addr; | 2197 | [nextblk].block_virt_addr; |
1671 | } | 2198 | } |
1672 | if (rxdpnext->Control_2 & BIT(0)) | 2199 | if (rxdpnext->Control_2 & BIT(0)) |
@@ -1682,6 +2209,10 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1682 | if (!skb) { | 2209 | if (!skb) { |
1683 | DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); | 2210 | DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); |
1684 | DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); | 2211 | DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); |
2212 | if (first_rxdp) { | ||
2213 | wmb(); | ||
2214 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2215 | } | ||
1685 | return -ENOMEM; | 2216 | return -ENOMEM; |
1686 | } | 2217 | } |
1687 | #ifndef CONFIG_2BUFF_MODE | 2218 | #ifndef CONFIG_2BUFF_MODE |
@@ -1692,12 +2223,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1692 | rxdp->Control_2 &= (~MASK_BUFFER0_SIZE); | 2223 | rxdp->Control_2 &= (~MASK_BUFFER0_SIZE); |
1693 | rxdp->Control_2 |= SET_BUFFER0_SIZE(size); | 2224 | rxdp->Control_2 |= SET_BUFFER0_SIZE(size); |
1694 | rxdp->Host_Control = (unsigned long) (skb); | 2225 | rxdp->Host_Control = (unsigned long) (skb); |
1695 | rxdp->Control_1 |= RXD_OWN_XENA; | 2226 | if (alloc_tab & ((1 << rxsync_frequency) - 1)) |
2227 | rxdp->Control_1 |= RXD_OWN_XENA; | ||
1696 | off++; | 2228 | off++; |
1697 | off %= (MAX_RXDS_PER_BLOCK + 1); | 2229 | off %= (MAX_RXDS_PER_BLOCK + 1); |
1698 | mac_control->rx_curr_put_info[ring_no].offset = off; | 2230 | mac_control->rings[ring_no].rx_curr_put_info.offset = off; |
1699 | #else | 2231 | #else |
1700 | ba = &nic->ba[ring_no][block_no][off]; | 2232 | ba = &mac_control->rings[ring_no].ba[block_no][off]; |
1701 | skb_reserve(skb, BUF0_LEN); | 2233 | skb_reserve(skb, BUF0_LEN); |
1702 | tmp = ((unsigned long) skb->data & ALIGN_SIZE); | 2234 | tmp = ((unsigned long) skb->data & ALIGN_SIZE); |
1703 | if (tmp) | 2235 | if (tmp) |
@@ -1719,22 +2251,41 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
1719 | rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */ | 2251 | rxdp->Control_2 |= SET_BUFFER1_SIZE(1); /* dummy. */ |
1720 | rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */ | 2252 | rxdp->Control_2 |= BIT(0); /* Set Buffer_Empty bit. */ |
1721 | rxdp->Host_Control = (u64) ((unsigned long) (skb)); | 2253 | rxdp->Host_Control = (u64) ((unsigned long) (skb)); |
1722 | rxdp->Control_1 |= RXD_OWN_XENA; | 2254 | if (alloc_tab & ((1 << rxsync_frequency) - 1)) |
2255 | rxdp->Control_1 |= RXD_OWN_XENA; | ||
1723 | off++; | 2256 | off++; |
1724 | mac_control->rx_curr_put_info[ring_no].offset = off; | 2257 | mac_control->rings[ring_no].rx_curr_put_info.offset = off; |
1725 | #endif | 2258 | #endif |
2259 | rxdp->Control_2 |= SET_RXD_MARKER; | ||
2260 | |||
2261 | if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) { | ||
2262 | if (first_rxdp) { | ||
2263 | wmb(); | ||
2264 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2265 | } | ||
2266 | first_rxdp = rxdp; | ||
2267 | } | ||
1726 | atomic_inc(&nic->rx_bufs_left[ring_no]); | 2268 | atomic_inc(&nic->rx_bufs_left[ring_no]); |
1727 | alloc_tab++; | 2269 | alloc_tab++; |
1728 | } | 2270 | } |
1729 | 2271 | ||
1730 | end: | 2272 | end: |
2273 | /* Transfer ownership of first descriptor to adapter just before | ||
2274 | * exiting. Before that, use memory barrier so that ownership | ||
2275 | * and other fields are seen by adapter correctly. | ||
2276 | */ | ||
2277 | if (first_rxdp) { | ||
2278 | wmb(); | ||
2279 | first_rxdp->Control_1 |= RXD_OWN_XENA; | ||
2280 | } | ||
2281 | |||
1731 | return SUCCESS; | 2282 | return SUCCESS; |
1732 | } | 2283 | } |
1733 | 2284 | ||
1734 | /** | 2285 | /** |
1735 | * free_rx_buffers - Frees all Rx buffers | 2286 | * free_rx_buffers - Frees all Rx buffers |
1736 | * @sp: device private variable. | 2287 | * @sp: device private variable. |
1737 | * Description: | 2288 | * Description: |
1738 | * This function will free all Rx buffers allocated by host. | 2289 | * This function will free all Rx buffers allocated by host. |
1739 | * Return Value: | 2290 | * Return Value: |
1740 | * NONE. | 2291 | * NONE. |
@@ -1758,7 +2309,8 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1758 | for (i = 0; i < config->rx_ring_num; i++) { | 2309 | for (i = 0; i < config->rx_ring_num; i++) { |
1759 | for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) { | 2310 | for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) { |
1760 | off = j % (MAX_RXDS_PER_BLOCK + 1); | 2311 | off = j % (MAX_RXDS_PER_BLOCK + 1); |
1761 | rxdp = sp->rx_blocks[i][blk].block_virt_addr + off; | 2312 | rxdp = mac_control->rings[i].rx_blocks[blk]. |
2313 | block_virt_addr + off; | ||
1762 | 2314 | ||
1763 | #ifndef CONFIG_2BUFF_MODE | 2315 | #ifndef CONFIG_2BUFF_MODE |
1764 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2316 | if (rxdp->Control_1 == END_OF_BLOCK) { |
@@ -1793,7 +2345,7 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1793 | HEADER_SNAP_SIZE, | 2345 | HEADER_SNAP_SIZE, |
1794 | PCI_DMA_FROMDEVICE); | 2346 | PCI_DMA_FROMDEVICE); |
1795 | #else | 2347 | #else |
1796 | ba = &sp->ba[i][blk][off]; | 2348 | ba = &mac_control->rings[i].ba[blk][off]; |
1797 | pci_unmap_single(sp->pdev, (dma_addr_t) | 2349 | pci_unmap_single(sp->pdev, (dma_addr_t) |
1798 | rxdp->Buffer0_ptr, | 2350 | rxdp->Buffer0_ptr, |
1799 | BUF0_LEN, | 2351 | BUF0_LEN, |
@@ -1813,10 +2365,10 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1813 | } | 2365 | } |
1814 | memset(rxdp, 0, sizeof(RxD_t)); | 2366 | memset(rxdp, 0, sizeof(RxD_t)); |
1815 | } | 2367 | } |
1816 | mac_control->rx_curr_put_info[i].block_index = 0; | 2368 | mac_control->rings[i].rx_curr_put_info.block_index = 0; |
1817 | mac_control->rx_curr_get_info[i].block_index = 0; | 2369 | mac_control->rings[i].rx_curr_get_info.block_index = 0; |
1818 | mac_control->rx_curr_put_info[i].offset = 0; | 2370 | mac_control->rings[i].rx_curr_put_info.offset = 0; |
1819 | mac_control->rx_curr_get_info[i].offset = 0; | 2371 | mac_control->rings[i].rx_curr_get_info.offset = 0; |
1820 | atomic_set(&sp->rx_bufs_left[i], 0); | 2372 | atomic_set(&sp->rx_bufs_left[i], 0); |
1821 | DBG_PRINT(INIT_DBG, "%s:Freed 0x%x Rx Buffers on ring%d\n", | 2373 | DBG_PRINT(INIT_DBG, "%s:Freed 0x%x Rx Buffers on ring%d\n", |
1822 | dev->name, buf_cnt, i); | 2374 | dev->name, buf_cnt, i); |
@@ -1826,7 +2378,7 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1826 | /** | 2378 | /** |
1827 | * s2io_poll - Rx interrupt handler for NAPI support | 2379 | * s2io_poll - Rx interrupt handler for NAPI support |
1828 | * @dev : pointer to the device structure. | 2380 | * @dev : pointer to the device structure. |
1829 | * @budget : The number of packets that were budgeted to be processed | 2381 | * @budget : The number of packets that were budgeted to be processed |
1830 | * during one pass through the 'Poll" function. | 2382 | * during one pass through the 'Poll" function. |
1831 | * Description: | 2383 | * Description: |
1832 | * Comes into picture only if NAPI support has been incorporated. It does | 2384 | * Comes into picture only if NAPI support has been incorporated. It does |
@@ -1836,160 +2388,36 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
1836 | * 0 on success and 1 if there are No Rx packets to be processed. | 2388 | * 0 on success and 1 if there are No Rx packets to be processed. |
1837 | */ | 2389 | */ |
1838 | 2390 | ||
1839 | #ifdef CONFIG_S2IO_NAPI | 2391 | #if defined(CONFIG_S2IO_NAPI) |
1840 | static int s2io_poll(struct net_device *dev, int *budget) | 2392 | static int s2io_poll(struct net_device *dev, int *budget) |
1841 | { | 2393 | { |
1842 | nic_t *nic = dev->priv; | 2394 | nic_t *nic = dev->priv; |
1843 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2395 | int pkt_cnt = 0, org_pkts_to_process; |
1844 | int pkts_to_process = *budget, pkt_cnt = 0; | ||
1845 | register u64 val64 = 0; | ||
1846 | rx_curr_get_info_t get_info, put_info; | ||
1847 | int i, get_block, put_block, get_offset, put_offset, ring_bufs; | ||
1848 | #ifndef CONFIG_2BUFF_MODE | ||
1849 | u16 val16, cksum; | ||
1850 | #endif | ||
1851 | struct sk_buff *skb; | ||
1852 | RxD_t *rxdp; | ||
1853 | mac_info_t *mac_control; | 2396 | mac_info_t *mac_control; |
1854 | struct config_param *config; | 2397 | struct config_param *config; |
1855 | #ifdef CONFIG_2BUFF_MODE | 2398 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; |
1856 | buffAdd_t *ba; | 2399 | u64 val64; |
1857 | #endif | 2400 | int i; |
1858 | 2401 | ||
2402 | atomic_inc(&nic->isr_cnt); | ||
1859 | mac_control = &nic->mac_control; | 2403 | mac_control = &nic->mac_control; |
1860 | config = &nic->config; | 2404 | config = &nic->config; |
1861 | 2405 | ||
1862 | if (pkts_to_process > dev->quota) | 2406 | nic->pkts_to_process = *budget; |
1863 | pkts_to_process = dev->quota; | 2407 | if (nic->pkts_to_process > dev->quota) |
2408 | nic->pkts_to_process = dev->quota; | ||
2409 | org_pkts_to_process = nic->pkts_to_process; | ||
1864 | 2410 | ||
1865 | val64 = readq(&bar0->rx_traffic_int); | 2411 | val64 = readq(&bar0->rx_traffic_int); |
1866 | writeq(val64, &bar0->rx_traffic_int); | 2412 | writeq(val64, &bar0->rx_traffic_int); |
1867 | 2413 | ||
1868 | for (i = 0; i < config->rx_ring_num; i++) { | 2414 | for (i = 0; i < config->rx_ring_num; i++) { |
1869 | get_info = mac_control->rx_curr_get_info[i]; | 2415 | rx_intr_handler(&mac_control->rings[i]); |
1870 | get_block = get_info.block_index; | 2416 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; |
1871 | put_info = mac_control->rx_curr_put_info[i]; | 2417 | if (!nic->pkts_to_process) { |
1872 | put_block = put_info.block_index; | 2418 | /* Quota for the current iteration has been met */ |
1873 | ring_bufs = config->rx_cfg[i].num_rxd; | 2419 | goto no_rx; |
1874 | rxdp = nic->rx_blocks[i][get_block].block_virt_addr + | ||
1875 | get_info.offset; | ||
1876 | #ifndef CONFIG_2BUFF_MODE | ||
1877 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1878 | get_info.offset; | ||
1879 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1880 | put_info.offset; | ||
1881 | while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
1882 | (((get_offset + 1) % ring_bufs) != put_offset)) { | ||
1883 | if (--pkts_to_process < 0) { | ||
1884 | goto no_rx; | ||
1885 | } | ||
1886 | if (rxdp->Control_1 == END_OF_BLOCK) { | ||
1887 | rxdp = | ||
1888 | (RxD_t *) ((unsigned long) rxdp-> | ||
1889 | Control_2); | ||
1890 | get_info.offset++; | ||
1891 | get_info.offset %= | ||
1892 | (MAX_RXDS_PER_BLOCK + 1); | ||
1893 | get_block++; | ||
1894 | get_block %= nic->block_count[i]; | ||
1895 | mac_control->rx_curr_get_info[i]. | ||
1896 | offset = get_info.offset; | ||
1897 | mac_control->rx_curr_get_info[i]. | ||
1898 | block_index = get_block; | ||
1899 | continue; | ||
1900 | } | ||
1901 | get_offset = | ||
1902 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1903 | get_info.offset; | ||
1904 | skb = | ||
1905 | (struct sk_buff *) ((unsigned long) rxdp-> | ||
1906 | Host_Control); | ||
1907 | if (skb == NULL) { | ||
1908 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
1909 | dev->name); | ||
1910 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
1911 | goto no_rx; | ||
1912 | } | ||
1913 | val64 = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
1914 | val16 = (u16) (val64 >> 48); | ||
1915 | cksum = RXD_GET_L4_CKSUM(rxdp->Control_1); | ||
1916 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1917 | rxdp->Buffer0_ptr, | ||
1918 | dev->mtu + | ||
1919 | HEADER_ETHERNET_II_802_3_SIZE + | ||
1920 | HEADER_802_2_SIZE + | ||
1921 | HEADER_SNAP_SIZE, | ||
1922 | PCI_DMA_FROMDEVICE); | ||
1923 | rx_osm_handler(nic, val16, rxdp, i); | ||
1924 | pkt_cnt++; | ||
1925 | get_info.offset++; | ||
1926 | get_info.offset %= (MAX_RXDS_PER_BLOCK + 1); | ||
1927 | rxdp = | ||
1928 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
1929 | get_info.offset; | ||
1930 | mac_control->rx_curr_get_info[i].offset = | ||
1931 | get_info.offset; | ||
1932 | } | 2420 | } |
1933 | #else | ||
1934 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1935 | get_info.offset; | ||
1936 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1937 | put_info.offset; | ||
1938 | while (((!(rxdp->Control_1 & RXD_OWN_XENA)) && | ||
1939 | !(rxdp->Control_2 & BIT(0))) && | ||
1940 | (((get_offset + 1) % ring_bufs) != put_offset)) { | ||
1941 | if (--pkts_to_process < 0) { | ||
1942 | goto no_rx; | ||
1943 | } | ||
1944 | skb = (struct sk_buff *) ((unsigned long) | ||
1945 | rxdp->Host_Control); | ||
1946 | if (skb == NULL) { | ||
1947 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
1948 | dev->name); | ||
1949 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
1950 | goto no_rx; | ||
1951 | } | ||
1952 | |||
1953 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1954 | rxdp->Buffer0_ptr, | ||
1955 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
1956 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1957 | rxdp->Buffer1_ptr, | ||
1958 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
1959 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
1960 | rxdp->Buffer2_ptr, | ||
1961 | dev->mtu + BUF0_LEN + 4, | ||
1962 | PCI_DMA_FROMDEVICE); | ||
1963 | ba = &nic->ba[i][get_block][get_info.offset]; | ||
1964 | |||
1965 | rx_osm_handler(nic, rxdp, i, ba); | ||
1966 | |||
1967 | get_info.offset++; | ||
1968 | mac_control->rx_curr_get_info[i].offset = | ||
1969 | get_info.offset; | ||
1970 | rxdp = | ||
1971 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
1972 | get_info.offset; | ||
1973 | |||
1974 | if (get_info.offset && | ||
1975 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { | ||
1976 | get_info.offset = 0; | ||
1977 | mac_control->rx_curr_get_info[i]. | ||
1978 | offset = get_info.offset; | ||
1979 | get_block++; | ||
1980 | get_block %= nic->block_count[i]; | ||
1981 | mac_control->rx_curr_get_info[i]. | ||
1982 | block_index = get_block; | ||
1983 | rxdp = | ||
1984 | nic->rx_blocks[i][get_block]. | ||
1985 | block_virt_addr; | ||
1986 | } | ||
1987 | get_offset = | ||
1988 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
1989 | get_info.offset; | ||
1990 | pkt_cnt++; | ||
1991 | } | ||
1992 | #endif | ||
1993 | } | 2421 | } |
1994 | if (!pkt_cnt) | 2422 | if (!pkt_cnt) |
1995 | pkt_cnt = 1; | 2423 | pkt_cnt = 1; |
@@ -2007,9 +2435,10 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2007 | } | 2435 | } |
2008 | /* Re enable the Rx interrupts. */ | 2436 | /* Re enable the Rx interrupts. */ |
2009 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); | 2437 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); |
2438 | atomic_dec(&nic->isr_cnt); | ||
2010 | return 0; | 2439 | return 0; |
2011 | 2440 | ||
2012 | no_rx: | 2441 | no_rx: |
2013 | dev->quota -= pkt_cnt; | 2442 | dev->quota -= pkt_cnt; |
2014 | *budget -= pkt_cnt; | 2443 | *budget -= pkt_cnt; |
2015 | 2444 | ||
@@ -2020,279 +2449,204 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
2020 | break; | 2449 | break; |
2021 | } | 2450 | } |
2022 | } | 2451 | } |
2452 | atomic_dec(&nic->isr_cnt); | ||
2023 | return 1; | 2453 | return 1; |
2024 | } | 2454 | } |
2025 | #else | 2455 | #endif |
2026 | /** | 2456 | |
2457 | /** | ||
2027 | * rx_intr_handler - Rx interrupt handler | 2458 | * rx_intr_handler - Rx interrupt handler |
2028 | * @nic: device private variable. | 2459 | * @nic: device private variable. |
2029 | * Description: | 2460 | * Description: |
2030 | * If the interrupt is because of a received frame or if the | 2461 | * If the interrupt is because of a received frame or if the |
2031 | * receive ring contains fresh as yet un-processed frames,this function is | 2462 | * receive ring contains fresh as yet un-processed frames,this function is |
2032 | * called. It picks out the RxD at which place the last Rx processing had | 2463 | * called. It picks out the RxD at which place the last Rx processing had |
2033 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2464 | * stopped and sends the skb to the OSM's Rx handler and then increments |
2034 | * the offset. | 2465 | * the offset. |
2035 | * Return Value: | 2466 | * Return Value: |
2036 | * NONE. | 2467 | * NONE. |
2037 | */ | 2468 | */ |
2038 | 2469 | static void rx_intr_handler(ring_info_t *ring_data) | |
2039 | static void rx_intr_handler(struct s2io_nic *nic) | ||
2040 | { | 2470 | { |
2471 | nic_t *nic = ring_data->nic; | ||
2041 | struct net_device *dev = (struct net_device *) nic->dev; | 2472 | struct net_device *dev = (struct net_device *) nic->dev; |
2042 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | 2473 | int get_block, get_offset, put_block, put_offset, ring_bufs; |
2043 | rx_curr_get_info_t get_info, put_info; | 2474 | rx_curr_get_info_t get_info, put_info; |
2044 | RxD_t *rxdp; | 2475 | RxD_t *rxdp; |
2045 | struct sk_buff *skb; | 2476 | struct sk_buff *skb; |
2046 | #ifndef CONFIG_2BUFF_MODE | 2477 | #ifndef CONFIG_S2IO_NAPI |
2047 | u16 val16, cksum; | 2478 | int pkt_cnt = 0; |
2048 | #endif | ||
2049 | register u64 val64 = 0; | ||
2050 | int get_block, get_offset, put_block, put_offset, ring_bufs; | ||
2051 | int i, pkt_cnt = 0; | ||
2052 | mac_info_t *mac_control; | ||
2053 | struct config_param *config; | ||
2054 | #ifdef CONFIG_2BUFF_MODE | ||
2055 | buffAdd_t *ba; | ||
2056 | #endif | 2479 | #endif |
2480 | spin_lock(&nic->rx_lock); | ||
2481 | if (atomic_read(&nic->card_state) == CARD_DOWN) { | ||
2482 | DBG_PRINT(ERR_DBG, "%s: %s going down for reset\n", | ||
2483 | __FUNCTION__, dev->name); | ||
2484 | spin_unlock(&nic->rx_lock); | ||
2485 | } | ||
2057 | 2486 | ||
2058 | mac_control = &nic->mac_control; | 2487 | get_info = ring_data->rx_curr_get_info; |
2059 | config = &nic->config; | 2488 | get_block = get_info.block_index; |
2060 | 2489 | put_info = ring_data->rx_curr_put_info; | |
2061 | /* | 2490 | put_block = put_info.block_index; |
2062 | * rx_traffic_int reg is an R1 register, hence we read and write back | 2491 | ring_bufs = get_info.ring_len+1; |
2063 | * the samevalue in the register to clear it. | 2492 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr + |
2064 | */ | ||
2065 | val64 = readq(&bar0->rx_traffic_int); | ||
2066 | writeq(val64, &bar0->rx_traffic_int); | ||
2067 | |||
2068 | for (i = 0; i < config->rx_ring_num; i++) { | ||
2069 | get_info = mac_control->rx_curr_get_info[i]; | ||
2070 | get_block = get_info.block_index; | ||
2071 | put_info = mac_control->rx_curr_put_info[i]; | ||
2072 | put_block = put_info.block_index; | ||
2073 | ring_bufs = config->rx_cfg[i].num_rxd; | ||
2074 | rxdp = nic->rx_blocks[i][get_block].block_virt_addr + | ||
2075 | get_info.offset; | ||
2076 | #ifndef CONFIG_2BUFF_MODE | ||
2077 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2078 | get_info.offset; | 2493 | get_info.offset; |
2079 | spin_lock(&nic->put_lock); | 2494 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2080 | put_offset = nic->put_pos[i]; | 2495 | get_info.offset; |
2081 | spin_unlock(&nic->put_lock); | 2496 | #ifndef CONFIG_S2IO_NAPI |
2082 | while ((!(rxdp->Control_1 & RXD_OWN_XENA)) && | 2497 | spin_lock(&nic->put_lock); |
2083 | (((get_offset + 1) % ring_bufs) != put_offset)) { | 2498 | put_offset = ring_data->put_pos; |
2084 | if (rxdp->Control_1 == END_OF_BLOCK) { | 2499 | spin_unlock(&nic->put_lock); |
2085 | rxdp = (RxD_t *) ((unsigned long) | 2500 | #else |
2086 | rxdp->Control_2); | 2501 | put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2087 | get_info.offset++; | 2502 | put_info.offset; |
2088 | get_info.offset %= | 2503 | #endif |
2089 | (MAX_RXDS_PER_BLOCK + 1); | 2504 | while (RXD_IS_UP2DT(rxdp) && |
2090 | get_block++; | 2505 | (((get_offset + 1) % ring_bufs) != put_offset)) { |
2091 | get_block %= nic->block_count[i]; | 2506 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); |
2092 | mac_control->rx_curr_get_info[i]. | 2507 | if (skb == NULL) { |
2093 | offset = get_info.offset; | 2508 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2094 | mac_control->rx_curr_get_info[i]. | 2509 | dev->name); |
2095 | block_index = get_block; | 2510 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2096 | continue; | 2511 | spin_unlock(&nic->rx_lock); |
2097 | } | 2512 | return; |
2098 | get_offset = | ||
2099 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2100 | get_info.offset; | ||
2101 | skb = (struct sk_buff *) ((unsigned long) | ||
2102 | rxdp->Host_Control); | ||
2103 | if (skb == NULL) { | ||
2104 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | ||
2105 | dev->name); | ||
2106 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | ||
2107 | return; | ||
2108 | } | ||
2109 | val64 = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
2110 | val16 = (u16) (val64 >> 48); | ||
2111 | cksum = RXD_GET_L4_CKSUM(rxdp->Control_1); | ||
2112 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2113 | rxdp->Buffer0_ptr, | ||
2114 | dev->mtu + | ||
2115 | HEADER_ETHERNET_II_802_3_SIZE + | ||
2116 | HEADER_802_2_SIZE + | ||
2117 | HEADER_SNAP_SIZE, | ||
2118 | PCI_DMA_FROMDEVICE); | ||
2119 | rx_osm_handler(nic, val16, rxdp, i); | ||
2120 | get_info.offset++; | ||
2121 | get_info.offset %= (MAX_RXDS_PER_BLOCK + 1); | ||
2122 | rxdp = | ||
2123 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
2124 | get_info.offset; | ||
2125 | mac_control->rx_curr_get_info[i].offset = | ||
2126 | get_info.offset; | ||
2127 | pkt_cnt++; | ||
2128 | if ((indicate_max_pkts) | ||
2129 | && (pkt_cnt > indicate_max_pkts)) | ||
2130 | break; | ||
2131 | } | 2513 | } |
2514 | #ifndef CONFIG_2BUFF_MODE | ||
2515 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2516 | rxdp->Buffer0_ptr, | ||
2517 | dev->mtu + | ||
2518 | HEADER_ETHERNET_II_802_3_SIZE + | ||
2519 | HEADER_802_2_SIZE + | ||
2520 | HEADER_SNAP_SIZE, | ||
2521 | PCI_DMA_FROMDEVICE); | ||
2132 | #else | 2522 | #else |
2133 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | 2523 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2524 | rxdp->Buffer0_ptr, | ||
2525 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2526 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2527 | rxdp->Buffer1_ptr, | ||
2528 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2529 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2530 | rxdp->Buffer2_ptr, | ||
2531 | dev->mtu + BUF0_LEN + 4, | ||
2532 | PCI_DMA_FROMDEVICE); | ||
2533 | #endif | ||
2534 | rx_osm_handler(ring_data, rxdp); | ||
2535 | get_info.offset++; | ||
2536 | ring_data->rx_curr_get_info.offset = | ||
2134 | get_info.offset; | 2537 | get_info.offset; |
2135 | spin_lock(&nic->put_lock); | 2538 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr + |
2136 | put_offset = nic->put_pos[i]; | 2539 | get_info.offset; |
2137 | spin_unlock(&nic->put_lock); | 2540 | if (get_info.offset && |
2138 | while (((!(rxdp->Control_1 & RXD_OWN_XENA)) && | 2541 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { |
2139 | !(rxdp->Control_2 & BIT(0))) && | 2542 | get_info.offset = 0; |
2140 | (((get_offset + 1) % ring_bufs) != put_offset)) { | 2543 | ring_data->rx_curr_get_info.offset |
2141 | skb = (struct sk_buff *) ((unsigned long) | 2544 | = get_info.offset; |
2142 | rxdp->Host_Control); | 2545 | get_block++; |
2143 | if (skb == NULL) { | 2546 | get_block %= ring_data->block_count; |
2144 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 2547 | ring_data->rx_curr_get_info.block_index |
2145 | dev->name); | 2548 | = get_block; |
2146 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 2549 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
2147 | return; | 2550 | } |
2148 | } | ||
2149 | |||
2150 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2151 | rxdp->Buffer0_ptr, | ||
2152 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2153 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2154 | rxdp->Buffer1_ptr, | ||
2155 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2156 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2157 | rxdp->Buffer2_ptr, | ||
2158 | dev->mtu + BUF0_LEN + 4, | ||
2159 | PCI_DMA_FROMDEVICE); | ||
2160 | ba = &nic->ba[i][get_block][get_info.offset]; | ||
2161 | |||
2162 | rx_osm_handler(nic, rxdp, i, ba); | ||
2163 | |||
2164 | get_info.offset++; | ||
2165 | mac_control->rx_curr_get_info[i].offset = | ||
2166 | get_info.offset; | ||
2167 | rxdp = | ||
2168 | nic->rx_blocks[i][get_block].block_virt_addr + | ||
2169 | get_info.offset; | ||
2170 | 2551 | ||
2171 | if (get_info.offset && | 2552 | get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) + |
2172 | (!(get_info.offset % MAX_RXDS_PER_BLOCK))) { | ||
2173 | get_info.offset = 0; | ||
2174 | mac_control->rx_curr_get_info[i]. | ||
2175 | offset = get_info.offset; | ||
2176 | get_block++; | ||
2177 | get_block %= nic->block_count[i]; | ||
2178 | mac_control->rx_curr_get_info[i]. | ||
2179 | block_index = get_block; | ||
2180 | rxdp = | ||
2181 | nic->rx_blocks[i][get_block]. | ||
2182 | block_virt_addr; | ||
2183 | } | ||
2184 | get_offset = | ||
2185 | (get_block * (MAX_RXDS_PER_BLOCK + 1)) + | ||
2186 | get_info.offset; | 2553 | get_info.offset; |
2187 | pkt_cnt++; | 2554 | #ifdef CONFIG_S2IO_NAPI |
2188 | if ((indicate_max_pkts) | 2555 | nic->pkts_to_process -= 1; |
2189 | && (pkt_cnt > indicate_max_pkts)) | 2556 | if (!nic->pkts_to_process) |
2190 | break; | 2557 | break; |
2191 | } | 2558 | #else |
2192 | #endif | 2559 | pkt_cnt++; |
2193 | if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) | 2560 | if ((indicate_max_pkts) && (pkt_cnt > indicate_max_pkts)) |
2194 | break; | 2561 | break; |
2562 | #endif | ||
2195 | } | 2563 | } |
2564 | spin_unlock(&nic->rx_lock); | ||
2196 | } | 2565 | } |
2197 | #endif | 2566 | |
2198 | /** | 2567 | /** |
2199 | * tx_intr_handler - Transmit interrupt handler | 2568 | * tx_intr_handler - Transmit interrupt handler |
2200 | * @nic : device private variable | 2569 | * @nic : device private variable |
2201 | * Description: | 2570 | * Description: |
2202 | * If an interrupt was raised to indicate DMA complete of the | 2571 | * If an interrupt was raised to indicate DMA complete of the |
2203 | * Tx packet, this function is called. It identifies the last TxD | 2572 | * Tx packet, this function is called. It identifies the last TxD |
2204 | * whose buffer was freed and frees all skbs whose data have already | 2573 | * whose buffer was freed and frees all skbs whose data have already |
2205 | * DMA'ed into the NICs internal memory. | 2574 | * DMA'ed into the NICs internal memory. |
2206 | * Return Value: | 2575 | * Return Value: |
2207 | * NONE | 2576 | * NONE |
2208 | */ | 2577 | */ |
2209 | 2578 | ||
2210 | static void tx_intr_handler(struct s2io_nic *nic) | 2579 | static void tx_intr_handler(fifo_info_t *fifo_data) |
2211 | { | 2580 | { |
2212 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2581 | nic_t *nic = fifo_data->nic; |
2213 | struct net_device *dev = (struct net_device *) nic->dev; | 2582 | struct net_device *dev = (struct net_device *) nic->dev; |
2214 | tx_curr_get_info_t get_info, put_info; | 2583 | tx_curr_get_info_t get_info, put_info; |
2215 | struct sk_buff *skb; | 2584 | struct sk_buff *skb; |
2216 | TxD_t *txdlp; | 2585 | TxD_t *txdlp; |
2217 | register u64 val64 = 0; | ||
2218 | int i; | ||
2219 | u16 j, frg_cnt; | 2586 | u16 j, frg_cnt; |
2220 | mac_info_t *mac_control; | ||
2221 | struct config_param *config; | ||
2222 | 2587 | ||
2223 | mac_control = &nic->mac_control; | 2588 | get_info = fifo_data->tx_curr_get_info; |
2224 | config = &nic->config; | 2589 | put_info = fifo_data->tx_curr_put_info; |
2225 | 2590 | txdlp = (TxD_t *) fifo_data->list_info[get_info.offset]. | |
2226 | /* | 2591 | list_virt_addr; |
2227 | * tx_traffic_int reg is an R1 register, hence we read and write | 2592 | while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && |
2228 | * back the samevalue in the register to clear it. | 2593 | (get_info.offset != put_info.offset) && |
2229 | */ | 2594 | (txdlp->Host_Control)) { |
2230 | val64 = readq(&bar0->tx_traffic_int); | 2595 | /* Check for TxD errors */ |
2231 | writeq(val64, &bar0->tx_traffic_int); | 2596 | if (txdlp->Control_1 & TXD_T_CODE) { |
2597 | unsigned long long err; | ||
2598 | err = txdlp->Control_1 & TXD_T_CODE; | ||
2599 | DBG_PRINT(ERR_DBG, "***TxD error %llx\n", | ||
2600 | err); | ||
2601 | } | ||
2232 | 2602 | ||
2233 | for (i = 0; i < config->tx_fifo_num; i++) { | 2603 | skb = (struct sk_buff *) ((unsigned long) |
2234 | get_info = mac_control->tx_curr_get_info[i]; | 2604 | txdlp->Host_Control); |
2235 | put_info = mac_control->tx_curr_put_info[i]; | 2605 | if (skb == NULL) { |
2236 | txdlp = (TxD_t *) nic->list_info[i][get_info.offset]. | 2606 | DBG_PRINT(ERR_DBG, "%s: Null skb ", |
2237 | list_virt_addr; | 2607 | __FUNCTION__); |
2238 | while ((!(txdlp->Control_1 & TXD_LIST_OWN_XENA)) && | 2608 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); |
2239 | (get_info.offset != put_info.offset) && | 2609 | return; |
2240 | (txdlp->Host_Control)) { | 2610 | } |
2241 | /* Check for TxD errors */ | ||
2242 | if (txdlp->Control_1 & TXD_T_CODE) { | ||
2243 | unsigned long long err; | ||
2244 | err = txdlp->Control_1 & TXD_T_CODE; | ||
2245 | DBG_PRINT(ERR_DBG, "***TxD error %llx\n", | ||
2246 | err); | ||
2247 | } | ||
2248 | 2611 | ||
2249 | skb = (struct sk_buff *) ((unsigned long) | 2612 | frg_cnt = skb_shinfo(skb)->nr_frags; |
2250 | txdlp->Host_Control); | 2613 | nic->tx_pkt_count++; |
2251 | if (skb == NULL) { | 2614 | |
2252 | DBG_PRINT(ERR_DBG, "%s: Null skb ", | 2615 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2253 | dev->name); | 2616 | txdlp->Buffer_Pointer, |
2254 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); | 2617 | skb->len - skb->data_len, |
2255 | return; | 2618 | PCI_DMA_TODEVICE); |
2619 | if (frg_cnt) { | ||
2620 | TxD_t *temp; | ||
2621 | temp = txdlp; | ||
2622 | txdlp++; | ||
2623 | for (j = 0; j < frg_cnt; j++, txdlp++) { | ||
2624 | skb_frag_t *frag = | ||
2625 | &skb_shinfo(skb)->frags[j]; | ||
2626 | if (!txdlp->Buffer_Pointer) | ||
2627 | break; | ||
2628 | pci_unmap_page(nic->pdev, | ||
2629 | (dma_addr_t) | ||
2630 | txdlp-> | ||
2631 | Buffer_Pointer, | ||
2632 | frag->size, | ||
2633 | PCI_DMA_TODEVICE); | ||
2256 | } | 2634 | } |
2257 | nic->tx_pkt_count++; | 2635 | txdlp = temp; |
2258 | |||
2259 | frg_cnt = skb_shinfo(skb)->nr_frags; | ||
2260 | |||
2261 | /* For unfragmented skb */ | ||
2262 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2263 | txdlp->Buffer_Pointer, | ||
2264 | skb->len - skb->data_len, | ||
2265 | PCI_DMA_TODEVICE); | ||
2266 | if (frg_cnt) { | ||
2267 | TxD_t *temp = txdlp; | ||
2268 | txdlp++; | ||
2269 | for (j = 0; j < frg_cnt; j++, txdlp++) { | ||
2270 | skb_frag_t *frag = | ||
2271 | &skb_shinfo(skb)->frags[j]; | ||
2272 | pci_unmap_page(nic->pdev, | ||
2273 | (dma_addr_t) | ||
2274 | txdlp-> | ||
2275 | Buffer_Pointer, | ||
2276 | frag->size, | ||
2277 | PCI_DMA_TODEVICE); | ||
2278 | } | ||
2279 | txdlp = temp; | ||
2280 | } | ||
2281 | memset(txdlp, 0, | ||
2282 | (sizeof(TxD_t) * config->max_txds)); | ||
2283 | |||
2284 | /* Updating the statistics block */ | ||
2285 | nic->stats.tx_packets++; | ||
2286 | nic->stats.tx_bytes += skb->len; | ||
2287 | dev_kfree_skb_irq(skb); | ||
2288 | |||
2289 | get_info.offset++; | ||
2290 | get_info.offset %= get_info.fifo_len + 1; | ||
2291 | txdlp = (TxD_t *) nic->list_info[i] | ||
2292 | [get_info.offset].list_virt_addr; | ||
2293 | mac_control->tx_curr_get_info[i].offset = | ||
2294 | get_info.offset; | ||
2295 | } | 2636 | } |
2637 | memset(txdlp, 0, | ||
2638 | (sizeof(TxD_t) * fifo_data->max_txds)); | ||
2639 | |||
2640 | /* Updating the statistics block */ | ||
2641 | nic->stats.tx_bytes += skb->len; | ||
2642 | dev_kfree_skb_irq(skb); | ||
2643 | |||
2644 | get_info.offset++; | ||
2645 | get_info.offset %= get_info.fifo_len + 1; | ||
2646 | txdlp = (TxD_t *) fifo_data->list_info | ||
2647 | [get_info.offset].list_virt_addr; | ||
2648 | fifo_data->tx_curr_get_info.offset = | ||
2649 | get_info.offset; | ||
2296 | } | 2650 | } |
2297 | 2651 | ||
2298 | spin_lock(&nic->tx_lock); | 2652 | spin_lock(&nic->tx_lock); |
@@ -2301,13 +2655,13 @@ static void tx_intr_handler(struct s2io_nic *nic) | |||
2301 | spin_unlock(&nic->tx_lock); | 2655 | spin_unlock(&nic->tx_lock); |
2302 | } | 2656 | } |
2303 | 2657 | ||
2304 | /** | 2658 | /** |
2305 | * alarm_intr_handler - Alarm Interrrupt handler | 2659 | * alarm_intr_handler - Alarm Interrrupt handler |
2306 | * @nic: device private variable | 2660 | * @nic: device private variable |
2307 | * Description: If the interrupt was neither because of Rx packet or Tx | 2661 | * Description: If the interrupt was neither because of Rx packet or Tx |
2308 | * complete, this function is called. If the interrupt was to indicate | 2662 | * complete, this function is called. If the interrupt was to indicate |
2309 | * a loss of link, the OSM link status handler is invoked for any other | 2663 | * a loss of link, the OSM link status handler is invoked for any other |
2310 | * alarm interrupt the block that raised the interrupt is displayed | 2664 | * alarm interrupt the block that raised the interrupt is displayed |
2311 | * and a H/W reset is issued. | 2665 | * and a H/W reset is issued. |
2312 | * Return Value: | 2666 | * Return Value: |
2313 | * NONE | 2667 | * NONE |
@@ -2320,10 +2674,32 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2320 | register u64 val64 = 0, err_reg = 0; | 2674 | register u64 val64 = 0, err_reg = 0; |
2321 | 2675 | ||
2322 | /* Handling link status change error Intr */ | 2676 | /* Handling link status change error Intr */ |
2323 | err_reg = readq(&bar0->mac_rmac_err_reg); | 2677 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
2324 | writeq(err_reg, &bar0->mac_rmac_err_reg); | 2678 | err_reg = readq(&bar0->mac_rmac_err_reg); |
2325 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { | 2679 | writeq(err_reg, &bar0->mac_rmac_err_reg); |
2326 | schedule_work(&nic->set_link_task); | 2680 | if (err_reg & RMAC_LINK_STATE_CHANGE_INT) { |
2681 | schedule_work(&nic->set_link_task); | ||
2682 | } | ||
2683 | } | ||
2684 | |||
2685 | /* Handling Ecc errors */ | ||
2686 | val64 = readq(&bar0->mc_err_reg); | ||
2687 | writeq(val64, &bar0->mc_err_reg); | ||
2688 | if (val64 & (MC_ERR_REG_ECC_ALL_SNG | MC_ERR_REG_ECC_ALL_DBL)) { | ||
2689 | if (val64 & MC_ERR_REG_ECC_ALL_DBL) { | ||
2690 | nic->mac_control.stats_info->sw_stat. | ||
2691 | double_ecc_errs++; | ||
2692 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", | ||
2693 | dev->name); | ||
2694 | DBG_PRINT(ERR_DBG, "double ECC error!!\n"); | ||
2695 | if (nic->device_type != XFRAME_II_DEVICE) { | ||
2696 | netif_stop_queue(dev); | ||
2697 | schedule_work(&nic->rst_timer_task); | ||
2698 | } | ||
2699 | } else { | ||
2700 | nic->mac_control.stats_info->sw_stat. | ||
2701 | single_ecc_errs++; | ||
2702 | } | ||
2327 | } | 2703 | } |
2328 | 2704 | ||
2329 | /* In case of a serious error, the device will be Reset. */ | 2705 | /* In case of a serious error, the device will be Reset. */ |
@@ -2338,7 +2714,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2338 | /* | 2714 | /* |
2339 | * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC | 2715 | * Also as mentioned in the latest Errata sheets if the PCC_FB_ECC |
2340 | * Error occurs, the adapter will be recycled by disabling the | 2716 | * Error occurs, the adapter will be recycled by disabling the |
2341 | * adapter enable bit and enabling it again after the device | 2717 | * adapter enable bit and enabling it again after the device |
2342 | * becomes Quiescent. | 2718 | * becomes Quiescent. |
2343 | */ | 2719 | */ |
2344 | val64 = readq(&bar0->pcc_err_reg); | 2720 | val64 = readq(&bar0->pcc_err_reg); |
@@ -2354,18 +2730,18 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
2354 | /* Other type of interrupts are not being handled now, TODO */ | 2730 | /* Other type of interrupts are not being handled now, TODO */ |
2355 | } | 2731 | } |
2356 | 2732 | ||
2357 | /** | 2733 | /** |
2358 | * wait_for_cmd_complete - waits for a command to complete. | 2734 | * wait_for_cmd_complete - waits for a command to complete. |
2359 | * @sp : private member of the device structure, which is a pointer to the | 2735 | * @sp : private member of the device structure, which is a pointer to the |
2360 | * s2io_nic structure. | 2736 | * s2io_nic structure. |
2361 | * Description: Function that waits for a command to Write into RMAC | 2737 | * Description: Function that waits for a command to Write into RMAC |
2362 | * ADDR DATA registers to be completed and returns either success or | 2738 | * ADDR DATA registers to be completed and returns either success or |
2363 | * error depending on whether the command was complete or not. | 2739 | * error depending on whether the command was complete or not. |
2364 | * Return value: | 2740 | * Return value: |
2365 | * SUCCESS on success and FAILURE on failure. | 2741 | * SUCCESS on success and FAILURE on failure. |
2366 | */ | 2742 | */ |
2367 | 2743 | ||
2368 | static int wait_for_cmd_complete(nic_t * sp) | 2744 | int wait_for_cmd_complete(nic_t * sp) |
2369 | { | 2745 | { |
2370 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2746 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2371 | int ret = FAILURE, cnt = 0; | 2747 | int ret = FAILURE, cnt = 0; |
@@ -2385,29 +2761,32 @@ static int wait_for_cmd_complete(nic_t * sp) | |||
2385 | return ret; | 2761 | return ret; |
2386 | } | 2762 | } |
2387 | 2763 | ||
2388 | /** | 2764 | /** |
2389 | * s2io_reset - Resets the card. | 2765 | * s2io_reset - Resets the card. |
2390 | * @sp : private member of the device structure. | 2766 | * @sp : private member of the device structure. |
2391 | * Description: Function to Reset the card. This function then also | 2767 | * Description: Function to Reset the card. This function then also |
2392 | * restores the previously saved PCI configuration space registers as | 2768 | * restores the previously saved PCI configuration space registers as |
2393 | * the card reset also resets the configuration space. | 2769 | * the card reset also resets the configuration space. |
2394 | * Return value: | 2770 | * Return value: |
2395 | * void. | 2771 | * void. |
2396 | */ | 2772 | */ |
2397 | 2773 | ||
2398 | static void s2io_reset(nic_t * sp) | 2774 | void s2io_reset(nic_t * sp) |
2399 | { | 2775 | { |
2400 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2776 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2401 | u64 val64; | 2777 | u64 val64; |
2402 | u16 subid; | 2778 | u16 subid, pci_cmd; |
2779 | |||
2780 | /* Back up the PCI-X CMD reg, dont want to lose MMRBC, OST settings */ | ||
2781 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, &(pci_cmd)); | ||
2403 | 2782 | ||
2404 | val64 = SW_RESET_ALL; | 2783 | val64 = SW_RESET_ALL; |
2405 | writeq(val64, &bar0->sw_reset); | 2784 | writeq(val64, &bar0->sw_reset); |
2406 | 2785 | ||
2407 | /* | 2786 | /* |
2408 | * At this stage, if the PCI write is indeed completed, the | 2787 | * At this stage, if the PCI write is indeed completed, the |
2409 | * card is reset and so is the PCI Config space of the device. | 2788 | * card is reset and so is the PCI Config space of the device. |
2410 | * So a read cannot be issued at this stage on any of the | 2789 | * So a read cannot be issued at this stage on any of the |
2411 | * registers to ensure the write into "sw_reset" register | 2790 | * registers to ensure the write into "sw_reset" register |
2412 | * has gone through. | 2791 | * has gone through. |
2413 | * Question: Is there any system call that will explicitly force | 2792 | * Question: Is there any system call that will explicitly force |
@@ -2418,42 +2797,72 @@ static void s2io_reset(nic_t * sp) | |||
2418 | */ | 2797 | */ |
2419 | msleep(250); | 2798 | msleep(250); |
2420 | 2799 | ||
2421 | /* Restore the PCI state saved during initializarion. */ | 2800 | /* Restore the PCI state saved during initialization. */ |
2422 | pci_restore_state(sp->pdev); | 2801 | pci_restore_state(sp->pdev); |
2802 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
2803 | pci_cmd); | ||
2423 | s2io_init_pci(sp); | 2804 | s2io_init_pci(sp); |
2424 | 2805 | ||
2425 | msleep(250); | 2806 | msleep(250); |
2426 | 2807 | ||
2808 | /* Set swapper to enable I/O register access */ | ||
2809 | s2io_set_swapper(sp); | ||
2810 | |||
2811 | /* Clear certain PCI/PCI-X fields after reset */ | ||
2812 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
2813 | /* Clear parity err detect bit */ | ||
2814 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); | ||
2815 | |||
2816 | /* Clearing PCIX Ecc status register */ | ||
2817 | pci_write_config_dword(sp->pdev, 0x68, 0x7C); | ||
2818 | |||
2819 | /* Clearing PCI_STATUS error reflected here */ | ||
2820 | writeq(BIT(62), &bar0->txpic_int_reg); | ||
2821 | } | ||
2822 | |||
2823 | /* Reset device statistics maintained by OS */ | ||
2824 | memset(&sp->stats, 0, sizeof (struct net_device_stats)); | ||
2825 | |||
2427 | /* SXE-002: Configure link and activity LED to turn it off */ | 2826 | /* SXE-002: Configure link and activity LED to turn it off */ |
2428 | subid = sp->pdev->subsystem_device; | 2827 | subid = sp->pdev->subsystem_device; |
2429 | if ((subid & 0xFF) >= 0x07) { | 2828 | if (((subid & 0xFF) >= 0x07) && |
2829 | (sp->device_type == XFRAME_I_DEVICE)) { | ||
2430 | val64 = readq(&bar0->gpio_control); | 2830 | val64 = readq(&bar0->gpio_control); |
2431 | val64 |= 0x0000800000000000ULL; | 2831 | val64 |= 0x0000800000000000ULL; |
2432 | writeq(val64, &bar0->gpio_control); | 2832 | writeq(val64, &bar0->gpio_control); |
2433 | val64 = 0x0411040400000000ULL; | 2833 | val64 = 0x0411040400000000ULL; |
2434 | writeq(val64, (void __iomem *) bar0 + 0x2700); | 2834 | writeq(val64, (void __iomem *) ((u8 *) bar0 + 0x2700)); |
2835 | } | ||
2836 | |||
2837 | /* | ||
2838 | * Clear spurious ECC interrupts that would have occured on | ||
2839 | * XFRAME II cards after reset. | ||
2840 | */ | ||
2841 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
2842 | val64 = readq(&bar0->pcc_err_reg); | ||
2843 | writeq(val64, &bar0->pcc_err_reg); | ||
2435 | } | 2844 | } |
2436 | 2845 | ||
2437 | sp->device_enabled_once = FALSE; | 2846 | sp->device_enabled_once = FALSE; |
2438 | } | 2847 | } |
2439 | 2848 | ||
2440 | /** | 2849 | /** |
2441 | * s2io_set_swapper - to set the swapper controle on the card | 2850 | * s2io_set_swapper - to set the swapper controle on the card |
2442 | * @sp : private member of the device structure, | 2851 | * @sp : private member of the device structure, |
2443 | * pointer to the s2io_nic structure. | 2852 | * pointer to the s2io_nic structure. |
2444 | * Description: Function to set the swapper control on the card | 2853 | * Description: Function to set the swapper control on the card |
2445 | * correctly depending on the 'endianness' of the system. | 2854 | * correctly depending on the 'endianness' of the system. |
2446 | * Return value: | 2855 | * Return value: |
2447 | * SUCCESS on success and FAILURE on failure. | 2856 | * SUCCESS on success and FAILURE on failure. |
2448 | */ | 2857 | */ |
2449 | 2858 | ||
2450 | static int s2io_set_swapper(nic_t * sp) | 2859 | int s2io_set_swapper(nic_t * sp) |
2451 | { | 2860 | { |
2452 | struct net_device *dev = sp->dev; | 2861 | struct net_device *dev = sp->dev; |
2453 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 2862 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2454 | u64 val64, valt, valr; | 2863 | u64 val64, valt, valr; |
2455 | 2864 | ||
2456 | /* | 2865 | /* |
2457 | * Set proper endian settings and verify the same by reading | 2866 | * Set proper endian settings and verify the same by reading |
2458 | * the PIF Feed-back register. | 2867 | * the PIF Feed-back register. |
2459 | */ | 2868 | */ |
@@ -2505,8 +2914,9 @@ static int s2io_set_swapper(nic_t * sp) | |||
2505 | i++; | 2914 | i++; |
2506 | } | 2915 | } |
2507 | if(i == 4) { | 2916 | if(i == 4) { |
2917 | unsigned long long x = val64; | ||
2508 | DBG_PRINT(ERR_DBG, "Write failed, Xmsi_addr "); | 2918 | DBG_PRINT(ERR_DBG, "Write failed, Xmsi_addr "); |
2509 | DBG_PRINT(ERR_DBG, "reads:0x%llx\n",val64); | 2919 | DBG_PRINT(ERR_DBG, "reads:0x%llx\n", x); |
2510 | return FAILURE; | 2920 | return FAILURE; |
2511 | } | 2921 | } |
2512 | } | 2922 | } |
@@ -2514,8 +2924,8 @@ static int s2io_set_swapper(nic_t * sp) | |||
2514 | val64 &= 0xFFFF000000000000ULL; | 2924 | val64 &= 0xFFFF000000000000ULL; |
2515 | 2925 | ||
2516 | #ifdef __BIG_ENDIAN | 2926 | #ifdef __BIG_ENDIAN |
2517 | /* | 2927 | /* |
2518 | * The device by default set to a big endian format, so a | 2928 | * The device by default set to a big endian format, so a |
2519 | * big endian driver need not set anything. | 2929 | * big endian driver need not set anything. |
2520 | */ | 2930 | */ |
2521 | val64 |= (SWAPPER_CTRL_TXP_FE | | 2931 | val64 |= (SWAPPER_CTRL_TXP_FE | |
@@ -2531,9 +2941,9 @@ static int s2io_set_swapper(nic_t * sp) | |||
2531 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); | 2941 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); |
2532 | writeq(val64, &bar0->swapper_ctrl); | 2942 | writeq(val64, &bar0->swapper_ctrl); |
2533 | #else | 2943 | #else |
2534 | /* | 2944 | /* |
2535 | * Initially we enable all bits to make it accessible by the | 2945 | * Initially we enable all bits to make it accessible by the |
2536 | * driver, then we selectively enable only those bits that | 2946 | * driver, then we selectively enable only those bits that |
2537 | * we want to set. | 2947 | * we want to set. |
2538 | */ | 2948 | */ |
2539 | val64 |= (SWAPPER_CTRL_TXP_FE | | 2949 | val64 |= (SWAPPER_CTRL_TXP_FE | |
@@ -2555,8 +2965,8 @@ static int s2io_set_swapper(nic_t * sp) | |||
2555 | #endif | 2965 | #endif |
2556 | val64 = readq(&bar0->swapper_ctrl); | 2966 | val64 = readq(&bar0->swapper_ctrl); |
2557 | 2967 | ||
2558 | /* | 2968 | /* |
2559 | * Verifying if endian settings are accurate by reading a | 2969 | * Verifying if endian settings are accurate by reading a |
2560 | * feedback register. | 2970 | * feedback register. |
2561 | */ | 2971 | */ |
2562 | val64 = readq(&bar0->pif_rd_swapper_fb); | 2972 | val64 = readq(&bar0->pif_rd_swapper_fb); |
@@ -2576,55 +2986,63 @@ static int s2io_set_swapper(nic_t * sp) | |||
2576 | * Functions defined below concern the OS part of the driver * | 2986 | * Functions defined below concern the OS part of the driver * |
2577 | * ********************************************************* */ | 2987 | * ********************************************************* */ |
2578 | 2988 | ||
2579 | /** | 2989 | /** |
2580 | * s2io_open - open entry point of the driver | 2990 | * s2io_open - open entry point of the driver |
2581 | * @dev : pointer to the device structure. | 2991 | * @dev : pointer to the device structure. |
2582 | * Description: | 2992 | * Description: |
2583 | * This function is the open entry point of the driver. It mainly calls a | 2993 | * This function is the open entry point of the driver. It mainly calls a |
2584 | * function to allocate Rx buffers and inserts them into the buffer | 2994 | * function to allocate Rx buffers and inserts them into the buffer |
2585 | * descriptors and then enables the Rx part of the NIC. | 2995 | * descriptors and then enables the Rx part of the NIC. |
2586 | * Return value: | 2996 | * Return value: |
2587 | * 0 on success and an appropriate (-)ve integer as defined in errno.h | 2997 | * 0 on success and an appropriate (-)ve integer as defined in errno.h |
2588 | * file on failure. | 2998 | * file on failure. |
2589 | */ | 2999 | */ |
2590 | 3000 | ||
2591 | static int s2io_open(struct net_device *dev) | 3001 | int s2io_open(struct net_device *dev) |
2592 | { | 3002 | { |
2593 | nic_t *sp = dev->priv; | 3003 | nic_t *sp = dev->priv; |
2594 | int err = 0; | 3004 | int err = 0; |
2595 | 3005 | ||
2596 | /* | 3006 | /* |
2597 | * Make sure you have link off by default every time | 3007 | * Make sure you have link off by default every time |
2598 | * Nic is initialized | 3008 | * Nic is initialized |
2599 | */ | 3009 | */ |
2600 | netif_carrier_off(dev); | 3010 | netif_carrier_off(dev); |
2601 | sp->last_link_state = LINK_DOWN; | 3011 | sp->last_link_state = 0; |
2602 | 3012 | ||
2603 | /* Initialize H/W and enable interrupts */ | 3013 | /* Initialize H/W and enable interrupts */ |
2604 | if (s2io_card_up(sp)) { | 3014 | if (s2io_card_up(sp)) { |
2605 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 3015 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
2606 | dev->name); | 3016 | dev->name); |
2607 | return -ENODEV; | 3017 | err = -ENODEV; |
3018 | goto hw_init_failed; | ||
2608 | } | 3019 | } |
2609 | 3020 | ||
2610 | /* After proper initialization of H/W, register ISR */ | 3021 | /* After proper initialization of H/W, register ISR */ |
2611 | err = request_irq((int) sp->irq, s2io_isr, SA_SHIRQ, | 3022 | err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, |
2612 | sp->name, dev); | 3023 | sp->name, dev); |
2613 | if (err) { | 3024 | if (err) { |
2614 | s2io_reset(sp); | ||
2615 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | 3025 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", |
2616 | dev->name); | 3026 | dev->name); |
2617 | return err; | 3027 | goto isr_registration_failed; |
2618 | } | 3028 | } |
2619 | 3029 | ||
2620 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { | 3030 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { |
2621 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); | 3031 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); |
2622 | s2io_reset(sp); | 3032 | err = -ENODEV; |
2623 | return -ENODEV; | 3033 | goto setting_mac_address_failed; |
2624 | } | 3034 | } |
2625 | 3035 | ||
2626 | netif_start_queue(dev); | 3036 | netif_start_queue(dev); |
2627 | return 0; | 3037 | return 0; |
3038 | |||
3039 | setting_mac_address_failed: | ||
3040 | free_irq(sp->pdev->irq, dev); | ||
3041 | isr_registration_failed: | ||
3042 | del_timer_sync(&sp->alarm_timer); | ||
3043 | s2io_reset(sp); | ||
3044 | hw_init_failed: | ||
3045 | return err; | ||
2628 | } | 3046 | } |
2629 | 3047 | ||
2630 | /** | 3048 | /** |
@@ -2640,16 +3058,15 @@ static int s2io_open(struct net_device *dev) | |||
2640 | * file on failure. | 3058 | * file on failure. |
2641 | */ | 3059 | */ |
2642 | 3060 | ||
2643 | static int s2io_close(struct net_device *dev) | 3061 | int s2io_close(struct net_device *dev) |
2644 | { | 3062 | { |
2645 | nic_t *sp = dev->priv; | 3063 | nic_t *sp = dev->priv; |
2646 | |||
2647 | flush_scheduled_work(); | 3064 | flush_scheduled_work(); |
2648 | netif_stop_queue(dev); | 3065 | netif_stop_queue(dev); |
2649 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3066 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
2650 | s2io_card_down(sp); | 3067 | s2io_card_down(sp); |
2651 | 3068 | ||
2652 | free_irq(dev->irq, dev); | 3069 | free_irq(sp->pdev->irq, dev); |
2653 | sp->device_close_flag = TRUE; /* Device is shut down. */ | 3070 | sp->device_close_flag = TRUE; /* Device is shut down. */ |
2654 | return 0; | 3071 | return 0; |
2655 | } | 3072 | } |
@@ -2667,7 +3084,7 @@ static int s2io_close(struct net_device *dev) | |||
2667 | * 0 on success & 1 on failure. | 3084 | * 0 on success & 1 on failure. |
2668 | */ | 3085 | */ |
2669 | 3086 | ||
2670 | static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | 3087 | int s2io_xmit(struct sk_buff *skb, struct net_device *dev) |
2671 | { | 3088 | { |
2672 | nic_t *sp = dev->priv; | 3089 | nic_t *sp = dev->priv; |
2673 | u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; | 3090 | u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off; |
@@ -2678,29 +3095,39 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2678 | #ifdef NETIF_F_TSO | 3095 | #ifdef NETIF_F_TSO |
2679 | int mss; | 3096 | int mss; |
2680 | #endif | 3097 | #endif |
3098 | u16 vlan_tag = 0; | ||
3099 | int vlan_priority = 0; | ||
2681 | mac_info_t *mac_control; | 3100 | mac_info_t *mac_control; |
2682 | struct config_param *config; | 3101 | struct config_param *config; |
2683 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
2684 | 3102 | ||
2685 | mac_control = &sp->mac_control; | 3103 | mac_control = &sp->mac_control; |
2686 | config = &sp->config; | 3104 | config = &sp->config; |
2687 | 3105 | ||
2688 | DBG_PRINT(TX_DBG, "%s: In S2IO Tx routine\n", dev->name); | 3106 | DBG_PRINT(TX_DBG, "%s: In Neterion Tx routine\n", dev->name); |
2689 | spin_lock_irqsave(&sp->tx_lock, flags); | 3107 | spin_lock_irqsave(&sp->tx_lock, flags); |
2690 | |||
2691 | if (atomic_read(&sp->card_state) == CARD_DOWN) { | 3108 | if (atomic_read(&sp->card_state) == CARD_DOWN) { |
2692 | DBG_PRINT(ERR_DBG, "%s: Card going down for reset\n", | 3109 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", |
2693 | dev->name); | 3110 | dev->name); |
2694 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 3111 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
2695 | return 1; | 3112 | dev_kfree_skb(skb); |
3113 | return 0; | ||
2696 | } | 3114 | } |
2697 | 3115 | ||
2698 | queue = 0; | 3116 | queue = 0; |
2699 | put_off = (u16) mac_control->tx_curr_put_info[queue].offset; | ||
2700 | get_off = (u16) mac_control->tx_curr_get_info[queue].offset; | ||
2701 | txdp = (TxD_t *) sp->list_info[queue][put_off].list_virt_addr; | ||
2702 | 3117 | ||
2703 | queue_len = mac_control->tx_curr_put_info[queue].fifo_len + 1; | 3118 | /* Get Fifo number to Transmit based on vlan priority */ |
3119 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | ||
3120 | vlan_tag = vlan_tx_tag_get(skb); | ||
3121 | vlan_priority = vlan_tag >> 13; | ||
3122 | queue = config->fifo_mapping[vlan_priority]; | ||
3123 | } | ||
3124 | |||
3125 | put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; | ||
3126 | get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; | ||
3127 | txdp = (TxD_t *) mac_control->fifos[queue].list_info[put_off]. | ||
3128 | list_virt_addr; | ||
3129 | |||
3130 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | ||
2704 | /* Avoid "put" pointer going beyond "get" pointer */ | 3131 | /* Avoid "put" pointer going beyond "get" pointer */ |
2705 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { | 3132 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { |
2706 | DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); | 3133 | DBG_PRINT(ERR_DBG, "Error in xmit, No free TXDs.\n"); |
@@ -2709,6 +3136,15 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2709 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 3136 | spin_unlock_irqrestore(&sp->tx_lock, flags); |
2710 | return 0; | 3137 | return 0; |
2711 | } | 3138 | } |
3139 | |||
3140 | /* A buffer with no data will be dropped */ | ||
3141 | if (!skb->len) { | ||
3142 | DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); | ||
3143 | dev_kfree_skb(skb); | ||
3144 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
3145 | return 0; | ||
3146 | } | ||
3147 | |||
2712 | #ifdef NETIF_F_TSO | 3148 | #ifdef NETIF_F_TSO |
2713 | mss = skb_shinfo(skb)->tso_size; | 3149 | mss = skb_shinfo(skb)->tso_size; |
2714 | if (mss) { | 3150 | if (mss) { |
@@ -2720,9 +3156,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2720 | frg_cnt = skb_shinfo(skb)->nr_frags; | 3156 | frg_cnt = skb_shinfo(skb)->nr_frags; |
2721 | frg_len = skb->len - skb->data_len; | 3157 | frg_len = skb->len - skb->data_len; |
2722 | 3158 | ||
2723 | txdp->Host_Control = (unsigned long) skb; | ||
2724 | txdp->Buffer_Pointer = pci_map_single | 3159 | txdp->Buffer_Pointer = pci_map_single |
2725 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 3160 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
3161 | txdp->Host_Control = (unsigned long) skb; | ||
2726 | if (skb->ip_summed == CHECKSUM_HW) { | 3162 | if (skb->ip_summed == CHECKSUM_HW) { |
2727 | txdp->Control_2 |= | 3163 | txdp->Control_2 |= |
2728 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | | 3164 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | |
@@ -2731,6 +3167,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2731 | 3167 | ||
2732 | txdp->Control_2 |= config->tx_intr_type; | 3168 | txdp->Control_2 |= config->tx_intr_type; |
2733 | 3169 | ||
3170 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | ||
3171 | txdp->Control_2 |= TXD_VLAN_ENABLE; | ||
3172 | txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag); | ||
3173 | } | ||
3174 | |||
2734 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | | 3175 | txdp->Control_1 |= (TXD_BUFFER0_SIZE(frg_len) | |
2735 | TXD_GATHER_CODE_FIRST); | 3176 | TXD_GATHER_CODE_FIRST); |
2736 | txdp->Control_1 |= TXD_LIST_OWN_XENA; | 3177 | txdp->Control_1 |= TXD_LIST_OWN_XENA; |
@@ -2738,6 +3179,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2738 | /* For fragmented SKB. */ | 3179 | /* For fragmented SKB. */ |
2739 | for (i = 0; i < frg_cnt; i++) { | 3180 | for (i = 0; i < frg_cnt; i++) { |
2740 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 3181 | skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
3182 | /* A '0' length fragment will be ignored */ | ||
3183 | if (!frag->size) | ||
3184 | continue; | ||
2741 | txdp++; | 3185 | txdp++; |
2742 | txdp->Buffer_Pointer = (u64) pci_map_page | 3186 | txdp->Buffer_Pointer = (u64) pci_map_page |
2743 | (sp->pdev, frag->page, frag->page_offset, | 3187 | (sp->pdev, frag->page, frag->page_offset, |
@@ -2747,23 +3191,23 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2747 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; | 3191 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; |
2748 | 3192 | ||
2749 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 3193 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
2750 | val64 = sp->list_info[queue][put_off].list_phy_addr; | 3194 | val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr; |
2751 | writeq(val64, &tx_fifo->TxDL_Pointer); | 3195 | writeq(val64, &tx_fifo->TxDL_Pointer); |
2752 | 3196 | ||
2753 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 3197 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
2754 | TX_FIFO_LAST_LIST); | 3198 | TX_FIFO_LAST_LIST); |
3199 | |||
2755 | #ifdef NETIF_F_TSO | 3200 | #ifdef NETIF_F_TSO |
2756 | if (mss) | 3201 | if (mss) |
2757 | val64 |= TX_FIFO_SPECIAL_FUNC; | 3202 | val64 |= TX_FIFO_SPECIAL_FUNC; |
2758 | #endif | 3203 | #endif |
2759 | writeq(val64, &tx_fifo->List_Control); | 3204 | writeq(val64, &tx_fifo->List_Control); |
2760 | 3205 | ||
2761 | /* Perform a PCI read to flush previous writes */ | 3206 | mmiowb(); |
2762 | val64 = readq(&bar0->general_int_status); | ||
2763 | 3207 | ||
2764 | put_off++; | 3208 | put_off++; |
2765 | put_off %= mac_control->tx_curr_put_info[queue].fifo_len + 1; | 3209 | put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; |
2766 | mac_control->tx_curr_put_info[queue].offset = put_off; | 3210 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; |
2767 | 3211 | ||
2768 | /* Avoid "put" pointer going beyond "get" pointer */ | 3212 | /* Avoid "put" pointer going beyond "get" pointer */ |
2769 | if (((put_off + 1) % queue_len) == get_off) { | 3213 | if (((put_off + 1) % queue_len) == get_off) { |
@@ -2779,18 +3223,74 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
2779 | return 0; | 3223 | return 0; |
2780 | } | 3224 | } |
2781 | 3225 | ||
3226 | static void | ||
3227 | s2io_alarm_handle(unsigned long data) | ||
3228 | { | ||
3229 | nic_t *sp = (nic_t *)data; | ||
3230 | |||
3231 | alarm_intr_handler(sp); | ||
3232 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | ||
3233 | } | ||
3234 | |||
3235 | static void s2io_txpic_intr_handle(nic_t *sp) | ||
3236 | { | ||
3237 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) sp->bar0; | ||
3238 | u64 val64; | ||
3239 | |||
3240 | val64 = readq(&bar0->pic_int_status); | ||
3241 | if (val64 & PIC_INT_GPIO) { | ||
3242 | val64 = readq(&bar0->gpio_int_reg); | ||
3243 | if ((val64 & GPIO_INT_REG_LINK_DOWN) && | ||
3244 | (val64 & GPIO_INT_REG_LINK_UP)) { | ||
3245 | val64 |= GPIO_INT_REG_LINK_DOWN; | ||
3246 | val64 |= GPIO_INT_REG_LINK_UP; | ||
3247 | writeq(val64, &bar0->gpio_int_reg); | ||
3248 | goto masking; | ||
3249 | } | ||
3250 | |||
3251 | if (((sp->last_link_state == LINK_UP) && | ||
3252 | (val64 & GPIO_INT_REG_LINK_DOWN)) || | ||
3253 | ((sp->last_link_state == LINK_DOWN) && | ||
3254 | (val64 & GPIO_INT_REG_LINK_UP))) { | ||
3255 | val64 = readq(&bar0->gpio_int_mask); | ||
3256 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3257 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3258 | writeq(val64, &bar0->gpio_int_mask); | ||
3259 | s2io_set_link((unsigned long)sp); | ||
3260 | } | ||
3261 | masking: | ||
3262 | if (sp->last_link_state == LINK_UP) { | ||
3263 | /*enable down interrupt */ | ||
3264 | val64 = readq(&bar0->gpio_int_mask); | ||
3265 | /* unmasks link down intr */ | ||
3266 | val64 &= ~GPIO_INT_MASK_LINK_DOWN; | ||
3267 | /* masks link up intr */ | ||
3268 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
3269 | writeq(val64, &bar0->gpio_int_mask); | ||
3270 | } else { | ||
3271 | /*enable UP Interrupt */ | ||
3272 | val64 = readq(&bar0->gpio_int_mask); | ||
3273 | /* unmasks link up interrupt */ | ||
3274 | val64 &= ~GPIO_INT_MASK_LINK_UP; | ||
3275 | /* masks link down interrupt */ | ||
3276 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
3277 | writeq(val64, &bar0->gpio_int_mask); | ||
3278 | } | ||
3279 | } | ||
3280 | } | ||
3281 | |||
2782 | /** | 3282 | /** |
2783 | * s2io_isr - ISR handler of the device . | 3283 | * s2io_isr - ISR handler of the device . |
2784 | * @irq: the irq of the device. | 3284 | * @irq: the irq of the device. |
2785 | * @dev_id: a void pointer to the dev structure of the NIC. | 3285 | * @dev_id: a void pointer to the dev structure of the NIC. |
2786 | * @pt_regs: pointer to the registers pushed on the stack. | 3286 | * @pt_regs: pointer to the registers pushed on the stack. |
2787 | * Description: This function is the ISR handler of the device. It | 3287 | * Description: This function is the ISR handler of the device. It |
2788 | * identifies the reason for the interrupt and calls the relevant | 3288 | * identifies the reason for the interrupt and calls the relevant |
2789 | * service routines. As a contongency measure, this ISR allocates the | 3289 | * service routines. As a contongency measure, this ISR allocates the |
2790 | * recv buffers, if their numbers are below the panic value which is | 3290 | * recv buffers, if their numbers are below the panic value which is |
2791 | * presently set to 25% of the original number of rcv buffers allocated. | 3291 | * presently set to 25% of the original number of rcv buffers allocated. |
2792 | * Return value: | 3292 | * Return value: |
2793 | * IRQ_HANDLED: will be returned if IRQ was handled by this routine | 3293 | * IRQ_HANDLED: will be returned if IRQ was handled by this routine |
2794 | * IRQ_NONE: will be returned if interrupt is not from our device | 3294 | * IRQ_NONE: will be returned if interrupt is not from our device |
2795 | */ | 3295 | */ |
2796 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | 3296 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) |
@@ -2798,40 +3298,31 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2798 | struct net_device *dev = (struct net_device *) dev_id; | 3298 | struct net_device *dev = (struct net_device *) dev_id; |
2799 | nic_t *sp = dev->priv; | 3299 | nic_t *sp = dev->priv; |
2800 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 3300 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2801 | #ifndef CONFIG_S2IO_NAPI | 3301 | int i; |
2802 | int i, ret; | 3302 | u64 reason = 0, val64; |
2803 | #endif | ||
2804 | u64 reason = 0; | ||
2805 | mac_info_t *mac_control; | 3303 | mac_info_t *mac_control; |
2806 | struct config_param *config; | 3304 | struct config_param *config; |
2807 | 3305 | ||
3306 | atomic_inc(&sp->isr_cnt); | ||
2808 | mac_control = &sp->mac_control; | 3307 | mac_control = &sp->mac_control; |
2809 | config = &sp->config; | 3308 | config = &sp->config; |
2810 | 3309 | ||
2811 | /* | 3310 | /* |
2812 | * Identify the cause for interrupt and call the appropriate | 3311 | * Identify the cause for interrupt and call the appropriate |
2813 | * interrupt handler. Causes for the interrupt could be; | 3312 | * interrupt handler. Causes for the interrupt could be; |
2814 | * 1. Rx of packet. | 3313 | * 1. Rx of packet. |
2815 | * 2. Tx complete. | 3314 | * 2. Tx complete. |
2816 | * 3. Link down. | 3315 | * 3. Link down. |
2817 | * 4. Error in any functional blocks of the NIC. | 3316 | * 4. Error in any functional blocks of the NIC. |
2818 | */ | 3317 | */ |
2819 | reason = readq(&bar0->general_int_status); | 3318 | reason = readq(&bar0->general_int_status); |
2820 | 3319 | ||
2821 | if (!reason) { | 3320 | if (!reason) { |
2822 | /* The interrupt was not raised by Xena. */ | 3321 | /* The interrupt was not raised by Xena. */ |
3322 | atomic_dec(&sp->isr_cnt); | ||
2823 | return IRQ_NONE; | 3323 | return IRQ_NONE; |
2824 | } | 3324 | } |
2825 | 3325 | ||
2826 | /* If Intr is because of Tx Traffic */ | ||
2827 | if (reason & GEN_INTR_TXTRAFFIC) { | ||
2828 | tx_intr_handler(sp); | ||
2829 | } | ||
2830 | |||
2831 | /* If Intr is because of an error */ | ||
2832 | if (reason & (GEN_ERROR_INTR)) | ||
2833 | alarm_intr_handler(sp); | ||
2834 | |||
2835 | #ifdef CONFIG_S2IO_NAPI | 3326 | #ifdef CONFIG_S2IO_NAPI |
2836 | if (reason & GEN_INTR_RXTRAFFIC) { | 3327 | if (reason & GEN_INTR_RXTRAFFIC) { |
2837 | if (netif_rx_schedule_prep(dev)) { | 3328 | if (netif_rx_schedule_prep(dev)) { |
@@ -2843,17 +3334,43 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2843 | #else | 3334 | #else |
2844 | /* If Intr is because of Rx Traffic */ | 3335 | /* If Intr is because of Rx Traffic */ |
2845 | if (reason & GEN_INTR_RXTRAFFIC) { | 3336 | if (reason & GEN_INTR_RXTRAFFIC) { |
2846 | rx_intr_handler(sp); | 3337 | /* |
3338 | * rx_traffic_int reg is an R1 register, writing all 1's | ||
3339 | * will ensure that the actual interrupt causing bit get's | ||
3340 | * cleared and hence a read can be avoided. | ||
3341 | */ | ||
3342 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
3343 | writeq(val64, &bar0->rx_traffic_int); | ||
3344 | for (i = 0; i < config->rx_ring_num; i++) { | ||
3345 | rx_intr_handler(&mac_control->rings[i]); | ||
3346 | } | ||
2847 | } | 3347 | } |
2848 | #endif | 3348 | #endif |
2849 | 3349 | ||
2850 | /* | 3350 | /* If Intr is because of Tx Traffic */ |
2851 | * If the Rx buffer count is below the panic threshold then | 3351 | if (reason & GEN_INTR_TXTRAFFIC) { |
2852 | * reallocate the buffers from the interrupt handler itself, | 3352 | /* |
3353 | * tx_traffic_int reg is an R1 register, writing all 1's | ||
3354 | * will ensure that the actual interrupt causing bit get's | ||
3355 | * cleared and hence a read can be avoided. | ||
3356 | */ | ||
3357 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
3358 | writeq(val64, &bar0->tx_traffic_int); | ||
3359 | |||
3360 | for (i = 0; i < config->tx_fifo_num; i++) | ||
3361 | tx_intr_handler(&mac_control->fifos[i]); | ||
3362 | } | ||
3363 | |||
3364 | if (reason & GEN_INTR_TXPIC) | ||
3365 | s2io_txpic_intr_handle(sp); | ||
3366 | /* | ||
3367 | * If the Rx buffer count is below the panic threshold then | ||
3368 | * reallocate the buffers from the interrupt handler itself, | ||
2853 | * else schedule a tasklet to reallocate the buffers. | 3369 | * else schedule a tasklet to reallocate the buffers. |
2854 | */ | 3370 | */ |
2855 | #ifndef CONFIG_S2IO_NAPI | 3371 | #ifndef CONFIG_S2IO_NAPI |
2856 | for (i = 0; i < config->rx_ring_num; i++) { | 3372 | for (i = 0; i < config->rx_ring_num; i++) { |
3373 | int ret; | ||
2857 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | 3374 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); |
2858 | int level = rx_buffer_level(sp, rxb_size, i); | 3375 | int level = rx_buffer_level(sp, rxb_size, i); |
2859 | 3376 | ||
@@ -2865,6 +3382,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2865 | dev->name); | 3382 | dev->name); |
2866 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | 3383 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); |
2867 | clear_bit(0, (&sp->tasklet_status)); | 3384 | clear_bit(0, (&sp->tasklet_status)); |
3385 | atomic_dec(&sp->isr_cnt); | ||
2868 | return IRQ_HANDLED; | 3386 | return IRQ_HANDLED; |
2869 | } | 3387 | } |
2870 | clear_bit(0, (&sp->tasklet_status)); | 3388 | clear_bit(0, (&sp->tasklet_status)); |
@@ -2874,33 +3392,69 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
2874 | } | 3392 | } |
2875 | #endif | 3393 | #endif |
2876 | 3394 | ||
3395 | atomic_dec(&sp->isr_cnt); | ||
2877 | return IRQ_HANDLED; | 3396 | return IRQ_HANDLED; |
2878 | } | 3397 | } |
2879 | 3398 | ||
2880 | /** | 3399 | /** |
2881 | * s2io_get_stats - Updates the device statistics structure. | 3400 | * s2io_updt_stats - |
3401 | */ | ||
3402 | static void s2io_updt_stats(nic_t *sp) | ||
3403 | { | ||
3404 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
3405 | u64 val64; | ||
3406 | int cnt = 0; | ||
3407 | |||
3408 | if (atomic_read(&sp->card_state) == CARD_UP) { | ||
3409 | /* Apprx 30us on a 133 MHz bus */ | ||
3410 | val64 = SET_UPDT_CLICKS(10) | | ||
3411 | STAT_CFG_ONE_SHOT_EN | STAT_CFG_STAT_EN; | ||
3412 | writeq(val64, &bar0->stat_cfg); | ||
3413 | do { | ||
3414 | udelay(100); | ||
3415 | val64 = readq(&bar0->stat_cfg); | ||
3416 | if (!(val64 & BIT(0))) | ||
3417 | break; | ||
3418 | cnt++; | ||
3419 | if (cnt == 5) | ||
3420 | break; /* Updt failed */ | ||
3421 | } while(1); | ||
3422 | } | ||
3423 | } | ||
3424 | |||
3425 | /** | ||
3426 | * s2io_get_stats - Updates the device statistics structure. | ||
2882 | * @dev : pointer to the device structure. | 3427 | * @dev : pointer to the device structure. |
2883 | * Description: | 3428 | * Description: |
2884 | * This function updates the device statistics structure in the s2io_nic | 3429 | * This function updates the device statistics structure in the s2io_nic |
2885 | * structure and returns a pointer to the same. | 3430 | * structure and returns a pointer to the same. |
2886 | * Return value: | 3431 | * Return value: |
2887 | * pointer to the updated net_device_stats structure. | 3432 | * pointer to the updated net_device_stats structure. |
2888 | */ | 3433 | */ |
2889 | 3434 | ||
2890 | static struct net_device_stats *s2io_get_stats(struct net_device *dev) | 3435 | struct net_device_stats *s2io_get_stats(struct net_device *dev) |
2891 | { | 3436 | { |
2892 | nic_t *sp = dev->priv; | 3437 | nic_t *sp = dev->priv; |
2893 | mac_info_t *mac_control; | 3438 | mac_info_t *mac_control; |
2894 | struct config_param *config; | 3439 | struct config_param *config; |
2895 | 3440 | ||
3441 | |||
2896 | mac_control = &sp->mac_control; | 3442 | mac_control = &sp->mac_control; |
2897 | config = &sp->config; | 3443 | config = &sp->config; |
2898 | 3444 | ||
2899 | sp->stats.tx_errors = mac_control->stats_info->tmac_any_err_frms; | 3445 | /* Configure Stats for immediate updt */ |
2900 | sp->stats.rx_errors = mac_control->stats_info->rmac_drop_frms; | 3446 | s2io_updt_stats(sp); |
2901 | sp->stats.multicast = mac_control->stats_info->rmac_vld_mcst_frms; | 3447 | |
3448 | sp->stats.tx_packets = | ||
3449 | le32_to_cpu(mac_control->stats_info->tmac_frms); | ||
3450 | sp->stats.tx_errors = | ||
3451 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); | ||
3452 | sp->stats.rx_errors = | ||
3453 | le32_to_cpu(mac_control->stats_info->rmac_drop_frms); | ||
3454 | sp->stats.multicast = | ||
3455 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); | ||
2902 | sp->stats.rx_length_errors = | 3456 | sp->stats.rx_length_errors = |
2903 | mac_control->stats_info->rmac_long_frms; | 3457 | le32_to_cpu(mac_control->stats_info->rmac_long_frms); |
2904 | 3458 | ||
2905 | return (&sp->stats); | 3459 | return (&sp->stats); |
2906 | } | 3460 | } |
@@ -2909,8 +3463,8 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev) | |||
2909 | * s2io_set_multicast - entry point for multicast address enable/disable. | 3463 | * s2io_set_multicast - entry point for multicast address enable/disable. |
2910 | * @dev : pointer to the device structure | 3464 | * @dev : pointer to the device structure |
2911 | * Description: | 3465 | * Description: |
2912 | * This function is a driver entry point which gets called by the kernel | 3466 | * This function is a driver entry point which gets called by the kernel |
2913 | * whenever multicast addresses must be enabled/disabled. This also gets | 3467 | * whenever multicast addresses must be enabled/disabled. This also gets |
2914 | * called to set/reset promiscuous mode. Depending on the deivce flag, we | 3468 | * called to set/reset promiscuous mode. Depending on the deivce flag, we |
2915 | * determine, if multicast address must be enabled or if promiscuous mode | 3469 | * determine, if multicast address must be enabled or if promiscuous mode |
2916 | * is to be disabled etc. | 3470 | * is to be disabled etc. |
@@ -2948,6 +3502,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
2948 | /* Disable all Multicast addresses */ | 3502 | /* Disable all Multicast addresses */ |
2949 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), | 3503 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), |
2950 | &bar0->rmac_addr_data0_mem); | 3504 | &bar0->rmac_addr_data0_mem); |
3505 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0x0), | ||
3506 | &bar0->rmac_addr_data1_mem); | ||
2951 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3507 | val64 = RMAC_ADDR_CMD_MEM_WE | |
2952 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3508 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
2953 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); | 3509 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); |
@@ -3010,7 +3566,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3010 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), | 3566 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(dis_addr), |
3011 | &bar0->rmac_addr_data0_mem); | 3567 | &bar0->rmac_addr_data0_mem); |
3012 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), | 3568 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), |
3013 | &bar0->rmac_addr_data1_mem); | 3569 | &bar0->rmac_addr_data1_mem); |
3014 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3570 | val64 = RMAC_ADDR_CMD_MEM_WE | |
3015 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3571 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
3016 | RMAC_ADDR_CMD_MEM_OFFSET | 3572 | RMAC_ADDR_CMD_MEM_OFFSET |
@@ -3039,8 +3595,7 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3039 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr), | 3595 | writeq(RMAC_ADDR_DATA0_MEM_ADDR(mac_addr), |
3040 | &bar0->rmac_addr_data0_mem); | 3596 | &bar0->rmac_addr_data0_mem); |
3041 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), | 3597 | writeq(RMAC_ADDR_DATA1_MEM_MASK(0ULL), |
3042 | &bar0->rmac_addr_data1_mem); | 3598 | &bar0->rmac_addr_data1_mem); |
3043 | |||
3044 | val64 = RMAC_ADDR_CMD_MEM_WE | | 3599 | val64 = RMAC_ADDR_CMD_MEM_WE | |
3045 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 3600 | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
3046 | RMAC_ADDR_CMD_MEM_OFFSET | 3601 | RMAC_ADDR_CMD_MEM_OFFSET |
@@ -3059,12 +3614,12 @@ static void s2io_set_multicast(struct net_device *dev) | |||
3059 | } | 3614 | } |
3060 | 3615 | ||
3061 | /** | 3616 | /** |
3062 | * s2io_set_mac_addr - Programs the Xframe mac address | 3617 | * s2io_set_mac_addr - Programs the Xframe mac address |
3063 | * @dev : pointer to the device structure. | 3618 | * @dev : pointer to the device structure. |
3064 | * @addr: a uchar pointer to the new mac address which is to be set. | 3619 | * @addr: a uchar pointer to the new mac address which is to be set. |
3065 | * Description : This procedure will program the Xframe to receive | 3620 | * Description : This procedure will program the Xframe to receive |
3066 | * frames with new Mac Address | 3621 | * frames with new Mac Address |
3067 | * Return value: SUCCESS on success and an appropriate (-)ve integer | 3622 | * Return value: SUCCESS on success and an appropriate (-)ve integer |
3068 | * as defined in errno.h file on failure. | 3623 | * as defined in errno.h file on failure. |
3069 | */ | 3624 | */ |
3070 | 3625 | ||
@@ -3075,10 +3630,10 @@ int s2io_set_mac_addr(struct net_device *dev, u8 * addr) | |||
3075 | register u64 val64, mac_addr = 0; | 3630 | register u64 val64, mac_addr = 0; |
3076 | int i; | 3631 | int i; |
3077 | 3632 | ||
3078 | /* | 3633 | /* |
3079 | * Set the new MAC address as the new unicast filter and reflect this | 3634 | * Set the new MAC address as the new unicast filter and reflect this |
3080 | * change on the device address registered with the OS. It will be | 3635 | * change on the device address registered with the OS. It will be |
3081 | * at offset 0. | 3636 | * at offset 0. |
3082 | */ | 3637 | */ |
3083 | for (i = 0; i < ETH_ALEN; i++) { | 3638 | for (i = 0; i < ETH_ALEN; i++) { |
3084 | mac_addr <<= 8; | 3639 | mac_addr <<= 8; |
@@ -3102,12 +3657,12 @@ int s2io_set_mac_addr(struct net_device *dev, u8 * addr) | |||
3102 | } | 3657 | } |
3103 | 3658 | ||
3104 | /** | 3659 | /** |
3105 | * s2io_ethtool_sset - Sets different link parameters. | 3660 | * s2io_ethtool_sset - Sets different link parameters. |
3106 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 3661 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. |
3107 | * @info: pointer to the structure with parameters given by ethtool to set | 3662 | * @info: pointer to the structure with parameters given by ethtool to set |
3108 | * link information. | 3663 | * link information. |
3109 | * Description: | 3664 | * Description: |
3110 | * The function sets different link parameters provided by the user onto | 3665 | * The function sets different link parameters provided by the user onto |
3111 | * the NIC. | 3666 | * the NIC. |
3112 | * Return value: | 3667 | * Return value: |
3113 | * 0 on success. | 3668 | * 0 on success. |
@@ -3129,7 +3684,7 @@ static int s2io_ethtool_sset(struct net_device *dev, | |||
3129 | } | 3684 | } |
3130 | 3685 | ||
3131 | /** | 3686 | /** |
3132 | * s2io_ethtol_gset - Return link specific information. | 3687 | * s2io_ethtol_gset - Return link specific information. |
3133 | * @sp : private member of the device structure, pointer to the | 3688 | * @sp : private member of the device structure, pointer to the |
3134 | * s2io_nic structure. | 3689 | * s2io_nic structure. |
3135 | * @info : pointer to the structure with parameters given by ethtool | 3690 | * @info : pointer to the structure with parameters given by ethtool |
@@ -3161,8 +3716,8 @@ static int s2io_ethtool_gset(struct net_device *dev, struct ethtool_cmd *info) | |||
3161 | } | 3716 | } |
3162 | 3717 | ||
3163 | /** | 3718 | /** |
3164 | * s2io_ethtool_gdrvinfo - Returns driver specific information. | 3719 | * s2io_ethtool_gdrvinfo - Returns driver specific information. |
3165 | * @sp : private member of the device structure, which is a pointer to the | 3720 | * @sp : private member of the device structure, which is a pointer to the |
3166 | * s2io_nic structure. | 3721 | * s2io_nic structure. |
3167 | * @info : pointer to the structure with parameters given by ethtool to | 3722 | * @info : pointer to the structure with parameters given by ethtool to |
3168 | * return driver information. | 3723 | * return driver information. |
@@ -3190,9 +3745,9 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev, | |||
3190 | 3745 | ||
3191 | /** | 3746 | /** |
3192 | * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer. | 3747 | * s2io_ethtool_gregs - dumps the entire space of Xfame into the buffer. |
3193 | * @sp: private member of the device structure, which is a pointer to the | 3748 | * @sp: private member of the device structure, which is a pointer to the |
3194 | * s2io_nic structure. | 3749 | * s2io_nic structure. |
3195 | * @regs : pointer to the structure with parameters given by ethtool for | 3750 | * @regs : pointer to the structure with parameters given by ethtool for |
3196 | * dumping the registers. | 3751 | * dumping the registers. |
3197 | * @reg_space: The input argumnet into which all the registers are dumped. | 3752 | * @reg_space: The input argumnet into which all the registers are dumped. |
3198 | * Description: | 3753 | * Description: |
@@ -3221,11 +3776,11 @@ static void s2io_ethtool_gregs(struct net_device *dev, | |||
3221 | 3776 | ||
3222 | /** | 3777 | /** |
3223 | * s2io_phy_id - timer function that alternates adapter LED. | 3778 | * s2io_phy_id - timer function that alternates adapter LED. |
3224 | * @data : address of the private member of the device structure, which | 3779 | * @data : address of the private member of the device structure, which |
3225 | * is a pointer to the s2io_nic structure, provided as an u32. | 3780 | * is a pointer to the s2io_nic structure, provided as an u32. |
3226 | * Description: This is actually the timer function that alternates the | 3781 | * Description: This is actually the timer function that alternates the |
3227 | * adapter LED bit of the adapter control bit to set/reset every time on | 3782 | * adapter LED bit of the adapter control bit to set/reset every time on |
3228 | * invocation. The timer is set for 1/2 a second, hence tha NIC blinks | 3783 | * invocation. The timer is set for 1/2 a second, hence tha NIC blinks |
3229 | * once every second. | 3784 | * once every second. |
3230 | */ | 3785 | */ |
3231 | static void s2io_phy_id(unsigned long data) | 3786 | static void s2io_phy_id(unsigned long data) |
@@ -3236,7 +3791,8 @@ static void s2io_phy_id(unsigned long data) | |||
3236 | u16 subid; | 3791 | u16 subid; |
3237 | 3792 | ||
3238 | subid = sp->pdev->subsystem_device; | 3793 | subid = sp->pdev->subsystem_device; |
3239 | if ((subid & 0xFF) >= 0x07) { | 3794 | if ((sp->device_type == XFRAME_II_DEVICE) || |
3795 | ((subid & 0xFF) >= 0x07)) { | ||
3240 | val64 = readq(&bar0->gpio_control); | 3796 | val64 = readq(&bar0->gpio_control); |
3241 | val64 ^= GPIO_CTRL_GPIO_0; | 3797 | val64 ^= GPIO_CTRL_GPIO_0; |
3242 | writeq(val64, &bar0->gpio_control); | 3798 | writeq(val64, &bar0->gpio_control); |
@@ -3253,12 +3809,12 @@ static void s2io_phy_id(unsigned long data) | |||
3253 | * s2io_ethtool_idnic - To physically identify the nic on the system. | 3809 | * s2io_ethtool_idnic - To physically identify the nic on the system. |
3254 | * @sp : private member of the device structure, which is a pointer to the | 3810 | * @sp : private member of the device structure, which is a pointer to the |
3255 | * s2io_nic structure. | 3811 | * s2io_nic structure. |
3256 | * @id : pointer to the structure with identification parameters given by | 3812 | * @id : pointer to the structure with identification parameters given by |
3257 | * ethtool. | 3813 | * ethtool. |
3258 | * Description: Used to physically identify the NIC on the system. | 3814 | * Description: Used to physically identify the NIC on the system. |
3259 | * The Link LED will blink for a time specified by the user for | 3815 | * The Link LED will blink for a time specified by the user for |
3260 | * identification. | 3816 | * identification. |
3261 | * NOTE: The Link has to be Up to be able to blink the LED. Hence | 3817 | * NOTE: The Link has to be Up to be able to blink the LED. Hence |
3262 | * identification is possible only if it's link is up. | 3818 | * identification is possible only if it's link is up. |
3263 | * Return value: | 3819 | * Return value: |
3264 | * int , returns 0 on success | 3820 | * int , returns 0 on success |
@@ -3273,7 +3829,8 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3273 | 3829 | ||
3274 | subid = sp->pdev->subsystem_device; | 3830 | subid = sp->pdev->subsystem_device; |
3275 | last_gpio_ctrl_val = readq(&bar0->gpio_control); | 3831 | last_gpio_ctrl_val = readq(&bar0->gpio_control); |
3276 | if ((subid & 0xFF) < 0x07) { | 3832 | if ((sp->device_type == XFRAME_I_DEVICE) && |
3833 | ((subid & 0xFF) < 0x07)) { | ||
3277 | val64 = readq(&bar0->adapter_control); | 3834 | val64 = readq(&bar0->adapter_control); |
3278 | if (!(val64 & ADAPTER_CNTL_EN)) { | 3835 | if (!(val64 & ADAPTER_CNTL_EN)) { |
3279 | printk(KERN_ERR | 3836 | printk(KERN_ERR |
@@ -3288,12 +3845,12 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3288 | } | 3845 | } |
3289 | mod_timer(&sp->id_timer, jiffies); | 3846 | mod_timer(&sp->id_timer, jiffies); |
3290 | if (data) | 3847 | if (data) |
3291 | msleep(data * 1000); | 3848 | msleep_interruptible(data * HZ); |
3292 | else | 3849 | else |
3293 | msleep(0xFFFFFFFF); | 3850 | msleep_interruptible(MAX_FLICKER_TIME); |
3294 | del_timer_sync(&sp->id_timer); | 3851 | del_timer_sync(&sp->id_timer); |
3295 | 3852 | ||
3296 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 3853 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(sp->device_type, subid)) { |
3297 | writeq(last_gpio_ctrl_val, &bar0->gpio_control); | 3854 | writeq(last_gpio_ctrl_val, &bar0->gpio_control); |
3298 | last_gpio_ctrl_val = readq(&bar0->gpio_control); | 3855 | last_gpio_ctrl_val = readq(&bar0->gpio_control); |
3299 | } | 3856 | } |
@@ -3303,7 +3860,8 @@ static int s2io_ethtool_idnic(struct net_device *dev, u32 data) | |||
3303 | 3860 | ||
3304 | /** | 3861 | /** |
3305 | * s2io_ethtool_getpause_data -Pause frame frame generation and reception. | 3862 | * s2io_ethtool_getpause_data -Pause frame frame generation and reception. |
3306 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 3863 | * @sp : private member of the device structure, which is a pointer to the |
3864 | * s2io_nic structure. | ||
3307 | * @ep : pointer to the structure with pause parameters given by ethtool. | 3865 | * @ep : pointer to the structure with pause parameters given by ethtool. |
3308 | * Description: | 3866 | * Description: |
3309 | * Returns the Pause frame generation and reception capability of the NIC. | 3867 | * Returns the Pause frame generation and reception capability of the NIC. |
@@ -3327,7 +3885,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, | |||
3327 | 3885 | ||
3328 | /** | 3886 | /** |
3329 | * s2io_ethtool_setpause_data - set/reset pause frame generation. | 3887 | * s2io_ethtool_setpause_data - set/reset pause frame generation. |
3330 | * @sp : private member of the device structure, which is a pointer to the | 3888 | * @sp : private member of the device structure, which is a pointer to the |
3331 | * s2io_nic structure. | 3889 | * s2io_nic structure. |
3332 | * @ep : pointer to the structure with pause parameters given by ethtool. | 3890 | * @ep : pointer to the structure with pause parameters given by ethtool. |
3333 | * Description: | 3891 | * Description: |
@@ -3338,7 +3896,7 @@ static void s2io_ethtool_getpause_data(struct net_device *dev, | |||
3338 | */ | 3896 | */ |
3339 | 3897 | ||
3340 | static int s2io_ethtool_setpause_data(struct net_device *dev, | 3898 | static int s2io_ethtool_setpause_data(struct net_device *dev, |
3341 | struct ethtool_pauseparam *ep) | 3899 | struct ethtool_pauseparam *ep) |
3342 | { | 3900 | { |
3343 | u64 val64; | 3901 | u64 val64; |
3344 | nic_t *sp = dev->priv; | 3902 | nic_t *sp = dev->priv; |
@@ -3359,13 +3917,13 @@ static int s2io_ethtool_setpause_data(struct net_device *dev, | |||
3359 | 3917 | ||
3360 | /** | 3918 | /** |
3361 | * read_eeprom - reads 4 bytes of data from user given offset. | 3919 | * read_eeprom - reads 4 bytes of data from user given offset. |
3362 | * @sp : private member of the device structure, which is a pointer to the | 3920 | * @sp : private member of the device structure, which is a pointer to the |
3363 | * s2io_nic structure. | 3921 | * s2io_nic structure. |
3364 | * @off : offset at which the data must be written | 3922 | * @off : offset at which the data must be written |
3365 | * @data : Its an output parameter where the data read at the given | 3923 | * @data : Its an output parameter where the data read at the given |
3366 | * offset is stored. | 3924 | * offset is stored. |
3367 | * Description: | 3925 | * Description: |
3368 | * Will read 4 bytes of data from the user given offset and return the | 3926 | * Will read 4 bytes of data from the user given offset and return the |
3369 | * read data. | 3927 | * read data. |
3370 | * NOTE: Will allow to read only part of the EEPROM visible through the | 3928 | * NOTE: Will allow to read only part of the EEPROM visible through the |
3371 | * I2C bus. | 3929 | * I2C bus. |
@@ -3406,7 +3964,7 @@ static int read_eeprom(nic_t * sp, int off, u32 * data) | |||
3406 | * s2io_nic structure. | 3964 | * s2io_nic structure. |
3407 | * @off : offset at which the data must be written | 3965 | * @off : offset at which the data must be written |
3408 | * @data : The data that is to be written | 3966 | * @data : The data that is to be written |
3409 | * @cnt : Number of bytes of the data that are actually to be written into | 3967 | * @cnt : Number of bytes of the data that are actually to be written into |
3410 | * the Eeprom. (max of 3) | 3968 | * the Eeprom. (max of 3) |
3411 | * Description: | 3969 | * Description: |
3412 | * Actually writes the relevant part of the data value into the Eeprom | 3970 | * Actually writes the relevant part of the data value into the Eeprom |
@@ -3443,7 +4001,7 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | |||
3443 | /** | 4001 | /** |
3444 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. | 4002 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. |
3445 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. | 4003 | * @sp : private member of the device structure, which is a pointer to the * s2io_nic structure. |
3446 | * @eeprom : pointer to the user level structure provided by ethtool, | 4004 | * @eeprom : pointer to the user level structure provided by ethtool, |
3447 | * containing all relevant information. | 4005 | * containing all relevant information. |
3448 | * @data_buf : user defined value to be written into Eeprom. | 4006 | * @data_buf : user defined value to be written into Eeprom. |
3449 | * Description: Reads the values stored in the Eeprom at given offset | 4007 | * Description: Reads the values stored in the Eeprom at given offset |
@@ -3454,7 +4012,7 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | |||
3454 | */ | 4012 | */ |
3455 | 4013 | ||
3456 | static int s2io_ethtool_geeprom(struct net_device *dev, | 4014 | static int s2io_ethtool_geeprom(struct net_device *dev, |
3457 | struct ethtool_eeprom *eeprom, u8 * data_buf) | 4015 | struct ethtool_eeprom *eeprom, u8 * data_buf) |
3458 | { | 4016 | { |
3459 | u32 data, i, valid; | 4017 | u32 data, i, valid; |
3460 | nic_t *sp = dev->priv; | 4018 | nic_t *sp = dev->priv; |
@@ -3479,7 +4037,7 @@ static int s2io_ethtool_geeprom(struct net_device *dev, | |||
3479 | * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom | 4037 | * s2io_ethtool_seeprom - tries to write the user provided value in Eeprom |
3480 | * @sp : private member of the device structure, which is a pointer to the | 4038 | * @sp : private member of the device structure, which is a pointer to the |
3481 | * s2io_nic structure. | 4039 | * s2io_nic structure. |
3482 | * @eeprom : pointer to the user level structure provided by ethtool, | 4040 | * @eeprom : pointer to the user level structure provided by ethtool, |
3483 | * containing all relevant information. | 4041 | * containing all relevant information. |
3484 | * @data_buf ; user defined value to be written into Eeprom. | 4042 | * @data_buf ; user defined value to be written into Eeprom. |
3485 | * Description: | 4043 | * Description: |
@@ -3527,8 +4085,8 @@ static int s2io_ethtool_seeprom(struct net_device *dev, | |||
3527 | } | 4085 | } |
3528 | 4086 | ||
3529 | /** | 4087 | /** |
3530 | * s2io_register_test - reads and writes into all clock domains. | 4088 | * s2io_register_test - reads and writes into all clock domains. |
3531 | * @sp : private member of the device structure, which is a pointer to the | 4089 | * @sp : private member of the device structure, which is a pointer to the |
3532 | * s2io_nic structure. | 4090 | * s2io_nic structure. |
3533 | * @data : variable that returns the result of each of the test conducted b | 4091 | * @data : variable that returns the result of each of the test conducted b |
3534 | * by the driver. | 4092 | * by the driver. |
@@ -3545,8 +4103,8 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
3545 | u64 val64 = 0; | 4103 | u64 val64 = 0; |
3546 | int fail = 0; | 4104 | int fail = 0; |
3547 | 4105 | ||
3548 | val64 = readq(&bar0->pcc_enable); | 4106 | val64 = readq(&bar0->pif_rd_swapper_fb); |
3549 | if (val64 != 0xff00000000000000ULL) { | 4107 | if (val64 != 0x123456789abcdefULL) { |
3550 | fail = 1; | 4108 | fail = 1; |
3551 | DBG_PRINT(INFO_DBG, "Read Test level 1 fails\n"); | 4109 | DBG_PRINT(INFO_DBG, "Read Test level 1 fails\n"); |
3552 | } | 4110 | } |
@@ -3590,13 +4148,13 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
3590 | } | 4148 | } |
3591 | 4149 | ||
3592 | /** | 4150 | /** |
3593 | * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. | 4151 | * s2io_eeprom_test - to verify that EEprom in the xena can be programmed. |
3594 | * @sp : private member of the device structure, which is a pointer to the | 4152 | * @sp : private member of the device structure, which is a pointer to the |
3595 | * s2io_nic structure. | 4153 | * s2io_nic structure. |
3596 | * @data:variable that returns the result of each of the test conducted by | 4154 | * @data:variable that returns the result of each of the test conducted by |
3597 | * the driver. | 4155 | * the driver. |
3598 | * Description: | 4156 | * Description: |
3599 | * Verify that EEPROM in the xena can be programmed using I2C_CONTROL | 4157 | * Verify that EEPROM in the xena can be programmed using I2C_CONTROL |
3600 | * register. | 4158 | * register. |
3601 | * Return value: | 4159 | * Return value: |
3602 | * 0 on success. | 4160 | * 0 on success. |
@@ -3661,14 +4219,14 @@ static int s2io_eeprom_test(nic_t * sp, uint64_t * data) | |||
3661 | 4219 | ||
3662 | /** | 4220 | /** |
3663 | * s2io_bist_test - invokes the MemBist test of the card . | 4221 | * s2io_bist_test - invokes the MemBist test of the card . |
3664 | * @sp : private member of the device structure, which is a pointer to the | 4222 | * @sp : private member of the device structure, which is a pointer to the |
3665 | * s2io_nic structure. | 4223 | * s2io_nic structure. |
3666 | * @data:variable that returns the result of each of the test conducted by | 4224 | * @data:variable that returns the result of each of the test conducted by |
3667 | * the driver. | 4225 | * the driver. |
3668 | * Description: | 4226 | * Description: |
3669 | * This invokes the MemBist test of the card. We give around | 4227 | * This invokes the MemBist test of the card. We give around |
3670 | * 2 secs time for the Test to complete. If it's still not complete | 4228 | * 2 secs time for the Test to complete. If it's still not complete |
3671 | * within this peiod, we consider that the test failed. | 4229 | * within this peiod, we consider that the test failed. |
3672 | * Return value: | 4230 | * Return value: |
3673 | * 0 on success and -1 on failure. | 4231 | * 0 on success and -1 on failure. |
3674 | */ | 4232 | */ |
@@ -3697,13 +4255,13 @@ static int s2io_bist_test(nic_t * sp, uint64_t * data) | |||
3697 | } | 4255 | } |
3698 | 4256 | ||
3699 | /** | 4257 | /** |
3700 | * s2io-link_test - verifies the link state of the nic | 4258 | * s2io-link_test - verifies the link state of the nic |
3701 | * @sp ; private member of the device structure, which is a pointer to the | 4259 | * @sp ; private member of the device structure, which is a pointer to the |
3702 | * s2io_nic structure. | 4260 | * s2io_nic structure. |
3703 | * @data: variable that returns the result of each of the test conducted by | 4261 | * @data: variable that returns the result of each of the test conducted by |
3704 | * the driver. | 4262 | * the driver. |
3705 | * Description: | 4263 | * Description: |
3706 | * The function verifies the link state of the NIC and updates the input | 4264 | * The function verifies the link state of the NIC and updates the input |
3707 | * argument 'data' appropriately. | 4265 | * argument 'data' appropriately. |
3708 | * Return value: | 4266 | * Return value: |
3709 | * 0 on success. | 4267 | * 0 on success. |
@@ -3722,13 +4280,13 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
3722 | } | 4280 | } |
3723 | 4281 | ||
3724 | /** | 4282 | /** |
3725 | * s2io_rldram_test - offline test for access to the RldRam chip on the NIC | 4283 | * s2io_rldram_test - offline test for access to the RldRam chip on the NIC |
3726 | * @sp - private member of the device structure, which is a pointer to the | 4284 | * @sp - private member of the device structure, which is a pointer to the |
3727 | * s2io_nic structure. | 4285 | * s2io_nic structure. |
3728 | * @data - variable that returns the result of each of the test | 4286 | * @data - variable that returns the result of each of the test |
3729 | * conducted by the driver. | 4287 | * conducted by the driver. |
3730 | * Description: | 4288 | * Description: |
3731 | * This is one of the offline test that tests the read and write | 4289 | * This is one of the offline test that tests the read and write |
3732 | * access to the RldRam chip on the NIC. | 4290 | * access to the RldRam chip on the NIC. |
3733 | * Return value: | 4291 | * Return value: |
3734 | * 0 on success. | 4292 | * 0 on success. |
@@ -3833,7 +4391,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
3833 | * s2io_nic structure. | 4391 | * s2io_nic structure. |
3834 | * @ethtest : pointer to a ethtool command specific structure that will be | 4392 | * @ethtest : pointer to a ethtool command specific structure that will be |
3835 | * returned to the user. | 4393 | * returned to the user. |
3836 | * @data : variable that returns the result of each of the test | 4394 | * @data : variable that returns the result of each of the test |
3837 | * conducted by the driver. | 4395 | * conducted by the driver. |
3838 | * Description: | 4396 | * Description: |
3839 | * This function conducts 6 tests ( 4 offline and 2 online) to determine | 4397 | * This function conducts 6 tests ( 4 offline and 2 online) to determine |
@@ -3851,23 +4409,18 @@ static void s2io_ethtool_test(struct net_device *dev, | |||
3851 | 4409 | ||
3852 | if (ethtest->flags == ETH_TEST_FL_OFFLINE) { | 4410 | if (ethtest->flags == ETH_TEST_FL_OFFLINE) { |
3853 | /* Offline Tests. */ | 4411 | /* Offline Tests. */ |
3854 | if (orig_state) { | 4412 | if (orig_state) |
3855 | s2io_close(sp->dev); | 4413 | s2io_close(sp->dev); |
3856 | s2io_set_swapper(sp); | ||
3857 | } else | ||
3858 | s2io_set_swapper(sp); | ||
3859 | 4414 | ||
3860 | if (s2io_register_test(sp, &data[0])) | 4415 | if (s2io_register_test(sp, &data[0])) |
3861 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4416 | ethtest->flags |= ETH_TEST_FL_FAILED; |
3862 | 4417 | ||
3863 | s2io_reset(sp); | 4418 | s2io_reset(sp); |
3864 | s2io_set_swapper(sp); | ||
3865 | 4419 | ||
3866 | if (s2io_rldram_test(sp, &data[3])) | 4420 | if (s2io_rldram_test(sp, &data[3])) |
3867 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4421 | ethtest->flags |= ETH_TEST_FL_FAILED; |
3868 | 4422 | ||
3869 | s2io_reset(sp); | 4423 | s2io_reset(sp); |
3870 | s2io_set_swapper(sp); | ||
3871 | 4424 | ||
3872 | if (s2io_eeprom_test(sp, &data[1])) | 4425 | if (s2io_eeprom_test(sp, &data[1])) |
3873 | ethtest->flags |= ETH_TEST_FL_FAILED; | 4426 | ethtest->flags |= ETH_TEST_FL_FAILED; |
@@ -3910,61 +4463,111 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
3910 | nic_t *sp = dev->priv; | 4463 | nic_t *sp = dev->priv; |
3911 | StatInfo_t *stat_info = sp->mac_control.stats_info; | 4464 | StatInfo_t *stat_info = sp->mac_control.stats_info; |
3912 | 4465 | ||
3913 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_frms); | 4466 | s2io_updt_stats(sp); |
3914 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_data_octets); | 4467 | tmp_stats[i++] = |
4468 | (u64)le32_to_cpu(stat_info->tmac_frms_oflow) << 32 | | ||
4469 | le32_to_cpu(stat_info->tmac_frms); | ||
4470 | tmp_stats[i++] = | ||
4471 | (u64)le32_to_cpu(stat_info->tmac_data_octets_oflow) << 32 | | ||
4472 | le32_to_cpu(stat_info->tmac_data_octets); | ||
3915 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); | 4473 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_drop_frms); |
3916 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_mcst_frms); | 4474 | tmp_stats[i++] = |
3917 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_bcst_frms); | 4475 | (u64)le32_to_cpu(stat_info->tmac_mcst_frms_oflow) << 32 | |
4476 | le32_to_cpu(stat_info->tmac_mcst_frms); | ||
4477 | tmp_stats[i++] = | ||
4478 | (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 | | ||
4479 | le32_to_cpu(stat_info->tmac_bcst_frms); | ||
3918 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); | 4480 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); |
3919 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_any_err_frms); | 4481 | tmp_stats[i++] = |
4482 | (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 | | ||
4483 | le32_to_cpu(stat_info->tmac_any_err_frms); | ||
3920 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); | 4484 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); |
3921 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_vld_ip); | 4485 | tmp_stats[i++] = |
3922 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_drop_ip); | 4486 | (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 | |
3923 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_icmp); | 4487 | le32_to_cpu(stat_info->tmac_vld_ip); |
3924 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_rst_tcp); | 4488 | tmp_stats[i++] = |
4489 | (u64)le32_to_cpu(stat_info->tmac_drop_ip_oflow) << 32 | | ||
4490 | le32_to_cpu(stat_info->tmac_drop_ip); | ||
4491 | tmp_stats[i++] = | ||
4492 | (u64)le32_to_cpu(stat_info->tmac_icmp_oflow) << 32 | | ||
4493 | le32_to_cpu(stat_info->tmac_icmp); | ||
4494 | tmp_stats[i++] = | ||
4495 | (u64)le32_to_cpu(stat_info->tmac_rst_tcp_oflow) << 32 | | ||
4496 | le32_to_cpu(stat_info->tmac_rst_tcp); | ||
3925 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp); | 4497 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_tcp); |
3926 | tmp_stats[i++] = le32_to_cpu(stat_info->tmac_udp); | 4498 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->tmac_udp_oflow) << 32 | |
3927 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_frms); | 4499 | le32_to_cpu(stat_info->tmac_udp); |
3928 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_data_octets); | 4500 | tmp_stats[i++] = |
4501 | (u64)le32_to_cpu(stat_info->rmac_vld_frms_oflow) << 32 | | ||
4502 | le32_to_cpu(stat_info->rmac_vld_frms); | ||
4503 | tmp_stats[i++] = | ||
4504 | (u64)le32_to_cpu(stat_info->rmac_data_octets_oflow) << 32 | | ||
4505 | le32_to_cpu(stat_info->rmac_data_octets); | ||
3929 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms); | 4506 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_fcs_err_frms); |
3930 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms); | 4507 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_drop_frms); |
3931 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_mcst_frms); | 4508 | tmp_stats[i++] = |
3932 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_vld_bcst_frms); | 4509 | (u64)le32_to_cpu(stat_info->rmac_vld_mcst_frms_oflow) << 32 | |
4510 | le32_to_cpu(stat_info->rmac_vld_mcst_frms); | ||
4511 | tmp_stats[i++] = | ||
4512 | (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 | | ||
4513 | le32_to_cpu(stat_info->rmac_vld_bcst_frms); | ||
3933 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); | 4514 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); |
3934 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); | 4515 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); |
3935 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); | 4516 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); |
3936 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_discarded_frms); | 4517 | tmp_stats[i++] = |
3937 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_usized_frms); | 4518 | (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 | |
3938 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_osized_frms); | 4519 | le32_to_cpu(stat_info->rmac_discarded_frms); |
3939 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_frag_frms); | 4520 | tmp_stats[i++] = |
3940 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_jabber_frms); | 4521 | (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 | |
3941 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ip); | 4522 | le32_to_cpu(stat_info->rmac_usized_frms); |
4523 | tmp_stats[i++] = | ||
4524 | (u64)le32_to_cpu(stat_info->rmac_osized_frms_oflow) << 32 | | ||
4525 | le32_to_cpu(stat_info->rmac_osized_frms); | ||
4526 | tmp_stats[i++] = | ||
4527 | (u64)le32_to_cpu(stat_info->rmac_frag_frms_oflow) << 32 | | ||
4528 | le32_to_cpu(stat_info->rmac_frag_frms); | ||
4529 | tmp_stats[i++] = | ||
4530 | (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 | | ||
4531 | le32_to_cpu(stat_info->rmac_jabber_frms); | ||
4532 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | | ||
4533 | le32_to_cpu(stat_info->rmac_ip); | ||
3942 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); | 4534 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); |
3943 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); | 4535 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); |
3944 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_drop_ip); | 4536 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | |
3945 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_icmp); | 4537 | le32_to_cpu(stat_info->rmac_drop_ip); |
4538 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | | ||
4539 | le32_to_cpu(stat_info->rmac_icmp); | ||
3946 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); | 4540 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); |
3947 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_udp); | 4541 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | |
3948 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_drp_udp); | 4542 | le32_to_cpu(stat_info->rmac_udp); |
3949 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pause_cnt); | 4543 | tmp_stats[i++] = |
3950 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_accepted_ip); | 4544 | (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 | |
4545 | le32_to_cpu(stat_info->rmac_err_drp_udp); | ||
4546 | tmp_stats[i++] = | ||
4547 | (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 | | ||
4548 | le32_to_cpu(stat_info->rmac_pause_cnt); | ||
4549 | tmp_stats[i++] = | ||
4550 | (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 | | ||
4551 | le32_to_cpu(stat_info->rmac_accepted_ip); | ||
3951 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); | 4552 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); |
4553 | tmp_stats[i++] = 0; | ||
4554 | tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; | ||
4555 | tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; | ||
3952 | } | 4556 | } |
3953 | 4557 | ||
3954 | static int s2io_ethtool_get_regs_len(struct net_device *dev) | 4558 | int s2io_ethtool_get_regs_len(struct net_device *dev) |
3955 | { | 4559 | { |
3956 | return (XENA_REG_SPACE); | 4560 | return (XENA_REG_SPACE); |
3957 | } | 4561 | } |
3958 | 4562 | ||
3959 | 4563 | ||
3960 | static u32 s2io_ethtool_get_rx_csum(struct net_device * dev) | 4564 | u32 s2io_ethtool_get_rx_csum(struct net_device * dev) |
3961 | { | 4565 | { |
3962 | nic_t *sp = dev->priv; | 4566 | nic_t *sp = dev->priv; |
3963 | 4567 | ||
3964 | return (sp->rx_csum); | 4568 | return (sp->rx_csum); |
3965 | } | 4569 | } |
3966 | 4570 | int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | |
3967 | static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | ||
3968 | { | 4571 | { |
3969 | nic_t *sp = dev->priv; | 4572 | nic_t *sp = dev->priv; |
3970 | 4573 | ||
@@ -3975,19 +4578,17 @@ static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data) | |||
3975 | 4578 | ||
3976 | return 0; | 4579 | return 0; |
3977 | } | 4580 | } |
3978 | 4581 | int s2io_get_eeprom_len(struct net_device *dev) | |
3979 | static int s2io_get_eeprom_len(struct net_device *dev) | ||
3980 | { | 4582 | { |
3981 | return (XENA_EEPROM_SPACE); | 4583 | return (XENA_EEPROM_SPACE); |
3982 | } | 4584 | } |
3983 | 4585 | ||
3984 | static int s2io_ethtool_self_test_count(struct net_device *dev) | 4586 | int s2io_ethtool_self_test_count(struct net_device *dev) |
3985 | { | 4587 | { |
3986 | return (S2IO_TEST_LEN); | 4588 | return (S2IO_TEST_LEN); |
3987 | } | 4589 | } |
3988 | 4590 | void s2io_ethtool_get_strings(struct net_device *dev, | |
3989 | static void s2io_ethtool_get_strings(struct net_device *dev, | 4591 | u32 stringset, u8 * data) |
3990 | u32 stringset, u8 * data) | ||
3991 | { | 4592 | { |
3992 | switch (stringset) { | 4593 | switch (stringset) { |
3993 | case ETH_SS_TEST: | 4594 | case ETH_SS_TEST: |
@@ -3998,13 +4599,12 @@ static void s2io_ethtool_get_strings(struct net_device *dev, | |||
3998 | sizeof(ethtool_stats_keys)); | 4599 | sizeof(ethtool_stats_keys)); |
3999 | } | 4600 | } |
4000 | } | 4601 | } |
4001 | |||
4002 | static int s2io_ethtool_get_stats_count(struct net_device *dev) | 4602 | static int s2io_ethtool_get_stats_count(struct net_device *dev) |
4003 | { | 4603 | { |
4004 | return (S2IO_STAT_LEN); | 4604 | return (S2IO_STAT_LEN); |
4005 | } | 4605 | } |
4006 | 4606 | ||
4007 | static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | 4607 | int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) |
4008 | { | 4608 | { |
4009 | if (data) | 4609 | if (data) |
4010 | dev->features |= NETIF_F_IP_CSUM; | 4610 | dev->features |= NETIF_F_IP_CSUM; |
@@ -4046,21 +4646,18 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
4046 | }; | 4646 | }; |
4047 | 4647 | ||
4048 | /** | 4648 | /** |
4049 | * s2io_ioctl - Entry point for the Ioctl | 4649 | * s2io_ioctl - Entry point for the Ioctl |
4050 | * @dev : Device pointer. | 4650 | * @dev : Device pointer. |
4051 | * @ifr : An IOCTL specefic structure, that can contain a pointer to | 4651 | * @ifr : An IOCTL specefic structure, that can contain a pointer to |
4052 | * a proprietary structure used to pass information to the driver. | 4652 | * a proprietary structure used to pass information to the driver. |
4053 | * @cmd : This is used to distinguish between the different commands that | 4653 | * @cmd : This is used to distinguish between the different commands that |
4054 | * can be passed to the IOCTL functions. | 4654 | * can be passed to the IOCTL functions. |
4055 | * Description: | 4655 | * Description: |
4056 | * This function has support for ethtool, adding multiple MAC addresses on | 4656 | * Currently there are no special functionality supported in IOCTL, hence |
4057 | * the NIC and some DBG commands for the util tool. | 4657 | * function always return EOPNOTSUPPORTED |
4058 | * Return value: | ||
4059 | * Currently the IOCTL supports no operations, hence by default this | ||
4060 | * function returns OP NOT SUPPORTED value. | ||
4061 | */ | 4658 | */ |
4062 | 4659 | ||
4063 | static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | 4660 | int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) |
4064 | { | 4661 | { |
4065 | return -EOPNOTSUPP; | 4662 | return -EOPNOTSUPP; |
4066 | } | 4663 | } |
@@ -4076,17 +4673,9 @@ static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
4076 | * file on failure. | 4673 | * file on failure. |
4077 | */ | 4674 | */ |
4078 | 4675 | ||
4079 | static int s2io_change_mtu(struct net_device *dev, int new_mtu) | 4676 | int s2io_change_mtu(struct net_device *dev, int new_mtu) |
4080 | { | 4677 | { |
4081 | nic_t *sp = dev->priv; | 4678 | nic_t *sp = dev->priv; |
4082 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
4083 | register u64 val64; | ||
4084 | |||
4085 | if (netif_running(dev)) { | ||
4086 | DBG_PRINT(ERR_DBG, "%s: Must be stopped to ", dev->name); | ||
4087 | DBG_PRINT(ERR_DBG, "change its MTU \n"); | ||
4088 | return -EBUSY; | ||
4089 | } | ||
4090 | 4679 | ||
4091 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { | 4680 | if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) { |
4092 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", | 4681 | DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n", |
@@ -4094,11 +4683,22 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
4094 | return -EPERM; | 4683 | return -EPERM; |
4095 | } | 4684 | } |
4096 | 4685 | ||
4097 | /* Set the new MTU into the PYLD register of the NIC */ | ||
4098 | val64 = new_mtu; | ||
4099 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | ||
4100 | |||
4101 | dev->mtu = new_mtu; | 4686 | dev->mtu = new_mtu; |
4687 | if (netif_running(dev)) { | ||
4688 | s2io_card_down(sp); | ||
4689 | netif_stop_queue(dev); | ||
4690 | if (s2io_card_up(sp)) { | ||
4691 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | ||
4692 | __FUNCTION__); | ||
4693 | } | ||
4694 | if (netif_queue_stopped(dev)) | ||
4695 | netif_wake_queue(dev); | ||
4696 | } else { /* Device is down */ | ||
4697 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
4698 | u64 val64 = new_mtu; | ||
4699 | |||
4700 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | ||
4701 | } | ||
4102 | 4702 | ||
4103 | return 0; | 4703 | return 0; |
4104 | } | 4704 | } |
@@ -4108,9 +4708,9 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
4108 | * @dev_adr : address of the device structure in dma_addr_t format. | 4708 | * @dev_adr : address of the device structure in dma_addr_t format. |
4109 | * Description: | 4709 | * Description: |
4110 | * This is the tasklet or the bottom half of the ISR. This is | 4710 | * This is the tasklet or the bottom half of the ISR. This is |
4111 | * an extension of the ISR which is scheduled by the scheduler to be run | 4711 | * an extension of the ISR which is scheduled by the scheduler to be run |
4112 | * when the load on the CPU is low. All low priority tasks of the ISR can | 4712 | * when the load on the CPU is low. All low priority tasks of the ISR can |
4113 | * be pushed into the tasklet. For now the tasklet is used only to | 4713 | * be pushed into the tasklet. For now the tasklet is used only to |
4114 | * replenish the Rx buffers in the Rx buffer descriptors. | 4714 | * replenish the Rx buffers in the Rx buffer descriptors. |
4115 | * Return value: | 4715 | * Return value: |
4116 | * void. | 4716 | * void. |
@@ -4166,19 +4766,22 @@ static void s2io_set_link(unsigned long data) | |||
4166 | } | 4766 | } |
4167 | 4767 | ||
4168 | subid = nic->pdev->subsystem_device; | 4768 | subid = nic->pdev->subsystem_device; |
4169 | /* | 4769 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
4170 | * Allow a small delay for the NICs self initiated | 4770 | /* |
4171 | * cleanup to complete. | 4771 | * Allow a small delay for the NICs self initiated |
4172 | */ | 4772 | * cleanup to complete. |
4173 | msleep(100); | 4773 | */ |
4774 | msleep(100); | ||
4775 | } | ||
4174 | 4776 | ||
4175 | val64 = readq(&bar0->adapter_status); | 4777 | val64 = readq(&bar0->adapter_status); |
4176 | if (verify_xena_quiescence(val64, nic->device_enabled_once)) { | 4778 | if (verify_xena_quiescence(nic, val64, nic->device_enabled_once)) { |
4177 | if (LINK_IS_UP(val64)) { | 4779 | if (LINK_IS_UP(val64)) { |
4178 | val64 = readq(&bar0->adapter_control); | 4780 | val64 = readq(&bar0->adapter_control); |
4179 | val64 |= ADAPTER_CNTL_EN; | 4781 | val64 |= ADAPTER_CNTL_EN; |
4180 | writeq(val64, &bar0->adapter_control); | 4782 | writeq(val64, &bar0->adapter_control); |
4181 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 4783 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, |
4784 | subid)) { | ||
4182 | val64 = readq(&bar0->gpio_control); | 4785 | val64 = readq(&bar0->gpio_control); |
4183 | val64 |= GPIO_CTRL_GPIO_0; | 4786 | val64 |= GPIO_CTRL_GPIO_0; |
4184 | writeq(val64, &bar0->gpio_control); | 4787 | writeq(val64, &bar0->gpio_control); |
@@ -4187,20 +4790,24 @@ static void s2io_set_link(unsigned long data) | |||
4187 | val64 |= ADAPTER_LED_ON; | 4790 | val64 |= ADAPTER_LED_ON; |
4188 | writeq(val64, &bar0->adapter_control); | 4791 | writeq(val64, &bar0->adapter_control); |
4189 | } | 4792 | } |
4190 | val64 = readq(&bar0->adapter_status); | 4793 | if (s2io_link_fault_indication(nic) == |
4191 | if (!LINK_IS_UP(val64)) { | 4794 | MAC_RMAC_ERR_TIMER) { |
4192 | DBG_PRINT(ERR_DBG, "%s:", dev->name); | 4795 | val64 = readq(&bar0->adapter_status); |
4193 | DBG_PRINT(ERR_DBG, " Link down"); | 4796 | if (!LINK_IS_UP(val64)) { |
4194 | DBG_PRINT(ERR_DBG, "after "); | 4797 | DBG_PRINT(ERR_DBG, "%s:", dev->name); |
4195 | DBG_PRINT(ERR_DBG, "enabling "); | 4798 | DBG_PRINT(ERR_DBG, " Link down"); |
4196 | DBG_PRINT(ERR_DBG, "device \n"); | 4799 | DBG_PRINT(ERR_DBG, "after "); |
4800 | DBG_PRINT(ERR_DBG, "enabling "); | ||
4801 | DBG_PRINT(ERR_DBG, "device \n"); | ||
4802 | } | ||
4197 | } | 4803 | } |
4198 | if (nic->device_enabled_once == FALSE) { | 4804 | if (nic->device_enabled_once == FALSE) { |
4199 | nic->device_enabled_once = TRUE; | 4805 | nic->device_enabled_once = TRUE; |
4200 | } | 4806 | } |
4201 | s2io_link(nic, LINK_UP); | 4807 | s2io_link(nic, LINK_UP); |
4202 | } else { | 4808 | } else { |
4203 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(subid)) { | 4809 | if (CARDS_WITH_FAULTY_LINK_INDICATORS(nic->device_type, |
4810 | subid)) { | ||
4204 | val64 = readq(&bar0->gpio_control); | 4811 | val64 = readq(&bar0->gpio_control); |
4205 | val64 &= ~GPIO_CTRL_GPIO_0; | 4812 | val64 &= ~GPIO_CTRL_GPIO_0; |
4206 | writeq(val64, &bar0->gpio_control); | 4813 | writeq(val64, &bar0->gpio_control); |
@@ -4223,9 +4830,11 @@ static void s2io_card_down(nic_t * sp) | |||
4223 | unsigned long flags; | 4830 | unsigned long flags; |
4224 | register u64 val64 = 0; | 4831 | register u64 val64 = 0; |
4225 | 4832 | ||
4833 | del_timer_sync(&sp->alarm_timer); | ||
4226 | /* If s2io_set_link task is executing, wait till it completes. */ | 4834 | /* If s2io_set_link task is executing, wait till it completes. */ |
4227 | while (test_and_set_bit(0, &(sp->link_state))) | 4835 | while (test_and_set_bit(0, &(sp->link_state))) { |
4228 | msleep(50); | 4836 | msleep(50); |
4837 | } | ||
4229 | atomic_set(&sp->card_state, CARD_DOWN); | 4838 | atomic_set(&sp->card_state, CARD_DOWN); |
4230 | 4839 | ||
4231 | /* disable Tx and Rx traffic on the NIC */ | 4840 | /* disable Tx and Rx traffic on the NIC */ |
@@ -4237,7 +4846,7 @@ static void s2io_card_down(nic_t * sp) | |||
4237 | /* Check if the device is Quiescent and then Reset the NIC */ | 4846 | /* Check if the device is Quiescent and then Reset the NIC */ |
4238 | do { | 4847 | do { |
4239 | val64 = readq(&bar0->adapter_status); | 4848 | val64 = readq(&bar0->adapter_status); |
4240 | if (verify_xena_quiescence(val64, sp->device_enabled_once)) { | 4849 | if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { |
4241 | break; | 4850 | break; |
4242 | } | 4851 | } |
4243 | 4852 | ||
@@ -4251,14 +4860,27 @@ static void s2io_card_down(nic_t * sp) | |||
4251 | break; | 4860 | break; |
4252 | } | 4861 | } |
4253 | } while (1); | 4862 | } while (1); |
4254 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4255 | s2io_reset(sp); | 4863 | s2io_reset(sp); |
4256 | 4864 | ||
4257 | /* Free all unused Tx and Rx buffers */ | 4865 | /* Waiting till all Interrupt handlers are complete */ |
4866 | cnt = 0; | ||
4867 | do { | ||
4868 | msleep(10); | ||
4869 | if (!atomic_read(&sp->isr_cnt)) | ||
4870 | break; | ||
4871 | cnt++; | ||
4872 | } while(cnt < 5); | ||
4873 | |||
4874 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
4875 | /* Free all Tx buffers */ | ||
4258 | free_tx_buffers(sp); | 4876 | free_tx_buffers(sp); |
4877 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4878 | |||
4879 | /* Free all Rx buffers */ | ||
4880 | spin_lock_irqsave(&sp->rx_lock, flags); | ||
4259 | free_rx_buffers(sp); | 4881 | free_rx_buffers(sp); |
4882 | spin_unlock_irqrestore(&sp->rx_lock, flags); | ||
4260 | 4883 | ||
4261 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
4262 | clear_bit(0, &(sp->link_state)); | 4884 | clear_bit(0, &(sp->link_state)); |
4263 | } | 4885 | } |
4264 | 4886 | ||
@@ -4276,8 +4898,8 @@ static int s2io_card_up(nic_t * sp) | |||
4276 | return -ENODEV; | 4898 | return -ENODEV; |
4277 | } | 4899 | } |
4278 | 4900 | ||
4279 | /* | 4901 | /* |
4280 | * Initializing the Rx buffers. For now we are considering only 1 | 4902 | * Initializing the Rx buffers. For now we are considering only 1 |
4281 | * Rx ring and initializing buffers into 30 Rx blocks | 4903 | * Rx ring and initializing buffers into 30 Rx blocks |
4282 | */ | 4904 | */ |
4283 | mac_control = &sp->mac_control; | 4905 | mac_control = &sp->mac_control; |
@@ -4311,16 +4933,18 @@ static int s2io_card_up(nic_t * sp) | |||
4311 | return -ENODEV; | 4933 | return -ENODEV; |
4312 | } | 4934 | } |
4313 | 4935 | ||
4936 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); | ||
4937 | |||
4314 | atomic_set(&sp->card_state, CARD_UP); | 4938 | atomic_set(&sp->card_state, CARD_UP); |
4315 | return 0; | 4939 | return 0; |
4316 | } | 4940 | } |
4317 | 4941 | ||
4318 | /** | 4942 | /** |
4319 | * s2io_restart_nic - Resets the NIC. | 4943 | * s2io_restart_nic - Resets the NIC. |
4320 | * @data : long pointer to the device private structure | 4944 | * @data : long pointer to the device private structure |
4321 | * Description: | 4945 | * Description: |
4322 | * This function is scheduled to be run by the s2io_tx_watchdog | 4946 | * This function is scheduled to be run by the s2io_tx_watchdog |
4323 | * function after 0.5 secs to reset the NIC. The idea is to reduce | 4947 | * function after 0.5 secs to reset the NIC. The idea is to reduce |
4324 | * the run time of the watch dog routine which is run holding a | 4948 | * the run time of the watch dog routine which is run holding a |
4325 | * spin lock. | 4949 | * spin lock. |
4326 | */ | 4950 | */ |
@@ -4338,10 +4962,11 @@ static void s2io_restart_nic(unsigned long data) | |||
4338 | netif_wake_queue(dev); | 4962 | netif_wake_queue(dev); |
4339 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", | 4963 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", |
4340 | dev->name); | 4964 | dev->name); |
4965 | |||
4341 | } | 4966 | } |
4342 | 4967 | ||
4343 | /** | 4968 | /** |
4344 | * s2io_tx_watchdog - Watchdog for transmit side. | 4969 | * s2io_tx_watchdog - Watchdog for transmit side. |
4345 | * @dev : Pointer to net device structure | 4970 | * @dev : Pointer to net device structure |
4346 | * Description: | 4971 | * Description: |
4347 | * This function is triggered if the Tx Queue is stopped | 4972 | * This function is triggered if the Tx Queue is stopped |
@@ -4369,7 +4994,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
4369 | * @len : length of the packet | 4994 | * @len : length of the packet |
4370 | * @cksum : FCS checksum of the frame. | 4995 | * @cksum : FCS checksum of the frame. |
4371 | * @ring_no : the ring from which this RxD was extracted. | 4996 | * @ring_no : the ring from which this RxD was extracted. |
4372 | * Description: | 4997 | * Description: |
4373 | * This function is called by the Tx interrupt serivce routine to perform | 4998 | * This function is called by the Tx interrupt serivce routine to perform |
4374 | * some OS related operations on the SKB before passing it to the upper | 4999 | * some OS related operations on the SKB before passing it to the upper |
4375 | * layers. It mainly checks if the checksum is OK, if so adds it to the | 5000 | * layers. It mainly checks if the checksum is OK, if so adds it to the |
@@ -4379,35 +5004,68 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
4379 | * Return value: | 5004 | * Return value: |
4380 | * SUCCESS on success and -1 on failure. | 5005 | * SUCCESS on success and -1 on failure. |
4381 | */ | 5006 | */ |
4382 | #ifndef CONFIG_2BUFF_MODE | 5007 | static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) |
4383 | static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no) | ||
4384 | #else | ||
4385 | static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | ||
4386 | buffAdd_t * ba) | ||
4387 | #endif | ||
4388 | { | 5008 | { |
5009 | nic_t *sp = ring_data->nic; | ||
4389 | struct net_device *dev = (struct net_device *) sp->dev; | 5010 | struct net_device *dev = (struct net_device *) sp->dev; |
4390 | struct sk_buff *skb = | 5011 | struct sk_buff *skb = (struct sk_buff *) |
4391 | (struct sk_buff *) ((unsigned long) rxdp->Host_Control); | 5012 | ((unsigned long) rxdp->Host_Control); |
5013 | int ring_no = ring_data->ring_no; | ||
4392 | u16 l3_csum, l4_csum; | 5014 | u16 l3_csum, l4_csum; |
4393 | #ifdef CONFIG_2BUFF_MODE | 5015 | #ifdef CONFIG_2BUFF_MODE |
4394 | int buf0_len, buf2_len; | 5016 | int buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); |
5017 | int buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2); | ||
5018 | int get_block = ring_data->rx_curr_get_info.block_index; | ||
5019 | int get_off = ring_data->rx_curr_get_info.offset; | ||
5020 | buffAdd_t *ba = &ring_data->ba[get_block][get_off]; | ||
4395 | unsigned char *buff; | 5021 | unsigned char *buff; |
5022 | #else | ||
5023 | u16 len = (u16) ((RXD_GET_BUFFER0_SIZE(rxdp->Control_2)) >> 48);; | ||
4396 | #endif | 5024 | #endif |
5025 | skb->dev = dev; | ||
5026 | if (rxdp->Control_1 & RXD_T_CODE) { | ||
5027 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | ||
5028 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | ||
5029 | dev->name, err); | ||
5030 | dev_kfree_skb(skb); | ||
5031 | sp->stats.rx_crc_errors++; | ||
5032 | atomic_dec(&sp->rx_bufs_left[ring_no]); | ||
5033 | rxdp->Host_Control = 0; | ||
5034 | return 0; | ||
5035 | } | ||
4397 | 5036 | ||
4398 | l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); | 5037 | /* Updating statistics */ |
4399 | if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && (sp->rx_csum)) { | 5038 | rxdp->Host_Control = 0; |
5039 | sp->rx_pkt_count++; | ||
5040 | sp->stats.rx_packets++; | ||
5041 | #ifndef CONFIG_2BUFF_MODE | ||
5042 | sp->stats.rx_bytes += len; | ||
5043 | #else | ||
5044 | sp->stats.rx_bytes += buf0_len + buf2_len; | ||
5045 | #endif | ||
5046 | |||
5047 | #ifndef CONFIG_2BUFF_MODE | ||
5048 | skb_put(skb, len); | ||
5049 | #else | ||
5050 | buff = skb_push(skb, buf0_len); | ||
5051 | memcpy(buff, ba->ba_0, buf0_len); | ||
5052 | skb_put(skb, buf2_len); | ||
5053 | #endif | ||
5054 | |||
5055 | if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) && | ||
5056 | (sp->rx_csum)) { | ||
5057 | l3_csum = RXD_GET_L3_CKSUM(rxdp->Control_1); | ||
4400 | l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); | 5058 | l4_csum = RXD_GET_L4_CKSUM(rxdp->Control_1); |
4401 | if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) { | 5059 | if ((l3_csum == L3_CKSUM_OK) && (l4_csum == L4_CKSUM_OK)) { |
4402 | /* | 5060 | /* |
4403 | * NIC verifies if the Checksum of the received | 5061 | * NIC verifies if the Checksum of the received |
4404 | * frame is Ok or not and accordingly returns | 5062 | * frame is Ok or not and accordingly returns |
4405 | * a flag in the RxD. | 5063 | * a flag in the RxD. |
4406 | */ | 5064 | */ |
4407 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 5065 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
4408 | } else { | 5066 | } else { |
4409 | /* | 5067 | /* |
4410 | * Packet with erroneous checksum, let the | 5068 | * Packet with erroneous checksum, let the |
4411 | * upper layers deal with it. | 5069 | * upper layers deal with it. |
4412 | */ | 5070 | */ |
4413 | skb->ip_summed = CHECKSUM_NONE; | 5071 | skb->ip_summed = CHECKSUM_NONE; |
@@ -4416,44 +5074,26 @@ static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | |||
4416 | skb->ip_summed = CHECKSUM_NONE; | 5074 | skb->ip_summed = CHECKSUM_NONE; |
4417 | } | 5075 | } |
4418 | 5076 | ||
4419 | if (rxdp->Control_1 & RXD_T_CODE) { | ||
4420 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | ||
4421 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | ||
4422 | dev->name, err); | ||
4423 | } | ||
4424 | #ifdef CONFIG_2BUFF_MODE | ||
4425 | buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2); | ||
4426 | buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2); | ||
4427 | #endif | ||
4428 | |||
4429 | skb->dev = dev; | ||
4430 | #ifndef CONFIG_2BUFF_MODE | ||
4431 | skb_put(skb, len); | ||
4432 | skb->protocol = eth_type_trans(skb, dev); | ||
4433 | #else | ||
4434 | buff = skb_push(skb, buf0_len); | ||
4435 | memcpy(buff, ba->ba_0, buf0_len); | ||
4436 | skb_put(skb, buf2_len); | ||
4437 | skb->protocol = eth_type_trans(skb, dev); | 5077 | skb->protocol = eth_type_trans(skb, dev); |
4438 | #endif | ||
4439 | |||
4440 | #ifdef CONFIG_S2IO_NAPI | 5078 | #ifdef CONFIG_S2IO_NAPI |
4441 | netif_receive_skb(skb); | 5079 | if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { |
5080 | /* Queueing the vlan frame to the upper layer */ | ||
5081 | vlan_hwaccel_receive_skb(skb, sp->vlgrp, | ||
5082 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
5083 | } else { | ||
5084 | netif_receive_skb(skb); | ||
5085 | } | ||
4442 | #else | 5086 | #else |
4443 | netif_rx(skb); | 5087 | if (sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2)) { |
5088 | /* Queueing the vlan frame to the upper layer */ | ||
5089 | vlan_hwaccel_rx(skb, sp->vlgrp, | ||
5090 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
5091 | } else { | ||
5092 | netif_rx(skb); | ||
5093 | } | ||
4444 | #endif | 5094 | #endif |
4445 | |||
4446 | dev->last_rx = jiffies; | 5095 | dev->last_rx = jiffies; |
4447 | sp->rx_pkt_count++; | ||
4448 | sp->stats.rx_packets++; | ||
4449 | #ifndef CONFIG_2BUFF_MODE | ||
4450 | sp->stats.rx_bytes += len; | ||
4451 | #else | ||
4452 | sp->stats.rx_bytes += buf0_len + buf2_len; | ||
4453 | #endif | ||
4454 | |||
4455 | atomic_dec(&sp->rx_bufs_left[ring_no]); | 5096 | atomic_dec(&sp->rx_bufs_left[ring_no]); |
4456 | rxdp->Host_Control = 0; | ||
4457 | return SUCCESS; | 5097 | return SUCCESS; |
4458 | } | 5098 | } |
4459 | 5099 | ||
@@ -4464,13 +5104,13 @@ static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | |||
4464 | * @link : inidicates whether link is UP/DOWN. | 5104 | * @link : inidicates whether link is UP/DOWN. |
4465 | * Description: | 5105 | * Description: |
4466 | * This function stops/starts the Tx queue depending on whether the link | 5106 | * This function stops/starts the Tx queue depending on whether the link |
4467 | * status of the NIC is is down or up. This is called by the Alarm | 5107 | * status of the NIC is is down or up. This is called by the Alarm |
4468 | * interrupt handler whenever a link change interrupt comes up. | 5108 | * interrupt handler whenever a link change interrupt comes up. |
4469 | * Return value: | 5109 | * Return value: |
4470 | * void. | 5110 | * void. |
4471 | */ | 5111 | */ |
4472 | 5112 | ||
4473 | static void s2io_link(nic_t * sp, int link) | 5113 | void s2io_link(nic_t * sp, int link) |
4474 | { | 5114 | { |
4475 | struct net_device *dev = (struct net_device *) sp->dev; | 5115 | struct net_device *dev = (struct net_device *) sp->dev; |
4476 | 5116 | ||
@@ -4487,8 +5127,25 @@ static void s2io_link(nic_t * sp, int link) | |||
4487 | } | 5127 | } |
4488 | 5128 | ||
4489 | /** | 5129 | /** |
4490 | * s2io_init_pci -Initialization of PCI and PCI-X configuration registers . | 5130 | * get_xena_rev_id - to identify revision ID of xena. |
4491 | * @sp : private member of the device structure, which is a pointer to the | 5131 | * @pdev : PCI Dev structure |
5132 | * Description: | ||
5133 | * Function to identify the Revision ID of xena. | ||
5134 | * Return value: | ||
5135 | * returns the revision ID of the device. | ||
5136 | */ | ||
5137 | |||
5138 | int get_xena_rev_id(struct pci_dev *pdev) | ||
5139 | { | ||
5140 | u8 id = 0; | ||
5141 | int ret; | ||
5142 | ret = pci_read_config_byte(pdev, PCI_REVISION_ID, (u8 *) & id); | ||
5143 | return id; | ||
5144 | } | ||
5145 | |||
5146 | /** | ||
5147 | * s2io_init_pci -Initialization of PCI and PCI-X configuration registers . | ||
5148 | * @sp : private member of the device structure, which is a pointer to the | ||
4492 | * s2io_nic structure. | 5149 | * s2io_nic structure. |
4493 | * Description: | 5150 | * Description: |
4494 | * This function initializes a few of the PCI and PCI-X configuration registers | 5151 | * This function initializes a few of the PCI and PCI-X configuration registers |
@@ -4499,15 +5156,15 @@ static void s2io_link(nic_t * sp, int link) | |||
4499 | 5156 | ||
4500 | static void s2io_init_pci(nic_t * sp) | 5157 | static void s2io_init_pci(nic_t * sp) |
4501 | { | 5158 | { |
4502 | u16 pci_cmd = 0; | 5159 | u16 pci_cmd = 0, pcix_cmd = 0; |
4503 | 5160 | ||
4504 | /* Enable Data Parity Error Recovery in PCI-X command register. */ | 5161 | /* Enable Data Parity Error Recovery in PCI-X command register. */ |
4505 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5162 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4506 | &(sp->pcix_cmd)); | 5163 | &(pcix_cmd)); |
4507 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5164 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4508 | (sp->pcix_cmd | 1)); | 5165 | (pcix_cmd | 1)); |
4509 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5166 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4510 | &(sp->pcix_cmd)); | 5167 | &(pcix_cmd)); |
4511 | 5168 | ||
4512 | /* Set the PErr Response bit in PCI command register. */ | 5169 | /* Set the PErr Response bit in PCI command register. */ |
4513 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 5170 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
@@ -4515,53 +5172,43 @@ static void s2io_init_pci(nic_t * sp) | |||
4515 | (pci_cmd | PCI_COMMAND_PARITY)); | 5172 | (pci_cmd | PCI_COMMAND_PARITY)); |
4516 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 5173 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
4517 | 5174 | ||
4518 | /* Set MMRB count to 1024 in PCI-X Command register. */ | ||
4519 | sp->pcix_cmd &= 0xFFF3; | ||
4520 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, (sp->pcix_cmd | (0x1 << 2))); /* MMRBC 1K */ | ||
4521 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4522 | &(sp->pcix_cmd)); | ||
4523 | |||
4524 | /* Setting Maximum outstanding splits based on system type. */ | ||
4525 | sp->pcix_cmd &= 0xFF8F; | ||
4526 | |||
4527 | sp->pcix_cmd |= XENA_MAX_OUTSTANDING_SPLITS(0x1); /* 2 splits. */ | ||
4528 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4529 | sp->pcix_cmd); | ||
4530 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
4531 | &(sp->pcix_cmd)); | ||
4532 | /* Forcibly disabling relaxed ordering capability of the card. */ | 5175 | /* Forcibly disabling relaxed ordering capability of the card. */ |
4533 | sp->pcix_cmd &= 0xfffd; | 5176 | pcix_cmd &= 0xfffd; |
4534 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5177 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4535 | sp->pcix_cmd); | 5178 | pcix_cmd); |
4536 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | 5179 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, |
4537 | &(sp->pcix_cmd)); | 5180 | &(pcix_cmd)); |
4538 | } | 5181 | } |
4539 | 5182 | ||
4540 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | 5183 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); |
4541 | MODULE_LICENSE("GPL"); | 5184 | MODULE_LICENSE("GPL"); |
4542 | module_param(tx_fifo_num, int, 0); | 5185 | module_param(tx_fifo_num, int, 0); |
4543 | module_param_array(tx_fifo_len, int, NULL, 0); | ||
4544 | module_param(rx_ring_num, int, 0); | 5186 | module_param(rx_ring_num, int, 0); |
4545 | module_param_array(rx_ring_sz, int, NULL, 0); | 5187 | module_param_array(tx_fifo_len, uint, NULL, 0); |
4546 | module_param(Stats_refresh_time, int, 0); | 5188 | module_param_array(rx_ring_sz, uint, NULL, 0); |
5189 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
5190 | module_param(use_continuous_tx_intrs, int, 1); | ||
4547 | module_param(rmac_pause_time, int, 0); | 5191 | module_param(rmac_pause_time, int, 0); |
4548 | module_param(mc_pause_threshold_q0q3, int, 0); | 5192 | module_param(mc_pause_threshold_q0q3, int, 0); |
4549 | module_param(mc_pause_threshold_q4q7, int, 0); | 5193 | module_param(mc_pause_threshold_q4q7, int, 0); |
4550 | module_param(shared_splits, int, 0); | 5194 | module_param(shared_splits, int, 0); |
4551 | module_param(tmac_util_period, int, 0); | 5195 | module_param(tmac_util_period, int, 0); |
4552 | module_param(rmac_util_period, int, 0); | 5196 | module_param(rmac_util_period, int, 0); |
5197 | module_param(bimodal, bool, 0); | ||
4553 | #ifndef CONFIG_S2IO_NAPI | 5198 | #ifndef CONFIG_S2IO_NAPI |
4554 | module_param(indicate_max_pkts, int, 0); | 5199 | module_param(indicate_max_pkts, int, 0); |
4555 | #endif | 5200 | #endif |
5201 | module_param(rxsync_frequency, int, 0); | ||
5202 | |||
4556 | /** | 5203 | /** |
4557 | * s2io_init_nic - Initialization of the adapter . | 5204 | * s2io_init_nic - Initialization of the adapter . |
4558 | * @pdev : structure containing the PCI related information of the device. | 5205 | * @pdev : structure containing the PCI related information of the device. |
4559 | * @pre: List of PCI devices supported by the driver listed in s2io_tbl. | 5206 | * @pre: List of PCI devices supported by the driver listed in s2io_tbl. |
4560 | * Description: | 5207 | * Description: |
4561 | * The function initializes an adapter identified by the pci_dec structure. | 5208 | * The function initializes an adapter identified by the pci_dec structure. |
4562 | * All OS related initialization including memory and device structure and | 5209 | * All OS related initialization including memory and device structure and |
4563 | * initlaization of the device private variable is done. Also the swapper | 5210 | * initlaization of the device private variable is done. Also the swapper |
4564 | * control register is initialized to enable read and write into the I/O | 5211 | * control register is initialized to enable read and write into the I/O |
4565 | * registers of the device. | 5212 | * registers of the device. |
4566 | * Return value: | 5213 | * Return value: |
4567 | * returns 0 on success and negative on failure. | 5214 | * returns 0 on success and negative on failure. |
@@ -4572,7 +5219,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4572 | { | 5219 | { |
4573 | nic_t *sp; | 5220 | nic_t *sp; |
4574 | struct net_device *dev; | 5221 | struct net_device *dev; |
4575 | char *dev_name = "S2IO 10GE NIC"; | ||
4576 | int i, j, ret; | 5222 | int i, j, ret; |
4577 | int dma_flag = FALSE; | 5223 | int dma_flag = FALSE; |
4578 | u32 mac_up, mac_down; | 5224 | u32 mac_up, mac_down; |
@@ -4581,10 +5227,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4581 | u16 subid; | 5227 | u16 subid; |
4582 | mac_info_t *mac_control; | 5228 | mac_info_t *mac_control; |
4583 | struct config_param *config; | 5229 | struct config_param *config; |
5230 | int mode; | ||
4584 | 5231 | ||
4585 | 5232 | #ifdef CONFIG_S2IO_NAPI | |
4586 | DBG_PRINT(ERR_DBG, "Loading S2IO driver with %s\n", | 5233 | DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); |
4587 | s2io_driver_version); | 5234 | #endif |
4588 | 5235 | ||
4589 | if ((ret = pci_enable_device(pdev))) { | 5236 | if ((ret = pci_enable_device(pdev))) { |
4590 | DBG_PRINT(ERR_DBG, | 5237 | DBG_PRINT(ERR_DBG, |
@@ -4595,7 +5242,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4595 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | 5242 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
4596 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); | 5243 | DBG_PRINT(INIT_DBG, "s2io_init_nic: Using 64bit DMA\n"); |
4597 | dma_flag = TRUE; | 5244 | dma_flag = TRUE; |
4598 | |||
4599 | if (pci_set_consistent_dma_mask | 5245 | if (pci_set_consistent_dma_mask |
4600 | (pdev, DMA_64BIT_MASK)) { | 5246 | (pdev, DMA_64BIT_MASK)) { |
4601 | DBG_PRINT(ERR_DBG, | 5247 | DBG_PRINT(ERR_DBG, |
@@ -4635,34 +5281,41 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4635 | memset(sp, 0, sizeof(nic_t)); | 5281 | memset(sp, 0, sizeof(nic_t)); |
4636 | sp->dev = dev; | 5282 | sp->dev = dev; |
4637 | sp->pdev = pdev; | 5283 | sp->pdev = pdev; |
4638 | sp->vendor_id = pdev->vendor; | ||
4639 | sp->device_id = pdev->device; | ||
4640 | sp->high_dma_flag = dma_flag; | 5284 | sp->high_dma_flag = dma_flag; |
4641 | sp->irq = pdev->irq; | ||
4642 | sp->device_enabled_once = FALSE; | 5285 | sp->device_enabled_once = FALSE; |
4643 | strcpy(sp->name, dev_name); | 5286 | |
5287 | if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) || | ||
5288 | (pdev->device == PCI_DEVICE_ID_HERC_UNI)) | ||
5289 | sp->device_type = XFRAME_II_DEVICE; | ||
5290 | else | ||
5291 | sp->device_type = XFRAME_I_DEVICE; | ||
4644 | 5292 | ||
4645 | /* Initialize some PCI/PCI-X fields of the NIC. */ | 5293 | /* Initialize some PCI/PCI-X fields of the NIC. */ |
4646 | s2io_init_pci(sp); | 5294 | s2io_init_pci(sp); |
4647 | 5295 | ||
4648 | /* | 5296 | /* |
4649 | * Setting the device configuration parameters. | 5297 | * Setting the device configuration parameters. |
4650 | * Most of these parameters can be specified by the user during | 5298 | * Most of these parameters can be specified by the user during |
4651 | * module insertion as they are module loadable parameters. If | 5299 | * module insertion as they are module loadable parameters. If |
4652 | * these parameters are not not specified during load time, they | 5300 | * these parameters are not not specified during load time, they |
4653 | * are initialized with default values. | 5301 | * are initialized with default values. |
4654 | */ | 5302 | */ |
4655 | mac_control = &sp->mac_control; | 5303 | mac_control = &sp->mac_control; |
4656 | config = &sp->config; | 5304 | config = &sp->config; |
4657 | 5305 | ||
4658 | /* Tx side parameters. */ | 5306 | /* Tx side parameters. */ |
4659 | tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ | 5307 | if (tx_fifo_len[0] == 0) |
5308 | tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ | ||
4660 | config->tx_fifo_num = tx_fifo_num; | 5309 | config->tx_fifo_num = tx_fifo_num; |
4661 | for (i = 0; i < MAX_TX_FIFOS; i++) { | 5310 | for (i = 0; i < MAX_TX_FIFOS; i++) { |
4662 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; | 5311 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; |
4663 | config->tx_cfg[i].fifo_priority = i; | 5312 | config->tx_cfg[i].fifo_priority = i; |
4664 | } | 5313 | } |
4665 | 5314 | ||
5315 | /* mapping the QoS priority to the configured fifos */ | ||
5316 | for (i = 0; i < MAX_TX_FIFOS; i++) | ||
5317 | config->fifo_mapping[i] = fifo_map[config->tx_fifo_num][i]; | ||
5318 | |||
4666 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; | 5319 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; |
4667 | for (i = 0; i < config->tx_fifo_num; i++) { | 5320 | for (i = 0; i < config->tx_fifo_num; i++) { |
4668 | config->tx_cfg[i].f_no_snoop = | 5321 | config->tx_cfg[i].f_no_snoop = |
@@ -4675,7 +5328,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4675 | config->max_txds = MAX_SKB_FRAGS; | 5328 | config->max_txds = MAX_SKB_FRAGS; |
4676 | 5329 | ||
4677 | /* Rx side parameters. */ | 5330 | /* Rx side parameters. */ |
4678 | rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ | 5331 | if (rx_ring_sz[0] == 0) |
5332 | rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ | ||
4679 | config->rx_ring_num = rx_ring_num; | 5333 | config->rx_ring_num = rx_ring_num; |
4680 | for (i = 0; i < MAX_RX_RINGS; i++) { | 5334 | for (i = 0; i < MAX_RX_RINGS; i++) { |
4681 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * | 5335 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * |
@@ -4699,10 +5353,13 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4699 | for (i = 0; i < config->rx_ring_num; i++) | 5353 | for (i = 0; i < config->rx_ring_num; i++) |
4700 | atomic_set(&sp->rx_bufs_left[i], 0); | 5354 | atomic_set(&sp->rx_bufs_left[i], 0); |
4701 | 5355 | ||
5356 | /* Initialize the number of ISRs currently running */ | ||
5357 | atomic_set(&sp->isr_cnt, 0); | ||
5358 | |||
4702 | /* initialize the shared memory used by the NIC and the host */ | 5359 | /* initialize the shared memory used by the NIC and the host */ |
4703 | if (init_shared_mem(sp)) { | 5360 | if (init_shared_mem(sp)) { |
4704 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 5361 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
4705 | dev->name); | 5362 | __FUNCTION__); |
4706 | ret = -ENOMEM; | 5363 | ret = -ENOMEM; |
4707 | goto mem_alloc_failed; | 5364 | goto mem_alloc_failed; |
4708 | } | 5365 | } |
@@ -4743,13 +5400,17 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4743 | dev->do_ioctl = &s2io_ioctl; | 5400 | dev->do_ioctl = &s2io_ioctl; |
4744 | dev->change_mtu = &s2io_change_mtu; | 5401 | dev->change_mtu = &s2io_change_mtu; |
4745 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 5402 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
5403 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | ||
5404 | dev->vlan_rx_register = s2io_vlan_rx_register; | ||
5405 | dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid; | ||
5406 | |||
4746 | /* | 5407 | /* |
4747 | * will use eth_mac_addr() for dev->set_mac_address | 5408 | * will use eth_mac_addr() for dev->set_mac_address |
4748 | * mac address will be set every time dev->open() is called | 5409 | * mac address will be set every time dev->open() is called |
4749 | */ | 5410 | */ |
4750 | #ifdef CONFIG_S2IO_NAPI | 5411 | #if defined(CONFIG_S2IO_NAPI) |
4751 | dev->poll = s2io_poll; | 5412 | dev->poll = s2io_poll; |
4752 | dev->weight = 90; | 5413 | dev->weight = 32; |
4753 | #endif | 5414 | #endif |
4754 | 5415 | ||
4755 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; | 5416 | dev->features |= NETIF_F_SG | NETIF_F_IP_CSUM; |
@@ -4776,22 +5437,28 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4776 | goto set_swap_failed; | 5437 | goto set_swap_failed; |
4777 | } | 5438 | } |
4778 | 5439 | ||
4779 | /* Fix for all "FFs" MAC address problems observed on Alpha platforms */ | 5440 | /* Verify if the Herc works on the slot its placed into */ |
4780 | fix_mac_address(sp); | 5441 | if (sp->device_type & XFRAME_II_DEVICE) { |
4781 | s2io_reset(sp); | 5442 | mode = s2io_verify_pci_mode(sp); |
5443 | if (mode < 0) { | ||
5444 | DBG_PRINT(ERR_DBG, "%s: ", __FUNCTION__); | ||
5445 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n"); | ||
5446 | ret = -EBADSLT; | ||
5447 | goto set_swap_failed; | ||
5448 | } | ||
5449 | } | ||
4782 | 5450 | ||
4783 | /* | 5451 | /* Not needed for Herc */ |
4784 | * Setting swapper control on the NIC, so the MAC address can be read. | 5452 | if (sp->device_type & XFRAME_I_DEVICE) { |
4785 | */ | 5453 | /* |
4786 | if (s2io_set_swapper(sp)) { | 5454 | * Fix for all "FFs" MAC address problems observed on |
4787 | DBG_PRINT(ERR_DBG, | 5455 | * Alpha platforms |
4788 | "%s: S2IO: swapper settings are wrong\n", | 5456 | */ |
4789 | dev->name); | 5457 | fix_mac_address(sp); |
4790 | ret = -EAGAIN; | 5458 | s2io_reset(sp); |
4791 | goto set_swap_failed; | ||
4792 | } | 5459 | } |
4793 | 5460 | ||
4794 | /* | 5461 | /* |
4795 | * MAC address initialization. | 5462 | * MAC address initialization. |
4796 | * For now only one mac address will be read and used. | 5463 | * For now only one mac address will be read and used. |
4797 | */ | 5464 | */ |
@@ -4814,37 +5481,28 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4814 | sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16); | 5481 | sp->def_mac_addr[0].mac_addr[5] = (u8) (mac_down >> 16); |
4815 | sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24); | 5482 | sp->def_mac_addr[0].mac_addr[4] = (u8) (mac_down >> 24); |
4816 | 5483 | ||
4817 | DBG_PRINT(INIT_DBG, | ||
4818 | "DEFAULT MAC ADDR:0x%02x-%02x-%02x-%02x-%02x-%02x\n", | ||
4819 | sp->def_mac_addr[0].mac_addr[0], | ||
4820 | sp->def_mac_addr[0].mac_addr[1], | ||
4821 | sp->def_mac_addr[0].mac_addr[2], | ||
4822 | sp->def_mac_addr[0].mac_addr[3], | ||
4823 | sp->def_mac_addr[0].mac_addr[4], | ||
4824 | sp->def_mac_addr[0].mac_addr[5]); | ||
4825 | |||
4826 | /* Set the factory defined MAC address initially */ | 5484 | /* Set the factory defined MAC address initially */ |
4827 | dev->addr_len = ETH_ALEN; | 5485 | dev->addr_len = ETH_ALEN; |
4828 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 5486 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
4829 | 5487 | ||
4830 | /* | 5488 | /* |
4831 | * Initialize the tasklet status and link state flags | 5489 | * Initialize the tasklet status and link state flags |
4832 | * and the card statte parameter | 5490 | * and the card state parameter |
4833 | */ | 5491 | */ |
4834 | atomic_set(&(sp->card_state), 0); | 5492 | atomic_set(&(sp->card_state), 0); |
4835 | sp->tasklet_status = 0; | 5493 | sp->tasklet_status = 0; |
4836 | sp->link_state = 0; | 5494 | sp->link_state = 0; |
4837 | 5495 | ||
4838 | |||
4839 | /* Initialize spinlocks */ | 5496 | /* Initialize spinlocks */ |
4840 | spin_lock_init(&sp->tx_lock); | 5497 | spin_lock_init(&sp->tx_lock); |
4841 | #ifndef CONFIG_S2IO_NAPI | 5498 | #ifndef CONFIG_S2IO_NAPI |
4842 | spin_lock_init(&sp->put_lock); | 5499 | spin_lock_init(&sp->put_lock); |
4843 | #endif | 5500 | #endif |
5501 | spin_lock_init(&sp->rx_lock); | ||
4844 | 5502 | ||
4845 | /* | 5503 | /* |
4846 | * SXE-002: Configure link and activity LED to init state | 5504 | * SXE-002: Configure link and activity LED to init state |
4847 | * on driver load. | 5505 | * on driver load. |
4848 | */ | 5506 | */ |
4849 | subid = sp->pdev->subsystem_device; | 5507 | subid = sp->pdev->subsystem_device; |
4850 | if ((subid & 0xFF) >= 0x07) { | 5508 | if ((subid & 0xFF) >= 0x07) { |
@@ -4864,13 +5522,61 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4864 | goto register_failed; | 5522 | goto register_failed; |
4865 | } | 5523 | } |
4866 | 5524 | ||
4867 | /* | 5525 | if (sp->device_type & XFRAME_II_DEVICE) { |
4868 | * Make Link state as off at this point, when the Link change | 5526 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", |
4869 | * interrupt comes the state will be automatically changed to | 5527 | dev->name); |
5528 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | ||
5529 | get_xena_rev_id(sp->pdev), | ||
5530 | s2io_driver_version); | ||
5531 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
5532 | sp->def_mac_addr[0].mac_addr[0], | ||
5533 | sp->def_mac_addr[0].mac_addr[1], | ||
5534 | sp->def_mac_addr[0].mac_addr[2], | ||
5535 | sp->def_mac_addr[0].mac_addr[3], | ||
5536 | sp->def_mac_addr[0].mac_addr[4], | ||
5537 | sp->def_mac_addr[0].mac_addr[5]); | ||
5538 | mode = s2io_print_pci_mode(sp); | ||
5539 | if (mode < 0) { | ||
5540 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode "); | ||
5541 | ret = -EBADSLT; | ||
5542 | goto set_swap_failed; | ||
5543 | } | ||
5544 | } else { | ||
5545 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", | ||
5546 | dev->name); | ||
5547 | DBG_PRINT(ERR_DBG, "(rev %d), Driver %s\n", | ||
5548 | get_xena_rev_id(sp->pdev), | ||
5549 | s2io_driver_version); | ||
5550 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
5551 | sp->def_mac_addr[0].mac_addr[0], | ||
5552 | sp->def_mac_addr[0].mac_addr[1], | ||
5553 | sp->def_mac_addr[0].mac_addr[2], | ||
5554 | sp->def_mac_addr[0].mac_addr[3], | ||
5555 | sp->def_mac_addr[0].mac_addr[4], | ||
5556 | sp->def_mac_addr[0].mac_addr[5]); | ||
5557 | } | ||
5558 | |||
5559 | /* Initialize device name */ | ||
5560 | strcpy(sp->name, dev->name); | ||
5561 | if (sp->device_type & XFRAME_II_DEVICE) | ||
5562 | strcat(sp->name, ": Neterion Xframe II 10GbE adapter"); | ||
5563 | else | ||
5564 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); | ||
5565 | |||
5566 | /* Initialize bimodal Interrupts */ | ||
5567 | sp->config.bimodal = bimodal; | ||
5568 | if (!(sp->device_type & XFRAME_II_DEVICE) && bimodal) { | ||
5569 | sp->config.bimodal = 0; | ||
5570 | DBG_PRINT(ERR_DBG,"%s:Bimodal intr not supported by Xframe I\n", | ||
5571 | dev->name); | ||
5572 | } | ||
5573 | |||
5574 | /* | ||
5575 | * Make Link state as off at this point, when the Link change | ||
5576 | * interrupt comes the state will be automatically changed to | ||
4870 | * the right state. | 5577 | * the right state. |
4871 | */ | 5578 | */ |
4872 | netif_carrier_off(dev); | 5579 | netif_carrier_off(dev); |
4873 | sp->last_link_state = LINK_DOWN; | ||
4874 | 5580 | ||
4875 | return 0; | 5581 | return 0; |
4876 | 5582 | ||
@@ -4891,11 +5597,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
4891 | } | 5597 | } |
4892 | 5598 | ||
4893 | /** | 5599 | /** |
4894 | * s2io_rem_nic - Free the PCI device | 5600 | * s2io_rem_nic - Free the PCI device |
4895 | * @pdev: structure containing the PCI related information of the device. | 5601 | * @pdev: structure containing the PCI related information of the device. |
4896 | * Description: This function is called by the Pci subsystem to release a | 5602 | * Description: This function is called by the Pci subsystem to release a |
4897 | * PCI device and free up all resource held up by the device. This could | 5603 | * PCI device and free up all resource held up by the device. This could |
4898 | * be in response to a Hot plug event or when the driver is to be removed | 5604 | * be in response to a Hot plug event or when the driver is to be removed |
4899 | * from memory. | 5605 | * from memory. |
4900 | */ | 5606 | */ |
4901 | 5607 | ||
@@ -4919,7 +5625,6 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) | |||
4919 | pci_disable_device(pdev); | 5625 | pci_disable_device(pdev); |
4920 | pci_release_regions(pdev); | 5626 | pci_release_regions(pdev); |
4921 | pci_set_drvdata(pdev, NULL); | 5627 | pci_set_drvdata(pdev, NULL); |
4922 | |||
4923 | free_netdev(dev); | 5628 | free_netdev(dev); |
4924 | } | 5629 | } |
4925 | 5630 | ||
@@ -4935,11 +5640,11 @@ int __init s2io_starter(void) | |||
4935 | } | 5640 | } |
4936 | 5641 | ||
4937 | /** | 5642 | /** |
4938 | * s2io_closer - Cleanup routine for the driver | 5643 | * s2io_closer - Cleanup routine for the driver |
4939 | * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. | 5644 | * Description: This function is the cleanup routine for the driver. It unregist * ers the driver. |
4940 | */ | 5645 | */ |
4941 | 5646 | ||
4942 | static void s2io_closer(void) | 5647 | void s2io_closer(void) |
4943 | { | 5648 | { |
4944 | pci_unregister_driver(&s2io_driver); | 5649 | pci_unregister_driver(&s2io_driver); |
4945 | DBG_PRINT(INIT_DBG, "cleanup done\n"); | 5650 | DBG_PRINT(INIT_DBG, "cleanup done\n"); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 1711c8c3dc99..5d9270730ca2 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -31,6 +31,9 @@ | |||
31 | #define SUCCESS 0 | 31 | #define SUCCESS 0 |
32 | #define FAILURE -1 | 32 | #define FAILURE -1 |
33 | 33 | ||
34 | /* Maximum time to flicker LED when asked to identify NIC using ethtool */ | ||
35 | #define MAX_FLICKER_TIME 60000 /* 60 Secs */ | ||
36 | |||
34 | /* Maximum outstanding splits to be configured into xena. */ | 37 | /* Maximum outstanding splits to be configured into xena. */ |
35 | typedef enum xena_max_outstanding_splits { | 38 | typedef enum xena_max_outstanding_splits { |
36 | XENA_ONE_SPLIT_TRANSACTION = 0, | 39 | XENA_ONE_SPLIT_TRANSACTION = 0, |
@@ -45,10 +48,10 @@ typedef enum xena_max_outstanding_splits { | |||
45 | #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) | 48 | #define XENA_MAX_OUTSTANDING_SPLITS(n) (n << 4) |
46 | 49 | ||
47 | /* OS concerned variables and constants */ | 50 | /* OS concerned variables and constants */ |
48 | #define WATCH_DOG_TIMEOUT 5*HZ | 51 | #define WATCH_DOG_TIMEOUT 15*HZ |
49 | #define EFILL 0x1234 | 52 | #define EFILL 0x1234 |
50 | #define ALIGN_SIZE 127 | 53 | #define ALIGN_SIZE 127 |
51 | #define PCIX_COMMAND_REGISTER 0x62 | 54 | #define PCIX_COMMAND_REGISTER 0x62 |
52 | 55 | ||
53 | /* | 56 | /* |
54 | * Debug related variables. | 57 | * Debug related variables. |
@@ -61,7 +64,7 @@ typedef enum xena_max_outstanding_splits { | |||
61 | #define INTR_DBG 4 | 64 | #define INTR_DBG 4 |
62 | 65 | ||
63 | /* Global variable that defines the present debug level of the driver. */ | 66 | /* Global variable that defines the present debug level of the driver. */ |
64 | static int debug_level = ERR_DBG; /* Default level. */ | 67 | int debug_level = ERR_DBG; /* Default level. */ |
65 | 68 | ||
66 | /* DEBUG message print. */ | 69 | /* DEBUG message print. */ |
67 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) | 70 | #define DBG_PRINT(dbg_level, args...) if(!(debug_level<dbg_level)) printk(args) |
@@ -71,6 +74,12 @@ static int debug_level = ERR_DBG; /* Default level. */ | |||
71 | #define L4_CKSUM_OK 0xFFFF | 74 | #define L4_CKSUM_OK 0xFFFF |
72 | #define S2IO_JUMBO_SIZE 9600 | 75 | #define S2IO_JUMBO_SIZE 9600 |
73 | 76 | ||
77 | /* Driver statistics maintained by driver */ | ||
78 | typedef struct { | ||
79 | unsigned long long single_ecc_errs; | ||
80 | unsigned long long double_ecc_errs; | ||
81 | } swStat_t; | ||
82 | |||
74 | /* The statistics block of Xena */ | 83 | /* The statistics block of Xena */ |
75 | typedef struct stat_block { | 84 | typedef struct stat_block { |
76 | /* Tx MAC statistics counters. */ | 85 | /* Tx MAC statistics counters. */ |
@@ -186,12 +195,90 @@ typedef struct stat_block { | |||
186 | u32 rxd_rd_cnt; | 195 | u32 rxd_rd_cnt; |
187 | u32 rxf_wr_cnt; | 196 | u32 rxf_wr_cnt; |
188 | u32 txf_rd_cnt; | 197 | u32 txf_rd_cnt; |
198 | |||
199 | /* Tx MAC statistics overflow counters. */ | ||
200 | u32 tmac_data_octets_oflow; | ||
201 | u32 tmac_frms_oflow; | ||
202 | u32 tmac_bcst_frms_oflow; | ||
203 | u32 tmac_mcst_frms_oflow; | ||
204 | u32 tmac_ucst_frms_oflow; | ||
205 | u32 tmac_ttl_octets_oflow; | ||
206 | u32 tmac_any_err_frms_oflow; | ||
207 | u32 tmac_nucst_frms_oflow; | ||
208 | u64 tmac_vlan_frms; | ||
209 | u32 tmac_drop_ip_oflow; | ||
210 | u32 tmac_vld_ip_oflow; | ||
211 | u32 tmac_rst_tcp_oflow; | ||
212 | u32 tmac_icmp_oflow; | ||
213 | u32 tpa_unknown_protocol; | ||
214 | u32 tmac_udp_oflow; | ||
215 | u32 reserved_10; | ||
216 | u32 tpa_parse_failure; | ||
217 | |||
218 | /* Rx MAC Statistics overflow counters. */ | ||
219 | u32 rmac_data_octets_oflow; | ||
220 | u32 rmac_vld_frms_oflow; | ||
221 | u32 rmac_vld_bcst_frms_oflow; | ||
222 | u32 rmac_vld_mcst_frms_oflow; | ||
223 | u32 rmac_accepted_ucst_frms_oflow; | ||
224 | u32 rmac_ttl_octets_oflow; | ||
225 | u32 rmac_discarded_frms_oflow; | ||
226 | u32 rmac_accepted_nucst_frms_oflow; | ||
227 | u32 rmac_usized_frms_oflow; | ||
228 | u32 rmac_drop_events_oflow; | ||
229 | u32 rmac_frag_frms_oflow; | ||
230 | u32 rmac_osized_frms_oflow; | ||
231 | u32 rmac_ip_oflow; | ||
232 | u32 rmac_jabber_frms_oflow; | ||
233 | u32 rmac_icmp_oflow; | ||
234 | u32 rmac_drop_ip_oflow; | ||
235 | u32 rmac_err_drp_udp_oflow; | ||
236 | u32 rmac_udp_oflow; | ||
237 | u32 reserved_11; | ||
238 | u32 rmac_pause_cnt_oflow; | ||
239 | u64 rmac_ttl_1519_4095_frms; | ||
240 | u64 rmac_ttl_4096_8191_frms; | ||
241 | u64 rmac_ttl_8192_max_frms; | ||
242 | u64 rmac_ttl_gt_max_frms; | ||
243 | u64 rmac_osized_alt_frms; | ||
244 | u64 rmac_jabber_alt_frms; | ||
245 | u64 rmac_gt_max_alt_frms; | ||
246 | u64 rmac_vlan_frms; | ||
247 | u32 rmac_len_discard; | ||
248 | u32 rmac_fcs_discard; | ||
249 | u32 rmac_pf_discard; | ||
250 | u32 rmac_da_discard; | ||
251 | u32 rmac_red_discard; | ||
252 | u32 rmac_rts_discard; | ||
253 | u32 reserved_12; | ||
254 | u32 rmac_ingm_full_discard; | ||
255 | u32 reserved_13; | ||
256 | u32 rmac_accepted_ip_oflow; | ||
257 | u32 reserved_14; | ||
258 | u32 link_fault_cnt; | ||
259 | swStat_t sw_stat; | ||
189 | } StatInfo_t; | 260 | } StatInfo_t; |
190 | 261 | ||
191 | /* Structures representing different init time configuration | 262 | /* |
263 | * Structures representing different init time configuration | ||
192 | * parameters of the NIC. | 264 | * parameters of the NIC. |
193 | */ | 265 | */ |
194 | 266 | ||
267 | #define MAX_TX_FIFOS 8 | ||
268 | #define MAX_RX_RINGS 8 | ||
269 | |||
270 | /* FIFO mappings for all possible number of fifos configured */ | ||
271 | int fifo_map[][MAX_TX_FIFOS] = { | ||
272 | {0, 0, 0, 0, 0, 0, 0, 0}, | ||
273 | {0, 0, 0, 0, 1, 1, 1, 1}, | ||
274 | {0, 0, 0, 1, 1, 1, 2, 2}, | ||
275 | {0, 0, 1, 1, 2, 2, 3, 3}, | ||
276 | {0, 0, 1, 1, 2, 2, 3, 4}, | ||
277 | {0, 0, 1, 1, 2, 3, 4, 5}, | ||
278 | {0, 0, 1, 2, 3, 4, 5, 6}, | ||
279 | {0, 1, 2, 3, 4, 5, 6, 7}, | ||
280 | }; | ||
281 | |||
195 | /* Maintains Per FIFO related information. */ | 282 | /* Maintains Per FIFO related information. */ |
196 | typedef struct tx_fifo_config { | 283 | typedef struct tx_fifo_config { |
197 | #define MAX_AVAILABLE_TXDS 8192 | 284 | #define MAX_AVAILABLE_TXDS 8192 |
@@ -237,14 +324,14 @@ typedef struct rx_ring_config { | |||
237 | #define NO_SNOOP_RXD_BUFFER 0x02 | 324 | #define NO_SNOOP_RXD_BUFFER 0x02 |
238 | } rx_ring_config_t; | 325 | } rx_ring_config_t; |
239 | 326 | ||
240 | /* This structure provides contains values of the tunable parameters | 327 | /* This structure provides contains values of the tunable parameters |
241 | * of the H/W | 328 | * of the H/W |
242 | */ | 329 | */ |
243 | struct config_param { | 330 | struct config_param { |
244 | /* Tx Side */ | 331 | /* Tx Side */ |
245 | u32 tx_fifo_num; /*Number of Tx FIFOs */ | 332 | u32 tx_fifo_num; /*Number of Tx FIFOs */ |
246 | #define MAX_TX_FIFOS 8 | ||
247 | 333 | ||
334 | u8 fifo_mapping[MAX_TX_FIFOS]; | ||
248 | tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ | 335 | tx_fifo_config_t tx_cfg[MAX_TX_FIFOS]; /*Per-Tx FIFO config */ |
249 | u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ | 336 | u32 max_txds; /*Max no. of Tx buffer descriptor per TxDL */ |
250 | u64 tx_intr_type; | 337 | u64 tx_intr_type; |
@@ -252,10 +339,10 @@ struct config_param { | |||
252 | 339 | ||
253 | /* Rx Side */ | 340 | /* Rx Side */ |
254 | u32 rx_ring_num; /*Number of receive rings */ | 341 | u32 rx_ring_num; /*Number of receive rings */ |
255 | #define MAX_RX_RINGS 8 | ||
256 | #define MAX_RX_BLOCKS_PER_RING 150 | 342 | #define MAX_RX_BLOCKS_PER_RING 150 |
257 | 343 | ||
258 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ | 344 | rx_ring_config_t rx_cfg[MAX_RX_RINGS]; /*Per-Rx Ring config */ |
345 | u8 bimodal; /*Flag for setting bimodal interrupts*/ | ||
259 | 346 | ||
260 | #define HEADER_ETHERNET_II_802_3_SIZE 14 | 347 | #define HEADER_ETHERNET_II_802_3_SIZE 14 |
261 | #define HEADER_802_2_SIZE 3 | 348 | #define HEADER_802_2_SIZE 3 |
@@ -269,6 +356,7 @@ struct config_param { | |||
269 | #define MAX_PYLD_JUMBO 9600 | 356 | #define MAX_PYLD_JUMBO 9600 |
270 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) | 357 | #define MAX_MTU_JUMBO (MAX_PYLD_JUMBO+18) |
271 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) | 358 | #define MAX_MTU_JUMBO_VLAN (MAX_PYLD_JUMBO+22) |
359 | u16 bus_speed; | ||
272 | }; | 360 | }; |
273 | 361 | ||
274 | /* Structure representing MAC Addrs */ | 362 | /* Structure representing MAC Addrs */ |
@@ -277,7 +365,7 @@ typedef struct mac_addr { | |||
277 | } macaddr_t; | 365 | } macaddr_t; |
278 | 366 | ||
279 | /* Structure that represent every FIFO element in the BAR1 | 367 | /* Structure that represent every FIFO element in the BAR1 |
280 | * Address location. | 368 | * Address location. |
281 | */ | 369 | */ |
282 | typedef struct _TxFIFO_element { | 370 | typedef struct _TxFIFO_element { |
283 | u64 TxDL_Pointer; | 371 | u64 TxDL_Pointer; |
@@ -339,6 +427,7 @@ typedef struct _RxD_t { | |||
339 | #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) | 427 | #define RXD_FRAME_PROTO vBIT(0xFFFF,24,8) |
340 | #define RXD_FRAME_PROTO_IPV4 BIT(27) | 428 | #define RXD_FRAME_PROTO_IPV4 BIT(27) |
341 | #define RXD_FRAME_PROTO_IPV6 BIT(28) | 429 | #define RXD_FRAME_PROTO_IPV6 BIT(28) |
430 | #define RXD_FRAME_IP_FRAG BIT(29) | ||
342 | #define RXD_FRAME_PROTO_TCP BIT(30) | 431 | #define RXD_FRAME_PROTO_TCP BIT(30) |
343 | #define RXD_FRAME_PROTO_UDP BIT(31) | 432 | #define RXD_FRAME_PROTO_UDP BIT(31) |
344 | #define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP) | 433 | #define TCP_OR_UDP_FRAME (RXD_FRAME_PROTO_TCP | RXD_FRAME_PROTO_UDP) |
@@ -346,11 +435,15 @@ typedef struct _RxD_t { | |||
346 | #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) | 435 | #define RXD_GET_L4_CKSUM(val) ((u16)(val) & 0xFFFF) |
347 | 436 | ||
348 | u64 Control_2; | 437 | u64 Control_2; |
438 | #define THE_RXD_MARK 0x3 | ||
439 | #define SET_RXD_MARKER vBIT(THE_RXD_MARK, 0, 2) | ||
440 | #define GET_RXD_MARKER(ctrl) ((ctrl & SET_RXD_MARKER) >> 62) | ||
441 | |||
349 | #ifndef CONFIG_2BUFF_MODE | 442 | #ifndef CONFIG_2BUFF_MODE |
350 | #define MASK_BUFFER0_SIZE vBIT(0xFFFF,0,16) | 443 | #define MASK_BUFFER0_SIZE vBIT(0x3FFF,2,14) |
351 | #define SET_BUFFER0_SIZE(val) vBIT(val,0,16) | 444 | #define SET_BUFFER0_SIZE(val) vBIT(val,2,14) |
352 | #else | 445 | #else |
353 | #define MASK_BUFFER0_SIZE vBIT(0xFF,0,16) | 446 | #define MASK_BUFFER0_SIZE vBIT(0xFF,2,14) |
354 | #define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16) | 447 | #define MASK_BUFFER1_SIZE vBIT(0xFFFF,16,16) |
355 | #define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16) | 448 | #define MASK_BUFFER2_SIZE vBIT(0xFFFF,32,16) |
356 | #define SET_BUFFER0_SIZE(val) vBIT(val,8,8) | 449 | #define SET_BUFFER0_SIZE(val) vBIT(val,8,8) |
@@ -363,7 +456,7 @@ typedef struct _RxD_t { | |||
363 | #define SET_NUM_TAG(val) vBIT(val,16,32) | 456 | #define SET_NUM_TAG(val) vBIT(val,16,32) |
364 | 457 | ||
365 | #ifndef CONFIG_2BUFF_MODE | 458 | #ifndef CONFIG_2BUFF_MODE |
366 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0xFFFF,0,16))) | 459 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0x3FFF,2,14))) |
367 | #else | 460 | #else |
368 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \ | 461 | #define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \ |
369 | >> 48) | 462 | >> 48) |
@@ -382,7 +475,7 @@ typedef struct _RxD_t { | |||
382 | #endif | 475 | #endif |
383 | } RxD_t; | 476 | } RxD_t; |
384 | 477 | ||
385 | /* Structure that represents the Rx descriptor block which contains | 478 | /* Structure that represents the Rx descriptor block which contains |
386 | * 128 Rx descriptors. | 479 | * 128 Rx descriptors. |
387 | */ | 480 | */ |
388 | #ifndef CONFIG_2BUFF_MODE | 481 | #ifndef CONFIG_2BUFF_MODE |
@@ -392,11 +485,11 @@ typedef struct _RxD_block { | |||
392 | 485 | ||
393 | u64 reserved_0; | 486 | u64 reserved_0; |
394 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL | 487 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL |
395 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last | 488 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last |
396 | * Rxd in this blk */ | 489 | * Rxd in this blk */ |
397 | u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */ | 490 | u64 reserved_2_pNext_RxD_block; /* Logical ptr to next */ |
398 | u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch | 491 | u64 pNext_RxD_Blk_physical; /* Buff0_ptr.In a 32 bit arch |
399 | * the upper 32 bits should | 492 | * the upper 32 bits should |
400 | * be 0 */ | 493 | * be 0 */ |
401 | } RxD_block_t; | 494 | } RxD_block_t; |
402 | #else | 495 | #else |
@@ -405,13 +498,13 @@ typedef struct _RxD_block { | |||
405 | RxD_t rxd[MAX_RXDS_PER_BLOCK]; | 498 | RxD_t rxd[MAX_RXDS_PER_BLOCK]; |
406 | 499 | ||
407 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL | 500 | #define END_OF_BLOCK 0xFEFFFFFFFFFFFFFFULL |
408 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd | 501 | u64 reserved_1; /* 0xFEFFFFFFFFFFFFFF to mark last Rxd |
409 | * in this blk */ | 502 | * in this blk */ |
410 | u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */ | 503 | u64 pNext_RxD_Blk_physical; /* Phy ponter to next blk. */ |
411 | } RxD_block_t; | 504 | } RxD_block_t; |
412 | #define SIZE_OF_BLOCK 4096 | 505 | #define SIZE_OF_BLOCK 4096 |
413 | 506 | ||
414 | /* Structure to hold virtual addresses of Buf0 and Buf1 in | 507 | /* Structure to hold virtual addresses of Buf0 and Buf1 in |
415 | * 2buf mode. */ | 508 | * 2buf mode. */ |
416 | typedef struct bufAdd { | 509 | typedef struct bufAdd { |
417 | void *ba_0_org; | 510 | void *ba_0_org; |
@@ -423,8 +516,8 @@ typedef struct bufAdd { | |||
423 | 516 | ||
424 | /* Structure which stores all the MAC control parameters */ | 517 | /* Structure which stores all the MAC control parameters */ |
425 | 518 | ||
426 | /* This structure stores the offset of the RxD in the ring | 519 | /* This structure stores the offset of the RxD in the ring |
427 | * from which the Rx Interrupt processor can start picking | 520 | * from which the Rx Interrupt processor can start picking |
428 | * up the RxDs for processing. | 521 | * up the RxDs for processing. |
429 | */ | 522 | */ |
430 | typedef struct _rx_curr_get_info_t { | 523 | typedef struct _rx_curr_get_info_t { |
@@ -436,7 +529,7 @@ typedef struct _rx_curr_get_info_t { | |||
436 | typedef rx_curr_get_info_t rx_curr_put_info_t; | 529 | typedef rx_curr_get_info_t rx_curr_put_info_t; |
437 | 530 | ||
438 | /* This structure stores the offset of the TxDl in the FIFO | 531 | /* This structure stores the offset of the TxDl in the FIFO |
439 | * from which the Tx Interrupt processor can start picking | 532 | * from which the Tx Interrupt processor can start picking |
440 | * up the TxDLs for send complete interrupt processing. | 533 | * up the TxDLs for send complete interrupt processing. |
441 | */ | 534 | */ |
442 | typedef struct { | 535 | typedef struct { |
@@ -446,32 +539,96 @@ typedef struct { | |||
446 | 539 | ||
447 | typedef tx_curr_get_info_t tx_curr_put_info_t; | 540 | typedef tx_curr_get_info_t tx_curr_put_info_t; |
448 | 541 | ||
449 | /* Infomation related to the Tx and Rx FIFOs and Rings of Xena | 542 | /* Structure that holds the Phy and virt addresses of the Blocks */ |
450 | * is maintained in this structure. | 543 | typedef struct rx_block_info { |
451 | */ | 544 | RxD_t *block_virt_addr; |
452 | typedef struct mac_info { | 545 | dma_addr_t block_dma_addr; |
453 | /* rx side stuff */ | 546 | } rx_block_info_t; |
454 | /* Put pointer info which indictes which RxD has to be replenished | 547 | |
548 | /* pre declaration of the nic structure */ | ||
549 | typedef struct s2io_nic nic_t; | ||
550 | |||
551 | /* Ring specific structure */ | ||
552 | typedef struct ring_info { | ||
553 | /* The ring number */ | ||
554 | int ring_no; | ||
555 | |||
556 | /* | ||
557 | * Place holders for the virtual and physical addresses of | ||
558 | * all the Rx Blocks | ||
559 | */ | ||
560 | rx_block_info_t rx_blocks[MAX_RX_BLOCKS_PER_RING]; | ||
561 | int block_count; | ||
562 | int pkt_cnt; | ||
563 | |||
564 | /* | ||
565 | * Put pointer info which indictes which RxD has to be replenished | ||
455 | * with a new buffer. | 566 | * with a new buffer. |
456 | */ | 567 | */ |
457 | rx_curr_put_info_t rx_curr_put_info[MAX_RX_RINGS]; | 568 | rx_curr_put_info_t rx_curr_put_info; |
458 | 569 | ||
459 | /* Get pointer info which indictes which is the last RxD that was | 570 | /* |
571 | * Get pointer info which indictes which is the last RxD that was | ||
460 | * processed by the driver. | 572 | * processed by the driver. |
461 | */ | 573 | */ |
462 | rx_curr_get_info_t rx_curr_get_info[MAX_RX_RINGS]; | 574 | rx_curr_get_info_t rx_curr_get_info; |
463 | 575 | ||
464 | u16 rmac_pause_time; | 576 | #ifndef CONFIG_S2IO_NAPI |
465 | u16 mc_pause_threshold_q0q3; | 577 | /* Index to the absolute position of the put pointer of Rx ring */ |
466 | u16 mc_pause_threshold_q4q7; | 578 | int put_pos; |
579 | #endif | ||
580 | |||
581 | #ifdef CONFIG_2BUFF_MODE | ||
582 | /* Buffer Address store. */ | ||
583 | buffAdd_t **ba; | ||
584 | #endif | ||
585 | nic_t *nic; | ||
586 | } ring_info_t; | ||
467 | 587 | ||
588 | /* Fifo specific structure */ | ||
589 | typedef struct fifo_info { | ||
590 | /* FIFO number */ | ||
591 | int fifo_no; | ||
592 | |||
593 | /* Maximum TxDs per TxDL */ | ||
594 | int max_txds; | ||
595 | |||
596 | /* Place holder of all the TX List's Phy and Virt addresses. */ | ||
597 | list_info_hold_t *list_info; | ||
598 | |||
599 | /* | ||
600 | * Current offset within the tx FIFO where driver would write | ||
601 | * new Tx frame | ||
602 | */ | ||
603 | tx_curr_put_info_t tx_curr_put_info; | ||
604 | |||
605 | /* | ||
606 | * Current offset within tx FIFO from where the driver would start freeing | ||
607 | * the buffers | ||
608 | */ | ||
609 | tx_curr_get_info_t tx_curr_get_info; | ||
610 | |||
611 | nic_t *nic; | ||
612 | }fifo_info_t; | ||
613 | |||
614 | /* Infomation related to the Tx and Rx FIFOs and Rings of Xena | ||
615 | * is maintained in this structure. | ||
616 | */ | ||
617 | typedef struct mac_info { | ||
468 | /* tx side stuff */ | 618 | /* tx side stuff */ |
469 | /* logical pointer of start of each Tx FIFO */ | 619 | /* logical pointer of start of each Tx FIFO */ |
470 | TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; | 620 | TxFIFO_element_t __iomem *tx_FIFO_start[MAX_TX_FIFOS]; |
471 | 621 | ||
472 | /* Current offset within tx_FIFO_start, where driver would write new Tx frame*/ | 622 | /* Fifo specific structure */ |
473 | tx_curr_put_info_t tx_curr_put_info[MAX_TX_FIFOS]; | 623 | fifo_info_t fifos[MAX_TX_FIFOS]; |
474 | tx_curr_get_info_t tx_curr_get_info[MAX_TX_FIFOS]; | 624 | |
625 | /* rx side stuff */ | ||
626 | /* Ring specific structure */ | ||
627 | ring_info_t rings[MAX_RX_RINGS]; | ||
628 | |||
629 | u16 rmac_pause_time; | ||
630 | u16 mc_pause_threshold_q0q3; | ||
631 | u16 mc_pause_threshold_q4q7; | ||
475 | 632 | ||
476 | void *stats_mem; /* orignal pointer to allocated mem */ | 633 | void *stats_mem; /* orignal pointer to allocated mem */ |
477 | dma_addr_t stats_mem_phy; /* Physical address of the stat block */ | 634 | dma_addr_t stats_mem_phy; /* Physical address of the stat block */ |
@@ -485,12 +642,6 @@ typedef struct { | |||
485 | int usage_cnt; | 642 | int usage_cnt; |
486 | } usr_addr_t; | 643 | } usr_addr_t; |
487 | 644 | ||
488 | /* Structure that holds the Phy and virt addresses of the Blocks */ | ||
489 | typedef struct rx_block_info { | ||
490 | RxD_t *block_virt_addr; | ||
491 | dma_addr_t block_dma_addr; | ||
492 | } rx_block_info_t; | ||
493 | |||
494 | /* Default Tunable parameters of the NIC. */ | 645 | /* Default Tunable parameters of the NIC. */ |
495 | #define DEFAULT_FIFO_LEN 4096 | 646 | #define DEFAULT_FIFO_LEN 4096 |
496 | #define SMALL_RXD_CNT 30 * (MAX_RXDS_PER_BLOCK+1) | 647 | #define SMALL_RXD_CNT 30 * (MAX_RXDS_PER_BLOCK+1) |
@@ -499,7 +650,20 @@ typedef struct rx_block_info { | |||
499 | #define LARGE_BLK_CNT 100 | 650 | #define LARGE_BLK_CNT 100 |
500 | 651 | ||
501 | /* Structure representing one instance of the NIC */ | 652 | /* Structure representing one instance of the NIC */ |
502 | typedef struct s2io_nic { | 653 | struct s2io_nic { |
654 | #ifdef CONFIG_S2IO_NAPI | ||
655 | /* | ||
656 | * Count of packets to be processed in a given iteration, it will be indicated | ||
657 | * by the quota field of the device structure when NAPI is enabled. | ||
658 | */ | ||
659 | int pkts_to_process; | ||
660 | #endif | ||
661 | struct net_device *dev; | ||
662 | mac_info_t mac_control; | ||
663 | struct config_param config; | ||
664 | struct pci_dev *pdev; | ||
665 | void __iomem *bar0; | ||
666 | void __iomem *bar1; | ||
503 | #define MAX_MAC_SUPPORTED 16 | 667 | #define MAX_MAC_SUPPORTED 16 |
504 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED | 668 | #define MAX_SUPPORTED_MULTICASTS MAX_MAC_SUPPORTED |
505 | 669 | ||
@@ -507,33 +671,20 @@ typedef struct s2io_nic { | |||
507 | macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; | 671 | macaddr_t pre_mac_addr[MAX_MAC_SUPPORTED]; |
508 | 672 | ||
509 | struct net_device_stats stats; | 673 | struct net_device_stats stats; |
510 | void __iomem *bar0; | ||
511 | void __iomem *bar1; | ||
512 | struct config_param config; | ||
513 | mac_info_t mac_control; | ||
514 | int high_dma_flag; | 674 | int high_dma_flag; |
515 | int device_close_flag; | 675 | int device_close_flag; |
516 | int device_enabled_once; | 676 | int device_enabled_once; |
517 | 677 | ||
518 | char name[32]; | 678 | char name[50]; |
519 | struct tasklet_struct task; | 679 | struct tasklet_struct task; |
520 | volatile unsigned long tasklet_status; | 680 | volatile unsigned long tasklet_status; |
521 | struct timer_list timer; | ||
522 | struct net_device *dev; | ||
523 | struct pci_dev *pdev; | ||
524 | 681 | ||
525 | u16 vendor_id; | 682 | /* Timer that handles I/O errors/exceptions */ |
526 | u16 device_id; | 683 | struct timer_list alarm_timer; |
527 | u16 ccmd; | 684 | |
528 | u32 cbar0_1; | 685 | /* Space to back up the PCI config space */ |
529 | u32 cbar0_2; | 686 | u32 config_space[256 / sizeof(u32)]; |
530 | u32 cbar1_1; | 687 | |
531 | u32 cbar1_2; | ||
532 | u32 cirq; | ||
533 | u8 cache_line; | ||
534 | u32 rom_expansion; | ||
535 | u16 pcix_cmd; | ||
536 | u32 irq; | ||
537 | atomic_t rx_bufs_left[MAX_RX_RINGS]; | 688 | atomic_t rx_bufs_left[MAX_RX_RINGS]; |
538 | 689 | ||
539 | spinlock_t tx_lock; | 690 | spinlock_t tx_lock; |
@@ -558,27 +709,11 @@ typedef struct s2io_nic { | |||
558 | u16 tx_err_count; | 709 | u16 tx_err_count; |
559 | u16 rx_err_count; | 710 | u16 rx_err_count; |
560 | 711 | ||
561 | #ifndef CONFIG_S2IO_NAPI | ||
562 | /* Index to the absolute position of the put pointer of Rx ring. */ | ||
563 | int put_pos[MAX_RX_RINGS]; | ||
564 | #endif | ||
565 | |||
566 | /* | ||
567 | * Place holders for the virtual and physical addresses of | ||
568 | * all the Rx Blocks | ||
569 | */ | ||
570 | rx_block_info_t rx_blocks[MAX_RX_RINGS][MAX_RX_BLOCKS_PER_RING]; | ||
571 | int block_count[MAX_RX_RINGS]; | ||
572 | int pkt_cnt[MAX_RX_RINGS]; | ||
573 | |||
574 | /* Place holder of all the TX List's Phy and Virt addresses. */ | ||
575 | list_info_hold_t *list_info[MAX_TX_FIFOS]; | ||
576 | |||
577 | /* Id timer, used to blink NIC to physically identify NIC. */ | 712 | /* Id timer, used to blink NIC to physically identify NIC. */ |
578 | struct timer_list id_timer; | 713 | struct timer_list id_timer; |
579 | 714 | ||
580 | /* Restart timer, used to restart NIC if the device is stuck and | 715 | /* Restart timer, used to restart NIC if the device is stuck and |
581 | * a schedule task that will set the correct Link state once the | 716 | * a schedule task that will set the correct Link state once the |
582 | * NIC's PHY has stabilized after a state change. | 717 | * NIC's PHY has stabilized after a state change. |
583 | */ | 718 | */ |
584 | #ifdef INIT_TQUEUE | 719 | #ifdef INIT_TQUEUE |
@@ -589,12 +724,12 @@ typedef struct s2io_nic { | |||
589 | struct work_struct set_link_task; | 724 | struct work_struct set_link_task; |
590 | #endif | 725 | #endif |
591 | 726 | ||
592 | /* Flag that can be used to turn on or turn off the Rx checksum | 727 | /* Flag that can be used to turn on or turn off the Rx checksum |
593 | * offload feature. | 728 | * offload feature. |
594 | */ | 729 | */ |
595 | int rx_csum; | 730 | int rx_csum; |
596 | 731 | ||
597 | /* after blink, the adapter must be restored with original | 732 | /* after blink, the adapter must be restored with original |
598 | * values. | 733 | * values. |
599 | */ | 734 | */ |
600 | u64 adapt_ctrl_org; | 735 | u64 adapt_ctrl_org; |
@@ -604,16 +739,19 @@ typedef struct s2io_nic { | |||
604 | #define LINK_DOWN 1 | 739 | #define LINK_DOWN 1 |
605 | #define LINK_UP 2 | 740 | #define LINK_UP 2 |
606 | 741 | ||
607 | #ifdef CONFIG_2BUFF_MODE | ||
608 | /* Buffer Address store. */ | ||
609 | buffAdd_t **ba[MAX_RX_RINGS]; | ||
610 | #endif | ||
611 | int task_flag; | 742 | int task_flag; |
612 | #define CARD_DOWN 1 | 743 | #define CARD_DOWN 1 |
613 | #define CARD_UP 2 | 744 | #define CARD_UP 2 |
614 | atomic_t card_state; | 745 | atomic_t card_state; |
615 | volatile unsigned long link_state; | 746 | volatile unsigned long link_state; |
616 | } nic_t; | 747 | struct vlan_group *vlgrp; |
748 | #define XFRAME_I_DEVICE 1 | ||
749 | #define XFRAME_II_DEVICE 2 | ||
750 | u8 device_type; | ||
751 | |||
752 | spinlock_t rx_lock; | ||
753 | atomic_t isr_cnt; | ||
754 | }; | ||
617 | 755 | ||
618 | #define RESET_ERROR 1; | 756 | #define RESET_ERROR 1; |
619 | #define CMD_ERROR 2; | 757 | #define CMD_ERROR 2; |
@@ -622,9 +760,10 @@ typedef struct s2io_nic { | |||
622 | #ifndef readq | 760 | #ifndef readq |
623 | static inline u64 readq(void __iomem *addr) | 761 | static inline u64 readq(void __iomem *addr) |
624 | { | 762 | { |
625 | u64 ret = readl(addr + 4); | 763 | u64 ret = 0; |
626 | ret <<= 32; | 764 | ret = readl(addr + 4); |
627 | ret |= readl(addr); | 765 | (u64) ret <<= 32; |
766 | (u64) ret |= readl(addr); | ||
628 | 767 | ||
629 | return ret; | 768 | return ret; |
630 | } | 769 | } |
@@ -637,10 +776,10 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
637 | writel((u32) (val >> 32), (addr + 4)); | 776 | writel((u32) (val >> 32), (addr + 4)); |
638 | } | 777 | } |
639 | 778 | ||
640 | /* In 32 bit modes, some registers have to be written in a | 779 | /* In 32 bit modes, some registers have to be written in a |
641 | * particular order to expect correct hardware operation. The | 780 | * particular order to expect correct hardware operation. The |
642 | * macro SPECIAL_REG_WRITE is used to perform such ordered | 781 | * macro SPECIAL_REG_WRITE is used to perform such ordered |
643 | * writes. Defines UF (Upper First) and LF (Lower First) will | 782 | * writes. Defines UF (Upper First) and LF (Lower First) will |
644 | * be used to specify the required write order. | 783 | * be used to specify the required write order. |
645 | */ | 784 | */ |
646 | #define UF 1 | 785 | #define UF 1 |
@@ -716,6 +855,7 @@ static inline void SPECIAL_REG_WRITE(u64 val, void __iomem *addr, int order) | |||
716 | #define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate | 855 | #define PCC_FB_ECC_ERR vBIT(0xff, 16, 8) /* Interrupt to indicate |
717 | PCC_FB_ECC Error. */ | 856 | PCC_FB_ECC Error. */ |
718 | 857 | ||
858 | #define RXD_GET_VLAN_TAG(Control_2) (u16)(Control_2 & MASK_VLAN_TAG) | ||
719 | /* | 859 | /* |
720 | * Prototype declaration. | 860 | * Prototype declaration. |
721 | */ | 861 | */ |
@@ -725,36 +865,30 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); | |||
725 | static int init_shared_mem(struct s2io_nic *sp); | 865 | static int init_shared_mem(struct s2io_nic *sp); |
726 | static void free_shared_mem(struct s2io_nic *sp); | 866 | static void free_shared_mem(struct s2io_nic *sp); |
727 | static int init_nic(struct s2io_nic *nic); | 867 | static int init_nic(struct s2io_nic *nic); |
728 | #ifndef CONFIG_S2IO_NAPI | 868 | static void rx_intr_handler(ring_info_t *ring_data); |
729 | static void rx_intr_handler(struct s2io_nic *sp); | 869 | static void tx_intr_handler(fifo_info_t *fifo_data); |
730 | #endif | ||
731 | static void tx_intr_handler(struct s2io_nic *sp); | ||
732 | static void alarm_intr_handler(struct s2io_nic *sp); | 870 | static void alarm_intr_handler(struct s2io_nic *sp); |
733 | 871 | ||
734 | static int s2io_starter(void); | 872 | static int s2io_starter(void); |
735 | static void s2io_closer(void); | 873 | void s2io_closer(void); |
736 | static void s2io_tx_watchdog(struct net_device *dev); | 874 | static void s2io_tx_watchdog(struct net_device *dev); |
737 | static void s2io_tasklet(unsigned long dev_addr); | 875 | static void s2io_tasklet(unsigned long dev_addr); |
738 | static void s2io_set_multicast(struct net_device *dev); | 876 | static void s2io_set_multicast(struct net_device *dev); |
739 | #ifndef CONFIG_2BUFF_MODE | 877 | static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp); |
740 | static int rx_osm_handler(nic_t * sp, u16 len, RxD_t * rxdp, int ring_no); | 878 | void s2io_link(nic_t * sp, int link); |
741 | #else | 879 | void s2io_reset(nic_t * sp); |
742 | static int rx_osm_handler(nic_t * sp, RxD_t * rxdp, int ring_no, | 880 | #if defined(CONFIG_S2IO_NAPI) |
743 | buffAdd_t * ba); | ||
744 | #endif | ||
745 | static void s2io_link(nic_t * sp, int link); | ||
746 | static void s2io_reset(nic_t * sp); | ||
747 | #ifdef CONFIG_S2IO_NAPI | ||
748 | static int s2io_poll(struct net_device *dev, int *budget); | 881 | static int s2io_poll(struct net_device *dev, int *budget); |
749 | #endif | 882 | #endif |
750 | static void s2io_init_pci(nic_t * sp); | 883 | static void s2io_init_pci(nic_t * sp); |
751 | static int s2io_set_mac_addr(struct net_device *dev, u8 * addr); | 884 | int s2io_set_mac_addr(struct net_device *dev, u8 * addr); |
885 | static void s2io_alarm_handle(unsigned long data); | ||
752 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); | 886 | static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs); |
753 | static int verify_xena_quiescence(u64 val64, int flag); | 887 | static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag); |
754 | static struct ethtool_ops netdev_ethtool_ops; | 888 | static struct ethtool_ops netdev_ethtool_ops; |
755 | static void s2io_set_link(unsigned long data); | 889 | static void s2io_set_link(unsigned long data); |
756 | static int s2io_set_swapper(nic_t * sp); | 890 | int s2io_set_swapper(nic_t * sp); |
757 | static void s2io_card_down(nic_t * nic); | 891 | static void s2io_card_down(nic_t *nic); |
758 | static int s2io_card_up(nic_t * nic); | 892 | static int s2io_card_up(nic_t *nic); |
759 | 893 | int get_xena_rev_id(struct pci_dev *pdev); | |
760 | #endif /* _S2IO_H */ | 894 | #endif /* _S2IO_H */ |
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index f15739481d62..d7c98515fdfd 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include "skge.h" | 42 | #include "skge.h" |
43 | 43 | ||
44 | #define DRV_NAME "skge" | 44 | #define DRV_NAME "skge" |
45 | #define DRV_VERSION "0.8" | 45 | #define DRV_VERSION "0.9" |
46 | #define PFX DRV_NAME " " | 46 | #define PFX DRV_NAME " " |
47 | 47 | ||
48 | #define DEFAULT_TX_RING_SIZE 128 | 48 | #define DEFAULT_TX_RING_SIZE 128 |
@@ -79,8 +79,8 @@ static const struct pci_device_id skge_id_table[] = { | |||
79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, | 79 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4320) }, |
80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ | 80 | { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x5005) }, /* Belkin */ |
81 | { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, | 81 | { PCI_DEVICE(PCI_VENDOR_ID_CNET, PCI_DEVICE_ID_CNET_GIGACARD) }, |
82 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1032) }, | ||
83 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, | 82 | { PCI_DEVICE(PCI_VENDOR_ID_LINKSYS, PCI_DEVICE_ID_LINKSYS_EG1064) }, |
83 | { PCI_VENDOR_ID_LINKSYS, 0x1032, PCI_ANY_ID, 0x0015, }, | ||
84 | { 0 } | 84 | { 0 } |
85 | }; | 85 | }; |
86 | MODULE_DEVICE_TABLE(pci, skge_id_table); | 86 | MODULE_DEVICE_TABLE(pci, skge_id_table); |
@@ -189,7 +189,7 @@ static u32 skge_supported_modes(const struct skge_hw *hw) | |||
189 | { | 189 | { |
190 | u32 supported; | 190 | u32 supported; |
191 | 191 | ||
192 | if (iscopper(hw)) { | 192 | if (hw->copper) { |
193 | supported = SUPPORTED_10baseT_Half | 193 | supported = SUPPORTED_10baseT_Half |
194 | | SUPPORTED_10baseT_Full | 194 | | SUPPORTED_10baseT_Full |
195 | | SUPPORTED_100baseT_Half | 195 | | SUPPORTED_100baseT_Half |
@@ -222,7 +222,7 @@ static int skge_get_settings(struct net_device *dev, | |||
222 | ecmd->transceiver = XCVR_INTERNAL; | 222 | ecmd->transceiver = XCVR_INTERNAL; |
223 | ecmd->supported = skge_supported_modes(hw); | 223 | ecmd->supported = skge_supported_modes(hw); |
224 | 224 | ||
225 | if (iscopper(hw)) { | 225 | if (hw->copper) { |
226 | ecmd->port = PORT_TP; | 226 | ecmd->port = PORT_TP; |
227 | ecmd->phy_address = hw->phy_addr; | 227 | ecmd->phy_address = hw->phy_addr; |
228 | } else | 228 | } else |
@@ -876,6 +876,9 @@ static int skge_rx_fill(struct skge_port *skge) | |||
876 | 876 | ||
877 | static void skge_link_up(struct skge_port *skge) | 877 | static void skge_link_up(struct skge_port *skge) |
878 | { | 878 | { |
879 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), | ||
880 | LED_BLK_OFF|LED_SYNC_OFF|LED_ON); | ||
881 | |||
879 | netif_carrier_on(skge->netdev); | 882 | netif_carrier_on(skge->netdev); |
880 | if (skge->tx_avail > MAX_SKB_FRAGS + 1) | 883 | if (skge->tx_avail > MAX_SKB_FRAGS + 1) |
881 | netif_wake_queue(skge->netdev); | 884 | netif_wake_queue(skge->netdev); |
@@ -894,6 +897,7 @@ static void skge_link_up(struct skge_port *skge) | |||
894 | 897 | ||
895 | static void skge_link_down(struct skge_port *skge) | 898 | static void skge_link_down(struct skge_port *skge) |
896 | { | 899 | { |
900 | skge_write8(skge->hw, SK_REG(skge->port, LNK_LED_REG), LED_OFF); | ||
897 | netif_carrier_off(skge->netdev); | 901 | netif_carrier_off(skge->netdev); |
898 | netif_stop_queue(skge->netdev); | 902 | netif_stop_queue(skge->netdev); |
899 | 903 | ||
@@ -1599,7 +1603,7 @@ static void yukon_init(struct skge_hw *hw, int port) | |||
1599 | adv = PHY_AN_CSMA; | 1603 | adv = PHY_AN_CSMA; |
1600 | 1604 | ||
1601 | if (skge->autoneg == AUTONEG_ENABLE) { | 1605 | if (skge->autoneg == AUTONEG_ENABLE) { |
1602 | if (iscopper(hw)) { | 1606 | if (hw->copper) { |
1603 | if (skge->advertising & ADVERTISED_1000baseT_Full) | 1607 | if (skge->advertising & ADVERTISED_1000baseT_Full) |
1604 | ct1000 |= PHY_M_1000C_AFD; | 1608 | ct1000 |= PHY_M_1000C_AFD; |
1605 | if (skge->advertising & ADVERTISED_1000baseT_Half) | 1609 | if (skge->advertising & ADVERTISED_1000baseT_Half) |
@@ -1691,7 +1695,7 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1691 | /* Set hardware config mode */ | 1695 | /* Set hardware config mode */ |
1692 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | | 1696 | reg = GPC_INT_POL_HI | GPC_DIS_FC | GPC_DIS_SLEEP | |
1693 | GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE; | 1697 | GPC_ENA_XC | GPC_ANEG_ADV_ALL_M | GPC_ENA_PAUSE; |
1694 | reg |= iscopper(hw) ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; | 1698 | reg |= hw->copper ? GPC_HWCFG_GMII_COP : GPC_HWCFG_GMII_FIB; |
1695 | 1699 | ||
1696 | /* Clear GMC reset */ | 1700 | /* Clear GMC reset */ |
1697 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); | 1701 | skge_write32(hw, SK_REG(port, GPHY_CTRL), reg | GPC_RST_SET); |
@@ -1780,7 +1784,12 @@ static void yukon_mac_init(struct skge_hw *hw, int port) | |||
1780 | reg &= ~GMF_RX_F_FL_ON; | 1784 | reg &= ~GMF_RX_F_FL_ON; |
1781 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); | 1785 | skge_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_CLR); |
1782 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); | 1786 | skge_write16(hw, SK_REG(port, RX_GMF_CTRL_T), reg); |
1783 | skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF); | 1787 | /* |
1788 | * because Pause Packet Truncation in GMAC is not working | ||
1789 | * we have to increase the Flush Threshold to 64 bytes | ||
1790 | * in order to flush pause packets in Rx FIFO on Yukon-1 | ||
1791 | */ | ||
1792 | skge_write16(hw, SK_REG(port, RX_GMF_FL_THR), RX_GMF_FL_THR_DEF+1); | ||
1784 | 1793 | ||
1785 | /* Configure Tx MAC FIFO */ | 1794 | /* Configure Tx MAC FIFO */ |
1786 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); | 1795 | skge_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_CLR); |
@@ -2670,18 +2679,6 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2670 | /* Timestamp (unused) overflow */ | 2679 | /* Timestamp (unused) overflow */ |
2671 | if (hwstatus & IS_IRQ_TIST_OV) | 2680 | if (hwstatus & IS_IRQ_TIST_OV) |
2672 | skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); | 2681 | skge_write8(hw, GMAC_TI_ST_CTRL, GMT_ST_CLR_IRQ); |
2673 | |||
2674 | if (hwstatus & IS_IRQ_SENSOR) { | ||
2675 | /* no sensors on 32-bit Yukon */ | ||
2676 | if (!(skge_read16(hw, B0_CTST) & CS_BUS_SLOT_SZ)) { | ||
2677 | printk(KERN_ERR PFX "ignoring bogus sensor interrups\n"); | ||
2678 | skge_write32(hw, B0_HWE_IMSK, | ||
2679 | IS_ERR_MSK & ~IS_IRQ_SENSOR); | ||
2680 | } else | ||
2681 | printk(KERN_WARNING PFX "sensor interrupt\n"); | ||
2682 | } | ||
2683 | |||
2684 | |||
2685 | } | 2682 | } |
2686 | 2683 | ||
2687 | if (hwstatus & IS_RAM_RD_PAR) { | 2684 | if (hwstatus & IS_RAM_RD_PAR) { |
@@ -2712,9 +2709,10 @@ static void skge_error_irq(struct skge_hw *hw) | |||
2712 | 2709 | ||
2713 | skge_pci_clear(hw); | 2710 | skge_pci_clear(hw); |
2714 | 2711 | ||
2712 | /* if error still set then just ignore it */ | ||
2715 | hwstatus = skge_read32(hw, B0_HWE_ISRC); | 2713 | hwstatus = skge_read32(hw, B0_HWE_ISRC); |
2716 | if (hwstatus & IS_IRQ_STAT) { | 2714 | if (hwstatus & IS_IRQ_STAT) { |
2717 | printk(KERN_WARNING PFX "IRQ status %x: still set ignoring hardware errors\n", | 2715 | pr_debug("IRQ status %x: still set ignoring hardware errors\n", |
2718 | hwstatus); | 2716 | hwstatus); |
2719 | hw->intr_mask &= ~IS_HW_ERR; | 2717 | hw->intr_mask &= ~IS_HW_ERR; |
2720 | } | 2718 | } |
@@ -2876,7 +2874,7 @@ static const char *skge_board_name(const struct skge_hw *hw) | |||
2876 | static int skge_reset(struct skge_hw *hw) | 2874 | static int skge_reset(struct skge_hw *hw) |
2877 | { | 2875 | { |
2878 | u16 ctst; | 2876 | u16 ctst; |
2879 | u8 t8, mac_cfg; | 2877 | u8 t8, mac_cfg, pmd_type, phy_type; |
2880 | int i; | 2878 | int i; |
2881 | 2879 | ||
2882 | ctst = skge_read16(hw, B0_CTST); | 2880 | ctst = skge_read16(hw, B0_CTST); |
@@ -2895,18 +2893,19 @@ static int skge_reset(struct skge_hw *hw) | |||
2895 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); | 2893 | ctst & (CS_CLK_RUN_HOT|CS_CLK_RUN_RST|CS_CLK_RUN_ENA)); |
2896 | 2894 | ||
2897 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); | 2895 | hw->chip_id = skge_read8(hw, B2_CHIP_ID); |
2898 | hw->phy_type = skge_read8(hw, B2_E_1) & 0xf; | 2896 | phy_type = skge_read8(hw, B2_E_1) & 0xf; |
2899 | hw->pmd_type = skge_read8(hw, B2_PMD_TYP); | 2897 | pmd_type = skge_read8(hw, B2_PMD_TYP); |
2898 | hw->copper = (pmd_type == 'T' || pmd_type == '1'); | ||
2900 | 2899 | ||
2901 | switch (hw->chip_id) { | 2900 | switch (hw->chip_id) { |
2902 | case CHIP_ID_GENESIS: | 2901 | case CHIP_ID_GENESIS: |
2903 | switch (hw->phy_type) { | 2902 | switch (phy_type) { |
2904 | case SK_PHY_BCOM: | 2903 | case SK_PHY_BCOM: |
2905 | hw->phy_addr = PHY_ADDR_BCOM; | 2904 | hw->phy_addr = PHY_ADDR_BCOM; |
2906 | break; | 2905 | break; |
2907 | default: | 2906 | default: |
2908 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", | 2907 | printk(KERN_ERR PFX "%s: unsupported phy type 0x%x\n", |
2909 | pci_name(hw->pdev), hw->phy_type); | 2908 | pci_name(hw->pdev), phy_type); |
2910 | return -EOPNOTSUPP; | 2909 | return -EOPNOTSUPP; |
2911 | } | 2910 | } |
2912 | break; | 2911 | break; |
@@ -2914,13 +2913,10 @@ static int skge_reset(struct skge_hw *hw) | |||
2914 | case CHIP_ID_YUKON: | 2913 | case CHIP_ID_YUKON: |
2915 | case CHIP_ID_YUKON_LITE: | 2914 | case CHIP_ID_YUKON_LITE: |
2916 | case CHIP_ID_YUKON_LP: | 2915 | case CHIP_ID_YUKON_LP: |
2917 | if (hw->phy_type < SK_PHY_MARV_COPPER && hw->pmd_type != 'S') | 2916 | if (phy_type < SK_PHY_MARV_COPPER && pmd_type != 'S') |
2918 | hw->phy_type = SK_PHY_MARV_COPPER; | 2917 | hw->copper = 1; |
2919 | 2918 | ||
2920 | hw->phy_addr = PHY_ADDR_MARV; | 2919 | hw->phy_addr = PHY_ADDR_MARV; |
2921 | if (!iscopper(hw)) | ||
2922 | hw->phy_type = SK_PHY_MARV_FIBER; | ||
2923 | |||
2924 | break; | 2920 | break; |
2925 | 2921 | ||
2926 | default: | 2922 | default: |
@@ -2948,12 +2944,20 @@ static int skge_reset(struct skge_hw *hw) | |||
2948 | else | 2944 | else |
2949 | hw->ram_size = t8 * 4096; | 2945 | hw->ram_size = t8 * 4096; |
2950 | 2946 | ||
2947 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; | ||
2951 | if (hw->chip_id == CHIP_ID_GENESIS) | 2948 | if (hw->chip_id == CHIP_ID_GENESIS) |
2952 | genesis_init(hw); | 2949 | genesis_init(hw); |
2953 | else { | 2950 | else { |
2954 | /* switch power to VCC (WA for VAUX problem) */ | 2951 | /* switch power to VCC (WA for VAUX problem) */ |
2955 | skge_write8(hw, B0_POWER_CTRL, | 2952 | skge_write8(hw, B0_POWER_CTRL, |
2956 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); | 2953 | PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON); |
2954 | /* avoid boards with stuck Hardware error bits */ | ||
2955 | if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) && | ||
2956 | (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) { | ||
2957 | printk(KERN_WARNING PFX "stuck hardware sensor bit\n"); | ||
2958 | hw->intr_mask &= ~IS_HW_ERR; | ||
2959 | } | ||
2960 | |||
2957 | for (i = 0; i < hw->ports; i++) { | 2961 | for (i = 0; i < hw->ports; i++) { |
2958 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); | 2962 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET); |
2959 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); | 2963 | skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR); |
@@ -2994,7 +2998,6 @@ static int skge_reset(struct skge_hw *hw) | |||
2994 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); | 2998 | skge_write32(hw, B2_IRQM_INI, skge_usecs2clk(hw, 100)); |
2995 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); | 2999 | skge_write32(hw, B2_IRQM_CTRL, TIM_START); |
2996 | 3000 | ||
2997 | hw->intr_mask = IS_HW_ERR | IS_EXT_REG; | ||
2998 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 3001 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2999 | 3002 | ||
3000 | if (hw->chip_id != CHIP_ID_GENESIS) | 3003 | if (hw->chip_id != CHIP_ID_GENESIS) |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index b432f1bb8168..f1680beb8e68 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -214,8 +214,6 @@ enum { | |||
214 | 214 | ||
215 | /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ | 215 | /* B2_IRQM_HWE_MSK 32 bit IRQ Moderation HW Error Mask */ |
216 | enum { | 216 | enum { |
217 | IS_ERR_MSK = 0x00003fff,/* All Error bits */ | ||
218 | |||
219 | IS_IRQ_TIST_OV = 1<<13, /* Time Stamp Timer Overflow (YUKON only) */ | 217 | IS_IRQ_TIST_OV = 1<<13, /* Time Stamp Timer Overflow (YUKON only) */ |
220 | IS_IRQ_SENSOR = 1<<12, /* IRQ from Sensor (YUKON only) */ | 218 | IS_IRQ_SENSOR = 1<<12, /* IRQ from Sensor (YUKON only) */ |
221 | IS_IRQ_MST_ERR = 1<<11, /* IRQ master error detected */ | 219 | IS_IRQ_MST_ERR = 1<<11, /* IRQ master error detected */ |
@@ -230,6 +228,12 @@ enum { | |||
230 | IS_M2_PAR_ERR = 1<<2, /* MAC 2 Parity Error */ | 228 | IS_M2_PAR_ERR = 1<<2, /* MAC 2 Parity Error */ |
231 | IS_R1_PAR_ERR = 1<<1, /* Queue R1 Parity Error */ | 229 | IS_R1_PAR_ERR = 1<<1, /* Queue R1 Parity Error */ |
232 | IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */ | 230 | IS_R2_PAR_ERR = 1<<0, /* Queue R2 Parity Error */ |
231 | |||
232 | IS_ERR_MSK = IS_IRQ_MST_ERR | IS_IRQ_STAT | ||
233 | | IS_NO_STAT_M1 | IS_NO_STAT_M2 | ||
234 | | IS_RAM_RD_PAR | IS_RAM_WR_PAR | ||
235 | | IS_M1_PAR_ERR | IS_M2_PAR_ERR | ||
236 | | IS_R1_PAR_ERR | IS_R2_PAR_ERR, | ||
233 | }; | 237 | }; |
234 | 238 | ||
235 | /* B2_TST_CTRL1 8 bit Test Control Register 1 */ | 239 | /* B2_TST_CTRL1 8 bit Test Control Register 1 */ |
@@ -2456,24 +2460,17 @@ struct skge_hw { | |||
2456 | 2460 | ||
2457 | u8 chip_id; | 2461 | u8 chip_id; |
2458 | u8 chip_rev; | 2462 | u8 chip_rev; |
2459 | u8 phy_type; | 2463 | u8 copper; |
2460 | u8 pmd_type; | ||
2461 | u16 phy_addr; | ||
2462 | u8 ports; | 2464 | u8 ports; |
2463 | 2465 | ||
2464 | u32 ram_size; | 2466 | u32 ram_size; |
2465 | u32 ram_offset; | 2467 | u32 ram_offset; |
2468 | u16 phy_addr; | ||
2466 | 2469 | ||
2467 | struct tasklet_struct ext_tasklet; | 2470 | struct tasklet_struct ext_tasklet; |
2468 | spinlock_t phy_lock; | 2471 | spinlock_t phy_lock; |
2469 | }; | 2472 | }; |
2470 | 2473 | ||
2471 | |||
2472 | static inline int iscopper(const struct skge_hw *hw) | ||
2473 | { | ||
2474 | return (hw->pmd_type == 'T'); | ||
2475 | } | ||
2476 | |||
2477 | enum { | 2474 | enum { |
2478 | FLOW_MODE_NONE = 0, /* No Flow-Control */ | 2475 | FLOW_MODE_NONE = 0, /* No Flow-Control */ |
2479 | FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ | 2476 | FLOW_MODE_LOC_SEND = 1, /* Local station sends PAUSE */ |
diff --git a/drivers/net/sonic.c b/drivers/net/sonic.c index cdc9cc873e06..90b818a8de6e 100644 --- a/drivers/net/sonic.c +++ b/drivers/net/sonic.c | |||
@@ -1,6 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * sonic.c | 2 | * sonic.c |
3 | * | 3 | * |
4 | * (C) 2005 Finn Thain | ||
5 | * | ||
6 | * Converted to DMA API, added zero-copy buffer handling, and | ||
7 | * (from the mac68k project) introduced dhd's support for 16-bit cards. | ||
8 | * | ||
4 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) | 9 | * (C) 1996,1998 by Thomas Bogendoerfer (tsbogend@alpha.franken.de) |
5 | * | 10 | * |
6 | * This driver is based on work from Andreas Busse, but most of | 11 | * This driver is based on work from Andreas Busse, but most of |
@@ -9,12 +14,23 @@ | |||
9 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) | 14 | * (C) 1995 by Andreas Busse (andy@waldorf-gmbh.de) |
10 | * | 15 | * |
11 | * Core code included by system sonic drivers | 16 | * Core code included by system sonic drivers |
17 | * | ||
18 | * And... partially rewritten again by David Huggins-Daines in order | ||
19 | * to cope with screwed up Macintosh NICs that may or may not use | ||
20 | * 16-bit DMA. | ||
21 | * | ||
22 | * (C) 1999 David Huggins-Daines <dhd@debian.org> | ||
23 | * | ||
12 | */ | 24 | */ |
13 | 25 | ||
14 | /* | 26 | /* |
15 | * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, | 27 | * Sources: Olivetti M700-10 Risc Personal Computer hardware handbook, |
16 | * National Semiconductors data sheet for the DP83932B Sonic Ethernet | 28 | * National Semiconductors data sheet for the DP83932B Sonic Ethernet |
17 | * controller, and the files "8390.c" and "skeleton.c" in this directory. | 29 | * controller, and the files "8390.c" and "skeleton.c" in this directory. |
30 | * | ||
31 | * Additional sources: Nat Semi data sheet for the DP83932C and Nat Semi | ||
32 | * Application Note AN-746, the files "lance.c" and "ibmlana.c". See also | ||
33 | * the NetBSD file "sys/arch/mac68k/dev/if_sn.c". | ||
18 | */ | 34 | */ |
19 | 35 | ||
20 | 36 | ||
@@ -28,6 +44,9 @@ | |||
28 | */ | 44 | */ |
29 | static int sonic_open(struct net_device *dev) | 45 | static int sonic_open(struct net_device *dev) |
30 | { | 46 | { |
47 | struct sonic_local *lp = netdev_priv(dev); | ||
48 | int i; | ||
49 | |||
31 | if (sonic_debug > 2) | 50 | if (sonic_debug > 2) |
32 | printk("sonic_open: initializing sonic driver.\n"); | 51 | printk("sonic_open: initializing sonic driver.\n"); |
33 | 52 | ||
@@ -40,14 +59,59 @@ static int sonic_open(struct net_device *dev) | |||
40 | * This means that during execution of the handler interrupt are disabled | 59 | * This means that during execution of the handler interrupt are disabled |
41 | * covering another bug otherwise corrupting data. This doesn't mean | 60 | * covering another bug otherwise corrupting data. This doesn't mean |
42 | * this glue works ok under all situations. | 61 | * this glue works ok under all situations. |
62 | * | ||
63 | * Note (dhd): this also appears to prevent lockups on the Macintrash | ||
64 | * when more than one Ethernet card is installed (knock on wood) | ||
65 | * | ||
66 | * Note (fthain): whether the above is still true is anyones guess. Certainly | ||
67 | * the buffer handling algorithms will not tolerate re-entrance without some | ||
68 | * mutual exclusion added. Anyway, the memcpy has now been eliminated from the | ||
69 | * rx code to make this a faster "fast interrupt". | ||
43 | */ | 70 | */ |
44 | // if (sonic_request_irq(dev->irq, &sonic_interrupt, 0, "sonic", dev)) { | 71 | if (request_irq(dev->irq, &sonic_interrupt, SONIC_IRQ_FLAG, "sonic", dev)) { |
45 | if (sonic_request_irq(dev->irq, &sonic_interrupt, SA_INTERRUPT, | 72 | printk(KERN_ERR "\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); |
46 | "sonic", dev)) { | ||
47 | printk("\n%s: unable to get IRQ %d .\n", dev->name, dev->irq); | ||
48 | return -EAGAIN; | 73 | return -EAGAIN; |
49 | } | 74 | } |
50 | 75 | ||
76 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
77 | struct sk_buff *skb = dev_alloc_skb(SONIC_RBSIZE + 2); | ||
78 | if (skb == NULL) { | ||
79 | while(i > 0) { /* free any that were allocated successfully */ | ||
80 | i--; | ||
81 | dev_kfree_skb(lp->rx_skb[i]); | ||
82 | lp->rx_skb[i] = NULL; | ||
83 | } | ||
84 | printk(KERN_ERR "%s: couldn't allocate receive buffers\n", | ||
85 | dev->name); | ||
86 | return -ENOMEM; | ||
87 | } | ||
88 | skb->dev = dev; | ||
89 | /* align IP header unless DMA requires otherwise */ | ||
90 | if (SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
91 | skb_reserve(skb, 2); | ||
92 | lp->rx_skb[i] = skb; | ||
93 | } | ||
94 | |||
95 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
96 | dma_addr_t laddr = dma_map_single(lp->device, skb_put(lp->rx_skb[i], SONIC_RBSIZE), | ||
97 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
98 | if (!laddr) { | ||
99 | while(i > 0) { /* free any that were mapped successfully */ | ||
100 | i--; | ||
101 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
102 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
103 | } | ||
104 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
105 | dev_kfree_skb(lp->rx_skb[i]); | ||
106 | lp->rx_skb[i] = NULL; | ||
107 | } | ||
108 | printk(KERN_ERR "%s: couldn't map rx DMA buffers\n", | ||
109 | dev->name); | ||
110 | return -ENOMEM; | ||
111 | } | ||
112 | lp->rx_laddr[i] = laddr; | ||
113 | } | ||
114 | |||
51 | /* | 115 | /* |
52 | * Initialize the SONIC | 116 | * Initialize the SONIC |
53 | */ | 117 | */ |
@@ -67,7 +131,8 @@ static int sonic_open(struct net_device *dev) | |||
67 | */ | 131 | */ |
68 | static int sonic_close(struct net_device *dev) | 132 | static int sonic_close(struct net_device *dev) |
69 | { | 133 | { |
70 | unsigned int base_addr = dev->base_addr; | 134 | struct sonic_local *lp = netdev_priv(dev); |
135 | int i; | ||
71 | 136 | ||
72 | if (sonic_debug > 2) | 137 | if (sonic_debug > 2) |
73 | printk("sonic_close\n"); | 138 | printk("sonic_close\n"); |
@@ -77,20 +142,56 @@ static int sonic_close(struct net_device *dev) | |||
77 | /* | 142 | /* |
78 | * stop the SONIC, disable interrupts | 143 | * stop the SONIC, disable interrupts |
79 | */ | 144 | */ |
80 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
81 | SONIC_WRITE(SONIC_IMR, 0); | 145 | SONIC_WRITE(SONIC_IMR, 0); |
146 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
82 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | 147 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
83 | 148 | ||
84 | sonic_free_irq(dev->irq, dev); /* release the IRQ */ | 149 | /* unmap and free skbs that haven't been transmitted */ |
150 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
151 | if(lp->tx_laddr[i]) { | ||
152 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
153 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
154 | } | ||
155 | if(lp->tx_skb[i]) { | ||
156 | dev_kfree_skb(lp->tx_skb[i]); | ||
157 | lp->tx_skb[i] = NULL; | ||
158 | } | ||
159 | } | ||
160 | |||
161 | /* unmap and free the receive buffers */ | ||
162 | for (i = 0; i < SONIC_NUM_RRS; i++) { | ||
163 | if(lp->rx_laddr[i]) { | ||
164 | dma_unmap_single(lp->device, lp->rx_laddr[i], SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
165 | lp->rx_laddr[i] = (dma_addr_t)0; | ||
166 | } | ||
167 | if(lp->rx_skb[i]) { | ||
168 | dev_kfree_skb(lp->rx_skb[i]); | ||
169 | lp->rx_skb[i] = NULL; | ||
170 | } | ||
171 | } | ||
172 | |||
173 | free_irq(dev->irq, dev); /* release the IRQ */ | ||
85 | 174 | ||
86 | return 0; | 175 | return 0; |
87 | } | 176 | } |
88 | 177 | ||
89 | static void sonic_tx_timeout(struct net_device *dev) | 178 | static void sonic_tx_timeout(struct net_device *dev) |
90 | { | 179 | { |
91 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 180 | struct sonic_local *lp = netdev_priv(dev); |
92 | printk("%s: transmit timed out.\n", dev->name); | 181 | int i; |
93 | 182 | /* Stop the interrupts for this */ | |
183 | SONIC_WRITE(SONIC_IMR, 0); | ||
184 | /* We could resend the original skbs. Easier to re-initialise. */ | ||
185 | for (i = 0; i < SONIC_NUM_TDS; i++) { | ||
186 | if(lp->tx_laddr[i]) { | ||
187 | dma_unmap_single(lp->device, lp->tx_laddr[i], lp->tx_len[i], DMA_TO_DEVICE); | ||
188 | lp->tx_laddr[i] = (dma_addr_t)0; | ||
189 | } | ||
190 | if(lp->tx_skb[i]) { | ||
191 | dev_kfree_skb(lp->tx_skb[i]); | ||
192 | lp->tx_skb[i] = NULL; | ||
193 | } | ||
194 | } | ||
94 | /* Try to restart the adaptor. */ | 195 | /* Try to restart the adaptor. */ |
95 | sonic_init(dev); | 196 | sonic_init(dev); |
96 | lp->stats.tx_errors++; | 197 | lp->stats.tx_errors++; |
@@ -100,60 +201,92 @@ static void sonic_tx_timeout(struct net_device *dev) | |||
100 | 201 | ||
101 | /* | 202 | /* |
102 | * transmit packet | 203 | * transmit packet |
204 | * | ||
205 | * Appends new TD during transmission thus avoiding any TX interrupts | ||
206 | * until we run out of TDs. | ||
207 | * This routine interacts closely with the ISR in that it may, | ||
208 | * set tx_skb[i] | ||
209 | * reset the status flags of the new TD | ||
210 | * set and reset EOL flags | ||
211 | * stop the tx queue | ||
212 | * The ISR interacts with this routine in various ways. It may, | ||
213 | * reset tx_skb[i] | ||
214 | * test the EOL and status flags of the TDs | ||
215 | * wake the tx queue | ||
216 | * Concurrently with all of this, the SONIC is potentially writing to | ||
217 | * the status flags of the TDs. | ||
218 | * Until some mutual exclusion is added, this code will not work with SMP. However, | ||
219 | * MIPS Jazz machines and m68k Macs were all uni-processor machines. | ||
103 | */ | 220 | */ |
221 | |||
104 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | 222 | static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) |
105 | { | 223 | { |
106 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 224 | struct sonic_local *lp = netdev_priv(dev); |
107 | unsigned int base_addr = dev->base_addr; | 225 | dma_addr_t laddr; |
108 | unsigned int laddr; | 226 | int length; |
109 | int entry, length; | 227 | int entry = lp->next_tx; |
110 | |||
111 | netif_stop_queue(dev); | ||
112 | 228 | ||
113 | if (sonic_debug > 2) | 229 | if (sonic_debug > 2) |
114 | printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); | 230 | printk("sonic_send_packet: skb=%p, dev=%p\n", skb, dev); |
115 | 231 | ||
232 | length = skb->len; | ||
233 | if (length < ETH_ZLEN) { | ||
234 | skb = skb_padto(skb, ETH_ZLEN); | ||
235 | if (skb == NULL) | ||
236 | return 0; | ||
237 | length = ETH_ZLEN; | ||
238 | } | ||
239 | |||
116 | /* | 240 | /* |
117 | * Map the packet data into the logical DMA address space | 241 | * Map the packet data into the logical DMA address space |
118 | */ | 242 | */ |
119 | if ((laddr = vdma_alloc(CPHYSADDR(skb->data), skb->len)) == ~0UL) { | 243 | |
120 | printk("%s: no VDMA entry for transmit available.\n", | 244 | laddr = dma_map_single(lp->device, skb->data, length, DMA_TO_DEVICE); |
121 | dev->name); | 245 | if (!laddr) { |
246 | printk(KERN_ERR "%s: failed to map tx DMA buffer.\n", dev->name); | ||
122 | dev_kfree_skb(skb); | 247 | dev_kfree_skb(skb); |
123 | netif_start_queue(dev); | ||
124 | return 1; | 248 | return 1; |
125 | } | 249 | } |
126 | entry = lp->cur_tx & SONIC_TDS_MASK; | 250 | |
251 | sonic_tda_put(dev, entry, SONIC_TD_STATUS, 0); /* clear status */ | ||
252 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_COUNT, 1); /* single fragment */ | ||
253 | sonic_tda_put(dev, entry, SONIC_TD_PKTSIZE, length); /* length of packet */ | ||
254 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_L, laddr & 0xffff); | ||
255 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_PTR_H, laddr >> 16); | ||
256 | sonic_tda_put(dev, entry, SONIC_TD_FRAG_SIZE, length); | ||
257 | sonic_tda_put(dev, entry, SONIC_TD_LINK, | ||
258 | sonic_tda_get(dev, entry, SONIC_TD_LINK) | SONIC_EOL); | ||
259 | |||
260 | /* | ||
261 | * Must set tx_skb[entry] only after clearing status, and | ||
262 | * before clearing EOL and before stopping queue | ||
263 | */ | ||
264 | wmb(); | ||
265 | lp->tx_len[entry] = length; | ||
127 | lp->tx_laddr[entry] = laddr; | 266 | lp->tx_laddr[entry] = laddr; |
128 | lp->tx_skb[entry] = skb; | 267 | lp->tx_skb[entry] = skb; |
129 | 268 | ||
130 | length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; | 269 | wmb(); |
131 | flush_cache_all(); | 270 | sonic_tda_put(dev, lp->eol_tx, SONIC_TD_LINK, |
271 | sonic_tda_get(dev, lp->eol_tx, SONIC_TD_LINK) & ~SONIC_EOL); | ||
272 | lp->eol_tx = entry; | ||
132 | 273 | ||
133 | /* | 274 | lp->next_tx = (entry + 1) & SONIC_TDS_MASK; |
134 | * Setup the transmit descriptor and issue the transmit command. | 275 | if (lp->tx_skb[lp->next_tx] != NULL) { |
135 | */ | 276 | /* The ring is full, the ISR has yet to process the next TD. */ |
136 | lp->tda[entry].tx_status = 0; /* clear status */ | 277 | if (sonic_debug > 3) |
137 | lp->tda[entry].tx_frag_count = 1; /* single fragment */ | 278 | printk("%s: stopping queue\n", dev->name); |
138 | lp->tda[entry].tx_pktsize = length; /* length of packet */ | 279 | netif_stop_queue(dev); |
139 | lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff; | 280 | /* after this packet, wait for ISR to free up some TDAs */ |
140 | lp->tda[entry].tx_frag_ptr_h = laddr >> 16; | 281 | } else netif_start_queue(dev); |
141 | lp->tda[entry].tx_frag_size = length; | ||
142 | lp->cur_tx++; | ||
143 | lp->stats.tx_bytes += length; | ||
144 | 282 | ||
145 | if (sonic_debug > 2) | 283 | if (sonic_debug > 2) |
146 | printk("sonic_send_packet: issueing Tx command\n"); | 284 | printk("sonic_send_packet: issuing Tx command\n"); |
147 | 285 | ||
148 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); | 286 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); |
149 | 287 | ||
150 | dev->trans_start = jiffies; | 288 | dev->trans_start = jiffies; |
151 | 289 | ||
152 | if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS) | ||
153 | netif_start_queue(dev); | ||
154 | else | ||
155 | lp->tx_full = 1; | ||
156 | |||
157 | return 0; | 290 | return 0; |
158 | } | 291 | } |
159 | 292 | ||
@@ -164,175 +297,199 @@ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) | |||
164 | static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 297 | static irqreturn_t sonic_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
165 | { | 298 | { |
166 | struct net_device *dev = (struct net_device *) dev_id; | 299 | struct net_device *dev = (struct net_device *) dev_id; |
167 | unsigned int base_addr = dev->base_addr; | 300 | struct sonic_local *lp = netdev_priv(dev); |
168 | struct sonic_local *lp; | ||
169 | int status; | 301 | int status; |
170 | 302 | ||
171 | if (dev == NULL) { | 303 | if (dev == NULL) { |
172 | printk("sonic_interrupt: irq %d for unknown device.\n", irq); | 304 | printk(KERN_ERR "sonic_interrupt: irq %d for unknown device.\n", irq); |
173 | return IRQ_NONE; | 305 | return IRQ_NONE; |
174 | } | 306 | } |
175 | 307 | ||
176 | lp = (struct sonic_local *) dev->priv; | 308 | if (!(status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)) |
177 | 309 | return IRQ_NONE; | |
178 | status = SONIC_READ(SONIC_ISR); | ||
179 | SONIC_WRITE(SONIC_ISR, 0x7fff); /* clear all bits */ | ||
180 | |||
181 | if (sonic_debug > 2) | ||
182 | printk("sonic_interrupt: ISR=%x\n", status); | ||
183 | |||
184 | if (status & SONIC_INT_PKTRX) { | ||
185 | sonic_rx(dev); /* got packet(s) */ | ||
186 | } | ||
187 | |||
188 | if (status & SONIC_INT_TXDN) { | ||
189 | int dirty_tx = lp->dirty_tx; | ||
190 | |||
191 | while (dirty_tx < lp->cur_tx) { | ||
192 | int entry = dirty_tx & SONIC_TDS_MASK; | ||
193 | int status = lp->tda[entry].tx_status; | ||
194 | 310 | ||
195 | if (sonic_debug > 3) | 311 | do { |
196 | printk | 312 | if (status & SONIC_INT_PKTRX) { |
197 | ("sonic_interrupt: status %d, cur_tx %d, dirty_tx %d\n", | 313 | if (sonic_debug > 2) |
198 | status, lp->cur_tx, lp->dirty_tx); | 314 | printk("%s: packet rx\n", dev->name); |
315 | sonic_rx(dev); /* got packet(s) */ | ||
316 | SONIC_WRITE(SONIC_ISR, SONIC_INT_PKTRX); /* clear the interrupt */ | ||
317 | } | ||
199 | 318 | ||
200 | if (status == 0) { | 319 | if (status & SONIC_INT_TXDN) { |
201 | /* It still hasn't been Txed, kick the sonic again */ | 320 | int entry = lp->cur_tx; |
202 | SONIC_WRITE(SONIC_CMD, SONIC_CR_TXP); | 321 | int td_status; |
203 | break; | 322 | int freed_some = 0; |
204 | } | ||
205 | 323 | ||
206 | /* put back EOL and free descriptor */ | 324 | /* At this point, cur_tx is the index of a TD that is one of: |
207 | lp->tda[entry].tx_frag_count = 0; | 325 | * unallocated/freed (status set & tx_skb[entry] clear) |
208 | lp->tda[entry].tx_status = 0; | 326 | * allocated and sent (status set & tx_skb[entry] set ) |
209 | 327 | * allocated and not yet sent (status clear & tx_skb[entry] set ) | |
210 | if (status & 0x0001) | 328 | * still being allocated by sonic_send_packet (status clear & tx_skb[entry] clear) |
211 | lp->stats.tx_packets++; | 329 | */ |
212 | else { | ||
213 | lp->stats.tx_errors++; | ||
214 | if (status & 0x0642) | ||
215 | lp->stats.tx_aborted_errors++; | ||
216 | if (status & 0x0180) | ||
217 | lp->stats.tx_carrier_errors++; | ||
218 | if (status & 0x0020) | ||
219 | lp->stats.tx_window_errors++; | ||
220 | if (status & 0x0004) | ||
221 | lp->stats.tx_fifo_errors++; | ||
222 | } | ||
223 | 330 | ||
224 | /* We must free the original skb */ | 331 | if (sonic_debug > 2) |
225 | if (lp->tx_skb[entry]) { | 332 | printk("%s: tx done\n", dev->name); |
333 | |||
334 | while (lp->tx_skb[entry] != NULL) { | ||
335 | if ((td_status = sonic_tda_get(dev, entry, SONIC_TD_STATUS)) == 0) | ||
336 | break; | ||
337 | |||
338 | if (td_status & 0x0001) { | ||
339 | lp->stats.tx_packets++; | ||
340 | lp->stats.tx_bytes += sonic_tda_get(dev, entry, SONIC_TD_PKTSIZE); | ||
341 | } else { | ||
342 | lp->stats.tx_errors++; | ||
343 | if (td_status & 0x0642) | ||
344 | lp->stats.tx_aborted_errors++; | ||
345 | if (td_status & 0x0180) | ||
346 | lp->stats.tx_carrier_errors++; | ||
347 | if (td_status & 0x0020) | ||
348 | lp->stats.tx_window_errors++; | ||
349 | if (td_status & 0x0004) | ||
350 | lp->stats.tx_fifo_errors++; | ||
351 | } | ||
352 | |||
353 | /* We must free the original skb */ | ||
226 | dev_kfree_skb_irq(lp->tx_skb[entry]); | 354 | dev_kfree_skb_irq(lp->tx_skb[entry]); |
227 | lp->tx_skb[entry] = 0; | 355 | lp->tx_skb[entry] = NULL; |
356 | /* and unmap DMA buffer */ | ||
357 | dma_unmap_single(lp->device, lp->tx_laddr[entry], lp->tx_len[entry], DMA_TO_DEVICE); | ||
358 | lp->tx_laddr[entry] = (dma_addr_t)0; | ||
359 | freed_some = 1; | ||
360 | |||
361 | if (sonic_tda_get(dev, entry, SONIC_TD_LINK) & SONIC_EOL) { | ||
362 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
363 | break; | ||
364 | } | ||
365 | entry = (entry + 1) & SONIC_TDS_MASK; | ||
228 | } | 366 | } |
229 | /* and the VDMA address */ | ||
230 | vdma_free(lp->tx_laddr[entry]); | ||
231 | dirty_tx++; | ||
232 | } | ||
233 | 367 | ||
234 | if (lp->tx_full | 368 | if (freed_some || lp->tx_skb[entry] == NULL) |
235 | && dirty_tx + SONIC_NUM_TDS > lp->cur_tx + 2) { | 369 | netif_wake_queue(dev); /* The ring is no longer full */ |
236 | /* The ring is no longer full, clear tbusy. */ | 370 | lp->cur_tx = entry; |
237 | lp->tx_full = 0; | 371 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXDN); /* clear the interrupt */ |
238 | netif_wake_queue(dev); | ||
239 | } | 372 | } |
240 | 373 | ||
241 | lp->dirty_tx = dirty_tx; | 374 | /* |
242 | } | 375 | * check error conditions |
376 | */ | ||
377 | if (status & SONIC_INT_RFO) { | ||
378 | if (sonic_debug > 1) | ||
379 | printk("%s: rx fifo overrun\n", dev->name); | ||
380 | lp->stats.rx_fifo_errors++; | ||
381 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RFO); /* clear the interrupt */ | ||
382 | } | ||
383 | if (status & SONIC_INT_RDE) { | ||
384 | if (sonic_debug > 1) | ||
385 | printk("%s: rx descriptors exhausted\n", dev->name); | ||
386 | lp->stats.rx_dropped++; | ||
387 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RDE); /* clear the interrupt */ | ||
388 | } | ||
389 | if (status & SONIC_INT_RBAE) { | ||
390 | if (sonic_debug > 1) | ||
391 | printk("%s: rx buffer area exceeded\n", dev->name); | ||
392 | lp->stats.rx_dropped++; | ||
393 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBAE); /* clear the interrupt */ | ||
394 | } | ||
243 | 395 | ||
244 | /* | 396 | /* counter overruns; all counters are 16bit wide */ |
245 | * check error conditions | 397 | if (status & SONIC_INT_FAE) { |
246 | */ | 398 | lp->stats.rx_frame_errors += 65536; |
247 | if (status & SONIC_INT_RFO) { | 399 | SONIC_WRITE(SONIC_ISR, SONIC_INT_FAE); /* clear the interrupt */ |
248 | printk("%s: receive fifo underrun\n", dev->name); | 400 | } |
249 | lp->stats.rx_fifo_errors++; | 401 | if (status & SONIC_INT_CRC) { |
250 | } | 402 | lp->stats.rx_crc_errors += 65536; |
251 | if (status & SONIC_INT_RDE) { | 403 | SONIC_WRITE(SONIC_ISR, SONIC_INT_CRC); /* clear the interrupt */ |
252 | printk("%s: receive descriptors exhausted\n", dev->name); | 404 | } |
253 | lp->stats.rx_dropped++; | 405 | if (status & SONIC_INT_MP) { |
254 | } | 406 | lp->stats.rx_missed_errors += 65536; |
255 | if (status & SONIC_INT_RBE) { | 407 | SONIC_WRITE(SONIC_ISR, SONIC_INT_MP); /* clear the interrupt */ |
256 | printk("%s: receive buffer exhausted\n", dev->name); | 408 | } |
257 | lp->stats.rx_dropped++; | ||
258 | } | ||
259 | if (status & SONIC_INT_RBAE) { | ||
260 | printk("%s: receive buffer area exhausted\n", dev->name); | ||
261 | lp->stats.rx_dropped++; | ||
262 | } | ||
263 | 409 | ||
264 | /* counter overruns; all counters are 16bit wide */ | 410 | /* transmit error */ |
265 | if (status & SONIC_INT_FAE) | 411 | if (status & SONIC_INT_TXER) { |
266 | lp->stats.rx_frame_errors += 65536; | 412 | if ((SONIC_READ(SONIC_TCR) & SONIC_TCR_FU) && (sonic_debug > 2)) |
267 | if (status & SONIC_INT_CRC) | 413 | printk(KERN_ERR "%s: tx fifo underrun\n", dev->name); |
268 | lp->stats.rx_crc_errors += 65536; | 414 | SONIC_WRITE(SONIC_ISR, SONIC_INT_TXER); /* clear the interrupt */ |
269 | if (status & SONIC_INT_MP) | 415 | } |
270 | lp->stats.rx_missed_errors += 65536; | ||
271 | 416 | ||
272 | /* transmit error */ | 417 | /* bus retry */ |
273 | if (status & SONIC_INT_TXER) | 418 | if (status & SONIC_INT_BR) { |
274 | lp->stats.tx_errors++; | 419 | printk(KERN_ERR "%s: Bus retry occurred! Device interrupt disabled.\n", |
420 | dev->name); | ||
421 | /* ... to help debug DMA problems causing endless interrupts. */ | ||
422 | /* Bounce the eth interface to turn on the interrupt again. */ | ||
423 | SONIC_WRITE(SONIC_IMR, 0); | ||
424 | SONIC_WRITE(SONIC_ISR, SONIC_INT_BR); /* clear the interrupt */ | ||
425 | } | ||
275 | 426 | ||
276 | /* | 427 | /* load CAM done */ |
277 | * clear interrupt bits and return | 428 | if (status & SONIC_INT_LCD) |
278 | */ | 429 | SONIC_WRITE(SONIC_ISR, SONIC_INT_LCD); /* clear the interrupt */ |
279 | SONIC_WRITE(SONIC_ISR, status); | 430 | } while((status = SONIC_READ(SONIC_ISR) & SONIC_IMR_DEFAULT)); |
280 | return IRQ_HANDLED; | 431 | return IRQ_HANDLED; |
281 | } | 432 | } |
282 | 433 | ||
283 | /* | 434 | /* |
284 | * We have a good packet(s), get it/them out of the buffers. | 435 | * We have a good packet(s), pass it/them up the network stack. |
285 | */ | 436 | */ |
286 | static void sonic_rx(struct net_device *dev) | 437 | static void sonic_rx(struct net_device *dev) |
287 | { | 438 | { |
288 | unsigned int base_addr = dev->base_addr; | 439 | struct sonic_local *lp = netdev_priv(dev); |
289 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | ||
290 | sonic_rd_t *rd = &lp->rda[lp->cur_rx & SONIC_RDS_MASK]; | ||
291 | int status; | 440 | int status; |
292 | 441 | int entry = lp->cur_rx; | |
293 | while (rd->in_use == 0) { | 442 | |
294 | struct sk_buff *skb; | 443 | while (sonic_rda_get(dev, entry, SONIC_RD_IN_USE) == 0) { |
444 | struct sk_buff *used_skb; | ||
445 | struct sk_buff *new_skb; | ||
446 | dma_addr_t new_laddr; | ||
447 | u16 bufadr_l; | ||
448 | u16 bufadr_h; | ||
295 | int pkt_len; | 449 | int pkt_len; |
296 | unsigned char *pkt_ptr; | ||
297 | 450 | ||
298 | status = rd->rx_status; | 451 | status = sonic_rda_get(dev, entry, SONIC_RD_STATUS); |
299 | if (sonic_debug > 3) | ||
300 | printk("status %x, cur_rx %d, cur_rra %x\n", | ||
301 | status, lp->cur_rx, lp->cur_rra); | ||
302 | if (status & SONIC_RCR_PRX) { | 452 | if (status & SONIC_RCR_PRX) { |
303 | pkt_len = rd->rx_pktlen; | ||
304 | pkt_ptr = | ||
305 | (char *) | ||
306 | sonic_chiptomem((rd->rx_pktptr_h << 16) + | ||
307 | rd->rx_pktptr_l); | ||
308 | |||
309 | if (sonic_debug > 3) | ||
310 | printk | ||
311 | ("pktptr %p (rba %p) h:%x l:%x, bsize h:%x l:%x\n", | ||
312 | pkt_ptr, lp->rba, rd->rx_pktptr_h, | ||
313 | rd->rx_pktptr_l, | ||
314 | SONIC_READ(SONIC_RBWC1), | ||
315 | SONIC_READ(SONIC_RBWC0)); | ||
316 | |||
317 | /* Malloc up new buffer. */ | 453 | /* Malloc up new buffer. */ |
318 | skb = dev_alloc_skb(pkt_len + 2); | 454 | new_skb = dev_alloc_skb(SONIC_RBSIZE + 2); |
319 | if (skb == NULL) { | 455 | if (new_skb == NULL) { |
320 | printk | 456 | printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", dev->name); |
321 | ("%s: Memory squeeze, dropping packet.\n", | 457 | lp->stats.rx_dropped++; |
322 | dev->name); | 458 | break; |
459 | } | ||
460 | new_skb->dev = dev; | ||
461 | /* provide 16 byte IP header alignment unless DMA requires otherwise */ | ||
462 | if(SONIC_BUS_SCALE(lp->dma_bitmode) == 2) | ||
463 | skb_reserve(new_skb, 2); | ||
464 | |||
465 | new_laddr = dma_map_single(lp->device, skb_put(new_skb, SONIC_RBSIZE), | ||
466 | SONIC_RBSIZE, DMA_FROM_DEVICE); | ||
467 | if (!new_laddr) { | ||
468 | dev_kfree_skb(new_skb); | ||
469 | printk(KERN_ERR "%s: Failed to map rx buffer, dropping packet.\n", dev->name); | ||
323 | lp->stats.rx_dropped++; | 470 | lp->stats.rx_dropped++; |
324 | break; | 471 | break; |
325 | } | 472 | } |
326 | skb->dev = dev; | 473 | |
327 | skb_reserve(skb, 2); /* 16 byte align */ | 474 | /* now we have a new skb to replace it, pass the used one up the stack */ |
328 | skb_put(skb, pkt_len); /* Make room */ | 475 | dma_unmap_single(lp->device, lp->rx_laddr[entry], SONIC_RBSIZE, DMA_FROM_DEVICE); |
329 | eth_copy_and_sum(skb, pkt_ptr, pkt_len, 0); | 476 | used_skb = lp->rx_skb[entry]; |
330 | skb->protocol = eth_type_trans(skb, dev); | 477 | pkt_len = sonic_rda_get(dev, entry, SONIC_RD_PKTLEN); |
331 | netif_rx(skb); /* pass the packet to upper layers */ | 478 | skb_trim(used_skb, pkt_len); |
479 | used_skb->protocol = eth_type_trans(used_skb, dev); | ||
480 | netif_rx(used_skb); | ||
332 | dev->last_rx = jiffies; | 481 | dev->last_rx = jiffies; |
333 | lp->stats.rx_packets++; | 482 | lp->stats.rx_packets++; |
334 | lp->stats.rx_bytes += pkt_len; | 483 | lp->stats.rx_bytes += pkt_len; |
335 | 484 | ||
485 | /* and insert the new skb */ | ||
486 | lp->rx_laddr[entry] = new_laddr; | ||
487 | lp->rx_skb[entry] = new_skb; | ||
488 | |||
489 | bufadr_l = (unsigned long)new_laddr & 0xffff; | ||
490 | bufadr_h = (unsigned long)new_laddr >> 16; | ||
491 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_L, bufadr_l); | ||
492 | sonic_rra_put(dev, entry, SONIC_RR_BUFADR_H, bufadr_h); | ||
336 | } else { | 493 | } else { |
337 | /* This should only happen, if we enable accepting broken packets. */ | 494 | /* This should only happen, if we enable accepting broken packets. */ |
338 | lp->stats.rx_errors++; | 495 | lp->stats.rx_errors++; |
@@ -341,29 +498,35 @@ static void sonic_rx(struct net_device *dev) | |||
341 | if (status & SONIC_RCR_CRCR) | 498 | if (status & SONIC_RCR_CRCR) |
342 | lp->stats.rx_crc_errors++; | 499 | lp->stats.rx_crc_errors++; |
343 | } | 500 | } |
344 | |||
345 | rd->in_use = 1; | ||
346 | rd = &lp->rda[(++lp->cur_rx) & SONIC_RDS_MASK]; | ||
347 | /* now give back the buffer to the receive buffer area */ | ||
348 | if (status & SONIC_RCR_LPKT) { | 501 | if (status & SONIC_RCR_LPKT) { |
349 | /* | 502 | /* |
350 | * this was the last packet out of the current receice buffer | 503 | * this was the last packet out of the current receive buffer |
351 | * give the buffer back to the SONIC | 504 | * give the buffer back to the SONIC |
352 | */ | 505 | */ |
353 | lp->cur_rra += sizeof(sonic_rr_t); | 506 | lp->cur_rwp += SIZEOF_SONIC_RR * SONIC_BUS_SCALE(lp->dma_bitmode); |
354 | if (lp->cur_rra > | 507 | if (lp->cur_rwp >= lp->rra_end) lp->cur_rwp = lp->rra_laddr & 0xffff; |
355 | (lp->rra_laddr + | 508 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); |
356 | (SONIC_NUM_RRS - | 509 | if (SONIC_READ(SONIC_ISR) & SONIC_INT_RBE) { |
357 | 1) * sizeof(sonic_rr_t))) lp->cur_rra = | 510 | if (sonic_debug > 2) |
358 | lp->rra_laddr; | 511 | printk("%s: rx buffer exhausted\n", dev->name); |
359 | SONIC_WRITE(SONIC_RWP, lp->cur_rra & 0xffff); | 512 | SONIC_WRITE(SONIC_ISR, SONIC_INT_RBE); /* clear the flag */ |
513 | } | ||
360 | } else | 514 | } else |
361 | printk | 515 | printk(KERN_ERR "%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", |
362 | ("%s: rx desc without RCR_LPKT. Shouldn't happen !?\n", | ||
363 | dev->name); | 516 | dev->name); |
517 | /* | ||
518 | * give back the descriptor | ||
519 | */ | ||
520 | sonic_rda_put(dev, entry, SONIC_RD_LINK, | ||
521 | sonic_rda_get(dev, entry, SONIC_RD_LINK) | SONIC_EOL); | ||
522 | sonic_rda_put(dev, entry, SONIC_RD_IN_USE, 1); | ||
523 | sonic_rda_put(dev, lp->eol_rx, SONIC_RD_LINK, | ||
524 | sonic_rda_get(dev, lp->eol_rx, SONIC_RD_LINK) & ~SONIC_EOL); | ||
525 | lp->eol_rx = entry; | ||
526 | lp->cur_rx = entry = (entry + 1) & SONIC_RDS_MASK; | ||
364 | } | 527 | } |
365 | /* | 528 | /* |
366 | * If any worth-while packets have been received, dev_rint() | 529 | * If any worth-while packets have been received, netif_rx() |
367 | * has done a mark_bh(NET_BH) for us and will work on them | 530 | * has done a mark_bh(NET_BH) for us and will work on them |
368 | * when we get to the bottom-half routine. | 531 | * when we get to the bottom-half routine. |
369 | */ | 532 | */ |
@@ -376,8 +539,7 @@ static void sonic_rx(struct net_device *dev) | |||
376 | */ | 539 | */ |
377 | static struct net_device_stats *sonic_get_stats(struct net_device *dev) | 540 | static struct net_device_stats *sonic_get_stats(struct net_device *dev) |
378 | { | 541 | { |
379 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 542 | struct sonic_local *lp = netdev_priv(dev); |
380 | unsigned int base_addr = dev->base_addr; | ||
381 | 543 | ||
382 | /* read the tally counter from the SONIC and reset them */ | 544 | /* read the tally counter from the SONIC and reset them */ |
383 | lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); | 545 | lp->stats.rx_crc_errors += SONIC_READ(SONIC_CRCT); |
@@ -396,8 +558,7 @@ static struct net_device_stats *sonic_get_stats(struct net_device *dev) | |||
396 | */ | 558 | */ |
397 | static void sonic_multicast_list(struct net_device *dev) | 559 | static void sonic_multicast_list(struct net_device *dev) |
398 | { | 560 | { |
399 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 561 | struct sonic_local *lp = netdev_priv(dev); |
400 | unsigned int base_addr = dev->base_addr; | ||
401 | unsigned int rcr; | 562 | unsigned int rcr; |
402 | struct dev_mc_list *dmi = dev->mc_list; | 563 | struct dev_mc_list *dmi = dev->mc_list; |
403 | unsigned char *addr; | 564 | unsigned char *addr; |
@@ -413,20 +574,15 @@ static void sonic_multicast_list(struct net_device *dev) | |||
413 | rcr |= SONIC_RCR_AMC; | 574 | rcr |= SONIC_RCR_AMC; |
414 | } else { | 575 | } else { |
415 | if (sonic_debug > 2) | 576 | if (sonic_debug > 2) |
416 | printk | 577 | printk("sonic_multicast_list: mc_count %d\n", dev->mc_count); |
417 | ("sonic_multicast_list: mc_count %d\n", | 578 | sonic_set_cam_enable(dev, 1); /* always enable our own address */ |
418 | dev->mc_count); | ||
419 | lp->cda.cam_enable = 1; /* always enable our own address */ | ||
420 | for (i = 1; i <= dev->mc_count; i++) { | 579 | for (i = 1; i <= dev->mc_count; i++) { |
421 | addr = dmi->dmi_addr; | 580 | addr = dmi->dmi_addr; |
422 | dmi = dmi->next; | 581 | dmi = dmi->next; |
423 | lp->cda.cam_desc[i].cam_cap0 = | 582 | sonic_cda_put(dev, i, SONIC_CD_CAP0, addr[1] << 8 | addr[0]); |
424 | addr[1] << 8 | addr[0]; | 583 | sonic_cda_put(dev, i, SONIC_CD_CAP1, addr[3] << 8 | addr[2]); |
425 | lp->cda.cam_desc[i].cam_cap1 = | 584 | sonic_cda_put(dev, i, SONIC_CD_CAP2, addr[5] << 8 | addr[4]); |
426 | addr[3] << 8 | addr[2]; | 585 | sonic_set_cam_enable(dev, sonic_get_cam_enable(dev) | (1 << i)); |
427 | lp->cda.cam_desc[i].cam_cap2 = | ||
428 | addr[5] << 8 | addr[4]; | ||
429 | lp->cda.cam_enable |= (1 << i); | ||
430 | } | 586 | } |
431 | SONIC_WRITE(SONIC_CDC, 16); | 587 | SONIC_WRITE(SONIC_CDC, 16); |
432 | /* issue Load CAM command */ | 588 | /* issue Load CAM command */ |
@@ -447,19 +603,16 @@ static void sonic_multicast_list(struct net_device *dev) | |||
447 | */ | 603 | */ |
448 | static int sonic_init(struct net_device *dev) | 604 | static int sonic_init(struct net_device *dev) |
449 | { | 605 | { |
450 | unsigned int base_addr = dev->base_addr; | ||
451 | unsigned int cmd; | 606 | unsigned int cmd; |
452 | struct sonic_local *lp = (struct sonic_local *) dev->priv; | 607 | struct sonic_local *lp = netdev_priv(dev); |
453 | unsigned int rra_start; | ||
454 | unsigned int rra_end; | ||
455 | int i; | 608 | int i; |
456 | 609 | ||
457 | /* | 610 | /* |
458 | * put the Sonic into software-reset mode and | 611 | * put the Sonic into software-reset mode and |
459 | * disable all interrupts | 612 | * disable all interrupts |
460 | */ | 613 | */ |
461 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
462 | SONIC_WRITE(SONIC_IMR, 0); | 614 | SONIC_WRITE(SONIC_IMR, 0); |
615 | SONIC_WRITE(SONIC_ISR, 0x7fff); | ||
463 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); | 616 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RST); |
464 | 617 | ||
465 | /* | 618 | /* |
@@ -475,34 +628,32 @@ static int sonic_init(struct net_device *dev) | |||
475 | if (sonic_debug > 2) | 628 | if (sonic_debug > 2) |
476 | printk("sonic_init: initialize receive resource area\n"); | 629 | printk("sonic_init: initialize receive resource area\n"); |
477 | 630 | ||
478 | rra_start = lp->rra_laddr & 0xffff; | ||
479 | rra_end = | ||
480 | (rra_start + (SONIC_NUM_RRS * sizeof(sonic_rr_t))) & 0xffff; | ||
481 | |||
482 | for (i = 0; i < SONIC_NUM_RRS; i++) { | 631 | for (i = 0; i < SONIC_NUM_RRS; i++) { |
483 | lp->rra[i].rx_bufadr_l = | 632 | u16 bufadr_l = (unsigned long)lp->rx_laddr[i] & 0xffff; |
484 | (lp->rba_laddr + i * SONIC_RBSIZE) & 0xffff; | 633 | u16 bufadr_h = (unsigned long)lp->rx_laddr[i] >> 16; |
485 | lp->rra[i].rx_bufadr_h = | 634 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_L, bufadr_l); |
486 | (lp->rba_laddr + i * SONIC_RBSIZE) >> 16; | 635 | sonic_rra_put(dev, i, SONIC_RR_BUFADR_H, bufadr_h); |
487 | lp->rra[i].rx_bufsize_l = SONIC_RBSIZE >> 1; | 636 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_L, SONIC_RBSIZE >> 1); |
488 | lp->rra[i].rx_bufsize_h = 0; | 637 | sonic_rra_put(dev, i, SONIC_RR_BUFSIZE_H, 0); |
489 | } | 638 | } |
490 | 639 | ||
491 | /* initialize all RRA registers */ | 640 | /* initialize all RRA registers */ |
492 | SONIC_WRITE(SONIC_RSA, rra_start); | 641 | lp->rra_end = (lp->rra_laddr + SONIC_NUM_RRS * SIZEOF_SONIC_RR * |
493 | SONIC_WRITE(SONIC_REA, rra_end); | 642 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; |
494 | SONIC_WRITE(SONIC_RRP, rra_start); | 643 | lp->cur_rwp = (lp->rra_laddr + (SONIC_NUM_RRS - 1) * SIZEOF_SONIC_RR * |
495 | SONIC_WRITE(SONIC_RWP, rra_end); | 644 | SONIC_BUS_SCALE(lp->dma_bitmode)) & 0xffff; |
645 | |||
646 | SONIC_WRITE(SONIC_RSA, lp->rra_laddr & 0xffff); | ||
647 | SONIC_WRITE(SONIC_REA, lp->rra_end); | ||
648 | SONIC_WRITE(SONIC_RRP, lp->rra_laddr & 0xffff); | ||
649 | SONIC_WRITE(SONIC_RWP, lp->cur_rwp); | ||
496 | SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); | 650 | SONIC_WRITE(SONIC_URRA, lp->rra_laddr >> 16); |
497 | SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE - 2) >> 1); | 651 | SONIC_WRITE(SONIC_EOBC, (SONIC_RBSIZE >> 1) - (lp->dma_bitmode ? 2 : 1)); |
498 | |||
499 | lp->cur_rra = | ||
500 | lp->rra_laddr + (SONIC_NUM_RRS - 1) * sizeof(sonic_rr_t); | ||
501 | 652 | ||
502 | /* load the resource pointers */ | 653 | /* load the resource pointers */ |
503 | if (sonic_debug > 3) | 654 | if (sonic_debug > 3) |
504 | printk("sonic_init: issueing RRRA command\n"); | 655 | printk("sonic_init: issuing RRRA command\n"); |
505 | 656 | ||
506 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); | 657 | SONIC_WRITE(SONIC_CMD, SONIC_CR_RRRA); |
507 | i = 0; | 658 | i = 0; |
508 | while (i++ < 100) { | 659 | while (i++ < 100) { |
@@ -511,27 +662,30 @@ static int sonic_init(struct net_device *dev) | |||
511 | } | 662 | } |
512 | 663 | ||
513 | if (sonic_debug > 2) | 664 | if (sonic_debug > 2) |
514 | printk("sonic_init: status=%x\n", SONIC_READ(SONIC_CMD)); | 665 | printk("sonic_init: status=%x i=%d\n", SONIC_READ(SONIC_CMD), i); |
515 | 666 | ||
516 | /* | 667 | /* |
517 | * Initialize the receive descriptors so that they | 668 | * Initialize the receive descriptors so that they |
518 | * become a circular linked list, ie. let the last | 669 | * become a circular linked list, ie. let the last |
519 | * descriptor point to the first again. | 670 | * descriptor point to the first again. |
520 | */ | 671 | */ |
521 | if (sonic_debug > 2) | 672 | if (sonic_debug > 2) |
522 | printk("sonic_init: initialize receive descriptors\n"); | 673 | printk("sonic_init: initialize receive descriptors\n"); |
523 | for (i = 0; i < SONIC_NUM_RDS; i++) { | 674 | for (i=0; i<SONIC_NUM_RDS; i++) { |
524 | lp->rda[i].rx_status = 0; | 675 | sonic_rda_put(dev, i, SONIC_RD_STATUS, 0); |
525 | lp->rda[i].rx_pktlen = 0; | 676 | sonic_rda_put(dev, i, SONIC_RD_PKTLEN, 0); |
526 | lp->rda[i].rx_pktptr_l = 0; | 677 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_L, 0); |
527 | lp->rda[i].rx_pktptr_h = 0; | 678 | sonic_rda_put(dev, i, SONIC_RD_PKTPTR_H, 0); |
528 | lp->rda[i].rx_seqno = 0; | 679 | sonic_rda_put(dev, i, SONIC_RD_SEQNO, 0); |
529 | lp->rda[i].in_use = 1; | 680 | sonic_rda_put(dev, i, SONIC_RD_IN_USE, 1); |
530 | lp->rda[i].link = | 681 | sonic_rda_put(dev, i, SONIC_RD_LINK, |
531 | lp->rda_laddr + (i + 1) * sizeof(sonic_rd_t); | 682 | lp->rda_laddr + |
683 | ((i+1) * SIZEOF_SONIC_RD * SONIC_BUS_SCALE(lp->dma_bitmode))); | ||
532 | } | 684 | } |
533 | /* fix last descriptor */ | 685 | /* fix last descriptor */ |
534 | lp->rda[SONIC_NUM_RDS - 1].link = lp->rda_laddr; | 686 | sonic_rda_put(dev, SONIC_NUM_RDS - 1, SONIC_RD_LINK, |
687 | (lp->rda_laddr & 0xffff) | SONIC_EOL); | ||
688 | lp->eol_rx = SONIC_NUM_RDS - 1; | ||
535 | lp->cur_rx = 0; | 689 | lp->cur_rx = 0; |
536 | SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); | 690 | SONIC_WRITE(SONIC_URDA, lp->rda_laddr >> 16); |
537 | SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); | 691 | SONIC_WRITE(SONIC_CRDA, lp->rda_laddr & 0xffff); |
@@ -542,34 +696,34 @@ static int sonic_init(struct net_device *dev) | |||
542 | if (sonic_debug > 2) | 696 | if (sonic_debug > 2) |
543 | printk("sonic_init: initialize transmit descriptors\n"); | 697 | printk("sonic_init: initialize transmit descriptors\n"); |
544 | for (i = 0; i < SONIC_NUM_TDS; i++) { | 698 | for (i = 0; i < SONIC_NUM_TDS; i++) { |
545 | lp->tda[i].tx_status = 0; | 699 | sonic_tda_put(dev, i, SONIC_TD_STATUS, 0); |
546 | lp->tda[i].tx_config = 0; | 700 | sonic_tda_put(dev, i, SONIC_TD_CONFIG, 0); |
547 | lp->tda[i].tx_pktsize = 0; | 701 | sonic_tda_put(dev, i, SONIC_TD_PKTSIZE, 0); |
548 | lp->tda[i].tx_frag_count = 0; | 702 | sonic_tda_put(dev, i, SONIC_TD_FRAG_COUNT, 0); |
549 | lp->tda[i].link = | 703 | sonic_tda_put(dev, i, SONIC_TD_LINK, |
550 | (lp->tda_laddr + | 704 | (lp->tda_laddr & 0xffff) + |
551 | (i + 1) * sizeof(sonic_td_t)) | SONIC_END_OF_LINKS; | 705 | (i + 1) * SIZEOF_SONIC_TD * SONIC_BUS_SCALE(lp->dma_bitmode)); |
706 | lp->tx_skb[i] = NULL; | ||
552 | } | 707 | } |
553 | lp->tda[SONIC_NUM_TDS - 1].link = | 708 | /* fix last descriptor */ |
554 | (lp->tda_laddr & 0xffff) | SONIC_END_OF_LINKS; | 709 | sonic_tda_put(dev, SONIC_NUM_TDS - 1, SONIC_TD_LINK, |
710 | (lp->tda_laddr & 0xffff)); | ||
555 | 711 | ||
556 | SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); | 712 | SONIC_WRITE(SONIC_UTDA, lp->tda_laddr >> 16); |
557 | SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); | 713 | SONIC_WRITE(SONIC_CTDA, lp->tda_laddr & 0xffff); |
558 | lp->cur_tx = lp->dirty_tx = 0; | 714 | lp->cur_tx = lp->next_tx = 0; |
559 | 715 | lp->eol_tx = SONIC_NUM_TDS - 1; | |
716 | |||
560 | /* | 717 | /* |
561 | * put our own address to CAM desc[0] | 718 | * put our own address to CAM desc[0] |
562 | */ | 719 | */ |
563 | lp->cda.cam_desc[0].cam_cap0 = | 720 | sonic_cda_put(dev, 0, SONIC_CD_CAP0, dev->dev_addr[1] << 8 | dev->dev_addr[0]); |
564 | dev->dev_addr[1] << 8 | dev->dev_addr[0]; | 721 | sonic_cda_put(dev, 0, SONIC_CD_CAP1, dev->dev_addr[3] << 8 | dev->dev_addr[2]); |
565 | lp->cda.cam_desc[0].cam_cap1 = | 722 | sonic_cda_put(dev, 0, SONIC_CD_CAP2, dev->dev_addr[5] << 8 | dev->dev_addr[4]); |
566 | dev->dev_addr[3] << 8 | dev->dev_addr[2]; | 723 | sonic_set_cam_enable(dev, 1); |
567 | lp->cda.cam_desc[0].cam_cap2 = | ||
568 | dev->dev_addr[5] << 8 | dev->dev_addr[4]; | ||
569 | lp->cda.cam_enable = 1; | ||
570 | 724 | ||
571 | for (i = 0; i < 16; i++) | 725 | for (i = 0; i < 16; i++) |
572 | lp->cda.cam_desc[i].cam_entry_pointer = i; | 726 | sonic_cda_put(dev, i, SONIC_CD_ENTRY_POINTER, i); |
573 | 727 | ||
574 | /* | 728 | /* |
575 | * initialize CAM registers | 729 | * initialize CAM registers |
@@ -588,8 +742,8 @@ static int sonic_init(struct net_device *dev) | |||
588 | break; | 742 | break; |
589 | } | 743 | } |
590 | if (sonic_debug > 2) { | 744 | if (sonic_debug > 2) { |
591 | printk("sonic_init: CMD=%x, ISR=%x\n", | 745 | printk("sonic_init: CMD=%x, ISR=%x\n, i=%d", |
592 | SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR)); | 746 | SONIC_READ(SONIC_CMD), SONIC_READ(SONIC_ISR), i); |
593 | } | 747 | } |
594 | 748 | ||
595 | /* | 749 | /* |
@@ -604,7 +758,7 @@ static int sonic_init(struct net_device *dev) | |||
604 | 758 | ||
605 | cmd = SONIC_READ(SONIC_CMD); | 759 | cmd = SONIC_READ(SONIC_CMD); |
606 | if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) | 760 | if ((cmd & SONIC_CR_RXEN) == 0 || (cmd & SONIC_CR_STP) == 0) |
607 | printk("sonic_init: failed, status=%x\n", cmd); | 761 | printk(KERN_ERR "sonic_init: failed, status=%x\n", cmd); |
608 | 762 | ||
609 | if (sonic_debug > 2) | 763 | if (sonic_debug > 2) |
610 | printk("sonic_init: new status=%x\n", | 764 | printk("sonic_init: new status=%x\n", |
diff --git a/drivers/net/sonic.h b/drivers/net/sonic.h index c4a6d58e4afb..cede969a8baa 100644 --- a/drivers/net/sonic.h +++ b/drivers/net/sonic.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Helpfile for sonic.c | 2 | * Header file for sonic.c |
3 | * | 3 | * |
4 | * (C) Waldorf Electronics, Germany | 4 | * (C) Waldorf Electronics, Germany |
5 | * Written by Andreas Busse | 5 | * Written by Andreas Busse |
@@ -9,10 +9,16 @@ | |||
9 | * and pad structure members must be exchanged. Also, the structures | 9 | * and pad structure members must be exchanged. Also, the structures |
10 | * need to be changed accordingly to the bus size. | 10 | * need to be changed accordingly to the bus size. |
11 | * | 11 | * |
12 | * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian), | 12 | * 981229 MSch: did just that for the 68k Mac port (32 bit, big endian) |
13 | * see CONFIG_MACSONIC branch below. | ||
14 | * | 13 | * |
14 | * 990611 David Huggins-Daines <dhd@debian.org>: This machine abstraction | ||
15 | * does not cope with 16-bit bus sizes very well. Therefore I have | ||
16 | * rewritten it with ugly macros and evil inlines. | ||
17 | * | ||
18 | * 050625 Finn Thain: introduced more 32-bit cards and dhd's support | ||
19 | * for 16-bit cards (from the mac68k project). | ||
15 | */ | 20 | */ |
21 | |||
16 | #ifndef SONIC_H | 22 | #ifndef SONIC_H |
17 | #define SONIC_H | 23 | #define SONIC_H |
18 | 24 | ||
@@ -83,6 +89,7 @@ | |||
83 | /* | 89 | /* |
84 | * Error counters | 90 | * Error counters |
85 | */ | 91 | */ |
92 | |||
86 | #define SONIC_CRCT 0x2c | 93 | #define SONIC_CRCT 0x2c |
87 | #define SONIC_FAET 0x2d | 94 | #define SONIC_FAET 0x2d |
88 | #define SONIC_MPT 0x2e | 95 | #define SONIC_MPT 0x2e |
@@ -182,14 +189,14 @@ | |||
182 | 189 | ||
183 | #define SONIC_INT_BR 0x4000 | 190 | #define SONIC_INT_BR 0x4000 |
184 | #define SONIC_INT_HBL 0x2000 | 191 | #define SONIC_INT_HBL 0x2000 |
185 | #define SONIC_INT_LCD 0x1000 | 192 | #define SONIC_INT_LCD 0x1000 |
186 | #define SONIC_INT_PINT 0x0800 | 193 | #define SONIC_INT_PINT 0x0800 |
187 | #define SONIC_INT_PKTRX 0x0400 | 194 | #define SONIC_INT_PKTRX 0x0400 |
188 | #define SONIC_INT_TXDN 0x0200 | 195 | #define SONIC_INT_TXDN 0x0200 |
189 | #define SONIC_INT_TXER 0x0100 | 196 | #define SONIC_INT_TXER 0x0100 |
190 | #define SONIC_INT_TC 0x0080 | 197 | #define SONIC_INT_TC 0x0080 |
191 | #define SONIC_INT_RDE 0x0040 | 198 | #define SONIC_INT_RDE 0x0040 |
192 | #define SONIC_INT_RBE 0x0020 | 199 | #define SONIC_INT_RBE 0x0020 |
193 | #define SONIC_INT_RBAE 0x0010 | 200 | #define SONIC_INT_RBAE 0x0010 |
194 | #define SONIC_INT_CRC 0x0008 | 201 | #define SONIC_INT_CRC 0x0008 |
195 | #define SONIC_INT_FAE 0x0004 | 202 | #define SONIC_INT_FAE 0x0004 |
@@ -201,224 +208,61 @@ | |||
201 | * The interrupts we allow. | 208 | * The interrupts we allow. |
202 | */ | 209 | */ |
203 | 210 | ||
204 | #define SONIC_IMR_DEFAULT (SONIC_INT_BR | \ | 211 | #define SONIC_IMR_DEFAULT ( SONIC_INT_BR | \ |
205 | SONIC_INT_LCD | \ | 212 | SONIC_INT_LCD | \ |
206 | SONIC_INT_PINT | \ | 213 | SONIC_INT_RFO | \ |
207 | SONIC_INT_PKTRX | \ | 214 | SONIC_INT_PKTRX | \ |
208 | SONIC_INT_TXDN | \ | 215 | SONIC_INT_TXDN | \ |
209 | SONIC_INT_TXER | \ | 216 | SONIC_INT_TXER | \ |
210 | SONIC_INT_RDE | \ | 217 | SONIC_INT_RDE | \ |
211 | SONIC_INT_RBE | \ | ||
212 | SONIC_INT_RBAE | \ | 218 | SONIC_INT_RBAE | \ |
213 | SONIC_INT_CRC | \ | 219 | SONIC_INT_CRC | \ |
214 | SONIC_INT_FAE | \ | 220 | SONIC_INT_FAE | \ |
215 | SONIC_INT_MP) | 221 | SONIC_INT_MP) |
216 | 222 | ||
217 | 223 | ||
218 | #define SONIC_END_OF_LINKS 0x0001 | 224 | #define SONIC_EOL 0x0001 |
219 | |||
220 | |||
221 | #ifdef CONFIG_MACSONIC | ||
222 | /* | ||
223 | * Big endian like structures on 680x0 Macs | ||
224 | */ | ||
225 | |||
226 | typedef struct { | ||
227 | u32 rx_bufadr_l; /* receive buffer ptr */ | ||
228 | u32 rx_bufadr_h; | ||
229 | |||
230 | u32 rx_bufsize_l; /* no. of words in the receive buffer */ | ||
231 | u32 rx_bufsize_h; | ||
232 | } sonic_rr_t; | ||
233 | |||
234 | /* | ||
235 | * Sonic receive descriptor. Receive descriptors are | ||
236 | * kept in a linked list of these structures. | ||
237 | */ | ||
238 | |||
239 | typedef struct { | ||
240 | SREGS_PAD(pad0); | ||
241 | u16 rx_status; /* status after reception of a packet */ | ||
242 | SREGS_PAD(pad1); | ||
243 | u16 rx_pktlen; /* length of the packet incl. CRC */ | ||
244 | |||
245 | /* | ||
246 | * Pointers to the location in the receive buffer area (RBA) | ||
247 | * where the packet resides. A packet is always received into | ||
248 | * a contiguous piece of memory. | ||
249 | */ | ||
250 | SREGS_PAD(pad2); | ||
251 | u16 rx_pktptr_l; | ||
252 | SREGS_PAD(pad3); | ||
253 | u16 rx_pktptr_h; | ||
254 | |||
255 | SREGS_PAD(pad4); | ||
256 | u16 rx_seqno; /* sequence no. */ | ||
257 | |||
258 | SREGS_PAD(pad5); | ||
259 | u16 link; /* link to next RDD (end if EOL bit set) */ | ||
260 | |||
261 | /* | ||
262 | * Owner of this descriptor, 0= driver, 1=sonic | ||
263 | */ | ||
264 | |||
265 | SREGS_PAD(pad6); | ||
266 | u16 in_use; | ||
267 | |||
268 | caddr_t rda_next; /* pointer to next RD */ | ||
269 | } sonic_rd_t; | ||
270 | |||
271 | |||
272 | /* | ||
273 | * Describes a Transmit Descriptor | ||
274 | */ | ||
275 | typedef struct { | ||
276 | SREGS_PAD(pad0); | ||
277 | u16 tx_status; /* status after transmission of a packet */ | ||
278 | SREGS_PAD(pad1); | ||
279 | u16 tx_config; /* transmit configuration for this packet */ | ||
280 | SREGS_PAD(pad2); | ||
281 | u16 tx_pktsize; /* size of the packet to be transmitted */ | ||
282 | SREGS_PAD(pad3); | ||
283 | u16 tx_frag_count; /* no. of fragments */ | ||
284 | |||
285 | SREGS_PAD(pad4); | ||
286 | u16 tx_frag_ptr_l; | ||
287 | SREGS_PAD(pad5); | ||
288 | u16 tx_frag_ptr_h; | ||
289 | SREGS_PAD(pad6); | ||
290 | u16 tx_frag_size; | ||
291 | |||
292 | SREGS_PAD(pad7); | ||
293 | u16 link; /* ptr to next descriptor */ | ||
294 | } sonic_td_t; | ||
295 | |||
296 | |||
297 | /* | ||
298 | * Describes an entry in the CAM Descriptor Area. | ||
299 | */ | ||
300 | |||
301 | typedef struct { | ||
302 | SREGS_PAD(pad0); | ||
303 | u16 cam_entry_pointer; | ||
304 | SREGS_PAD(pad1); | ||
305 | u16 cam_cap0; | ||
306 | SREGS_PAD(pad2); | ||
307 | u16 cam_cap1; | ||
308 | SREGS_PAD(pad3); | ||
309 | u16 cam_cap2; | ||
310 | } sonic_cd_t; | ||
311 | |||
312 | #define CAM_DESCRIPTORS 16 | 225 | #define CAM_DESCRIPTORS 16 |
313 | 226 | ||
314 | 227 | /* Offsets in the various DMA buffers accessed by the SONIC */ | |
315 | typedef struct { | 228 | |
316 | sonic_cd_t cam_desc[CAM_DESCRIPTORS]; | 229 | #define SONIC_BITMODE16 0 |
317 | SREGS_PAD(pad); | 230 | #define SONIC_BITMODE32 1 |
318 | u16 cam_enable; | 231 | #define SONIC_BUS_SCALE(bitmode) ((bitmode) ? 4 : 2) |
319 | } sonic_cda_t; | 232 | /* Note! These are all measured in bus-size units, so use SONIC_BUS_SCALE */ |
320 | 233 | #define SIZEOF_SONIC_RR 4 | |
321 | #else /* original declarations, little endian 32 bit */ | 234 | #define SONIC_RR_BUFADR_L 0 |
322 | 235 | #define SONIC_RR_BUFADR_H 1 | |
323 | /* | 236 | #define SONIC_RR_BUFSIZE_L 2 |
324 | * structure definitions | 237 | #define SONIC_RR_BUFSIZE_H 3 |
325 | */ | 238 | |
326 | 239 | #define SIZEOF_SONIC_RD 7 | |
327 | typedef struct { | 240 | #define SONIC_RD_STATUS 0 |
328 | u32 rx_bufadr_l; /* receive buffer ptr */ | 241 | #define SONIC_RD_PKTLEN 1 |
329 | u32 rx_bufadr_h; | 242 | #define SONIC_RD_PKTPTR_L 2 |
330 | 243 | #define SONIC_RD_PKTPTR_H 3 | |
331 | u32 rx_bufsize_l; /* no. of words in the receive buffer */ | 244 | #define SONIC_RD_SEQNO 4 |
332 | u32 rx_bufsize_h; | 245 | #define SONIC_RD_LINK 5 |
333 | } sonic_rr_t; | 246 | #define SONIC_RD_IN_USE 6 |
334 | 247 | ||
335 | /* | 248 | #define SIZEOF_SONIC_TD 8 |
336 | * Sonic receive descriptor. Receive descriptors are | 249 | #define SONIC_TD_STATUS 0 |
337 | * kept in a linked list of these structures. | 250 | #define SONIC_TD_CONFIG 1 |
338 | */ | 251 | #define SONIC_TD_PKTSIZE 2 |
339 | 252 | #define SONIC_TD_FRAG_COUNT 3 | |
340 | typedef struct { | 253 | #define SONIC_TD_FRAG_PTR_L 4 |
341 | u16 rx_status; /* status after reception of a packet */ | 254 | #define SONIC_TD_FRAG_PTR_H 5 |
342 | SREGS_PAD(pad0); | 255 | #define SONIC_TD_FRAG_SIZE 6 |
343 | u16 rx_pktlen; /* length of the packet incl. CRC */ | 256 | #define SONIC_TD_LINK 7 |
344 | SREGS_PAD(pad1); | 257 | |
345 | 258 | #define SIZEOF_SONIC_CD 4 | |
346 | /* | 259 | #define SONIC_CD_ENTRY_POINTER 0 |
347 | * Pointers to the location in the receive buffer area (RBA) | 260 | #define SONIC_CD_CAP0 1 |
348 | * where the packet resides. A packet is always received into | 261 | #define SONIC_CD_CAP1 2 |
349 | * a contiguous piece of memory. | 262 | #define SONIC_CD_CAP2 3 |
350 | */ | 263 | |
351 | u16 rx_pktptr_l; | 264 | #define SIZEOF_SONIC_CDA ((CAM_DESCRIPTORS * SIZEOF_SONIC_CD) + 1) |
352 | SREGS_PAD(pad2); | 265 | #define SONIC_CDA_CAM_ENABLE (CAM_DESCRIPTORS * SIZEOF_SONIC_CD) |
353 | u16 rx_pktptr_h; | ||
354 | SREGS_PAD(pad3); | ||
355 | |||
356 | u16 rx_seqno; /* sequence no. */ | ||
357 | SREGS_PAD(pad4); | ||
358 | |||
359 | u16 link; /* link to next RDD (end if EOL bit set) */ | ||
360 | SREGS_PAD(pad5); | ||
361 | |||
362 | /* | ||
363 | * Owner of this descriptor, 0= driver, 1=sonic | ||
364 | */ | ||
365 | |||
366 | u16 in_use; | ||
367 | SREGS_PAD(pad6); | ||
368 | |||
369 | caddr_t rda_next; /* pointer to next RD */ | ||
370 | } sonic_rd_t; | ||
371 | |||
372 | |||
373 | /* | ||
374 | * Describes a Transmit Descriptor | ||
375 | */ | ||
376 | typedef struct { | ||
377 | u16 tx_status; /* status after transmission of a packet */ | ||
378 | SREGS_PAD(pad0); | ||
379 | u16 tx_config; /* transmit configuration for this packet */ | ||
380 | SREGS_PAD(pad1); | ||
381 | u16 tx_pktsize; /* size of the packet to be transmitted */ | ||
382 | SREGS_PAD(pad2); | ||
383 | u16 tx_frag_count; /* no. of fragments */ | ||
384 | SREGS_PAD(pad3); | ||
385 | |||
386 | u16 tx_frag_ptr_l; | ||
387 | SREGS_PAD(pad4); | ||
388 | u16 tx_frag_ptr_h; | ||
389 | SREGS_PAD(pad5); | ||
390 | u16 tx_frag_size; | ||
391 | SREGS_PAD(pad6); | ||
392 | |||
393 | u16 link; /* ptr to next descriptor */ | ||
394 | SREGS_PAD(pad7); | ||
395 | } sonic_td_t; | ||
396 | |||
397 | |||
398 | /* | ||
399 | * Describes an entry in the CAM Descriptor Area. | ||
400 | */ | ||
401 | |||
402 | typedef struct { | ||
403 | u16 cam_entry_pointer; | ||
404 | SREGS_PAD(pad0); | ||
405 | u16 cam_cap0; | ||
406 | SREGS_PAD(pad1); | ||
407 | u16 cam_cap1; | ||
408 | SREGS_PAD(pad2); | ||
409 | u16 cam_cap2; | ||
410 | SREGS_PAD(pad3); | ||
411 | } sonic_cd_t; | ||
412 | |||
413 | #define CAM_DESCRIPTORS 16 | ||
414 | |||
415 | |||
416 | typedef struct { | ||
417 | sonic_cd_t cam_desc[CAM_DESCRIPTORS]; | ||
418 | u16 cam_enable; | ||
419 | SREGS_PAD(pad); | ||
420 | } sonic_cda_t; | ||
421 | #endif /* endianness */ | ||
422 | 266 | ||
423 | /* | 267 | /* |
424 | * Some tunables for the buffer areas. Power of 2 is required | 268 | * Some tunables for the buffer areas. Power of 2 is required |
@@ -426,44 +270,60 @@ typedef struct { | |||
426 | * | 270 | * |
427 | * MSch: use more buffer space for the slow m68k Macs! | 271 | * MSch: use more buffer space for the slow m68k Macs! |
428 | */ | 272 | */ |
429 | #ifdef CONFIG_MACSONIC | 273 | #define SONIC_NUM_RRS 16 /* number of receive resources */ |
430 | #define SONIC_NUM_RRS 32 /* number of receive resources */ | 274 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ |
431 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ | 275 | #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ |
432 | #define SONIC_NUM_TDS 32 /* number of transmit descriptors */ | ||
433 | #else | ||
434 | #define SONIC_NUM_RRS 16 /* number of receive resources */ | ||
435 | #define SONIC_NUM_RDS SONIC_NUM_RRS /* number of receive descriptors */ | ||
436 | #define SONIC_NUM_TDS 16 /* number of transmit descriptors */ | ||
437 | #endif | ||
438 | #define SONIC_RBSIZE 1520 /* size of one resource buffer */ | ||
439 | 276 | ||
440 | #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) | 277 | #define SONIC_RDS_MASK (SONIC_NUM_RDS-1) |
441 | #define SONIC_TDS_MASK (SONIC_NUM_TDS-1) | 278 | #define SONIC_TDS_MASK (SONIC_NUM_TDS-1) |
442 | 279 | ||
280 | #define SONIC_RBSIZE 1520 /* size of one resource buffer */ | ||
281 | |||
282 | /* Again, measured in bus size units! */ | ||
283 | #define SIZEOF_SONIC_DESC (SIZEOF_SONIC_CDA \ | ||
284 | + (SIZEOF_SONIC_TD * SONIC_NUM_TDS) \ | ||
285 | + (SIZEOF_SONIC_RD * SONIC_NUM_RDS) \ | ||
286 | + (SIZEOF_SONIC_RR * SONIC_NUM_RRS)) | ||
443 | 287 | ||
444 | /* Information that need to be kept for each board. */ | 288 | /* Information that need to be kept for each board. */ |
445 | struct sonic_local { | 289 | struct sonic_local { |
446 | sonic_cda_t cda; /* virtual CPU address of CDA */ | 290 | /* Bus size. 0 == 16 bits, 1 == 32 bits. */ |
447 | sonic_td_t tda[SONIC_NUM_TDS]; /* transmit descriptor area */ | 291 | int dma_bitmode; |
448 | sonic_rr_t rra[SONIC_NUM_RRS]; /* receive resource area */ | 292 | /* Register offset within the longword (independent of endianness, |
449 | sonic_rd_t rda[SONIC_NUM_RDS]; /* receive descriptor area */ | 293 | and varies from one type of Macintosh SONIC to another |
450 | struct sk_buff *tx_skb[SONIC_NUM_TDS]; /* skbuffs for packets to transmit */ | 294 | (Aarrgh)) */ |
451 | unsigned int tx_laddr[SONIC_NUM_TDS]; /* logical DMA address fro skbuffs */ | 295 | int reg_offset; |
452 | unsigned char *rba; /* start of receive buffer areas */ | 296 | void *descriptors; |
453 | unsigned int cda_laddr; /* logical DMA address of CDA */ | 297 | /* Crud. These areas have to be within the same 64K. Therefore |
454 | unsigned int tda_laddr; /* logical DMA address of TDA */ | 298 | we allocate a desriptors page, and point these to places within it. */ |
455 | unsigned int rra_laddr; /* logical DMA address of RRA */ | 299 | void *cda; /* CAM descriptor area */ |
456 | unsigned int rda_laddr; /* logical DMA address of RDA */ | 300 | void *tda; /* Transmit descriptor area */ |
457 | unsigned int rba_laddr; /* logical DMA address of RBA */ | 301 | void *rra; /* Receive resource area */ |
458 | unsigned int cur_rra; /* current indexes to resource areas */ | 302 | void *rda; /* Receive descriptor area */ |
303 | struct sk_buff* volatile rx_skb[SONIC_NUM_RRS]; /* packets to be received */ | ||
304 | struct sk_buff* volatile tx_skb[SONIC_NUM_TDS]; /* packets to be transmitted */ | ||
305 | unsigned int tx_len[SONIC_NUM_TDS]; /* lengths of tx DMA mappings */ | ||
306 | /* Logical DMA addresses on MIPS, bus addresses on m68k | ||
307 | * (so "laddr" is a bit misleading) */ | ||
308 | dma_addr_t descriptors_laddr; | ||
309 | u32 cda_laddr; /* logical DMA address of CDA */ | ||
310 | u32 tda_laddr; /* logical DMA address of TDA */ | ||
311 | u32 rra_laddr; /* logical DMA address of RRA */ | ||
312 | u32 rda_laddr; /* logical DMA address of RDA */ | ||
313 | dma_addr_t rx_laddr[SONIC_NUM_RRS]; /* logical DMA addresses of rx skbuffs */ | ||
314 | dma_addr_t tx_laddr[SONIC_NUM_TDS]; /* logical DMA addresses of tx skbuffs */ | ||
315 | unsigned int rra_end; | ||
316 | unsigned int cur_rwp; | ||
459 | unsigned int cur_rx; | 317 | unsigned int cur_rx; |
460 | unsigned int cur_tx; | 318 | unsigned int cur_tx; /* first unacked transmit packet */ |
461 | unsigned int dirty_tx; /* last unacked transmit packet */ | 319 | unsigned int eol_rx; |
462 | char tx_full; | 320 | unsigned int eol_tx; /* last unacked transmit packet */ |
321 | unsigned int next_tx; /* next free TD */ | ||
322 | struct device *device; /* generic device */ | ||
463 | struct net_device_stats stats; | 323 | struct net_device_stats stats; |
464 | }; | 324 | }; |
465 | 325 | ||
466 | #define TX_TIMEOUT 6 | 326 | #define TX_TIMEOUT (3 * HZ) |
467 | 327 | ||
468 | /* Index to functions, as function prototypes. */ | 328 | /* Index to functions, as function prototypes. */ |
469 | 329 | ||
@@ -477,6 +337,114 @@ static void sonic_multicast_list(struct net_device *dev); | |||
477 | static int sonic_init(struct net_device *dev); | 337 | static int sonic_init(struct net_device *dev); |
478 | static void sonic_tx_timeout(struct net_device *dev); | 338 | static void sonic_tx_timeout(struct net_device *dev); |
479 | 339 | ||
340 | /* Internal inlines for reading/writing DMA buffers. Note that bus | ||
341 | size and endianness matter here, whereas they don't for registers, | ||
342 | as far as we can tell. */ | ||
343 | /* OpenBSD calls this "SWO". I'd like to think that sonic_buf_put() | ||
344 | is a much better name. */ | ||
345 | static inline void sonic_buf_put(void* base, int bitmode, | ||
346 | int offset, __u16 val) | ||
347 | { | ||
348 | if (bitmode) | ||
349 | #ifdef __BIG_ENDIAN | ||
350 | ((__u16 *) base + (offset*2))[1] = val; | ||
351 | #else | ||
352 | ((__u16 *) base + (offset*2))[0] = val; | ||
353 | #endif | ||
354 | else | ||
355 | ((__u16 *) base)[offset] = val; | ||
356 | } | ||
357 | |||
358 | static inline __u16 sonic_buf_get(void* base, int bitmode, | ||
359 | int offset) | ||
360 | { | ||
361 | if (bitmode) | ||
362 | #ifdef __BIG_ENDIAN | ||
363 | return ((volatile __u16 *) base + (offset*2))[1]; | ||
364 | #else | ||
365 | return ((volatile __u16 *) base + (offset*2))[0]; | ||
366 | #endif | ||
367 | else | ||
368 | return ((volatile __u16 *) base)[offset]; | ||
369 | } | ||
370 | |||
371 | /* Inlines that you should actually use for reading/writing DMA buffers */ | ||
372 | static inline void sonic_cda_put(struct net_device* dev, int entry, | ||
373 | int offset, __u16 val) | ||
374 | { | ||
375 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
376 | sonic_buf_put(lp->cda, lp->dma_bitmode, | ||
377 | (entry * SIZEOF_SONIC_CD) + offset, val); | ||
378 | } | ||
379 | |||
380 | static inline __u16 sonic_cda_get(struct net_device* dev, int entry, | ||
381 | int offset) | ||
382 | { | ||
383 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
384 | return sonic_buf_get(lp->cda, lp->dma_bitmode, | ||
385 | (entry * SIZEOF_SONIC_CD) + offset); | ||
386 | } | ||
387 | |||
388 | static inline void sonic_set_cam_enable(struct net_device* dev, __u16 val) | ||
389 | { | ||
390 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
391 | sonic_buf_put(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE, val); | ||
392 | } | ||
393 | |||
394 | static inline __u16 sonic_get_cam_enable(struct net_device* dev) | ||
395 | { | ||
396 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
397 | return sonic_buf_get(lp->cda, lp->dma_bitmode, SONIC_CDA_CAM_ENABLE); | ||
398 | } | ||
399 | |||
400 | static inline void sonic_tda_put(struct net_device* dev, int entry, | ||
401 | int offset, __u16 val) | ||
402 | { | ||
403 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
404 | sonic_buf_put(lp->tda, lp->dma_bitmode, | ||
405 | (entry * SIZEOF_SONIC_TD) + offset, val); | ||
406 | } | ||
407 | |||
408 | static inline __u16 sonic_tda_get(struct net_device* dev, int entry, | ||
409 | int offset) | ||
410 | { | ||
411 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
412 | return sonic_buf_get(lp->tda, lp->dma_bitmode, | ||
413 | (entry * SIZEOF_SONIC_TD) + offset); | ||
414 | } | ||
415 | |||
416 | static inline void sonic_rda_put(struct net_device* dev, int entry, | ||
417 | int offset, __u16 val) | ||
418 | { | ||
419 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
420 | sonic_buf_put(lp->rda, lp->dma_bitmode, | ||
421 | (entry * SIZEOF_SONIC_RD) + offset, val); | ||
422 | } | ||
423 | |||
424 | static inline __u16 sonic_rda_get(struct net_device* dev, int entry, | ||
425 | int offset) | ||
426 | { | ||
427 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
428 | return sonic_buf_get(lp->rda, lp->dma_bitmode, | ||
429 | (entry * SIZEOF_SONIC_RD) + offset); | ||
430 | } | ||
431 | |||
432 | static inline void sonic_rra_put(struct net_device* dev, int entry, | ||
433 | int offset, __u16 val) | ||
434 | { | ||
435 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
436 | sonic_buf_put(lp->rra, lp->dma_bitmode, | ||
437 | (entry * SIZEOF_SONIC_RR) + offset, val); | ||
438 | } | ||
439 | |||
440 | static inline __u16 sonic_rra_get(struct net_device* dev, int entry, | ||
441 | int offset) | ||
442 | { | ||
443 | struct sonic_local* lp = (struct sonic_local *) dev->priv; | ||
444 | return sonic_buf_get(lp->rra, lp->dma_bitmode, | ||
445 | (entry * SIZEOF_SONIC_RR) + offset); | ||
446 | } | ||
447 | |||
480 | static const char *version = | 448 | static const char *version = |
481 | "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; | 449 | "sonic.c:v0.92 20.9.98 tsbogend@alpha.franken.de\n"; |
482 | 450 | ||
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index 368b8fb14023..6d4ab1e333b5 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -66,8 +66,8 @@ | |||
66 | 66 | ||
67 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
68 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
69 | #define DRV_MODULE_VERSION "3.35" | 69 | #define DRV_MODULE_VERSION "3.37" |
70 | #define DRV_MODULE_RELDATE "August 6, 2005" | 70 | #define DRV_MODULE_RELDATE "August 25, 2005" |
71 | 71 | ||
72 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
73 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -7865,8 +7865,6 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7865 | 7865 | ||
7866 | err = -EIO; | 7866 | err = -EIO; |
7867 | 7867 | ||
7868 | tg3_abort_hw(tp, 1); | ||
7869 | |||
7870 | tg3_reset_hw(tp); | 7868 | tg3_reset_hw(tp); |
7871 | 7869 | ||
7872 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | 7870 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
@@ -8970,6 +8968,8 @@ static int __devinit tg3_phy_probe(struct tg3 *tp) | |||
8970 | tp->phy_id = hw_phy_id; | 8968 | tp->phy_id = hw_phy_id; |
8971 | if (hw_phy_id_masked == PHY_ID_BCM8002) | 8969 | if (hw_phy_id_masked == PHY_ID_BCM8002) |
8972 | tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; | 8970 | tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES; |
8971 | else | ||
8972 | tp->tg3_flags2 &= ~TG3_FLG2_PHY_SERDES; | ||
8973 | } else { | 8973 | } else { |
8974 | if (tp->phy_id != PHY_ID_INVALID) { | 8974 | if (tp->phy_id != PHY_ID_INVALID) { |
8975 | /* Do nothing, phy ID already set up in | 8975 | /* Do nothing, phy ID already set up in |
diff --git a/drivers/net/tokenring/Kconfig b/drivers/net/tokenring/Kconfig index 23d0fa4bbceb..e4cfc80b283b 100644 --- a/drivers/net/tokenring/Kconfig +++ b/drivers/net/tokenring/Kconfig | |||
@@ -84,7 +84,7 @@ config 3C359 | |||
84 | 84 | ||
85 | config TMS380TR | 85 | config TMS380TR |
86 | tristate "Generic TMS380 Token Ring ISA/PCI adapter support" | 86 | tristate "Generic TMS380 Token Ring ISA/PCI adapter support" |
87 | depends on TR && (PCI || ISA) | 87 | depends on TR && (PCI || ISA && ISA_DMA_API || MCA) |
88 | select FW_LOADER | 88 | select FW_LOADER |
89 | ---help--- | 89 | ---help--- |
90 | This driver provides generic support for token ring adapters | 90 | This driver provides generic support for token ring adapters |
@@ -158,7 +158,7 @@ config ABYSS | |||
158 | 158 | ||
159 | config MADGEMC | 159 | config MADGEMC |
160 | tristate "Madge Smart 16/4 Ringnode MicroChannel" | 160 | tristate "Madge Smart 16/4 Ringnode MicroChannel" |
161 | depends on TR && TMS380TR && MCA_LEGACY | 161 | depends on TR && TMS380TR && MCA |
162 | help | 162 | help |
163 | This tms380 module supports the Madge Smart 16/4 MC16 and MC32 | 163 | This tms380 module supports the Madge Smart 16/4 MC16 and MC32 |
164 | MicroChannel adapters. | 164 | MicroChannel adapters. |
diff --git a/drivers/net/tokenring/abyss.c b/drivers/net/tokenring/abyss.c index 87103c400999..9345e68c451e 100644 --- a/drivers/net/tokenring/abyss.c +++ b/drivers/net/tokenring/abyss.c | |||
@@ -139,7 +139,7 @@ static int __devinit abyss_attach(struct pci_dev *pdev, const struct pci_device_ | |||
139 | */ | 139 | */ |
140 | dev->base_addr += 0x10; | 140 | dev->base_addr += 0x10; |
141 | 141 | ||
142 | ret = tmsdev_init(dev, PCI_MAX_ADDRESS, pdev); | 142 | ret = tmsdev_init(dev, &pdev->dev); |
143 | if (ret) { | 143 | if (ret) { |
144 | printk("%s: unable to get memory for dev->priv.\n", | 144 | printk("%s: unable to get memory for dev->priv.\n", |
145 | dev->name); | 145 | dev->name); |
diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index 659cbdbef7f3..3a25d191ea4a 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c | |||
@@ -20,7 +20,7 @@ | |||
20 | static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; | 20 | static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/mca-legacy.h> | 23 | #include <linux/mca.h> |
24 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/errno.h> | 25 | #include <linux/errno.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
@@ -38,9 +38,7 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; | |||
38 | #define MADGEMC_IO_EXTENT 32 | 38 | #define MADGEMC_IO_EXTENT 32 |
39 | #define MADGEMC_SIF_OFFSET 0x08 | 39 | #define MADGEMC_SIF_OFFSET 0x08 |
40 | 40 | ||
41 | struct madgemc_card { | 41 | struct card_info { |
42 | struct net_device *dev; | ||
43 | |||
44 | /* | 42 | /* |
45 | * These are read from the BIA ROM. | 43 | * These are read from the BIA ROM. |
46 | */ | 44 | */ |
@@ -57,16 +55,12 @@ struct madgemc_card { | |||
57 | unsigned int arblevel:4; | 55 | unsigned int arblevel:4; |
58 | unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ | 56 | unsigned int ringspeed:2; /* 0 = 4mb, 1 = 16, 2 = Auto/none */ |
59 | unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ | 57 | unsigned int cabletype:1; /* 0 = RJ45, 1 = DB9 */ |
60 | |||
61 | struct madgemc_card *next; | ||
62 | }; | 58 | }; |
63 | static struct madgemc_card *madgemc_card_list; | ||
64 | |||
65 | 59 | ||
66 | static int madgemc_open(struct net_device *dev); | 60 | static int madgemc_open(struct net_device *dev); |
67 | static int madgemc_close(struct net_device *dev); | 61 | static int madgemc_close(struct net_device *dev); |
68 | static int madgemc_chipset_init(struct net_device *dev); | 62 | static int madgemc_chipset_init(struct net_device *dev); |
69 | static void madgemc_read_rom(struct madgemc_card *card); | 63 | static void madgemc_read_rom(struct net_device *dev, struct card_info *card); |
70 | static unsigned short madgemc_setnselout_pins(struct net_device *dev); | 64 | static unsigned short madgemc_setnselout_pins(struct net_device *dev); |
71 | static void madgemc_setcabletype(struct net_device *dev, int type); | 65 | static void madgemc_setcabletype(struct net_device *dev, int type); |
72 | 66 | ||
@@ -151,261 +145,237 @@ static void madgemc_sifwritew(struct net_device *dev, unsigned short val, unsign | |||
151 | 145 | ||
152 | 146 | ||
153 | 147 | ||
154 | static int __init madgemc_probe(void) | 148 | static int __devinit madgemc_probe(struct device *device) |
155 | { | 149 | { |
156 | static int versionprinted; | 150 | static int versionprinted; |
157 | struct net_device *dev; | 151 | struct net_device *dev; |
158 | struct net_local *tp; | 152 | struct net_local *tp; |
159 | struct madgemc_card *card; | 153 | struct card_info *card; |
160 | int i,slot = 0; | 154 | struct mca_device *mdev = to_mca_device(device); |
161 | __u8 posreg[4]; | 155 | int ret = 0, i = 0; |
162 | 156 | ||
163 | if (!MCA_bus) | 157 | if (versionprinted++ == 0) |
164 | return -1; | 158 | printk("%s", version); |
165 | 159 | ||
166 | while (slot != MCA_NOTFOUND) { | 160 | if(mca_device_claimed(mdev)) |
167 | /* | 161 | return -EBUSY; |
168 | * Currently we only support the MC16/32 (MCA ID 002d) | 162 | mca_device_set_claim(mdev, 1); |
169 | */ | 163 | |
170 | slot = mca_find_unused_adapter(0x002d, slot); | 164 | dev = alloc_trdev(sizeof(struct net_local)); |
171 | if (slot == MCA_NOTFOUND) | 165 | if (!dev) { |
172 | break; | 166 | printk("madgemc: unable to allocate dev space\n"); |
173 | 167 | mca_device_set_claim(mdev, 0); | |
174 | /* | 168 | ret = -ENOMEM; |
175 | * If we get here, we have an adapter. | 169 | goto getout; |
176 | */ | 170 | } |
177 | if (versionprinted++ == 0) | ||
178 | printk("%s", version); | ||
179 | |||
180 | dev = alloc_trdev(sizeof(struct net_local)); | ||
181 | if (dev == NULL) { | ||
182 | printk("madgemc: unable to allocate dev space\n"); | ||
183 | if (madgemc_card_list) | ||
184 | return 0; | ||
185 | return -1; | ||
186 | } | ||
187 | 171 | ||
188 | SET_MODULE_OWNER(dev); | 172 | SET_MODULE_OWNER(dev); |
189 | dev->dma = 0; | 173 | dev->dma = 0; |
190 | 174 | ||
191 | /* | 175 | card = kmalloc(sizeof(struct card_info), GFP_KERNEL); |
192 | * Fetch MCA config registers | 176 | if (card==NULL) { |
193 | */ | 177 | printk("madgemc: unable to allocate card struct\n"); |
194 | for(i=0;i<4;i++) | 178 | ret = -ENOMEM; |
195 | posreg[i] = mca_read_stored_pos(slot, i+2); | 179 | goto getout1; |
196 | 180 | } | |
197 | card = kmalloc(sizeof(struct madgemc_card), GFP_KERNEL); | 181 | |
198 | if (card==NULL) { | 182 | /* |
199 | printk("madgemc: unable to allocate card struct\n"); | 183 | * Parse configuration information. This all comes |
200 | free_netdev(dev); | 184 | * directly from the publicly available @002d.ADF. |
201 | if (madgemc_card_list) | 185 | * Get it from Madge or your local ADF library. |
202 | return 0; | 186 | */ |
203 | return -1; | 187 | |
204 | } | 188 | /* |
205 | card->dev = dev; | 189 | * Base address |
206 | 190 | */ | |
207 | /* | 191 | dev->base_addr = 0x0a20 + |
208 | * Parse configuration information. This all comes | 192 | ((mdev->pos[2] & MC16_POS2_ADDR2)?0x0400:0) + |
209 | * directly from the publicly available @002d.ADF. | 193 | ((mdev->pos[0] & MC16_POS0_ADDR1)?0x1000:0) + |
210 | * Get it from Madge or your local ADF library. | 194 | ((mdev->pos[3] & MC16_POS3_ADDR3)?0x2000:0); |
211 | */ | 195 | |
212 | 196 | /* | |
213 | /* | 197 | * Interrupt line |
214 | * Base address | 198 | */ |
215 | */ | 199 | switch(mdev->pos[0] >> 6) { /* upper two bits */ |
216 | dev->base_addr = 0x0a20 + | ||
217 | ((posreg[2] & MC16_POS2_ADDR2)?0x0400:0) + | ||
218 | ((posreg[0] & MC16_POS0_ADDR1)?0x1000:0) + | ||
219 | ((posreg[3] & MC16_POS3_ADDR3)?0x2000:0); | ||
220 | |||
221 | /* | ||
222 | * Interrupt line | ||
223 | */ | ||
224 | switch(posreg[0] >> 6) { /* upper two bits */ | ||
225 | case 0x1: dev->irq = 3; break; | 200 | case 0x1: dev->irq = 3; break; |
226 | case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ | 201 | case 0x2: dev->irq = 9; break; /* IRQ 2 = IRQ 9 */ |
227 | case 0x3: dev->irq = 10; break; | 202 | case 0x3: dev->irq = 10; break; |
228 | default: dev->irq = 0; break; | 203 | default: dev->irq = 0; break; |
229 | } | 204 | } |
230 | 205 | ||
231 | if (dev->irq == 0) { | 206 | if (dev->irq == 0) { |
232 | printk("%s: invalid IRQ\n", dev->name); | 207 | printk("%s: invalid IRQ\n", dev->name); |
233 | goto getout1; | 208 | ret = -EBUSY; |
234 | } | 209 | goto getout2; |
210 | } | ||
235 | 211 | ||
236 | if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, | 212 | if (!request_region(dev->base_addr, MADGEMC_IO_EXTENT, |
237 | "madgemc")) { | 213 | "madgemc")) { |
238 | printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", slot, dev->base_addr); | 214 | printk(KERN_INFO "madgemc: unable to setup Smart MC in slot %d because of I/O base conflict at 0x%04lx\n", mdev->slot, dev->base_addr); |
239 | dev->base_addr += MADGEMC_SIF_OFFSET; | ||
240 | goto getout1; | ||
241 | } | ||
242 | dev->base_addr += MADGEMC_SIF_OFFSET; | 215 | dev->base_addr += MADGEMC_SIF_OFFSET; |
216 | ret = -EBUSY; | ||
217 | goto getout2; | ||
218 | } | ||
219 | dev->base_addr += MADGEMC_SIF_OFFSET; | ||
220 | |||
221 | /* | ||
222 | * Arbitration Level | ||
223 | */ | ||
224 | card->arblevel = ((mdev->pos[0] >> 1) & 0x7) + 8; | ||
225 | |||
226 | /* | ||
227 | * Burst mode and Fairness | ||
228 | */ | ||
229 | card->burstmode = ((mdev->pos[2] >> 6) & 0x3); | ||
230 | card->fairness = ((mdev->pos[2] >> 4) & 0x1); | ||
231 | |||
232 | /* | ||
233 | * Ring Speed | ||
234 | */ | ||
235 | if ((mdev->pos[1] >> 2)&0x1) | ||
236 | card->ringspeed = 2; /* not selected */ | ||
237 | else if ((mdev->pos[2] >> 5) & 0x1) | ||
238 | card->ringspeed = 1; /* 16Mb */ | ||
239 | else | ||
240 | card->ringspeed = 0; /* 4Mb */ | ||
241 | |||
242 | /* | ||
243 | * Cable type | ||
244 | */ | ||
245 | if ((mdev->pos[1] >> 6)&0x1) | ||
246 | card->cabletype = 1; /* STP/DB9 */ | ||
247 | else | ||
248 | card->cabletype = 0; /* UTP/RJ-45 */ | ||
249 | |||
250 | |||
251 | /* | ||
252 | * ROM Info. This requires us to actually twiddle | ||
253 | * bits on the card, so we must ensure above that | ||
254 | * the base address is free of conflict (request_region above). | ||
255 | */ | ||
256 | madgemc_read_rom(dev, card); | ||
243 | 257 | ||
244 | /* | 258 | if (card->manid != 0x4d) { /* something went wrong */ |
245 | * Arbitration Level | 259 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); |
246 | */ | 260 | goto getout3; |
247 | card->arblevel = ((posreg[0] >> 1) & 0x7) + 8; | 261 | } |
248 | |||
249 | /* | ||
250 | * Burst mode and Fairness | ||
251 | */ | ||
252 | card->burstmode = ((posreg[2] >> 6) & 0x3); | ||
253 | card->fairness = ((posreg[2] >> 4) & 0x1); | ||
254 | |||
255 | /* | ||
256 | * Ring Speed | ||
257 | */ | ||
258 | if ((posreg[1] >> 2)&0x1) | ||
259 | card->ringspeed = 2; /* not selected */ | ||
260 | else if ((posreg[2] >> 5) & 0x1) | ||
261 | card->ringspeed = 1; /* 16Mb */ | ||
262 | else | ||
263 | card->ringspeed = 0; /* 4Mb */ | ||
264 | |||
265 | /* | ||
266 | * Cable type | ||
267 | */ | ||
268 | if ((posreg[1] >> 6)&0x1) | ||
269 | card->cabletype = 1; /* STP/DB9 */ | ||
270 | else | ||
271 | card->cabletype = 0; /* UTP/RJ-45 */ | ||
272 | |||
273 | |||
274 | /* | ||
275 | * ROM Info. This requires us to actually twiddle | ||
276 | * bits on the card, so we must ensure above that | ||
277 | * the base address is free of conflict (request_region above). | ||
278 | */ | ||
279 | madgemc_read_rom(card); | ||
280 | |||
281 | if (card->manid != 0x4d) { /* something went wrong */ | ||
282 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown manufacturer ID %02x)\n", dev->name, card->manid); | ||
283 | goto getout; | ||
284 | } | ||
285 | 262 | ||
286 | if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { | 263 | if ((card->cardtype != 0x08) && (card->cardtype != 0x0d)) { |
287 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); | 264 | printk(KERN_INFO "%s: Madge MC ROM read failed (unknown card ID %02x)\n", dev->name, card->cardtype); |
288 | goto getout; | 265 | ret = -EIO; |
289 | } | 266 | goto getout3; |
267 | } | ||
290 | 268 | ||
291 | /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ | 269 | /* All cards except Rev 0 and 1 MC16's have 256kb of RAM */ |
292 | if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) | 270 | if ((card->cardtype == 0x08) && (card->cardrev <= 0x01)) |
293 | card->ramsize = 128; | 271 | card->ramsize = 128; |
294 | else | 272 | else |
295 | card->ramsize = 256; | 273 | card->ramsize = 256; |
296 | 274 | ||
297 | printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", | 275 | printk("%s: %s Rev %d at 0x%04lx IRQ %d\n", |
298 | dev->name, | 276 | dev->name, |
299 | (card->cardtype == 0x08)?MADGEMC16_CARDNAME: | 277 | (card->cardtype == 0x08)?MADGEMC16_CARDNAME: |
300 | MADGEMC32_CARDNAME, card->cardrev, | 278 | MADGEMC32_CARDNAME, card->cardrev, |
301 | dev->base_addr, dev->irq); | 279 | dev->base_addr, dev->irq); |
302 | 280 | ||
303 | if (card->cardtype == 0x0d) | 281 | if (card->cardtype == 0x0d) |
304 | printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); | 282 | printk("%s: Warning: MC32 support is experimental and highly untested\n", dev->name); |
305 | 283 | ||
306 | if (card->ringspeed==2) { /* Unknown */ | 284 | if (card->ringspeed==2) { /* Unknown */ |
307 | printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); | 285 | printk("%s: Warning: Ring speed not set in POS -- Please run the reference disk and set it!\n", dev->name); |
308 | card->ringspeed = 1; /* default to 16mb */ | 286 | card->ringspeed = 1; /* default to 16mb */ |
309 | } | 287 | } |
310 | 288 | ||
311 | printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); | 289 | printk("%s: RAM Size: %dKB\n", dev->name, card->ramsize); |
312 | 290 | ||
313 | printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, | 291 | printk("%s: Ring Speed: %dMb/sec on %s\n", dev->name, |
314 | (card->ringspeed)?16:4, | 292 | (card->ringspeed)?16:4, |
315 | card->cabletype?"STP/DB9":"UTP/RJ-45"); | 293 | card->cabletype?"STP/DB9":"UTP/RJ-45"); |
316 | printk("%s: Arbitration Level: %d\n", dev->name, | 294 | printk("%s: Arbitration Level: %d\n", dev->name, |
317 | card->arblevel); | 295 | card->arblevel); |
318 | 296 | ||
319 | printk("%s: Burst Mode: ", dev->name); | 297 | printk("%s: Burst Mode: ", dev->name); |
320 | switch(card->burstmode) { | 298 | switch(card->burstmode) { |
321 | case 0: printk("Cycle steal"); break; | 299 | case 0: printk("Cycle steal"); break; |
322 | case 1: printk("Limited burst"); break; | 300 | case 1: printk("Limited burst"); break; |
323 | case 2: printk("Delayed release"); break; | 301 | case 2: printk("Delayed release"); break; |
324 | case 3: printk("Immediate release"); break; | 302 | case 3: printk("Immediate release"); break; |
325 | } | 303 | } |
326 | printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); | 304 | printk(" (%s)\n", (card->fairness)?"Unfair":"Fair"); |
327 | |||
328 | |||
329 | /* | ||
330 | * Enable SIF before we assign the interrupt handler, | ||
331 | * just in case we get spurious interrupts that need | ||
332 | * handling. | ||
333 | */ | ||
334 | outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ | ||
335 | madgemc_setsifsel(dev, 1); | ||
336 | if (request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, | ||
337 | "madgemc", dev)) | ||
338 | goto getout; | ||
339 | |||
340 | madgemc_chipset_init(dev); /* enables interrupts! */ | ||
341 | madgemc_setcabletype(dev, card->cabletype); | ||
342 | 305 | ||
343 | /* Setup MCA structures */ | ||
344 | mca_set_adapter_name(slot, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); | ||
345 | mca_set_adapter_procfn(slot, madgemc_mcaproc, dev); | ||
346 | mca_mark_as_used(slot); | ||
347 | 306 | ||
348 | printk("%s: Ring Station Address: ", dev->name); | 307 | /* |
349 | printk("%2.2x", dev->dev_addr[0]); | 308 | * Enable SIF before we assign the interrupt handler, |
350 | for (i = 1; i < 6; i++) | 309 | * just in case we get spurious interrupts that need |
351 | printk(":%2.2x", dev->dev_addr[i]); | 310 | * handling. |
352 | printk("\n"); | 311 | */ |
353 | 312 | outb(0, dev->base_addr + MC_CONTROL_REG0); /* sanity */ | |
354 | /* XXX is ISA_MAX_ADDRESS correct here? */ | 313 | madgemc_setsifsel(dev, 1); |
355 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) { | 314 | if (request_irq(dev->irq, madgemc_interrupt, SA_SHIRQ, |
356 | printk("%s: unable to get memory for dev->priv.\n", | 315 | "madgemc", dev)) { |
357 | dev->name); | 316 | ret = -EBUSY; |
358 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | 317 | goto getout3; |
359 | MADGEMC_IO_EXTENT); | ||
360 | |||
361 | kfree(card); | ||
362 | tmsdev_term(dev); | ||
363 | free_netdev(dev); | ||
364 | if (madgemc_card_list) | ||
365 | return 0; | ||
366 | return -1; | ||
367 | } | ||
368 | tp = netdev_priv(dev); | ||
369 | |||
370 | /* | ||
371 | * The MC16 is physically a 32bit card. However, Madge | ||
372 | * insists on calling it 16bit, so I'll assume here that | ||
373 | * they know what they're talking about. Cut off DMA | ||
374 | * at 16mb. | ||
375 | */ | ||
376 | tp->setnselout = madgemc_setnselout_pins; | ||
377 | tp->sifwriteb = madgemc_sifwriteb; | ||
378 | tp->sifreadb = madgemc_sifreadb; | ||
379 | tp->sifwritew = madgemc_sifwritew; | ||
380 | tp->sifreadw = madgemc_sifreadw; | ||
381 | tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; | ||
382 | |||
383 | memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); | ||
384 | |||
385 | dev->open = madgemc_open; | ||
386 | dev->stop = madgemc_close; | ||
387 | |||
388 | if (register_netdev(dev) == 0) { | ||
389 | /* Enlist in the card list */ | ||
390 | card->next = madgemc_card_list; | ||
391 | madgemc_card_list = card; | ||
392 | slot++; | ||
393 | continue; /* successful, try to find another */ | ||
394 | } | ||
395 | |||
396 | free_irq(dev->irq, dev); | ||
397 | getout: | ||
398 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | ||
399 | MADGEMC_IO_EXTENT); | ||
400 | getout1: | ||
401 | kfree(card); | ||
402 | free_netdev(dev); | ||
403 | slot++; | ||
404 | } | 318 | } |
405 | 319 | ||
406 | if (madgemc_card_list) | 320 | madgemc_chipset_init(dev); /* enables interrupts! */ |
321 | madgemc_setcabletype(dev, card->cabletype); | ||
322 | |||
323 | /* Setup MCA structures */ | ||
324 | mca_device_set_name(mdev, (card->cardtype == 0x08)?MADGEMC16_CARDNAME:MADGEMC32_CARDNAME); | ||
325 | mca_set_adapter_procfn(mdev->slot, madgemc_mcaproc, dev); | ||
326 | |||
327 | printk("%s: Ring Station Address: ", dev->name); | ||
328 | printk("%2.2x", dev->dev_addr[0]); | ||
329 | for (i = 1; i < 6; i++) | ||
330 | printk(":%2.2x", dev->dev_addr[i]); | ||
331 | printk("\n"); | ||
332 | |||
333 | if (tmsdev_init(dev, device)) { | ||
334 | printk("%s: unable to get memory for dev->priv.\n", | ||
335 | dev->name); | ||
336 | ret = -ENOMEM; | ||
337 | goto getout4; | ||
338 | } | ||
339 | tp = netdev_priv(dev); | ||
340 | |||
341 | /* | ||
342 | * The MC16 is physically a 32bit card. However, Madge | ||
343 | * insists on calling it 16bit, so I'll assume here that | ||
344 | * they know what they're talking about. Cut off DMA | ||
345 | * at 16mb. | ||
346 | */ | ||
347 | tp->setnselout = madgemc_setnselout_pins; | ||
348 | tp->sifwriteb = madgemc_sifwriteb; | ||
349 | tp->sifreadb = madgemc_sifreadb; | ||
350 | tp->sifwritew = madgemc_sifwritew; | ||
351 | tp->sifreadw = madgemc_sifreadw; | ||
352 | tp->DataRate = (card->ringspeed)?SPEED_16:SPEED_4; | ||
353 | |||
354 | memcpy(tp->ProductID, "Madge MCA 16/4 ", PROD_ID_SIZE + 1); | ||
355 | |||
356 | dev->open = madgemc_open; | ||
357 | dev->stop = madgemc_close; | ||
358 | |||
359 | tp->tmspriv = card; | ||
360 | dev_set_drvdata(device, dev); | ||
361 | |||
362 | if (register_netdev(dev) == 0) | ||
407 | return 0; | 363 | return 0; |
408 | return -1; | 364 | |
365 | dev_set_drvdata(device, NULL); | ||
366 | ret = -ENOMEM; | ||
367 | getout4: | ||
368 | free_irq(dev->irq, dev); | ||
369 | getout3: | ||
370 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, | ||
371 | MADGEMC_IO_EXTENT); | ||
372 | getout2: | ||
373 | kfree(card); | ||
374 | getout1: | ||
375 | free_netdev(dev); | ||
376 | getout: | ||
377 | mca_device_set_claim(mdev, 0); | ||
378 | return ret; | ||
409 | } | 379 | } |
410 | 380 | ||
411 | /* | 381 | /* |
@@ -664,12 +634,12 @@ static void madgemc_chipset_close(struct net_device *dev) | |||
664 | * is complete. | 634 | * is complete. |
665 | * | 635 | * |
666 | */ | 636 | */ |
667 | static void madgemc_read_rom(struct madgemc_card *card) | 637 | static void madgemc_read_rom(struct net_device *dev, struct card_info *card) |
668 | { | 638 | { |
669 | unsigned long ioaddr; | 639 | unsigned long ioaddr; |
670 | unsigned char reg0, reg1, tmpreg0, i; | 640 | unsigned char reg0, reg1, tmpreg0, i; |
671 | 641 | ||
672 | ioaddr = card->dev->base_addr; | 642 | ioaddr = dev->base_addr; |
673 | 643 | ||
674 | reg0 = inb(ioaddr + MC_CONTROL_REG0); | 644 | reg0 = inb(ioaddr + MC_CONTROL_REG0); |
675 | reg1 = inb(ioaddr + MC_CONTROL_REG1); | 645 | reg1 = inb(ioaddr + MC_CONTROL_REG1); |
@@ -686,9 +656,9 @@ static void madgemc_read_rom(struct madgemc_card *card) | |||
686 | outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); | 656 | outb(tmpreg0 | MC_CONTROL_REG0_PAGE, ioaddr + MC_CONTROL_REG0); |
687 | 657 | ||
688 | /* Read BIA */ | 658 | /* Read BIA */ |
689 | card->dev->addr_len = 6; | 659 | dev->addr_len = 6; |
690 | for (i = 0; i < 6; i++) | 660 | for (i = 0; i < 6; i++) |
691 | card->dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); | 661 | dev->dev_addr[i] = inb(ioaddr + MC_ROM_BIA_START + i); |
692 | 662 | ||
693 | /* Restore original register values */ | 663 | /* Restore original register values */ |
694 | outb(reg0, ioaddr + MC_CONTROL_REG0); | 664 | outb(reg0, ioaddr + MC_CONTROL_REG0); |
@@ -721,14 +691,10 @@ static int madgemc_close(struct net_device *dev) | |||
721 | static int madgemc_mcaproc(char *buf, int slot, void *d) | 691 | static int madgemc_mcaproc(char *buf, int slot, void *d) |
722 | { | 692 | { |
723 | struct net_device *dev = (struct net_device *)d; | 693 | struct net_device *dev = (struct net_device *)d; |
724 | struct madgemc_card *curcard = madgemc_card_list; | 694 | struct net_local *tp = dev->priv; |
695 | struct card_info *curcard = tp->tmspriv; | ||
725 | int len = 0; | 696 | int len = 0; |
726 | 697 | ||
727 | while (curcard) { /* search for card struct */ | ||
728 | if (curcard->dev == dev) | ||
729 | break; | ||
730 | curcard = curcard->next; | ||
731 | } | ||
732 | len += sprintf(buf+len, "-------\n"); | 698 | len += sprintf(buf+len, "-------\n"); |
733 | if (curcard) { | 699 | if (curcard) { |
734 | struct net_local *tp = netdev_priv(dev); | 700 | struct net_local *tp = netdev_priv(dev); |
@@ -763,25 +729,56 @@ static int madgemc_mcaproc(char *buf, int slot, void *d) | |||
763 | return len; | 729 | return len; |
764 | } | 730 | } |
765 | 731 | ||
766 | static void __exit madgemc_exit(void) | 732 | static int __devexit madgemc_remove(struct device *device) |
767 | { | 733 | { |
768 | struct net_device *dev; | 734 | struct net_device *dev = dev_get_drvdata(device); |
769 | struct madgemc_card *this_card; | 735 | struct net_local *tp; |
770 | 736 | struct card_info *card; | |
771 | while (madgemc_card_list) { | 737 | |
772 | dev = madgemc_card_list->dev; | 738 | if (!dev) |
773 | unregister_netdev(dev); | 739 | BUG(); |
774 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); | 740 | |
775 | free_irq(dev->irq, dev); | 741 | tp = dev->priv; |
776 | tmsdev_term(dev); | 742 | card = tp->tmspriv; |
777 | free_netdev(dev); | 743 | kfree(card); |
778 | this_card = madgemc_card_list; | 744 | tp->tmspriv = NULL; |
779 | madgemc_card_list = this_card->next; | 745 | |
780 | kfree(this_card); | 746 | unregister_netdev(dev); |
781 | } | 747 | release_region(dev->base_addr-MADGEMC_SIF_OFFSET, MADGEMC_IO_EXTENT); |
748 | free_irq(dev->irq, dev); | ||
749 | tmsdev_term(dev); | ||
750 | free_netdev(dev); | ||
751 | dev_set_drvdata(device, NULL); | ||
752 | |||
753 | return 0; | ||
754 | } | ||
755 | |||
756 | static short madgemc_adapter_ids[] __initdata = { | ||
757 | 0x002d, | ||
758 | 0x0000 | ||
759 | }; | ||
760 | |||
761 | static struct mca_driver madgemc_driver = { | ||
762 | .id_table = madgemc_adapter_ids, | ||
763 | .driver = { | ||
764 | .name = "madgemc", | ||
765 | .bus = &mca_bus_type, | ||
766 | .probe = madgemc_probe, | ||
767 | .remove = __devexit_p(madgemc_remove), | ||
768 | }, | ||
769 | }; | ||
770 | |||
771 | static int __init madgemc_init (void) | ||
772 | { | ||
773 | return mca_register_driver (&madgemc_driver); | ||
774 | } | ||
775 | |||
776 | static void __exit madgemc_exit (void) | ||
777 | { | ||
778 | mca_unregister_driver (&madgemc_driver); | ||
782 | } | 779 | } |
783 | 780 | ||
784 | module_init(madgemc_probe); | 781 | module_init(madgemc_init); |
785 | module_exit(madgemc_exit); | 782 | module_exit(madgemc_exit); |
786 | 783 | ||
787 | MODULE_LICENSE("GPL"); | 784 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/net/tokenring/proteon.c b/drivers/net/tokenring/proteon.c index 40ad0fde28af..eb1423ede75c 100644 --- a/drivers/net/tokenring/proteon.c +++ b/drivers/net/tokenring/proteon.c | |||
@@ -62,8 +62,7 @@ static int dmalist[] __initdata = { | |||
62 | }; | 62 | }; |
63 | 63 | ||
64 | static char cardname[] = "Proteon 1392\0"; | 64 | static char cardname[] = "Proteon 1392\0"; |
65 | 65 | static u64 dma_mask = ISA_MAX_ADDRESS; | |
66 | struct net_device *proteon_probe(int unit); | ||
67 | static int proteon_open(struct net_device *dev); | 66 | static int proteon_open(struct net_device *dev); |
68 | static void proteon_read_eeprom(struct net_device *dev); | 67 | static void proteon_read_eeprom(struct net_device *dev); |
69 | static unsigned short proteon_setnselout_pins(struct net_device *dev); | 68 | static unsigned short proteon_setnselout_pins(struct net_device *dev); |
@@ -116,7 +115,7 @@ nodev: | |||
116 | return -ENODEV; | 115 | return -ENODEV; |
117 | } | 116 | } |
118 | 117 | ||
119 | static int __init setup_card(struct net_device *dev) | 118 | static int __init setup_card(struct net_device *dev, struct device *pdev) |
120 | { | 119 | { |
121 | struct net_local *tp; | 120 | struct net_local *tp; |
122 | static int versionprinted; | 121 | static int versionprinted; |
@@ -137,7 +136,7 @@ static int __init setup_card(struct net_device *dev) | |||
137 | } | 136 | } |
138 | } | 137 | } |
139 | if (err) | 138 | if (err) |
140 | goto out4; | 139 | goto out5; |
141 | 140 | ||
142 | /* At this point we have found a valid card. */ | 141 | /* At this point we have found a valid card. */ |
143 | 142 | ||
@@ -145,14 +144,15 @@ static int __init setup_card(struct net_device *dev) | |||
145 | printk(KERN_DEBUG "%s", version); | 144 | printk(KERN_DEBUG "%s", version); |
146 | 145 | ||
147 | err = -EIO; | 146 | err = -EIO; |
148 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) | 147 | pdev->dma_mask = &dma_mask; |
148 | if (tmsdev_init(dev, pdev)) | ||
149 | goto out4; | 149 | goto out4; |
150 | 150 | ||
151 | dev->base_addr &= ~3; | 151 | dev->base_addr &= ~3; |
152 | 152 | ||
153 | proteon_read_eeprom(dev); | 153 | proteon_read_eeprom(dev); |
154 | 154 | ||
155 | printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name); | 155 | printk(KERN_DEBUG "proteon.c: Ring Station Address: "); |
156 | printk("%2.2x", dev->dev_addr[0]); | 156 | printk("%2.2x", dev->dev_addr[0]); |
157 | for (j = 1; j < 6; j++) | 157 | for (j = 1; j < 6; j++) |
158 | printk(":%2.2x", dev->dev_addr[j]); | 158 | printk(":%2.2x", dev->dev_addr[j]); |
@@ -185,7 +185,7 @@ static int __init setup_card(struct net_device *dev) | |||
185 | 185 | ||
186 | if(irqlist[j] == 0) | 186 | if(irqlist[j] == 0) |
187 | { | 187 | { |
188 | printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name); | 188 | printk(KERN_INFO "proteon.c: AutoSelect no IRQ available\n"); |
189 | goto out3; | 189 | goto out3; |
190 | } | 190 | } |
191 | } | 191 | } |
@@ -196,15 +196,15 @@ static int __init setup_card(struct net_device *dev) | |||
196 | break; | 196 | break; |
197 | if (irqlist[j] == 0) | 197 | if (irqlist[j] == 0) |
198 | { | 198 | { |
199 | printk(KERN_INFO "%s: Illegal IRQ %d specified\n", | 199 | printk(KERN_INFO "proteon.c: Illegal IRQ %d specified\n", |
200 | dev->name, dev->irq); | 200 | dev->irq); |
201 | goto out3; | 201 | goto out3; |
202 | } | 202 | } |
203 | if (request_irq(dev->irq, tms380tr_interrupt, 0, | 203 | if (request_irq(dev->irq, tms380tr_interrupt, 0, |
204 | cardname, dev)) | 204 | cardname, dev)) |
205 | { | 205 | { |
206 | printk(KERN_INFO "%s: Selected IRQ %d not available\n", | 206 | printk(KERN_INFO "proteon.c: Selected IRQ %d not available\n", |
207 | dev->name, dev->irq); | 207 | dev->irq); |
208 | goto out3; | 208 | goto out3; |
209 | } | 209 | } |
210 | } | 210 | } |
@@ -220,7 +220,7 @@ static int __init setup_card(struct net_device *dev) | |||
220 | 220 | ||
221 | if(dmalist[j] == 0) | 221 | if(dmalist[j] == 0) |
222 | { | 222 | { |
223 | printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name); | 223 | printk(KERN_INFO "proteon.c: AutoSelect no DMA available\n"); |
224 | goto out2; | 224 | goto out2; |
225 | } | 225 | } |
226 | } | 226 | } |
@@ -231,25 +231,25 @@ static int __init setup_card(struct net_device *dev) | |||
231 | break; | 231 | break; |
232 | if (dmalist[j] == 0) | 232 | if (dmalist[j] == 0) |
233 | { | 233 | { |
234 | printk(KERN_INFO "%s: Illegal DMA %d specified\n", | 234 | printk(KERN_INFO "proteon.c: Illegal DMA %d specified\n", |
235 | dev->name, dev->dma); | 235 | dev->dma); |
236 | goto out2; | 236 | goto out2; |
237 | } | 237 | } |
238 | if (request_dma(dev->dma, cardname)) | 238 | if (request_dma(dev->dma, cardname)) |
239 | { | 239 | { |
240 | printk(KERN_INFO "%s: Selected DMA %d not available\n", | 240 | printk(KERN_INFO "proteon.c: Selected DMA %d not available\n", |
241 | dev->name, dev->dma); | 241 | dev->dma); |
242 | goto out2; | 242 | goto out2; |
243 | } | 243 | } |
244 | } | 244 | } |
245 | 245 | ||
246 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
247 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
248 | |||
249 | err = register_netdev(dev); | 246 | err = register_netdev(dev); |
250 | if (err) | 247 | if (err) |
251 | goto out; | 248 | goto out; |
252 | 249 | ||
250 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
251 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
252 | |||
253 | return 0; | 253 | return 0; |
254 | out: | 254 | out: |
255 | free_dma(dev->dma); | 255 | free_dma(dev->dma); |
@@ -258,34 +258,11 @@ out2: | |||
258 | out3: | 258 | out3: |
259 | tmsdev_term(dev); | 259 | tmsdev_term(dev); |
260 | out4: | 260 | out4: |
261 | release_region(dev->base_addr, PROTEON_IO_EXTENT); | 261 | release_region(dev->base_addr, PROTEON_IO_EXTENT); |
262 | out5: | ||
262 | return err; | 263 | return err; |
263 | } | 264 | } |
264 | 265 | ||
265 | struct net_device * __init proteon_probe(int unit) | ||
266 | { | ||
267 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
268 | int err = 0; | ||
269 | |||
270 | if (!dev) | ||
271 | return ERR_PTR(-ENOMEM); | ||
272 | |||
273 | if (unit >= 0) { | ||
274 | sprintf(dev->name, "tr%d", unit); | ||
275 | netdev_boot_setup_check(dev); | ||
276 | } | ||
277 | |||
278 | err = setup_card(dev); | ||
279 | if (err) | ||
280 | goto out; | ||
281 | |||
282 | return dev; | ||
283 | |||
284 | out: | ||
285 | free_netdev(dev); | ||
286 | return ERR_PTR(err); | ||
287 | } | ||
288 | |||
289 | /* | 266 | /* |
290 | * Reads MAC address from adapter RAM, which should've read it from | 267 | * Reads MAC address from adapter RAM, which should've read it from |
291 | * the onboard ROM. | 268 | * the onboard ROM. |
@@ -352,8 +329,6 @@ static int proteon_open(struct net_device *dev) | |||
352 | return tms380tr_open(dev); | 329 | return tms380tr_open(dev); |
353 | } | 330 | } |
354 | 331 | ||
355 | #ifdef MODULE | ||
356 | |||
357 | #define ISATR_MAX_ADAPTERS 3 | 332 | #define ISATR_MAX_ADAPTERS 3 |
358 | 333 | ||
359 | static int io[ISATR_MAX_ADAPTERS]; | 334 | static int io[ISATR_MAX_ADAPTERS]; |
@@ -366,13 +341,23 @@ module_param_array(io, int, NULL, 0); | |||
366 | module_param_array(irq, int, NULL, 0); | 341 | module_param_array(irq, int, NULL, 0); |
367 | module_param_array(dma, int, NULL, 0); | 342 | module_param_array(dma, int, NULL, 0); |
368 | 343 | ||
369 | static struct net_device *proteon_dev[ISATR_MAX_ADAPTERS]; | 344 | static struct platform_device *proteon_dev[ISATR_MAX_ADAPTERS]; |
345 | |||
346 | static struct device_driver proteon_driver = { | ||
347 | .name = "proteon", | ||
348 | .bus = &platform_bus_type, | ||
349 | }; | ||
370 | 350 | ||
371 | int init_module(void) | 351 | static int __init proteon_init(void) |
372 | { | 352 | { |
373 | struct net_device *dev; | 353 | struct net_device *dev; |
354 | struct platform_device *pdev; | ||
374 | int i, num = 0, err = 0; | 355 | int i, num = 0, err = 0; |
375 | 356 | ||
357 | err = driver_register(&proteon_driver); | ||
358 | if (err) | ||
359 | return err; | ||
360 | |||
376 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 361 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
377 | dev = alloc_trdev(sizeof(struct net_local)); | 362 | dev = alloc_trdev(sizeof(struct net_local)); |
378 | if (!dev) | 363 | if (!dev) |
@@ -381,11 +366,15 @@ int init_module(void) | |||
381 | dev->base_addr = io[i]; | 366 | dev->base_addr = io[i]; |
382 | dev->irq = irq[i]; | 367 | dev->irq = irq[i]; |
383 | dev->dma = dma[i]; | 368 | dev->dma = dma[i]; |
384 | err = setup_card(dev); | 369 | pdev = platform_device_register_simple("proteon", |
370 | i, NULL, 0); | ||
371 | err = setup_card(dev, &pdev->dev); | ||
385 | if (!err) { | 372 | if (!err) { |
386 | proteon_dev[i] = dev; | 373 | proteon_dev[i] = pdev; |
374 | dev_set_drvdata(&pdev->dev, dev); | ||
387 | ++num; | 375 | ++num; |
388 | } else { | 376 | } else { |
377 | platform_device_unregister(pdev); | ||
389 | free_netdev(dev); | 378 | free_netdev(dev); |
390 | } | 379 | } |
391 | } | 380 | } |
@@ -399,23 +388,28 @@ int init_module(void) | |||
399 | return (0); | 388 | return (0); |
400 | } | 389 | } |
401 | 390 | ||
402 | void cleanup_module(void) | 391 | static void __exit proteon_cleanup(void) |
403 | { | 392 | { |
393 | struct net_device *dev; | ||
404 | int i; | 394 | int i; |
405 | 395 | ||
406 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 396 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
407 | struct net_device *dev = proteon_dev[i]; | 397 | struct platform_device *pdev = proteon_dev[i]; |
408 | 398 | ||
409 | if (!dev) | 399 | if (!pdev) |
410 | continue; | 400 | continue; |
411 | 401 | dev = dev_get_drvdata(&pdev->dev); | |
412 | unregister_netdev(dev); | 402 | unregister_netdev(dev); |
413 | release_region(dev->base_addr, PROTEON_IO_EXTENT); | 403 | release_region(dev->base_addr, PROTEON_IO_EXTENT); |
414 | free_irq(dev->irq, dev); | 404 | free_irq(dev->irq, dev); |
415 | free_dma(dev->dma); | 405 | free_dma(dev->dma); |
416 | tmsdev_term(dev); | 406 | tmsdev_term(dev); |
417 | free_netdev(dev); | 407 | free_netdev(dev); |
408 | dev_set_drvdata(&pdev->dev, NULL); | ||
409 | platform_device_unregister(pdev); | ||
418 | } | 410 | } |
411 | driver_unregister(&proteon_driver); | ||
419 | } | 412 | } |
420 | #endif /* MODULE */ | ||
421 | 413 | ||
414 | module_init(proteon_init); | ||
415 | module_exit(proteon_cleanup); | ||
diff --git a/drivers/net/tokenring/skisa.c b/drivers/net/tokenring/skisa.c index f26796e2d0e5..3c7c66204f74 100644 --- a/drivers/net/tokenring/skisa.c +++ b/drivers/net/tokenring/skisa.c | |||
@@ -68,8 +68,7 @@ static int dmalist[] __initdata = { | |||
68 | }; | 68 | }; |
69 | 69 | ||
70 | static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; | 70 | static char isa_cardname[] = "SK NET TR 4/16 ISA\0"; |
71 | 71 | static u64 dma_mask = ISA_MAX_ADDRESS; | |
72 | struct net_device *sk_isa_probe(int unit); | ||
73 | static int sk_isa_open(struct net_device *dev); | 72 | static int sk_isa_open(struct net_device *dev); |
74 | static void sk_isa_read_eeprom(struct net_device *dev); | 73 | static void sk_isa_read_eeprom(struct net_device *dev); |
75 | static unsigned short sk_isa_setnselout_pins(struct net_device *dev); | 74 | static unsigned short sk_isa_setnselout_pins(struct net_device *dev); |
@@ -133,7 +132,7 @@ static int __init sk_isa_probe1(struct net_device *dev, int ioaddr) | |||
133 | return 0; | 132 | return 0; |
134 | } | 133 | } |
135 | 134 | ||
136 | static int __init setup_card(struct net_device *dev) | 135 | static int __init setup_card(struct net_device *dev, struct device *pdev) |
137 | { | 136 | { |
138 | struct net_local *tp; | 137 | struct net_local *tp; |
139 | static int versionprinted; | 138 | static int versionprinted; |
@@ -154,7 +153,7 @@ static int __init setup_card(struct net_device *dev) | |||
154 | } | 153 | } |
155 | } | 154 | } |
156 | if (err) | 155 | if (err) |
157 | goto out4; | 156 | goto out5; |
158 | 157 | ||
159 | /* At this point we have found a valid card. */ | 158 | /* At this point we have found a valid card. */ |
160 | 159 | ||
@@ -162,14 +161,15 @@ static int __init setup_card(struct net_device *dev) | |||
162 | printk(KERN_DEBUG "%s", version); | 161 | printk(KERN_DEBUG "%s", version); |
163 | 162 | ||
164 | err = -EIO; | 163 | err = -EIO; |
165 | if (tmsdev_init(dev, ISA_MAX_ADDRESS, NULL)) | 164 | pdev->dma_mask = &dma_mask; |
165 | if (tmsdev_init(dev, pdev)) | ||
166 | goto out4; | 166 | goto out4; |
167 | 167 | ||
168 | dev->base_addr &= ~3; | 168 | dev->base_addr &= ~3; |
169 | 169 | ||
170 | sk_isa_read_eeprom(dev); | 170 | sk_isa_read_eeprom(dev); |
171 | 171 | ||
172 | printk(KERN_DEBUG "%s: Ring Station Address: ", dev->name); | 172 | printk(KERN_DEBUG "skisa.c: Ring Station Address: "); |
173 | printk("%2.2x", dev->dev_addr[0]); | 173 | printk("%2.2x", dev->dev_addr[0]); |
174 | for (j = 1; j < 6; j++) | 174 | for (j = 1; j < 6; j++) |
175 | printk(":%2.2x", dev->dev_addr[j]); | 175 | printk(":%2.2x", dev->dev_addr[j]); |
@@ -202,7 +202,7 @@ static int __init setup_card(struct net_device *dev) | |||
202 | 202 | ||
203 | if(irqlist[j] == 0) | 203 | if(irqlist[j] == 0) |
204 | { | 204 | { |
205 | printk(KERN_INFO "%s: AutoSelect no IRQ available\n", dev->name); | 205 | printk(KERN_INFO "skisa.c: AutoSelect no IRQ available\n"); |
206 | goto out3; | 206 | goto out3; |
207 | } | 207 | } |
208 | } | 208 | } |
@@ -213,15 +213,15 @@ static int __init setup_card(struct net_device *dev) | |||
213 | break; | 213 | break; |
214 | if (irqlist[j] == 0) | 214 | if (irqlist[j] == 0) |
215 | { | 215 | { |
216 | printk(KERN_INFO "%s: Illegal IRQ %d specified\n", | 216 | printk(KERN_INFO "skisa.c: Illegal IRQ %d specified\n", |
217 | dev->name, dev->irq); | 217 | dev->irq); |
218 | goto out3; | 218 | goto out3; |
219 | } | 219 | } |
220 | if (request_irq(dev->irq, tms380tr_interrupt, 0, | 220 | if (request_irq(dev->irq, tms380tr_interrupt, 0, |
221 | isa_cardname, dev)) | 221 | isa_cardname, dev)) |
222 | { | 222 | { |
223 | printk(KERN_INFO "%s: Selected IRQ %d not available\n", | 223 | printk(KERN_INFO "skisa.c: Selected IRQ %d not available\n", |
224 | dev->name, dev->irq); | 224 | dev->irq); |
225 | goto out3; | 225 | goto out3; |
226 | } | 226 | } |
227 | } | 227 | } |
@@ -237,7 +237,7 @@ static int __init setup_card(struct net_device *dev) | |||
237 | 237 | ||
238 | if(dmalist[j] == 0) | 238 | if(dmalist[j] == 0) |
239 | { | 239 | { |
240 | printk(KERN_INFO "%s: AutoSelect no DMA available\n", dev->name); | 240 | printk(KERN_INFO "skisa.c: AutoSelect no DMA available\n"); |
241 | goto out2; | 241 | goto out2; |
242 | } | 242 | } |
243 | } | 243 | } |
@@ -248,25 +248,25 @@ static int __init setup_card(struct net_device *dev) | |||
248 | break; | 248 | break; |
249 | if (dmalist[j] == 0) | 249 | if (dmalist[j] == 0) |
250 | { | 250 | { |
251 | printk(KERN_INFO "%s: Illegal DMA %d specified\n", | 251 | printk(KERN_INFO "skisa.c: Illegal DMA %d specified\n", |
252 | dev->name, dev->dma); | 252 | dev->dma); |
253 | goto out2; | 253 | goto out2; |
254 | } | 254 | } |
255 | if (request_dma(dev->dma, isa_cardname)) | 255 | if (request_dma(dev->dma, isa_cardname)) |
256 | { | 256 | { |
257 | printk(KERN_INFO "%s: Selected DMA %d not available\n", | 257 | printk(KERN_INFO "skisa.c: Selected DMA %d not available\n", |
258 | dev->name, dev->dma); | 258 | dev->dma); |
259 | goto out2; | 259 | goto out2; |
260 | } | 260 | } |
261 | } | 261 | } |
262 | 262 | ||
263 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
264 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
265 | |||
266 | err = register_netdev(dev); | 263 | err = register_netdev(dev); |
267 | if (err) | 264 | if (err) |
268 | goto out; | 265 | goto out; |
269 | 266 | ||
267 | printk(KERN_DEBUG "%s: IO: %#4lx IRQ: %d DMA: %d\n", | ||
268 | dev->name, dev->base_addr, dev->irq, dev->dma); | ||
269 | |||
270 | return 0; | 270 | return 0; |
271 | out: | 271 | out: |
272 | free_dma(dev->dma); | 272 | free_dma(dev->dma); |
@@ -275,33 +275,11 @@ out2: | |||
275 | out3: | 275 | out3: |
276 | tmsdev_term(dev); | 276 | tmsdev_term(dev); |
277 | out4: | 277 | out4: |
278 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); | 278 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); |
279 | out5: | ||
279 | return err; | 280 | return err; |
280 | } | 281 | } |
281 | 282 | ||
282 | struct net_device * __init sk_isa_probe(int unit) | ||
283 | { | ||
284 | struct net_device *dev = alloc_trdev(sizeof(struct net_local)); | ||
285 | int err = 0; | ||
286 | |||
287 | if (!dev) | ||
288 | return ERR_PTR(-ENOMEM); | ||
289 | |||
290 | if (unit >= 0) { | ||
291 | sprintf(dev->name, "tr%d", unit); | ||
292 | netdev_boot_setup_check(dev); | ||
293 | } | ||
294 | |||
295 | err = setup_card(dev); | ||
296 | if (err) | ||
297 | goto out; | ||
298 | |||
299 | return dev; | ||
300 | out: | ||
301 | free_netdev(dev); | ||
302 | return ERR_PTR(err); | ||
303 | } | ||
304 | |||
305 | /* | 283 | /* |
306 | * Reads MAC address from adapter RAM, which should've read it from | 284 | * Reads MAC address from adapter RAM, which should've read it from |
307 | * the onboard ROM. | 285 | * the onboard ROM. |
@@ -361,8 +339,6 @@ static int sk_isa_open(struct net_device *dev) | |||
361 | return tms380tr_open(dev); | 339 | return tms380tr_open(dev); |
362 | } | 340 | } |
363 | 341 | ||
364 | #ifdef MODULE | ||
365 | |||
366 | #define ISATR_MAX_ADAPTERS 3 | 342 | #define ISATR_MAX_ADAPTERS 3 |
367 | 343 | ||
368 | static int io[ISATR_MAX_ADAPTERS]; | 344 | static int io[ISATR_MAX_ADAPTERS]; |
@@ -375,13 +351,23 @@ module_param_array(io, int, NULL, 0); | |||
375 | module_param_array(irq, int, NULL, 0); | 351 | module_param_array(irq, int, NULL, 0); |
376 | module_param_array(dma, int, NULL, 0); | 352 | module_param_array(dma, int, NULL, 0); |
377 | 353 | ||
378 | static struct net_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; | 354 | static struct platform_device *sk_isa_dev[ISATR_MAX_ADAPTERS]; |
379 | 355 | ||
380 | int init_module(void) | 356 | static struct device_driver sk_isa_driver = { |
357 | .name = "skisa", | ||
358 | .bus = &platform_bus_type, | ||
359 | }; | ||
360 | |||
361 | static int __init sk_isa_init(void) | ||
381 | { | 362 | { |
382 | struct net_device *dev; | 363 | struct net_device *dev; |
364 | struct platform_device *pdev; | ||
383 | int i, num = 0, err = 0; | 365 | int i, num = 0, err = 0; |
384 | 366 | ||
367 | err = driver_register(&sk_isa_driver); | ||
368 | if (err) | ||
369 | return err; | ||
370 | |||
385 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 371 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
386 | dev = alloc_trdev(sizeof(struct net_local)); | 372 | dev = alloc_trdev(sizeof(struct net_local)); |
387 | if (!dev) | 373 | if (!dev) |
@@ -390,12 +376,15 @@ int init_module(void) | |||
390 | dev->base_addr = io[i]; | 376 | dev->base_addr = io[i]; |
391 | dev->irq = irq[i]; | 377 | dev->irq = irq[i]; |
392 | dev->dma = dma[i]; | 378 | dev->dma = dma[i]; |
393 | err = setup_card(dev); | 379 | pdev = platform_device_register_simple("skisa", |
394 | 380 | i, NULL, 0); | |
381 | err = setup_card(dev, &pdev->dev); | ||
395 | if (!err) { | 382 | if (!err) { |
396 | sk_isa_dev[i] = dev; | 383 | sk_isa_dev[i] = pdev; |
384 | dev_set_drvdata(&sk_isa_dev[i]->dev, dev); | ||
397 | ++num; | 385 | ++num; |
398 | } else { | 386 | } else { |
387 | platform_device_unregister(pdev); | ||
399 | free_netdev(dev); | 388 | free_netdev(dev); |
400 | } | 389 | } |
401 | } | 390 | } |
@@ -409,23 +398,28 @@ int init_module(void) | |||
409 | return (0); | 398 | return (0); |
410 | } | 399 | } |
411 | 400 | ||
412 | void cleanup_module(void) | 401 | static void __exit sk_isa_cleanup(void) |
413 | { | 402 | { |
403 | struct net_device *dev; | ||
414 | int i; | 404 | int i; |
415 | 405 | ||
416 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { | 406 | for (i = 0; i < ISATR_MAX_ADAPTERS ; i++) { |
417 | struct net_device *dev = sk_isa_dev[i]; | 407 | struct platform_device *pdev = sk_isa_dev[i]; |
418 | 408 | ||
419 | if (!dev) | 409 | if (!pdev) |
420 | continue; | 410 | continue; |
421 | 411 | dev = dev_get_drvdata(&pdev->dev); | |
422 | unregister_netdev(dev); | 412 | unregister_netdev(dev); |
423 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); | 413 | release_region(dev->base_addr, SK_ISA_IO_EXTENT); |
424 | free_irq(dev->irq, dev); | 414 | free_irq(dev->irq, dev); |
425 | free_dma(dev->dma); | 415 | free_dma(dev->dma); |
426 | tmsdev_term(dev); | 416 | tmsdev_term(dev); |
427 | free_netdev(dev); | 417 | free_netdev(dev); |
418 | dev_set_drvdata(&pdev->dev, NULL); | ||
419 | platform_device_unregister(pdev); | ||
428 | } | 420 | } |
421 | driver_unregister(&sk_isa_driver); | ||
429 | } | 422 | } |
430 | #endif /* MODULE */ | ||
431 | 423 | ||
424 | module_init(sk_isa_init); | ||
425 | module_exit(sk_isa_cleanup); | ||
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c index 5e0b0ce98ed7..2e39bf1f7462 100644 --- a/drivers/net/tokenring/tms380tr.c +++ b/drivers/net/tokenring/tms380tr.c | |||
@@ -62,6 +62,7 @@ | |||
62 | * normal operation. | 62 | * normal operation. |
63 | * 30-Dec-02 JF Removed incorrect __init from | 63 | * 30-Dec-02 JF Removed incorrect __init from |
64 | * tms380tr_init_card. | 64 | * tms380tr_init_card. |
65 | * 22-Jul-05 JF Converted to dma-mapping. | ||
65 | * | 66 | * |
66 | * To do: | 67 | * To do: |
67 | * 1. Multi/Broadcast packet handling (this may have fixed itself) | 68 | * 1. Multi/Broadcast packet handling (this may have fixed itself) |
@@ -89,7 +90,7 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A | |||
89 | #include <linux/time.h> | 90 | #include <linux/time.h> |
90 | #include <linux/errno.h> | 91 | #include <linux/errno.h> |
91 | #include <linux/init.h> | 92 | #include <linux/init.h> |
92 | #include <linux/pci.h> | 93 | #include <linux/dma-mapping.h> |
93 | #include <linux/delay.h> | 94 | #include <linux/delay.h> |
94 | #include <linux/netdevice.h> | 95 | #include <linux/netdevice.h> |
95 | #include <linux/etherdevice.h> | 96 | #include <linux/etherdevice.h> |
@@ -114,8 +115,6 @@ static const char version[] = "tms380tr.c: v1.10 30/12/2002 by Christoph Goos, A | |||
114 | #endif | 115 | #endif |
115 | static unsigned int tms380tr_debug = TMS380TR_DEBUG; | 116 | static unsigned int tms380tr_debug = TMS380TR_DEBUG; |
116 | 117 | ||
117 | static struct device tms_device; | ||
118 | |||
119 | /* Index to functions, as function prototypes. | 118 | /* Index to functions, as function prototypes. |
120 | * Alphabetical by function name. | 119 | * Alphabetical by function name. |
121 | */ | 120 | */ |
@@ -434,7 +433,7 @@ static void tms380tr_init_net_local(struct net_device *dev) | |||
434 | skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); | 433 | skb_put(tp->Rpl[i].Skb, tp->MaxPacketSize); |
435 | 434 | ||
436 | /* data unreachable for DMA ? then use local buffer */ | 435 | /* data unreachable for DMA ? then use local buffer */ |
437 | dmabuf = pci_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, PCI_DMA_FROMDEVICE); | 436 | dmabuf = dma_map_single(tp->pdev, tp->Rpl[i].Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); |
438 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) | 437 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) |
439 | { | 438 | { |
440 | tp->Rpl[i].SkbStat = SKB_DATA_COPY; | 439 | tp->Rpl[i].SkbStat = SKB_DATA_COPY; |
@@ -638,10 +637,10 @@ static int tms380tr_hardware_send_packet(struct sk_buff *skb, struct net_device | |||
638 | /* Is buffer reachable for Busmaster-DMA? */ | 637 | /* Is buffer reachable for Busmaster-DMA? */ |
639 | 638 | ||
640 | length = skb->len; | 639 | length = skb->len; |
641 | dmabuf = pci_map_single(tp->pdev, skb->data, length, PCI_DMA_TODEVICE); | 640 | dmabuf = dma_map_single(tp->pdev, skb->data, length, DMA_TO_DEVICE); |
642 | if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { | 641 | if(tp->dmalimit && (dmabuf + length > tp->dmalimit)) { |
643 | /* Copy frame to local buffer */ | 642 | /* Copy frame to local buffer */ |
644 | pci_unmap_single(tp->pdev, dmabuf, length, PCI_DMA_TODEVICE); | 643 | dma_unmap_single(tp->pdev, dmabuf, length, DMA_TO_DEVICE); |
645 | dmabuf = 0; | 644 | dmabuf = 0; |
646 | i = tp->TplFree->TPLIndex; | 645 | i = tp->TplFree->TPLIndex; |
647 | buf = tp->LocalTxBuffers[i]; | 646 | buf = tp->LocalTxBuffers[i]; |
@@ -1284,9 +1283,7 @@ static int tms380tr_reset_adapter(struct net_device *dev) | |||
1284 | unsigned short count, c, count2; | 1283 | unsigned short count, c, count2; |
1285 | const struct firmware *fw_entry = NULL; | 1284 | const struct firmware *fw_entry = NULL; |
1286 | 1285 | ||
1287 | strncpy(tms_device.bus_id,dev->name, BUS_ID_SIZE); | 1286 | if (request_firmware(&fw_entry, "tms380tr.bin", tp->pdev) != 0) { |
1288 | |||
1289 | if (request_firmware(&fw_entry, "tms380tr.bin", &tms_device) != 0) { | ||
1290 | printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", | 1287 | printk(KERN_ALERT "%s: firmware %s is missing, cannot start.\n", |
1291 | dev->name, "tms380tr.bin"); | 1288 | dev->name, "tms380tr.bin"); |
1292 | return (-1); | 1289 | return (-1); |
@@ -2021,7 +2018,7 @@ static void tms380tr_cancel_tx_queue(struct net_local* tp) | |||
2021 | 2018 | ||
2022 | printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); | 2019 | printk(KERN_INFO "Cancel tx (%08lXh).\n", (unsigned long)tpl); |
2023 | if (tpl->DMABuff) | 2020 | if (tpl->DMABuff) |
2024 | pci_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, PCI_DMA_TODEVICE); | 2021 | dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); |
2025 | dev_kfree_skb_any(tpl->Skb); | 2022 | dev_kfree_skb_any(tpl->Skb); |
2026 | } | 2023 | } |
2027 | 2024 | ||
@@ -2090,7 +2087,7 @@ static void tms380tr_tx_status_irq(struct net_device *dev) | |||
2090 | 2087 | ||
2091 | tp->MacStat.tx_packets++; | 2088 | tp->MacStat.tx_packets++; |
2092 | if (tpl->DMABuff) | 2089 | if (tpl->DMABuff) |
2093 | pci_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, PCI_DMA_TODEVICE); | 2090 | dma_unmap_single(tp->pdev, tpl->DMABuff, tpl->Skb->len, DMA_TO_DEVICE); |
2094 | dev_kfree_skb_irq(tpl->Skb); | 2091 | dev_kfree_skb_irq(tpl->Skb); |
2095 | tpl->BusyFlag = 0; /* "free" TPL */ | 2092 | tpl->BusyFlag = 0; /* "free" TPL */ |
2096 | } | 2093 | } |
@@ -2209,7 +2206,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) | |||
2209 | tp->MacStat.rx_errors++; | 2206 | tp->MacStat.rx_errors++; |
2210 | } | 2207 | } |
2211 | if (rpl->DMABuff) | 2208 | if (rpl->DMABuff) |
2212 | pci_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, PCI_DMA_TODEVICE); | 2209 | dma_unmap_single(tp->pdev, rpl->DMABuff, tp->MaxPacketSize, DMA_TO_DEVICE); |
2213 | rpl->DMABuff = 0; | 2210 | rpl->DMABuff = 0; |
2214 | 2211 | ||
2215 | /* Allocate new skb for rpl */ | 2212 | /* Allocate new skb for rpl */ |
@@ -2227,7 +2224,7 @@ static void tms380tr_rcv_status_irq(struct net_device *dev) | |||
2227 | skb_put(rpl->Skb, tp->MaxPacketSize); | 2224 | skb_put(rpl->Skb, tp->MaxPacketSize); |
2228 | 2225 | ||
2229 | /* Data unreachable for DMA ? then use local buffer */ | 2226 | /* Data unreachable for DMA ? then use local buffer */ |
2230 | dmabuf = pci_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, PCI_DMA_FROMDEVICE); | 2227 | dmabuf = dma_map_single(tp->pdev, rpl->Skb->data, tp->MaxPacketSize, DMA_FROM_DEVICE); |
2231 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) | 2228 | if(tp->dmalimit && (dmabuf + tp->MaxPacketSize > tp->dmalimit)) |
2232 | { | 2229 | { |
2233 | rpl->SkbStat = SKB_DATA_COPY; | 2230 | rpl->SkbStat = SKB_DATA_COPY; |
@@ -2332,23 +2329,26 @@ void tmsdev_term(struct net_device *dev) | |||
2332 | struct net_local *tp; | 2329 | struct net_local *tp; |
2333 | 2330 | ||
2334 | tp = netdev_priv(dev); | 2331 | tp = netdev_priv(dev); |
2335 | pci_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), | 2332 | dma_unmap_single(tp->pdev, tp->dmabuffer, sizeof(struct net_local), |
2336 | PCI_DMA_BIDIRECTIONAL); | 2333 | DMA_BIDIRECTIONAL); |
2337 | } | 2334 | } |
2338 | 2335 | ||
2339 | int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | 2336 | int tmsdev_init(struct net_device *dev, struct device *pdev) |
2340 | struct pci_dev *pdev) | ||
2341 | { | 2337 | { |
2342 | struct net_local *tms_local; | 2338 | struct net_local *tms_local; |
2343 | 2339 | ||
2344 | memset(dev->priv, 0, sizeof(struct net_local)); | 2340 | memset(dev->priv, 0, sizeof(struct net_local)); |
2345 | tms_local = netdev_priv(dev); | 2341 | tms_local = netdev_priv(dev); |
2346 | init_waitqueue_head(&tms_local->wait_for_tok_int); | 2342 | init_waitqueue_head(&tms_local->wait_for_tok_int); |
2347 | tms_local->dmalimit = dmalimit; | 2343 | if (pdev->dma_mask) |
2344 | tms_local->dmalimit = *pdev->dma_mask; | ||
2345 | else | ||
2346 | return -ENOMEM; | ||
2348 | tms_local->pdev = pdev; | 2347 | tms_local->pdev = pdev; |
2349 | tms_local->dmabuffer = pci_map_single(pdev, (void *)tms_local, | 2348 | tms_local->dmabuffer = dma_map_single(pdev, (void *)tms_local, |
2350 | sizeof(struct net_local), PCI_DMA_BIDIRECTIONAL); | 2349 | sizeof(struct net_local), DMA_BIDIRECTIONAL); |
2351 | if (tms_local->dmabuffer + sizeof(struct net_local) > dmalimit) | 2350 | if (tms_local->dmabuffer + sizeof(struct net_local) > |
2351 | tms_local->dmalimit) | ||
2352 | { | 2352 | { |
2353 | printk(KERN_INFO "%s: Memory not accessible for DMA\n", | 2353 | printk(KERN_INFO "%s: Memory not accessible for DMA\n", |
2354 | dev->name); | 2354 | dev->name); |
@@ -2370,8 +2370,6 @@ int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | |||
2370 | return 0; | 2370 | return 0; |
2371 | } | 2371 | } |
2372 | 2372 | ||
2373 | #ifdef MODULE | ||
2374 | |||
2375 | EXPORT_SYMBOL(tms380tr_open); | 2373 | EXPORT_SYMBOL(tms380tr_open); |
2376 | EXPORT_SYMBOL(tms380tr_close); | 2374 | EXPORT_SYMBOL(tms380tr_close); |
2377 | EXPORT_SYMBOL(tms380tr_interrupt); | 2375 | EXPORT_SYMBOL(tms380tr_interrupt); |
@@ -2379,6 +2377,8 @@ EXPORT_SYMBOL(tmsdev_init); | |||
2379 | EXPORT_SYMBOL(tmsdev_term); | 2377 | EXPORT_SYMBOL(tmsdev_term); |
2380 | EXPORT_SYMBOL(tms380tr_wait); | 2378 | EXPORT_SYMBOL(tms380tr_wait); |
2381 | 2379 | ||
2380 | #ifdef MODULE | ||
2381 | |||
2382 | static struct module *TMS380_module = NULL; | 2382 | static struct module *TMS380_module = NULL; |
2383 | 2383 | ||
2384 | int init_module(void) | 2384 | int init_module(void) |
diff --git a/drivers/net/tokenring/tms380tr.h b/drivers/net/tokenring/tms380tr.h index f2c5ba0f37a5..30452c67bb68 100644 --- a/drivers/net/tokenring/tms380tr.h +++ b/drivers/net/tokenring/tms380tr.h | |||
@@ -17,8 +17,7 @@ | |||
17 | int tms380tr_open(struct net_device *dev); | 17 | int tms380tr_open(struct net_device *dev); |
18 | int tms380tr_close(struct net_device *dev); | 18 | int tms380tr_close(struct net_device *dev); |
19 | irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 19 | irqreturn_t tms380tr_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
20 | int tmsdev_init(struct net_device *dev, unsigned long dmalimit, | 20 | int tmsdev_init(struct net_device *dev, struct device *pdev); |
21 | struct pci_dev *pdev); | ||
22 | void tmsdev_term(struct net_device *dev); | 21 | void tmsdev_term(struct net_device *dev); |
23 | void tms380tr_wait(unsigned long time); | 22 | void tms380tr_wait(unsigned long time); |
24 | 23 | ||
@@ -719,7 +718,7 @@ struct s_TPL { /* Transmit Parameter List (align on even word boundaries) */ | |||
719 | struct sk_buff *Skb; | 718 | struct sk_buff *Skb; |
720 | unsigned char TPLIndex; | 719 | unsigned char TPLIndex; |
721 | volatile unsigned char BusyFlag;/* Flag: TPL busy? */ | 720 | volatile unsigned char BusyFlag;/* Flag: TPL busy? */ |
722 | dma_addr_t DMABuff; /* DMA IO bus address from pci_map */ | 721 | dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ |
723 | }; | 722 | }; |
724 | 723 | ||
725 | /* ---------------------Receive Functions-------------------------------* | 724 | /* ---------------------Receive Functions-------------------------------* |
@@ -1060,7 +1059,7 @@ struct s_RPL { /* Receive Parameter List */ | |||
1060 | struct sk_buff *Skb; | 1059 | struct sk_buff *Skb; |
1061 | SKB_STAT SkbStat; | 1060 | SKB_STAT SkbStat; |
1062 | int RPLIndex; | 1061 | int RPLIndex; |
1063 | dma_addr_t DMABuff; /* DMA IO bus address from pci_map */ | 1062 | dma_addr_t DMABuff; /* DMA IO bus address from dma_map */ |
1064 | }; | 1063 | }; |
1065 | 1064 | ||
1066 | /* Information that need to be kept for each board. */ | 1065 | /* Information that need to be kept for each board. */ |
@@ -1091,7 +1090,7 @@ typedef struct net_local { | |||
1091 | RPL *RplTail; | 1090 | RPL *RplTail; |
1092 | unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; | 1091 | unsigned char LocalRxBuffers[RPL_NUM][DEFAULT_PACKET_SIZE]; |
1093 | 1092 | ||
1094 | struct pci_dev *pdev; | 1093 | struct device *pdev; |
1095 | int DataRate; | 1094 | int DataRate; |
1096 | unsigned char ScbInUse; | 1095 | unsigned char ScbInUse; |
1097 | unsigned short CMDqueue; | 1096 | unsigned short CMDqueue; |
diff --git a/drivers/net/tokenring/tmspci.c b/drivers/net/tokenring/tmspci.c index 2e18c0a46482..ab47c0547a3b 100644 --- a/drivers/net/tokenring/tmspci.c +++ b/drivers/net/tokenring/tmspci.c | |||
@@ -100,7 +100,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
100 | unsigned int pci_irq_line; | 100 | unsigned int pci_irq_line; |
101 | unsigned long pci_ioaddr; | 101 | unsigned long pci_ioaddr; |
102 | struct card_info *cardinfo = &card_info_table[ent->driver_data]; | 102 | struct card_info *cardinfo = &card_info_table[ent->driver_data]; |
103 | 103 | ||
104 | if (versionprinted++ == 0) | 104 | if (versionprinted++ == 0) |
105 | printk("%s", version); | 105 | printk("%s", version); |
106 | 106 | ||
@@ -143,7 +143,7 @@ static int __devinit tms_pci_attach(struct pci_dev *pdev, const struct pci_devic | |||
143 | printk(":%2.2x", dev->dev_addr[i]); | 143 | printk(":%2.2x", dev->dev_addr[i]); |
144 | printk("\n"); | 144 | printk("\n"); |
145 | 145 | ||
146 | ret = tmsdev_init(dev, PCI_MAX_ADDRESS, pdev); | 146 | ret = tmsdev_init(dev, &pdev->dev); |
147 | if (ret) { | 147 | if (ret) { |
148 | printk("%s: unable to get memory for dev->priv.\n", dev->name); | 148 | printk("%s: unable to get memory for dev->priv.\n", dev->name); |
149 | goto err_out_irq; | 149 | goto err_out_irq; |
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c index 6e74af62ca08..9e56fc346ba4 100644 --- a/drivers/net/wan/cycx_drv.c +++ b/drivers/net/wan/cycx_drv.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <linux/sched.h> /* for jiffies, HZ, etc. */ | 56 | #include <linux/sched.h> /* for jiffies, HZ, etc. */ |
57 | #include <linux/cycx_drv.h> /* API definitions */ | 57 | #include <linux/cycx_drv.h> /* API definitions */ |
58 | #include <linux/cycx_cfm.h> /* CYCX firmware module definitions */ | 58 | #include <linux/cycx_cfm.h> /* CYCX firmware module definitions */ |
59 | #include <linux/delay.h> /* udelay */ | 59 | #include <linux/delay.h> /* udelay, msleep_interruptible */ |
60 | #include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */ | 60 | #include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */ |
61 | 61 | ||
62 | #define MOD_VERSION 0 | 62 | #define MOD_VERSION 0 |
@@ -74,7 +74,6 @@ static int reset_cyc2x(void __iomem *addr); | |||
74 | static int detect_cyc2x(void __iomem *addr); | 74 | static int detect_cyc2x(void __iomem *addr); |
75 | 75 | ||
76 | /* Miscellaneous functions */ | 76 | /* Miscellaneous functions */ |
77 | static void delay_cycx(int sec); | ||
78 | static int get_option_index(long *optlist, long optval); | 77 | static int get_option_index(long *optlist, long optval); |
79 | static u16 checksum(u8 *buf, u32 len); | 78 | static u16 checksum(u8 *buf, u32 len); |
80 | 79 | ||
@@ -259,7 +258,7 @@ static int memory_exists(void __iomem *addr) | |||
259 | if (readw(addr + 0x10) == TEST_PATTERN) | 258 | if (readw(addr + 0x10) == TEST_PATTERN) |
260 | return 1; | 259 | return 1; |
261 | 260 | ||
262 | delay_cycx(1); | 261 | msleep_interruptible(1 * 1000); |
263 | } | 262 | } |
264 | 263 | ||
265 | return 0; | 264 | return 0; |
@@ -316,7 +315,7 @@ static void cycx_reset_boot(void __iomem *addr, u8 *code, u32 len) | |||
316 | 315 | ||
317 | /* 80186 was in hold, go */ | 316 | /* 80186 was in hold, go */ |
318 | writeb(0, addr + START_CPU); | 317 | writeb(0, addr + START_CPU); |
319 | delay_cycx(1); | 318 | msleep_interruptible(1 * 1000); |
320 | } | 319 | } |
321 | 320 | ||
322 | /* Load data.bin file through boot (reset) interface. */ | 321 | /* Load data.bin file through boot (reset) interface. */ |
@@ -462,13 +461,13 @@ static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len) | |||
462 | cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size); | 461 | cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size); |
463 | /* reset is waiting for boot */ | 462 | /* reset is waiting for boot */ |
464 | writew(GEN_POWER_ON, pt_cycld); | 463 | writew(GEN_POWER_ON, pt_cycld); |
465 | delay_cycx(1); | 464 | msleep_interruptible(1 * 1000); |
466 | 465 | ||
467 | for (j = 0 ; j < 3 ; j++) | 466 | for (j = 0 ; j < 3 ; j++) |
468 | if (!readw(pt_cycld)) | 467 | if (!readw(pt_cycld)) |
469 | goto reset_loaded; | 468 | goto reset_loaded; |
470 | else | 469 | else |
471 | delay_cycx(1); | 470 | msleep_interruptible(1 * 1000); |
472 | } | 471 | } |
473 | 472 | ||
474 | printk(KERN_ERR "%s: reset not started.\n", modname); | 473 | printk(KERN_ERR "%s: reset not started.\n", modname); |
@@ -495,7 +494,7 @@ reset_loaded: | |||
495 | 494 | ||
496 | /* Arthur Ganzert's tip: wait a while after the firmware loading... | 495 | /* Arthur Ganzert's tip: wait a while after the firmware loading... |
497 | seg abr 26 17:17:12 EST 1999 - acme */ | 496 | seg abr 26 17:17:12 EST 1999 - acme */ |
498 | delay_cycx(7); | 497 | msleep_interruptible(7 * 1000); |
499 | printk(KERN_INFO "%s: firmware loaded!\n", modname); | 498 | printk(KERN_INFO "%s: firmware loaded!\n", modname); |
500 | 499 | ||
501 | /* enable interrupts */ | 500 | /* enable interrupts */ |
@@ -547,20 +546,13 @@ static int get_option_index(long *optlist, long optval) | |||
547 | static int reset_cyc2x(void __iomem *addr) | 546 | static int reset_cyc2x(void __iomem *addr) |
548 | { | 547 | { |
549 | writeb(0, addr + RST_ENABLE); | 548 | writeb(0, addr + RST_ENABLE); |
550 | delay_cycx(2); | 549 | msleep_interruptible(2 * 1000); |
551 | writeb(0, addr + RST_DISABLE); | 550 | writeb(0, addr + RST_DISABLE); |
552 | delay_cycx(2); | 551 | msleep_interruptible(2 * 1000); |
553 | 552 | ||
554 | return memory_exists(addr); | 553 | return memory_exists(addr); |
555 | } | 554 | } |
556 | 555 | ||
557 | /* Delay */ | ||
558 | static void delay_cycx(int sec) | ||
559 | { | ||
560 | set_current_state(TASK_INTERRUPTIBLE); | ||
561 | schedule_timeout(sec * HZ); | ||
562 | } | ||
563 | |||
564 | /* Calculate 16-bit CRC using CCITT polynomial. */ | 556 | /* Calculate 16-bit CRC using CCITT polynomial. */ |
565 | static u16 checksum(u8 *buf, u32 len) | 557 | static u16 checksum(u8 *buf, u32 len) |
566 | { | 558 | { |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 1d3231cc471a..ec3f75a030d2 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -270,7 +270,7 @@ config PCMCIA_HERMES | |||
270 | 270 | ||
271 | config AIRO_CS | 271 | config AIRO_CS |
272 | tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" | 272 | tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" |
273 | depends on NET_RADIO && PCMCIA | 273 | depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) |
274 | ---help--- | 274 | ---help--- |
275 | This is the standard Linux driver to support Cisco/Aironet PCMCIA | 275 | This is the standard Linux driver to support Cisco/Aironet PCMCIA |
276 | 802.11 wireless cards. This driver is the same as the Aironet | 276 | 802.11 wireless cards. This driver is the same as the Aironet |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index aabcdc2be05e..9c2d07cde010 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -4322,36 +4322,36 @@ static const struct iw_priv_args orinoco_privtab[] = { | |||
4322 | */ | 4322 | */ |
4323 | 4323 | ||
4324 | static const iw_handler orinoco_handler[] = { | 4324 | static const iw_handler orinoco_handler[] = { |
4325 | [SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) orinoco_ioctl_commit, | 4325 | [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_commit, |
4326 | [SIOCGIWNAME -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getname, | 4326 | [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getname, |
4327 | [SIOCSIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfreq, | 4327 | [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfreq, |
4328 | [SIOCGIWFREQ -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfreq, | 4328 | [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfreq, |
4329 | [SIOCSIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setmode, | 4329 | [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setmode, |
4330 | [SIOCGIWMODE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getmode, | 4330 | [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getmode, |
4331 | [SIOCSIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setsens, | 4331 | [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, |
4332 | [SIOCGIWSENS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getsens, | 4332 | [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, |
4333 | [SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwrange, | 4333 | [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, |
4334 | [SIOCSIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setspy, | 4334 | [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, |
4335 | [SIOCGIWSPY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getspy, | 4335 | [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, |
4336 | [SIOCSIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setwap, | 4336 | [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, |
4337 | [SIOCGIWAP -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getwap, | 4337 | [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, |
4338 | [SIOCSIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setscan, | 4338 | [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, |
4339 | [SIOCGIWSCAN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getscan, | 4339 | [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getscan, |
4340 | [SIOCSIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setessid, | 4340 | [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setessid, |
4341 | [SIOCGIWESSID -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getessid, | 4341 | [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getessid, |
4342 | [SIOCSIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setnick, | 4342 | [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setnick, |
4343 | [SIOCGIWNICKN -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getnick, | 4343 | [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getnick, |
4344 | [SIOCSIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrate, | 4344 | [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrate, |
4345 | [SIOCGIWRATE -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrate, | 4345 | [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrate, |
4346 | [SIOCSIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setrts, | 4346 | [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setrts, |
4347 | [SIOCGIWRTS -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getrts, | 4347 | [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getrts, |
4348 | [SIOCSIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setfrag, | 4348 | [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setfrag, |
4349 | [SIOCGIWFRAG -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getfrag, | 4349 | [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getfrag, |
4350 | [SIOCGIWRETRY -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getretry, | 4350 | [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getretry, |
4351 | [SIOCSIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_setiwencode, | 4351 | [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setiwencode, |
4352 | [SIOCGIWENCODE-SIOCIWFIRST] (iw_handler) orinoco_ioctl_getiwencode, | 4352 | [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwencode, |
4353 | [SIOCSIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_setpower, | 4353 | [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setpower, |
4354 | [SIOCGIWPOWER -SIOCIWFIRST] (iw_handler) orinoco_ioctl_getpower, | 4354 | [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getpower, |
4355 | }; | 4355 | }; |
4356 | 4356 | ||
4357 | 4357 | ||
@@ -4359,15 +4359,15 @@ static const iw_handler orinoco_handler[] = { | |||
4359 | Added typecasting since we no longer use iwreq_data -- Moustafa | 4359 | Added typecasting since we no longer use iwreq_data -- Moustafa |
4360 | */ | 4360 | */ |
4361 | static const iw_handler orinoco_private_handler[] = { | 4361 | static const iw_handler orinoco_private_handler[] = { |
4362 | [0] (iw_handler) orinoco_ioctl_reset, | 4362 | [0] = (iw_handler) orinoco_ioctl_reset, |
4363 | [1] (iw_handler) orinoco_ioctl_reset, | 4363 | [1] = (iw_handler) orinoco_ioctl_reset, |
4364 | [2] (iw_handler) orinoco_ioctl_setport3, | 4364 | [2] = (iw_handler) orinoco_ioctl_setport3, |
4365 | [3] (iw_handler) orinoco_ioctl_getport3, | 4365 | [3] = (iw_handler) orinoco_ioctl_getport3, |
4366 | [4] (iw_handler) orinoco_ioctl_setpreamble, | 4366 | [4] = (iw_handler) orinoco_ioctl_setpreamble, |
4367 | [5] (iw_handler) orinoco_ioctl_getpreamble, | 4367 | [5] = (iw_handler) orinoco_ioctl_getpreamble, |
4368 | [6] (iw_handler) orinoco_ioctl_setibssport, | 4368 | [6] = (iw_handler) orinoco_ioctl_setibssport, |
4369 | [7] (iw_handler) orinoco_ioctl_getibssport, | 4369 | [7] = (iw_handler) orinoco_ioctl_getibssport, |
4370 | [9] (iw_handler) orinoco_ioctl_getrid, | 4370 | [9] = (iw_handler) orinoco_ioctl_getrid, |
4371 | }; | 4371 | }; |
4372 | 4372 | ||
4373 | static const struct iw_handler_def orinoco_handler_def = { | 4373 | static const struct iw_handler_def orinoco_handler_def = { |
diff --git a/drivers/parport/Kconfig b/drivers/parport/Kconfig index 16a2e6ae37f4..725a14119f2a 100644 --- a/drivers/parport/Kconfig +++ b/drivers/parport/Kconfig | |||
@@ -34,7 +34,7 @@ config PARPORT | |||
34 | 34 | ||
35 | config PARPORT_PC | 35 | config PARPORT_PC |
36 | tristate "PC-style hardware" | 36 | tristate "PC-style hardware" |
37 | depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 | 37 | depends on PARPORT && (!SPARC64 || PCI) && !SPARC32 && !M32R |
38 | ---help--- | 38 | ---help--- |
39 | You should say Y here if you have a PC-style parallel port. All | 39 | You should say Y here if you have a PC-style parallel port. All |
40 | IBM PC compatible computers and some Alphas have PC-style | 40 | IBM PC compatible computers and some Alphas have PC-style |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index a2eebc6eaacc..6d864c502a1f 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -40,7 +40,7 @@ | |||
40 | * FIXME: IO should be max 256 bytes. However, since we may | 40 | * FIXME: IO should be max 256 bytes. However, since we may |
41 | * have a P2P bridge below a cardbus bridge, we need 4K. | 41 | * have a P2P bridge below a cardbus bridge, we need 4K. |
42 | */ | 42 | */ |
43 | #define CARDBUS_IO_SIZE (4096) | 43 | #define CARDBUS_IO_SIZE (256) |
44 | #define CARDBUS_MEM_SIZE (32*1024*1024) | 44 | #define CARDBUS_MEM_SIZE (32*1024*1024) |
45 | 45 | ||
46 | static void __devinit | 46 | static void __devinit |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 84eedc965688..5598b4714f77 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -53,7 +53,9 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) | |||
53 | if (resno < 6) { | 53 | if (resno < 6) { |
54 | reg = PCI_BASE_ADDRESS_0 + 4 * resno; | 54 | reg = PCI_BASE_ADDRESS_0 + 4 * resno; |
55 | } else if (resno == PCI_ROM_RESOURCE) { | 55 | } else if (resno == PCI_ROM_RESOURCE) { |
56 | new |= res->flags & IORESOURCE_ROM_ENABLE; | 56 | if (!(res->flags & IORESOURCE_ROM_ENABLE)) |
57 | return; | ||
58 | new |= PCI_ROM_ADDRESS_ENABLE; | ||
57 | reg = dev->rom_base_reg; | 59 | reg = dev->rom_base_reg; |
58 | } else { | 60 | } else { |
59 | /* Hmm, non-standard resource. */ | 61 | /* Hmm, non-standard resource. */ |
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 6f9fdb276402..599b116d9747 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -41,6 +41,7 @@ module_param(io_speed, int, 0444); | |||
41 | 41 | ||
42 | 42 | ||
43 | #ifdef CONFIG_PCMCIA_PROBE | 43 | #ifdef CONFIG_PCMCIA_PROBE |
44 | #include <asm/irq.h> | ||
44 | /* mask of IRQs already reserved by other cards, we should avoid using them */ | 45 | /* mask of IRQs already reserved by other cards, we should avoid using them */ |
45 | static u8 pcmcia_used_irq[NR_IRQS]; | 46 | static u8 pcmcia_used_irq[NR_IRQS]; |
46 | #endif | 47 | #endif |
diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index add12f7c489a..6e5229e92fbc 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c | |||
@@ -312,6 +312,8 @@ found: | |||
312 | if (drv->link.driver.probe) { | 312 | if (drv->link.driver.probe) { |
313 | if (drv->link.driver.probe(&dev->dev)) { | 313 | if (drv->link.driver.probe(&dev->dev)) { |
314 | dev->dev.driver = NULL; | 314 | dev->dev.driver = NULL; |
315 | dev->card_link = NULL; | ||
316 | up_write(&dev->dev.bus->subsys.rwsem); | ||
315 | return NULL; | 317 | return NULL; |
316 | } | 318 | } |
317 | } | 319 | } |
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index d36258d6665f..381f339e3200 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c | |||
@@ -112,7 +112,7 @@ qdio_min(int a,int b) | |||
112 | 112 | ||
113 | /***************** SCRUBBER HELPER ROUTINES **********************/ | 113 | /***************** SCRUBBER HELPER ROUTINES **********************/ |
114 | 114 | ||
115 | static inline volatile __u64 | 115 | static inline __u64 |
116 | qdio_get_micros(void) | 116 | qdio_get_micros(void) |
117 | { | 117 | { |
118 | return (get_clock() >> 10); /* time>>12 is microseconds */ | 118 | return (get_clock() >> 10); /* time>>12 is microseconds */ |
@@ -230,7 +230,7 @@ qdio_siga_input(struct qdio_q *q) | |||
230 | } | 230 | } |
231 | 231 | ||
232 | /* locked by the locks in qdio_activate and qdio_cleanup */ | 232 | /* locked by the locks in qdio_activate and qdio_cleanup */ |
233 | static __u32 * volatile | 233 | static __u32 volatile * |
234 | qdio_get_indicator(void) | 234 | qdio_get_indicator(void) |
235 | { | 235 | { |
236 | int i; | 236 | int i; |
diff --git a/drivers/s390/crypto/z90crypt.h b/drivers/s390/crypto/z90crypt.h index 82a1d97001d7..0a3bb5a10dd4 100644 --- a/drivers/s390/crypto/z90crypt.h +++ b/drivers/s390/crypto/z90crypt.h | |||
@@ -36,15 +36,6 @@ | |||
36 | #define z90crypt_VARIANT 2 // 2 = added PCIXCC MCL3 and CEX2C support | 36 | #define z90crypt_VARIANT 2 // 2 = added PCIXCC MCL3 and CEX2C support |
37 | 37 | ||
38 | /** | 38 | /** |
39 | * If we are not using the sparse checker, __user has no use. | ||
40 | */ | ||
41 | #ifdef __CHECKER__ | ||
42 | # define __user __attribute__((noderef, address_space(1))) | ||
43 | #else | ||
44 | # define __user | ||
45 | #endif | ||
46 | |||
47 | /** | ||
48 | * struct ica_rsa_modexpo | 39 | * struct ica_rsa_modexpo |
49 | * | 40 | * |
50 | * Requirements: | 41 | * Requirements: |
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index e17b4d58a9f6..bfe3ba73bc0f 100644 --- a/drivers/s390/scsi/zfcp_aux.c +++ b/drivers/s390/scsi/zfcp_aux.c | |||
@@ -1299,13 +1299,10 @@ struct zfcp_port * | |||
1299 | zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, | 1299 | zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, |
1300 | u32 d_id) | 1300 | u32 d_id) |
1301 | { | 1301 | { |
1302 | struct zfcp_port *port, *tmp_port; | 1302 | struct zfcp_port *port; |
1303 | int check_wwpn; | 1303 | int check_wwpn; |
1304 | scsi_id_t scsi_id; | ||
1305 | int found; | ||
1306 | 1304 | ||
1307 | check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN); | 1305 | check_wwpn = !(status & ZFCP_STATUS_PORT_NO_WWPN); |
1308 | |||
1309 | /* | 1306 | /* |
1310 | * check that there is no port with this WWPN already in list | 1307 | * check that there is no port with this WWPN already in list |
1311 | */ | 1308 | */ |
@@ -1368,7 +1365,7 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, | |||
1368 | } else { | 1365 | } else { |
1369 | snprintf(port->sysfs_device.bus_id, | 1366 | snprintf(port->sysfs_device.bus_id, |
1370 | BUS_ID_SIZE, "0x%016llx", wwpn); | 1367 | BUS_ID_SIZE, "0x%016llx", wwpn); |
1371 | port->sysfs_device.parent = &adapter->ccw_device->dev; | 1368 | port->sysfs_device.parent = &adapter->ccw_device->dev; |
1372 | } | 1369 | } |
1373 | port->sysfs_device.release = zfcp_sysfs_port_release; | 1370 | port->sysfs_device.release = zfcp_sysfs_port_release; |
1374 | dev_set_drvdata(&port->sysfs_device, port); | 1371 | dev_set_drvdata(&port->sysfs_device, port); |
@@ -1388,24 +1385,8 @@ zfcp_port_enqueue(struct zfcp_adapter *adapter, wwn_t wwpn, u32 status, | |||
1388 | 1385 | ||
1389 | zfcp_port_get(port); | 1386 | zfcp_port_get(port); |
1390 | 1387 | ||
1391 | scsi_id = 1; | ||
1392 | found = 0; | ||
1393 | write_lock_irq(&zfcp_data.config_lock); | 1388 | write_lock_irq(&zfcp_data.config_lock); |
1394 | list_for_each_entry(tmp_port, &adapter->port_list_head, list) { | 1389 | list_add_tail(&port->list, &adapter->port_list_head); |
1395 | if (atomic_test_mask(ZFCP_STATUS_PORT_NO_SCSI_ID, | ||
1396 | &tmp_port->status)) | ||
1397 | continue; | ||
1398 | if (tmp_port->scsi_id != scsi_id) { | ||
1399 | found = 1; | ||
1400 | break; | ||
1401 | } | ||
1402 | scsi_id++; | ||
1403 | } | ||
1404 | port->scsi_id = scsi_id; | ||
1405 | if (found) | ||
1406 | list_add_tail(&port->list, &tmp_port->list); | ||
1407 | else | ||
1408 | list_add_tail(&port->list, &adapter->port_list_head); | ||
1409 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); | 1390 | atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status); |
1410 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); | 1391 | atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status); |
1411 | if (d_id == ZFCP_DID_DIRECTORY_SERVICE) | 1392 | if (d_id == ZFCP_DID_DIRECTORY_SERVICE) |
@@ -1427,6 +1408,9 @@ zfcp_port_dequeue(struct zfcp_port *port) | |||
1427 | list_del(&port->list); | 1408 | list_del(&port->list); |
1428 | port->adapter->ports--; | 1409 | port->adapter->ports--; |
1429 | write_unlock_irq(&zfcp_data.config_lock); | 1410 | write_unlock_irq(&zfcp_data.config_lock); |
1411 | if (port->rport) | ||
1412 | fc_remote_port_delete(port->rport); | ||
1413 | port->rport = NULL; | ||
1430 | zfcp_adapter_put(port->adapter); | 1414 | zfcp_adapter_put(port->adapter); |
1431 | zfcp_sysfs_port_remove_files(&port->sysfs_device, | 1415 | zfcp_sysfs_port_remove_files(&port->sysfs_device, |
1432 | atomic_read(&port->status)); | 1416 | atomic_read(&port->status)); |
diff --git a/drivers/s390/scsi/zfcp_ccw.c b/drivers/s390/scsi/zfcp_ccw.c index 0fc46381fc22..b30abab77da3 100644 --- a/drivers/s390/scsi/zfcp_ccw.c +++ b/drivers/s390/scsi/zfcp_ccw.c | |||
@@ -202,9 +202,19 @@ static int | |||
202 | zfcp_ccw_set_offline(struct ccw_device *ccw_device) | 202 | zfcp_ccw_set_offline(struct ccw_device *ccw_device) |
203 | { | 203 | { |
204 | struct zfcp_adapter *adapter; | 204 | struct zfcp_adapter *adapter; |
205 | struct zfcp_port *port; | ||
206 | struct fc_rport *rport; | ||
205 | 207 | ||
206 | down(&zfcp_data.config_sema); | 208 | down(&zfcp_data.config_sema); |
207 | adapter = dev_get_drvdata(&ccw_device->dev); | 209 | adapter = dev_get_drvdata(&ccw_device->dev); |
210 | /* might be racy, but we cannot take config_lock due to the fact that | ||
211 | fc_remote_port_delete might sleep */ | ||
212 | list_for_each_entry(port, &adapter->port_list_head, list) | ||
213 | if (port->rport) { | ||
214 | rport = port->rport; | ||
215 | port->rport = NULL; | ||
216 | fc_remote_port_delete(rport); | ||
217 | } | ||
208 | zfcp_erp_adapter_shutdown(adapter, 0); | 218 | zfcp_erp_adapter_shutdown(adapter, 0); |
209 | zfcp_erp_wait(adapter); | 219 | zfcp_erp_wait(adapter); |
210 | zfcp_adapter_scsi_unregister(adapter); | 220 | zfcp_adapter_scsi_unregister(adapter); |
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 4103b5be7683..455e902533a9 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -906,6 +906,7 @@ struct zfcp_adapter { | |||
906 | */ | 906 | */ |
907 | struct zfcp_port { | 907 | struct zfcp_port { |
908 | struct device sysfs_device; /* sysfs device */ | 908 | struct device sysfs_device; /* sysfs device */ |
909 | struct fc_rport *rport; /* rport of fc transport class */ | ||
909 | struct list_head list; /* list of remote ports */ | 910 | struct list_head list; /* list of remote ports */ |
910 | atomic_t refcount; /* reference count */ | 911 | atomic_t refcount; /* reference count */ |
911 | wait_queue_head_t remove_wq; /* can be used to wait for | 912 | wait_queue_head_t remove_wq; /* can be used to wait for |
@@ -916,7 +917,6 @@ struct zfcp_port { | |||
916 | list */ | 917 | list */ |
917 | u32 units; /* # of logical units in list */ | 918 | u32 units; /* # of logical units in list */ |
918 | atomic_t status; /* status of this remote port */ | 919 | atomic_t status; /* status of this remote port */ |
919 | scsi_id_t scsi_id; /* own SCSI ID */ | ||
920 | wwn_t wwnn; /* WWNN if known */ | 920 | wwn_t wwnn; /* WWNN if known */ |
921 | wwn_t wwpn; /* WWPN */ | 921 | wwn_t wwpn; /* WWPN */ |
922 | fc_id_t d_id; /* D_ID */ | 922 | fc_id_t d_id; /* D_ID */ |
diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index 0cf31f7d1c0f..cb4f612550ba 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c | |||
@@ -3360,13 +3360,32 @@ zfcp_erp_action_cleanup(int action, struct zfcp_adapter *adapter, | |||
3360 | if ((result == ZFCP_ERP_SUCCEEDED) | 3360 | if ((result == ZFCP_ERP_SUCCEEDED) |
3361 | && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, | 3361 | && (!atomic_test_mask(ZFCP_STATUS_UNIT_TEMPORARY, |
3362 | &unit->status)) | 3362 | &unit->status)) |
3363 | && (!unit->device)) | 3363 | && !unit->device |
3364 | scsi_add_device(unit->port->adapter->scsi_host, 0, | 3364 | && port->rport) |
3365 | unit->port->scsi_id, unit->scsi_lun); | 3365 | scsi_add_device(port->adapter->scsi_host, 0, |
3366 | port->rport->scsi_target_id, | ||
3367 | unit->scsi_lun); | ||
3366 | zfcp_unit_put(unit); | 3368 | zfcp_unit_put(unit); |
3367 | break; | 3369 | break; |
3368 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: | 3370 | case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: |
3369 | case ZFCP_ERP_ACTION_REOPEN_PORT: | 3371 | case ZFCP_ERP_ACTION_REOPEN_PORT: |
3372 | if ((result == ZFCP_ERP_SUCCEEDED) | ||
3373 | && !atomic_test_mask(ZFCP_STATUS_PORT_NO_WWPN, | ||
3374 | &port->status) | ||
3375 | && !port->rport) { | ||
3376 | struct fc_rport_identifiers ids; | ||
3377 | ids.node_name = port->wwnn; | ||
3378 | ids.port_name = port->wwpn; | ||
3379 | ids.port_id = port->d_id; | ||
3380 | ids.roles = FC_RPORT_ROLE_FCP_TARGET; | ||
3381 | port->rport = | ||
3382 | fc_remote_port_add(adapter->scsi_host, 0, &ids); | ||
3383 | if (!port->rport) | ||
3384 | ZFCP_LOG_NORMAL("failed registration of rport" | ||
3385 | "(adapter %s, wwpn=0x%016Lx)\n", | ||
3386 | zfcp_get_busid_by_port(port), | ||
3387 | port->wwpn); | ||
3388 | } | ||
3370 | zfcp_port_put(port); | 3389 | zfcp_port_put(port); |
3371 | break; | 3390 | break; |
3372 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: | 3391 | case ZFCP_ERP_ACTION_REOPEN_ADAPTER: |
diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 42df7e57eeae..cd98a2de9f8f 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h | |||
@@ -143,6 +143,8 @@ extern int zfcp_scsi_command_async(struct zfcp_adapter *,struct zfcp_unit *, | |||
143 | struct scsi_cmnd *, struct timer_list *); | 143 | struct scsi_cmnd *, struct timer_list *); |
144 | extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, | 144 | extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, |
145 | struct timer_list *); | 145 | struct timer_list *); |
146 | extern void zfcp_set_fc_host_attrs(struct zfcp_adapter *); | ||
147 | extern void zfcp_set_fc_rport_attrs(struct zfcp_port *); | ||
146 | extern struct scsi_transport_template *zfcp_transport_template; | 148 | extern struct scsi_transport_template *zfcp_transport_template; |
147 | extern struct fc_function_template zfcp_transport_functions; | 149 | extern struct fc_function_template zfcp_transport_functions; |
148 | 150 | ||
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 0d9f20edc490..c007b6424e74 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -2062,6 +2062,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok) | |||
2062 | zfcp_erp_adapter_shutdown(adapter, 0); | 2062 | zfcp_erp_adapter_shutdown(adapter, 0); |
2063 | return -EIO; | 2063 | return -EIO; |
2064 | } | 2064 | } |
2065 | zfcp_set_fc_host_attrs(adapter); | ||
2065 | return 0; | 2066 | return 0; |
2066 | } | 2067 | } |
2067 | 2068 | ||
diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index b61d309352c3..31a76065cf28 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c | |||
@@ -389,7 +389,7 @@ zfcp_unit_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id, | |||
389 | struct zfcp_unit *unit, *retval = NULL; | 389 | struct zfcp_unit *unit, *retval = NULL; |
390 | 390 | ||
391 | list_for_each_entry(port, &adapter->port_list_head, list) { | 391 | list_for_each_entry(port, &adapter->port_list_head, list) { |
392 | if (id != port->scsi_id) | 392 | if (!port->rport || (id != port->rport->scsi_target_id)) |
393 | continue; | 393 | continue; |
394 | list_for_each_entry(unit, &port->unit_list_head, list) { | 394 | list_for_each_entry(unit, &port->unit_list_head, list) { |
395 | if (lun == unit->scsi_lun) { | 395 | if (lun == unit->scsi_lun) { |
@@ -408,7 +408,7 @@ zfcp_port_lookup(struct zfcp_adapter *adapter, int channel, scsi_id_t id) | |||
408 | struct zfcp_port *port; | 408 | struct zfcp_port *port; |
409 | 409 | ||
410 | list_for_each_entry(port, &adapter->port_list_head, list) { | 410 | list_for_each_entry(port, &adapter->port_list_head, list) { |
411 | if (id == port->scsi_id) | 411 | if (port->rport && (id == port->rport->scsi_target_id)) |
412 | return port; | 412 | return port; |
413 | } | 413 | } |
414 | return (struct zfcp_port *) NULL; | 414 | return (struct zfcp_port *) NULL; |
@@ -634,7 +634,6 @@ zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt) | |||
634 | { | 634 | { |
635 | int retval; | 635 | int retval; |
636 | struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata; | 636 | struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata; |
637 | struct Scsi_Host *scsi_host = scpnt->device->host; | ||
638 | 637 | ||
639 | if (!unit) { | 638 | if (!unit) { |
640 | ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n"); | 639 | ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n"); |
@@ -729,7 +728,6 @@ zfcp_scsi_eh_bus_reset_handler(struct scsi_cmnd *scpnt) | |||
729 | { | 728 | { |
730 | int retval = 0; | 729 | int retval = 0; |
731 | struct zfcp_unit *unit; | 730 | struct zfcp_unit *unit; |
732 | struct Scsi_Host *scsi_host = scpnt->device->host; | ||
733 | 731 | ||
734 | unit = (struct zfcp_unit *) scpnt->device->hostdata; | 732 | unit = (struct zfcp_unit *) scpnt->device->hostdata; |
735 | ZFCP_LOG_NORMAL("bus reset because of problems with " | 733 | ZFCP_LOG_NORMAL("bus reset because of problems with " |
@@ -753,7 +751,6 @@ zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt) | |||
753 | { | 751 | { |
754 | int retval = 0; | 752 | int retval = 0; |
755 | struct zfcp_unit *unit; | 753 | struct zfcp_unit *unit; |
756 | struct Scsi_Host *scsi_host = scpnt->device->host; | ||
757 | 754 | ||
758 | unit = (struct zfcp_unit *) scpnt->device->hostdata; | 755 | unit = (struct zfcp_unit *) scpnt->device->hostdata; |
759 | ZFCP_LOG_NORMAL("host reset because of problems with " | 756 | ZFCP_LOG_NORMAL("host reset because of problems with " |
@@ -833,6 +830,7 @@ zfcp_adapter_scsi_unregister(struct zfcp_adapter *adapter) | |||
833 | shost = adapter->scsi_host; | 830 | shost = adapter->scsi_host; |
834 | if (!shost) | 831 | if (!shost) |
835 | return; | 832 | return; |
833 | fc_remove_host(shost); | ||
836 | scsi_remove_host(shost); | 834 | scsi_remove_host(shost); |
837 | scsi_host_put(shost); | 835 | scsi_host_put(shost); |
838 | adapter->scsi_host = NULL; | 836 | adapter->scsi_host = NULL; |
@@ -906,6 +904,18 @@ zfcp_get_node_name(struct scsi_target *starget) | |||
906 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); | 904 | read_unlock_irqrestore(&zfcp_data.config_lock, flags); |
907 | } | 905 | } |
908 | 906 | ||
907 | void | ||
908 | zfcp_set_fc_host_attrs(struct zfcp_adapter *adapter) | ||
909 | { | ||
910 | struct Scsi_Host *shost = adapter->scsi_host; | ||
911 | |||
912 | fc_host_node_name(shost) = adapter->wwnn; | ||
913 | fc_host_port_name(shost) = adapter->wwpn; | ||
914 | strncpy(fc_host_serial_number(shost), adapter->serial_number, | ||
915 | min(FC_SERIAL_NUMBER_SIZE, 32)); | ||
916 | fc_host_supported_classes(shost) = FC_COS_CLASS2 | FC_COS_CLASS3; | ||
917 | } | ||
918 | |||
909 | struct fc_function_template zfcp_transport_functions = { | 919 | struct fc_function_template zfcp_transport_functions = { |
910 | .get_starget_port_id = zfcp_get_port_id, | 920 | .get_starget_port_id = zfcp_get_port_id, |
911 | .get_starget_port_name = zfcp_get_port_name, | 921 | .get_starget_port_name = zfcp_get_port_name, |
@@ -913,6 +923,11 @@ struct fc_function_template zfcp_transport_functions = { | |||
913 | .show_starget_port_id = 1, | 923 | .show_starget_port_id = 1, |
914 | .show_starget_port_name = 1, | 924 | .show_starget_port_name = 1, |
915 | .show_starget_node_name = 1, | 925 | .show_starget_node_name = 1, |
926 | .show_rport_supported_classes = 1, | ||
927 | .show_host_node_name = 1, | ||
928 | .show_host_port_name = 1, | ||
929 | .show_host_supported_classes = 1, | ||
930 | .show_host_serial_number = 1, | ||
916 | }; | 931 | }; |
917 | 932 | ||
918 | /** | 933 | /** |
diff --git a/drivers/s390/scsi/zfcp_sysfs_port.c b/drivers/s390/scsi/zfcp_sysfs_port.c index 7a84c7d474d9..c55e82d91deb 100644 --- a/drivers/s390/scsi/zfcp_sysfs_port.c +++ b/drivers/s390/scsi/zfcp_sysfs_port.c | |||
@@ -67,7 +67,6 @@ static DEVICE_ATTR(_name, S_IRUGO, zfcp_sysfs_port_##_name##_show, NULL); | |||
67 | ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status)); | 67 | ZFCP_DEFINE_PORT_ATTR(status, "0x%08x\n", atomic_read(&port->status)); |
68 | ZFCP_DEFINE_PORT_ATTR(wwnn, "0x%016llx\n", port->wwnn); | 68 | ZFCP_DEFINE_PORT_ATTR(wwnn, "0x%016llx\n", port->wwnn); |
69 | ZFCP_DEFINE_PORT_ATTR(d_id, "0x%06x\n", port->d_id); | 69 | ZFCP_DEFINE_PORT_ATTR(d_id, "0x%06x\n", port->d_id); |
70 | ZFCP_DEFINE_PORT_ATTR(scsi_id, "0x%x\n", port->scsi_id); | ||
71 | ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask | 70 | ZFCP_DEFINE_PORT_ATTR(in_recovery, "%d\n", atomic_test_mask |
72 | (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)); | 71 | (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)); |
73 | ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask | 72 | ZFCP_DEFINE_PORT_ATTR(access_denied, "%d\n", atomic_test_mask |
@@ -263,7 +262,6 @@ static struct attribute_group zfcp_port_common_attr_group = { | |||
263 | static struct attribute *zfcp_port_no_ns_attrs[] = { | 262 | static struct attribute *zfcp_port_no_ns_attrs[] = { |
264 | &dev_attr_unit_add.attr, | 263 | &dev_attr_unit_add.attr, |
265 | &dev_attr_unit_remove.attr, | 264 | &dev_attr_unit_remove.attr, |
266 | &dev_attr_scsi_id.attr, | ||
267 | NULL | 265 | NULL |
268 | }; | 266 | }; |
269 | 267 | ||
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index f1e8c4223ed1..12c208fb18c5 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -1696,7 +1696,7 @@ config TT_DMA_EMUL | |||
1696 | 1696 | ||
1697 | config MAC_SCSI | 1697 | config MAC_SCSI |
1698 | bool "Macintosh NCR5380 SCSI" | 1698 | bool "Macintosh NCR5380 SCSI" |
1699 | depends on MAC && SCSI | 1699 | depends on MAC && SCSI=y |
1700 | help | 1700 | help |
1701 | This is the NCR 5380 SCSI controller included on most of the 68030 | 1701 | This is the NCR 5380 SCSI controller included on most of the 68030 |
1702 | based Macintoshes. If you have one of these say Y and read the | 1702 | based Macintoshes. If you have one of these say Y and read the |
@@ -1717,7 +1717,7 @@ config SCSI_MAC_ESP | |||
1717 | 1717 | ||
1718 | config MVME147_SCSI | 1718 | config MVME147_SCSI |
1719 | bool "WD33C93 SCSI driver for MVME147" | 1719 | bool "WD33C93 SCSI driver for MVME147" |
1720 | depends on MVME147 && SCSI | 1720 | depends on MVME147 && SCSI=y |
1721 | help | 1721 | help |
1722 | Support for the on-board SCSI controller on the Motorola MVME147 | 1722 | Support for the on-board SCSI controller on the Motorola MVME147 |
1723 | single-board computer. | 1723 | single-board computer. |
@@ -1758,7 +1758,7 @@ config SUN3_SCSI | |||
1758 | 1758 | ||
1759 | config SUN3X_ESP | 1759 | config SUN3X_ESP |
1760 | bool "Sun3x ESP SCSI" | 1760 | bool "Sun3x ESP SCSI" |
1761 | depends on SUN3X && SCSI | 1761 | depends on SUN3X && SCSI=y |
1762 | help | 1762 | help |
1763 | The ESP was an on-board SCSI controller used on Sun 3/80 | 1763 | The ESP was an on-board SCSI controller used on Sun 3/80 |
1764 | machines. Say Y here to compile in support for it. | 1764 | machines. Say Y here to compile in support for it. |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index c5623694d10f..841f4e2cfe08 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -269,6 +269,8 @@ static struct pci_device_id ahci_pci_tbl[] = { | |||
269 | board_ahci }, /* ESB2 */ | 269 | board_ahci }, /* ESB2 */ |
270 | { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 270 | { PCI_VENDOR_ID_INTEL, 0x2683, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
271 | board_ahci }, /* ESB2 */ | 271 | board_ahci }, /* ESB2 */ |
272 | { PCI_VENDOR_ID_INTEL, 0x27c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
273 | board_ahci }, /* ICH7-M DH */ | ||
272 | { } /* terminate list */ | 274 | { } /* terminate list */ |
273 | }; | 275 | }; |
274 | 276 | ||
@@ -584,12 +586,16 @@ static void ahci_intr_error(struct ata_port *ap, u32 irq_stat) | |||
584 | 586 | ||
585 | static void ahci_eng_timeout(struct ata_port *ap) | 587 | static void ahci_eng_timeout(struct ata_port *ap) |
586 | { | 588 | { |
587 | void *mmio = ap->host_set->mmio_base; | 589 | struct ata_host_set *host_set = ap->host_set; |
590 | void *mmio = host_set->mmio_base; | ||
588 | void *port_mmio = ahci_port_base(mmio, ap->port_no); | 591 | void *port_mmio = ahci_port_base(mmio, ap->port_no); |
589 | struct ata_queued_cmd *qc; | 592 | struct ata_queued_cmd *qc; |
593 | unsigned long flags; | ||
590 | 594 | ||
591 | DPRINTK("ENTER\n"); | 595 | DPRINTK("ENTER\n"); |
592 | 596 | ||
597 | spin_lock_irqsave(&host_set->lock, flags); | ||
598 | |||
593 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); | 599 | ahci_intr_error(ap, readl(port_mmio + PORT_IRQ_STAT)); |
594 | 600 | ||
595 | qc = ata_qc_from_tag(ap, ap->active_tag); | 601 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -607,6 +613,7 @@ static void ahci_eng_timeout(struct ata_port *ap) | |||
607 | ata_qc_complete(qc, ATA_ERR); | 613 | ata_qc_complete(qc, ATA_ERR); |
608 | } | 614 | } |
609 | 615 | ||
616 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
610 | } | 617 | } |
611 | 618 | ||
612 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) | 619 | static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc) |
@@ -696,9 +703,6 @@ static int ahci_qc_issue(struct ata_queued_cmd *qc) | |||
696 | struct ata_port *ap = qc->ap; | 703 | struct ata_port *ap = qc->ap; |
697 | void *port_mmio = (void *) ap->ioaddr.cmd_addr; | 704 | void *port_mmio = (void *) ap->ioaddr.cmd_addr; |
698 | 705 | ||
699 | writel(1, port_mmio + PORT_SCR_ACT); | ||
700 | readl(port_mmio + PORT_SCR_ACT); /* flush */ | ||
701 | |||
702 | writel(1, port_mmio + PORT_CMD_ISSUE); | 706 | writel(1, port_mmio + PORT_CMD_ISSUE); |
703 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ | 707 | readl(port_mmio + PORT_CMD_ISSUE); /* flush */ |
704 | 708 | ||
@@ -1105,6 +1109,7 @@ MODULE_AUTHOR("Jeff Garzik"); | |||
1105 | MODULE_DESCRIPTION("AHCI SATA low-level driver"); | 1109 | MODULE_DESCRIPTION("AHCI SATA low-level driver"); |
1106 | MODULE_LICENSE("GPL"); | 1110 | MODULE_LICENSE("GPL"); |
1107 | MODULE_DEVICE_TABLE(pci, ahci_pci_tbl); | 1111 | MODULE_DEVICE_TABLE(pci, ahci_pci_tbl); |
1112 | MODULE_VERSION(DRV_VERSION); | ||
1108 | 1113 | ||
1109 | module_init(ahci_init); | 1114 | module_init(ahci_init); |
1110 | module_exit(ahci_exit); | 1115 | module_exit(ahci_exit); |
diff --git a/drivers/scsi/arm/Kconfig b/drivers/scsi/arm/Kconfig index 54b32868aaf7..13f23043c8a3 100644 --- a/drivers/scsi/arm/Kconfig +++ b/drivers/scsi/arm/Kconfig | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | config SCSI_ACORNSCSI_3 | 4 | config SCSI_ACORNSCSI_3 |
5 | tristate "Acorn SCSI card (aka30) support" | 5 | tristate "Acorn SCSI card (aka30) support" |
6 | depends on ARCH_ACORN && SCSI | 6 | depends on ARCH_ACORN && SCSI && BROKEN |
7 | help | 7 | help |
8 | This enables support for the Acorn SCSI card (aka30). If you have an | 8 | This enables support for the Acorn SCSI card (aka30). If you have an |
9 | Acorn system with one of these, say Y. If unsure, say N. | 9 | Acorn system with one of these, say Y. If unsure, say N. |
diff --git a/drivers/scsi/ata_piix.c b/drivers/scsi/ata_piix.c index a2cfade2c1c6..03695616e59e 100644 --- a/drivers/scsi/ata_piix.c +++ b/drivers/scsi/ata_piix.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/libata.h> | 32 | #include <linux/libata.h> |
33 | 33 | ||
34 | #define DRV_NAME "ata_piix" | 34 | #define DRV_NAME "ata_piix" |
35 | #define DRV_VERSION "1.03" | 35 | #define DRV_VERSION "1.04" |
36 | 36 | ||
37 | enum { | 37 | enum { |
38 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ | 38 | PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ |
@@ -629,13 +629,13 @@ static int piix_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
629 | port_info[1] = NULL; | 629 | port_info[1] = NULL; |
630 | 630 | ||
631 | if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { | 631 | if (port_info[0]->host_flags & PIIX_FLAG_AHCI) { |
632 | u8 tmp; | 632 | u8 tmp; |
633 | pci_read_config_byte(pdev, PIIX_SCC, &tmp); | 633 | pci_read_config_byte(pdev, PIIX_SCC, &tmp); |
634 | if (tmp == PIIX_AHCI_DEVICE) { | 634 | if (tmp == PIIX_AHCI_DEVICE) { |
635 | int rc = piix_disable_ahci(pdev); | 635 | int rc = piix_disable_ahci(pdev); |
636 | if (rc) | 636 | if (rc) |
637 | return rc; | 637 | return rc; |
638 | } | 638 | } |
639 | } | 639 | } |
640 | 640 | ||
641 | if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { | 641 | if (port_info[0]->host_flags & PIIX_FLAG_COMBINED) { |
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 73b1f72b7e43..f15a07f9f471 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1304,12 +1304,12 @@ static inline u8 ata_dev_knobble(struct ata_port *ap) | |||
1304 | /** | 1304 | /** |
1305 | * ata_dev_config - Run device specific handlers and check for | 1305 | * ata_dev_config - Run device specific handlers and check for |
1306 | * SATA->PATA bridges | 1306 | * SATA->PATA bridges |
1307 | * @ap: Bus | 1307 | * @ap: Bus |
1308 | * @i: Device | 1308 | * @i: Device |
1309 | * | 1309 | * |
1310 | * LOCKING: | 1310 | * LOCKING: |
1311 | */ | 1311 | */ |
1312 | 1312 | ||
1313 | void ata_dev_config(struct ata_port *ap, unsigned int i) | 1313 | void ata_dev_config(struct ata_port *ap, unsigned int i) |
1314 | { | 1314 | { |
1315 | /* limit bridge transfers to udma5, 200 sectors */ | 1315 | /* limit bridge transfers to udma5, 200 sectors */ |
@@ -2268,19 +2268,6 @@ void ata_qc_prep(struct ata_queued_cmd *qc) | |||
2268 | * spin_lock_irqsave(host_set lock) | 2268 | * spin_lock_irqsave(host_set lock) |
2269 | */ | 2269 | */ |
2270 | 2270 | ||
2271 | |||
2272 | |||
2273 | /** | ||
2274 | * ata_sg_init_one - Prepare a one-entry scatter-gather list. | ||
2275 | * @qc: Queued command | ||
2276 | * @buf: transfer buffer | ||
2277 | * @buflen: length of buf | ||
2278 | * | ||
2279 | * Builds a single-entry scatter-gather list to initiate a | ||
2280 | * transfer utilizing the specified buffer. | ||
2281 | * | ||
2282 | * LOCKING: | ||
2283 | */ | ||
2284 | void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) | 2271 | void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) |
2285 | { | 2272 | { |
2286 | struct scatterlist *sg; | 2273 | struct scatterlist *sg; |
@@ -2312,18 +2299,6 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) | |||
2312 | * spin_lock_irqsave(host_set lock) | 2299 | * spin_lock_irqsave(host_set lock) |
2313 | */ | 2300 | */ |
2314 | 2301 | ||
2315 | |||
2316 | /** | ||
2317 | * ata_sg_init - Assign a scatter gather list to a queued command | ||
2318 | * @qc: Queued command | ||
2319 | * @sg: Scatter-gather list | ||
2320 | * @n_elem: length of sg list | ||
2321 | * | ||
2322 | * Attaches a scatter-gather list to a queued command. | ||
2323 | * | ||
2324 | * LOCKING: | ||
2325 | */ | ||
2326 | |||
2327 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, | 2302 | void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg, |
2328 | unsigned int n_elem) | 2303 | unsigned int n_elem) |
2329 | { | 2304 | { |
@@ -2402,6 +2377,27 @@ static int ata_sg_setup(struct ata_queued_cmd *qc) | |||
2402 | } | 2377 | } |
2403 | 2378 | ||
2404 | /** | 2379 | /** |
2380 | * ata_poll_qc_complete - turn irq back on and finish qc | ||
2381 | * @qc: Command to complete | ||
2382 | * @drv_stat: ATA status register content | ||
2383 | * | ||
2384 | * LOCKING: | ||
2385 | * None. (grabs host lock) | ||
2386 | */ | ||
2387 | |||
2388 | void ata_poll_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | ||
2389 | { | ||
2390 | struct ata_port *ap = qc->ap; | ||
2391 | unsigned long flags; | ||
2392 | |||
2393 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
2394 | ap->flags &= ~ATA_FLAG_NOINTR; | ||
2395 | ata_irq_on(ap); | ||
2396 | ata_qc_complete(qc, drv_stat); | ||
2397 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
2398 | } | ||
2399 | |||
2400 | /** | ||
2405 | * ata_pio_poll - | 2401 | * ata_pio_poll - |
2406 | * @ap: | 2402 | * @ap: |
2407 | * | 2403 | * |
@@ -2463,11 +2459,10 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2463 | u8 drv_stat; | 2459 | u8 drv_stat; |
2464 | 2460 | ||
2465 | /* | 2461 | /* |
2466 | * This is purely hueristic. This is a fast path. | 2462 | * This is purely heuristic. This is a fast path. Sometimes when |
2467 | * Sometimes when we enter, BSY will be cleared in | 2463 | * we enter, BSY will be cleared in a chk-status or two. If not, |
2468 | * a chk-status or two. If not, the drive is probably seeking | 2464 | * the drive is probably seeking or something. Snooze for a couple |
2469 | * or something. Snooze for a couple msecs, then | 2465 | * msecs, then chk-status again. If still busy, fall back to |
2470 | * chk-status again. If still busy, fall back to | ||
2471 | * PIO_ST_POLL state. | 2466 | * PIO_ST_POLL state. |
2472 | */ | 2467 | */ |
2473 | drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); | 2468 | drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 10); |
@@ -2492,9 +2487,7 @@ static void ata_pio_complete (struct ata_port *ap) | |||
2492 | 2487 | ||
2493 | ap->pio_task_state = PIO_ST_IDLE; | 2488 | ap->pio_task_state = PIO_ST_IDLE; |
2494 | 2489 | ||
2495 | ata_irq_on(ap); | 2490 | ata_poll_qc_complete(qc, drv_stat); |
2496 | |||
2497 | ata_qc_complete(qc, drv_stat); | ||
2498 | } | 2491 | } |
2499 | 2492 | ||
2500 | 2493 | ||
@@ -2519,6 +2512,20 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
2519 | #endif /* __BIG_ENDIAN */ | 2512 | #endif /* __BIG_ENDIAN */ |
2520 | } | 2513 | } |
2521 | 2514 | ||
2515 | /** | ||
2516 | * ata_mmio_data_xfer - Transfer data by MMIO | ||
2517 | * @ap: port to read/write | ||
2518 | * @buf: data buffer | ||
2519 | * @buflen: buffer length | ||
2520 | * @do_write: read/write | ||
2521 | * | ||
2522 | * Transfer data from/to the device data register by MMIO. | ||
2523 | * | ||
2524 | * LOCKING: | ||
2525 | * Inherited from caller. | ||
2526 | * | ||
2527 | */ | ||
2528 | |||
2522 | static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, | 2529 | static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, |
2523 | unsigned int buflen, int write_data) | 2530 | unsigned int buflen, int write_data) |
2524 | { | 2531 | { |
@@ -2527,6 +2534,7 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, | |||
2527 | u16 *buf16 = (u16 *) buf; | 2534 | u16 *buf16 = (u16 *) buf; |
2528 | void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; | 2535 | void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr; |
2529 | 2536 | ||
2537 | /* Transfer multiple of 2 bytes */ | ||
2530 | if (write_data) { | 2538 | if (write_data) { |
2531 | for (i = 0; i < words; i++) | 2539 | for (i = 0; i < words; i++) |
2532 | writew(le16_to_cpu(buf16[i]), mmio); | 2540 | writew(le16_to_cpu(buf16[i]), mmio); |
@@ -2534,19 +2542,76 @@ static void ata_mmio_data_xfer(struct ata_port *ap, unsigned char *buf, | |||
2534 | for (i = 0; i < words; i++) | 2542 | for (i = 0; i < words; i++) |
2535 | buf16[i] = cpu_to_le16(readw(mmio)); | 2543 | buf16[i] = cpu_to_le16(readw(mmio)); |
2536 | } | 2544 | } |
2545 | |||
2546 | /* Transfer trailing 1 byte, if any. */ | ||
2547 | if (unlikely(buflen & 0x01)) { | ||
2548 | u16 align_buf[1] = { 0 }; | ||
2549 | unsigned char *trailing_buf = buf + buflen - 1; | ||
2550 | |||
2551 | if (write_data) { | ||
2552 | memcpy(align_buf, trailing_buf, 1); | ||
2553 | writew(le16_to_cpu(align_buf[0]), mmio); | ||
2554 | } else { | ||
2555 | align_buf[0] = cpu_to_le16(readw(mmio)); | ||
2556 | memcpy(trailing_buf, align_buf, 1); | ||
2557 | } | ||
2558 | } | ||
2537 | } | 2559 | } |
2538 | 2560 | ||
2561 | /** | ||
2562 | * ata_pio_data_xfer - Transfer data by PIO | ||
2563 | * @ap: port to read/write | ||
2564 | * @buf: data buffer | ||
2565 | * @buflen: buffer length | ||
2566 | * @do_write: read/write | ||
2567 | * | ||
2568 | * Transfer data from/to the device data register by PIO. | ||
2569 | * | ||
2570 | * LOCKING: | ||
2571 | * Inherited from caller. | ||
2572 | * | ||
2573 | */ | ||
2574 | |||
2539 | static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, | 2575 | static void ata_pio_data_xfer(struct ata_port *ap, unsigned char *buf, |
2540 | unsigned int buflen, int write_data) | 2576 | unsigned int buflen, int write_data) |
2541 | { | 2577 | { |
2542 | unsigned int dwords = buflen >> 1; | 2578 | unsigned int words = buflen >> 1; |
2543 | 2579 | ||
2580 | /* Transfer multiple of 2 bytes */ | ||
2544 | if (write_data) | 2581 | if (write_data) |
2545 | outsw(ap->ioaddr.data_addr, buf, dwords); | 2582 | outsw(ap->ioaddr.data_addr, buf, words); |
2546 | else | 2583 | else |
2547 | insw(ap->ioaddr.data_addr, buf, dwords); | 2584 | insw(ap->ioaddr.data_addr, buf, words); |
2585 | |||
2586 | /* Transfer trailing 1 byte, if any. */ | ||
2587 | if (unlikely(buflen & 0x01)) { | ||
2588 | u16 align_buf[1] = { 0 }; | ||
2589 | unsigned char *trailing_buf = buf + buflen - 1; | ||
2590 | |||
2591 | if (write_data) { | ||
2592 | memcpy(align_buf, trailing_buf, 1); | ||
2593 | outw(le16_to_cpu(align_buf[0]), ap->ioaddr.data_addr); | ||
2594 | } else { | ||
2595 | align_buf[0] = cpu_to_le16(inw(ap->ioaddr.data_addr)); | ||
2596 | memcpy(trailing_buf, align_buf, 1); | ||
2597 | } | ||
2598 | } | ||
2548 | } | 2599 | } |
2549 | 2600 | ||
2601 | /** | ||
2602 | * ata_data_xfer - Transfer data from/to the data register. | ||
2603 | * @ap: port to read/write | ||
2604 | * @buf: data buffer | ||
2605 | * @buflen: buffer length | ||
2606 | * @do_write: read/write | ||
2607 | * | ||
2608 | * Transfer data from/to the device data register. | ||
2609 | * | ||
2610 | * LOCKING: | ||
2611 | * Inherited from caller. | ||
2612 | * | ||
2613 | */ | ||
2614 | |||
2550 | static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, | 2615 | static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, |
2551 | unsigned int buflen, int do_write) | 2616 | unsigned int buflen, int do_write) |
2552 | { | 2617 | { |
@@ -2556,6 +2621,16 @@ static void ata_data_xfer(struct ata_port *ap, unsigned char *buf, | |||
2556 | ata_pio_data_xfer(ap, buf, buflen, do_write); | 2621 | ata_pio_data_xfer(ap, buf, buflen, do_write); |
2557 | } | 2622 | } |
2558 | 2623 | ||
2624 | /** | ||
2625 | * ata_pio_sector - Transfer ATA_SECT_SIZE (512 bytes) of data. | ||
2626 | * @qc: Command on going | ||
2627 | * | ||
2628 | * Transfer ATA_SECT_SIZE of data from/to the ATA device. | ||
2629 | * | ||
2630 | * LOCKING: | ||
2631 | * Inherited from caller. | ||
2632 | */ | ||
2633 | |||
2559 | static void ata_pio_sector(struct ata_queued_cmd *qc) | 2634 | static void ata_pio_sector(struct ata_queued_cmd *qc) |
2560 | { | 2635 | { |
2561 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | 2636 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); |
@@ -2594,6 +2669,18 @@ static void ata_pio_sector(struct ata_queued_cmd *qc) | |||
2594 | kunmap(page); | 2669 | kunmap(page); |
2595 | } | 2670 | } |
2596 | 2671 | ||
2672 | /** | ||
2673 | * __atapi_pio_bytes - Transfer data from/to the ATAPI device. | ||
2674 | * @qc: Command on going | ||
2675 | * @bytes: number of bytes | ||
2676 | * | ||
2677 | * Transfer Transfer data from/to the ATAPI device. | ||
2678 | * | ||
2679 | * LOCKING: | ||
2680 | * Inherited from caller. | ||
2681 | * | ||
2682 | */ | ||
2683 | |||
2597 | static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | 2684 | static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) |
2598 | { | 2685 | { |
2599 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); | 2686 | int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); |
@@ -2603,10 +2690,33 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes) | |||
2603 | unsigned char *buf; | 2690 | unsigned char *buf; |
2604 | unsigned int offset, count; | 2691 | unsigned int offset, count; |
2605 | 2692 | ||
2606 | if (qc->curbytes == qc->nbytes - bytes) | 2693 | if (qc->curbytes + bytes >= qc->nbytes) |
2607 | ap->pio_task_state = PIO_ST_LAST; | 2694 | ap->pio_task_state = PIO_ST_LAST; |
2608 | 2695 | ||
2609 | next_sg: | 2696 | next_sg: |
2697 | if (unlikely(qc->cursg >= qc->n_elem)) { | ||
2698 | /* | ||
2699 | * The end of qc->sg is reached and the device expects | ||
2700 | * more data to transfer. In order not to overrun qc->sg | ||
2701 | * and fulfill length specified in the byte count register, | ||
2702 | * - for read case, discard trailing data from the device | ||
2703 | * - for write case, padding zero data to the device | ||
2704 | */ | ||
2705 | u16 pad_buf[1] = { 0 }; | ||
2706 | unsigned int words = bytes >> 1; | ||
2707 | unsigned int i; | ||
2708 | |||
2709 | if (words) /* warning if bytes > 1 */ | ||
2710 | printk(KERN_WARNING "ata%u: %u bytes trailing data\n", | ||
2711 | ap->id, bytes); | ||
2712 | |||
2713 | for (i = 0; i < words; i++) | ||
2714 | ata_data_xfer(ap, (unsigned char*)pad_buf, 2, do_write); | ||
2715 | |||
2716 | ap->pio_task_state = PIO_ST_LAST; | ||
2717 | return; | ||
2718 | } | ||
2719 | |||
2610 | sg = &qc->sg[qc->cursg]; | 2720 | sg = &qc->sg[qc->cursg]; |
2611 | 2721 | ||
2612 | page = sg->page; | 2722 | page = sg->page; |
@@ -2640,11 +2750,21 @@ next_sg: | |||
2640 | 2750 | ||
2641 | kunmap(page); | 2751 | kunmap(page); |
2642 | 2752 | ||
2643 | if (bytes) { | 2753 | if (bytes) |
2644 | goto next_sg; | 2754 | goto next_sg; |
2645 | } | ||
2646 | } | 2755 | } |
2647 | 2756 | ||
2757 | /** | ||
2758 | * atapi_pio_bytes - Transfer data from/to the ATAPI device. | ||
2759 | * @qc: Command on going | ||
2760 | * | ||
2761 | * Transfer Transfer data from/to the ATAPI device. | ||
2762 | * | ||
2763 | * LOCKING: | ||
2764 | * Inherited from caller. | ||
2765 | * | ||
2766 | */ | ||
2767 | |||
2648 | static void atapi_pio_bytes(struct ata_queued_cmd *qc) | 2768 | static void atapi_pio_bytes(struct ata_queued_cmd *qc) |
2649 | { | 2769 | { |
2650 | struct ata_port *ap = qc->ap; | 2770 | struct ata_port *ap = qc->ap; |
@@ -2717,9 +2837,7 @@ static void ata_pio_block(struct ata_port *ap) | |||
2717 | if ((status & ATA_DRQ) == 0) { | 2837 | if ((status & ATA_DRQ) == 0) { |
2718 | ap->pio_task_state = PIO_ST_IDLE; | 2838 | ap->pio_task_state = PIO_ST_IDLE; |
2719 | 2839 | ||
2720 | ata_irq_on(ap); | 2840 | ata_poll_qc_complete(qc, status); |
2721 | |||
2722 | ata_qc_complete(qc, status); | ||
2723 | return; | 2841 | return; |
2724 | } | 2842 | } |
2725 | 2843 | ||
@@ -2749,9 +2867,7 @@ static void ata_pio_error(struct ata_port *ap) | |||
2749 | 2867 | ||
2750 | ap->pio_task_state = PIO_ST_IDLE; | 2868 | ap->pio_task_state = PIO_ST_IDLE; |
2751 | 2869 | ||
2752 | ata_irq_on(ap); | 2870 | ata_poll_qc_complete(qc, drv_stat | ATA_ERR); |
2753 | |||
2754 | ata_qc_complete(qc, drv_stat | ATA_ERR); | ||
2755 | } | 2871 | } |
2756 | 2872 | ||
2757 | static void ata_pio_task(void *_data) | 2873 | static void ata_pio_task(void *_data) |
@@ -2857,8 +2973,10 @@ static void atapi_request_sense(struct ata_port *ap, struct ata_device *dev, | |||
2857 | static void ata_qc_timeout(struct ata_queued_cmd *qc) | 2973 | static void ata_qc_timeout(struct ata_queued_cmd *qc) |
2858 | { | 2974 | { |
2859 | struct ata_port *ap = qc->ap; | 2975 | struct ata_port *ap = qc->ap; |
2976 | struct ata_host_set *host_set = ap->host_set; | ||
2860 | struct ata_device *dev = qc->dev; | 2977 | struct ata_device *dev = qc->dev; |
2861 | u8 host_stat = 0, drv_stat; | 2978 | u8 host_stat = 0, drv_stat; |
2979 | unsigned long flags; | ||
2862 | 2980 | ||
2863 | DPRINTK("ENTER\n"); | 2981 | DPRINTK("ENTER\n"); |
2864 | 2982 | ||
@@ -2869,7 +2987,9 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
2869 | if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { | 2987 | if (!(cmd->eh_eflags & SCSI_EH_CANCEL_CMD)) { |
2870 | 2988 | ||
2871 | /* finish completing original command */ | 2989 | /* finish completing original command */ |
2990 | spin_lock_irqsave(&host_set->lock, flags); | ||
2872 | __ata_qc_complete(qc); | 2991 | __ata_qc_complete(qc); |
2992 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
2873 | 2993 | ||
2874 | atapi_request_sense(ap, dev, cmd); | 2994 | atapi_request_sense(ap, dev, cmd); |
2875 | 2995 | ||
@@ -2880,6 +3000,8 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
2880 | } | 3000 | } |
2881 | } | 3001 | } |
2882 | 3002 | ||
3003 | spin_lock_irqsave(&host_set->lock, flags); | ||
3004 | |||
2883 | /* hack alert! We cannot use the supplied completion | 3005 | /* hack alert! We cannot use the supplied completion |
2884 | * function from inside the ->eh_strategy_handler() thread. | 3006 | * function from inside the ->eh_strategy_handler() thread. |
2885 | * libata is the only user of ->eh_strategy_handler() in | 3007 | * libata is the only user of ->eh_strategy_handler() in |
@@ -2895,7 +3017,7 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
2895 | host_stat = ap->ops->bmdma_status(ap); | 3017 | host_stat = ap->ops->bmdma_status(ap); |
2896 | 3018 | ||
2897 | /* before we do anything else, clear DMA-Start bit */ | 3019 | /* before we do anything else, clear DMA-Start bit */ |
2898 | ap->ops->bmdma_stop(ap); | 3020 | ap->ops->bmdma_stop(qc); |
2899 | 3021 | ||
2900 | /* fall through */ | 3022 | /* fall through */ |
2901 | 3023 | ||
@@ -2913,6 +3035,9 @@ static void ata_qc_timeout(struct ata_queued_cmd *qc) | |||
2913 | ata_qc_complete(qc, drv_stat); | 3035 | ata_qc_complete(qc, drv_stat); |
2914 | break; | 3036 | break; |
2915 | } | 3037 | } |
3038 | |||
3039 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
3040 | |||
2916 | out: | 3041 | out: |
2917 | DPRINTK("EXIT\n"); | 3042 | DPRINTK("EXIT\n"); |
2918 | } | 3043 | } |
@@ -3086,9 +3211,14 @@ void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat) | |||
3086 | if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) | 3211 | if (likely(qc->flags & ATA_QCFLAG_DMAMAP)) |
3087 | ata_sg_clean(qc); | 3212 | ata_sg_clean(qc); |
3088 | 3213 | ||
3214 | /* atapi: mark qc as inactive to prevent the interrupt handler | ||
3215 | * from completing the command twice later, before the error handler | ||
3216 | * is called. (when rc != 0 and atapi request sense is needed) | ||
3217 | */ | ||
3218 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | ||
3219 | |||
3089 | /* call completion callback */ | 3220 | /* call completion callback */ |
3090 | rc = qc->complete_fn(qc, drv_stat); | 3221 | rc = qc->complete_fn(qc, drv_stat); |
3091 | qc->flags &= ~ATA_QCFLAG_ACTIVE; | ||
3092 | 3222 | ||
3093 | /* if callback indicates not to complete command (non-zero), | 3223 | /* if callback indicates not to complete command (non-zero), |
3094 | * return immediately | 3224 | * return immediately |
@@ -3218,11 +3348,13 @@ int ata_qc_issue_prot(struct ata_queued_cmd *qc) | |||
3218 | break; | 3348 | break; |
3219 | 3349 | ||
3220 | case ATA_PROT_ATAPI_NODATA: | 3350 | case ATA_PROT_ATAPI_NODATA: |
3351 | ap->flags |= ATA_FLAG_NOINTR; | ||
3221 | ata_tf_to_host_nolock(ap, &qc->tf); | 3352 | ata_tf_to_host_nolock(ap, &qc->tf); |
3222 | queue_work(ata_wq, &ap->packet_task); | 3353 | queue_work(ata_wq, &ap->packet_task); |
3223 | break; | 3354 | break; |
3224 | 3355 | ||
3225 | case ATA_PROT_ATAPI_DMA: | 3356 | case ATA_PROT_ATAPI_DMA: |
3357 | ap->flags |= ATA_FLAG_NOINTR; | ||
3226 | ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ | 3358 | ap->ops->tf_load(ap, &qc->tf); /* load tf registers */ |
3227 | ap->ops->bmdma_setup(qc); /* set up bmdma */ | 3359 | ap->ops->bmdma_setup(qc); /* set up bmdma */ |
3228 | queue_work(ata_wq, &ap->packet_task); | 3360 | queue_work(ata_wq, &ap->packet_task); |
@@ -3267,7 +3399,7 @@ static void ata_bmdma_setup_mmio (struct ata_queued_cmd *qc) | |||
3267 | } | 3399 | } |
3268 | 3400 | ||
3269 | /** | 3401 | /** |
3270 | * ata_bmdma_start - Start a PCI IDE BMDMA transaction | 3402 | * ata_bmdma_start_mmio - Start a PCI IDE BMDMA transaction |
3271 | * @qc: Info associated with this ATA transaction. | 3403 | * @qc: Info associated with this ATA transaction. |
3272 | * | 3404 | * |
3273 | * LOCKING: | 3405 | * LOCKING: |
@@ -3438,7 +3570,7 @@ u8 ata_bmdma_status(struct ata_port *ap) | |||
3438 | 3570 | ||
3439 | /** | 3571 | /** |
3440 | * ata_bmdma_stop - Stop PCI IDE BMDMA transfer | 3572 | * ata_bmdma_stop - Stop PCI IDE BMDMA transfer |
3441 | * @ap: Port associated with this ATA transaction. | 3573 | * @qc: Command we are ending DMA for |
3442 | * | 3574 | * |
3443 | * Clears the ATA_DMA_START flag in the dma control register | 3575 | * Clears the ATA_DMA_START flag in the dma control register |
3444 | * | 3576 | * |
@@ -3448,8 +3580,9 @@ u8 ata_bmdma_status(struct ata_port *ap) | |||
3448 | * spin_lock_irqsave(host_set lock) | 3580 | * spin_lock_irqsave(host_set lock) |
3449 | */ | 3581 | */ |
3450 | 3582 | ||
3451 | void ata_bmdma_stop(struct ata_port *ap) | 3583 | void ata_bmdma_stop(struct ata_queued_cmd *qc) |
3452 | { | 3584 | { |
3585 | struct ata_port *ap = qc->ap; | ||
3453 | if (ap->flags & ATA_FLAG_MMIO) { | 3586 | if (ap->flags & ATA_FLAG_MMIO) { |
3454 | void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; | 3587 | void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr; |
3455 | 3588 | ||
@@ -3501,7 +3634,7 @@ inline unsigned int ata_host_intr (struct ata_port *ap, | |||
3501 | goto idle_irq; | 3634 | goto idle_irq; |
3502 | 3635 | ||
3503 | /* before we do anything else, clear DMA-Start bit */ | 3636 | /* before we do anything else, clear DMA-Start bit */ |
3504 | ap->ops->bmdma_stop(ap); | 3637 | ap->ops->bmdma_stop(qc); |
3505 | 3638 | ||
3506 | /* fall through */ | 3639 | /* fall through */ |
3507 | 3640 | ||
@@ -3576,7 +3709,8 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) | |||
3576 | struct ata_port *ap; | 3709 | struct ata_port *ap; |
3577 | 3710 | ||
3578 | ap = host_set->ports[i]; | 3711 | ap = host_set->ports[i]; |
3579 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 3712 | if (ap && |
3713 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
3580 | struct ata_queued_cmd *qc; | 3714 | struct ata_queued_cmd *qc; |
3581 | 3715 | ||
3582 | qc = ata_qc_from_tag(ap, ap->active_tag); | 3716 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -3628,19 +3762,27 @@ static void atapi_packet_task(void *_data) | |||
3628 | /* send SCSI cdb */ | 3762 | /* send SCSI cdb */ |
3629 | DPRINTK("send cdb\n"); | 3763 | DPRINTK("send cdb\n"); |
3630 | assert(ap->cdb_len >= 12); | 3764 | assert(ap->cdb_len >= 12); |
3631 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3632 | 3765 | ||
3633 | /* if we are DMA'ing, irq handler takes over from here */ | 3766 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA || |
3634 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) | 3767 | qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { |
3635 | ap->ops->bmdma_start(qc); /* initiate bmdma */ | 3768 | unsigned long flags; |
3636 | 3769 | ||
3637 | /* non-data commands are also handled via irq */ | 3770 | /* Once we're done issuing command and kicking bmdma, |
3638 | else if (qc->tf.protocol == ATA_PROT_ATAPI_NODATA) { | 3771 | * irq handler takes over. To not lose irq, we need |
3639 | /* do nothing */ | 3772 | * to clear NOINTR flag before sending cdb, but |
3640 | } | 3773 | * interrupt handler shouldn't be invoked before we're |
3774 | * finished. Hence, the following locking. | ||
3775 | */ | ||
3776 | spin_lock_irqsave(&ap->host_set->lock, flags); | ||
3777 | ap->flags &= ~ATA_FLAG_NOINTR; | ||
3778 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3779 | if (qc->tf.protocol == ATA_PROT_ATAPI_DMA) | ||
3780 | ap->ops->bmdma_start(qc); /* initiate bmdma */ | ||
3781 | spin_unlock_irqrestore(&ap->host_set->lock, flags); | ||
3782 | } else { | ||
3783 | ata_data_xfer(ap, qc->cdb, ap->cdb_len, 1); | ||
3641 | 3784 | ||
3642 | /* PIO commands are handled by polling */ | 3785 | /* PIO commands are handled by polling */ |
3643 | else { | ||
3644 | ap->pio_task_state = PIO_ST; | 3786 | ap->pio_task_state = PIO_ST; |
3645 | queue_work(ata_wq, &ap->pio_task); | 3787 | queue_work(ata_wq, &ap->pio_task); |
3646 | } | 3788 | } |
@@ -3648,7 +3790,7 @@ static void atapi_packet_task(void *_data) | |||
3648 | return; | 3790 | return; |
3649 | 3791 | ||
3650 | err_out: | 3792 | err_out: |
3651 | ata_qc_complete(qc, ATA_ERR); | 3793 | ata_poll_qc_complete(qc, ATA_ERR); |
3652 | } | 3794 | } |
3653 | 3795 | ||
3654 | 3796 | ||
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 6a75ec2187fd..4074e7877ba3 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -392,6 +392,60 @@ int ata_scsi_error(struct Scsi_Host *host) | |||
392 | } | 392 | } |
393 | 393 | ||
394 | /** | 394 | /** |
395 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | ||
396 | * @qc: Storage for translated ATA taskfile | ||
397 | * @scsicmd: SCSI command to translate | ||
398 | * | ||
399 | * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY | ||
400 | * (to start). Perhaps these commands should be preceded by | ||
401 | * CHECK POWER MODE to see what power mode the device is already in. | ||
402 | * [See SAT revision 5 at www.t10.org] | ||
403 | * | ||
404 | * LOCKING: | ||
405 | * spin_lock_irqsave(host_set lock) | ||
406 | * | ||
407 | * RETURNS: | ||
408 | * Zero on success, non-zero on error. | ||
409 | */ | ||
410 | |||
411 | static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc, | ||
412 | u8 *scsicmd) | ||
413 | { | ||
414 | struct ata_taskfile *tf = &qc->tf; | ||
415 | |||
416 | tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; | ||
417 | tf->protocol = ATA_PROT_NODATA; | ||
418 | if (scsicmd[1] & 0x1) { | ||
419 | ; /* ignore IMMED bit, violates sat-r05 */ | ||
420 | } | ||
421 | if (scsicmd[4] & 0x2) | ||
422 | return 1; /* LOEJ bit set not supported */ | ||
423 | if (((scsicmd[4] >> 4) & 0xf) != 0) | ||
424 | return 1; /* power conditions not supported */ | ||
425 | if (scsicmd[4] & 0x1) { | ||
426 | tf->nsect = 1; /* 1 sector, lba=0 */ | ||
427 | tf->lbah = 0x0; | ||
428 | tf->lbam = 0x0; | ||
429 | tf->lbal = 0x0; | ||
430 | tf->device |= ATA_LBA; | ||
431 | tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ | ||
432 | } else { | ||
433 | tf->nsect = 0; /* time period value (0 implies now) */ | ||
434 | tf->command = ATA_CMD_STANDBY; | ||
435 | /* Consider: ATA STANDBY IMMEDIATE command */ | ||
436 | } | ||
437 | /* | ||
438 | * Standby and Idle condition timers could be implemented but that | ||
439 | * would require libata to implement the Power condition mode page | ||
440 | * and allow the user to change it. Changing mode pages requires | ||
441 | * MODE SELECT to be implemented. | ||
442 | */ | ||
443 | |||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | |||
448 | /** | ||
395 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command | 449 | * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command |
396 | * @qc: Storage for translated ATA taskfile | 450 | * @qc: Storage for translated ATA taskfile |
397 | * @scsicmd: SCSI command to translate (ignored) | 451 | * @scsicmd: SCSI command to translate (ignored) |
@@ -576,11 +630,19 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
576 | tf->lbah = scsicmd[3]; | 630 | tf->lbah = scsicmd[3]; |
577 | 631 | ||
578 | VPRINTK("ten-byte command\n"); | 632 | VPRINTK("ten-byte command\n"); |
633 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
634 | return 1; | ||
579 | return 0; | 635 | return 0; |
580 | } | 636 | } |
581 | 637 | ||
582 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { | 638 | if (scsicmd[0] == READ_6 || scsicmd[0] == WRITE_6) { |
583 | qc->nsect = tf->nsect = scsicmd[4]; | 639 | qc->nsect = tf->nsect = scsicmd[4]; |
640 | if (!qc->nsect) { | ||
641 | qc->nsect = 256; | ||
642 | if (lba48) | ||
643 | tf->hob_nsect = 1; | ||
644 | } | ||
645 | |||
584 | tf->lbal = scsicmd[3]; | 646 | tf->lbal = scsicmd[3]; |
585 | tf->lbam = scsicmd[2]; | 647 | tf->lbam = scsicmd[2]; |
586 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ | 648 | tf->lbah = scsicmd[1] & 0x1f; /* mask out reserved bits */ |
@@ -620,6 +682,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd) | |||
620 | tf->lbah = scsicmd[7]; | 682 | tf->lbah = scsicmd[7]; |
621 | 683 | ||
622 | VPRINTK("sixteen-byte command\n"); | 684 | VPRINTK("sixteen-byte command\n"); |
685 | if (qc->nsect == 0) /* we don't support length==0 cmds */ | ||
686 | return 1; | ||
623 | return 0; | 687 | return 0; |
624 | } | 688 | } |
625 | 689 | ||
@@ -1435,6 +1499,8 @@ static inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) | |||
1435 | case VERIFY: | 1499 | case VERIFY: |
1436 | case VERIFY_16: | 1500 | case VERIFY_16: |
1437 | return ata_scsi_verify_xlat; | 1501 | return ata_scsi_verify_xlat; |
1502 | case START_STOP: | ||
1503 | return ata_scsi_start_stop_xlat; | ||
1438 | } | 1504 | } |
1439 | 1505 | ||
1440 | return NULL; | 1506 | return NULL; |
diff --git a/drivers/scsi/libata.h b/drivers/scsi/libata.h index d90430bbb0de..620d21772bd6 100644 --- a/drivers/scsi/libata.h +++ b/drivers/scsi/libata.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define __LIBATA_H__ | 26 | #define __LIBATA_H__ |
27 | 27 | ||
28 | #define DRV_NAME "libata" | 28 | #define DRV_NAME "libata" |
29 | #define DRV_VERSION "1.11" /* must be exactly four chars */ | 29 | #define DRV_VERSION "1.12" /* must be exactly four chars */ |
30 | 30 | ||
31 | struct ata_scsi_args { | 31 | struct ata_scsi_args { |
32 | u16 *id; | 32 | u16 *id; |
@@ -72,7 +72,7 @@ extern unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf, | |||
72 | extern void ata_scsi_badcmd(struct scsi_cmnd *cmd, | 72 | extern void ata_scsi_badcmd(struct scsi_cmnd *cmd, |
73 | void (*done)(struct scsi_cmnd *), | 73 | void (*done)(struct scsi_cmnd *), |
74 | u8 asc, u8 ascq); | 74 | u8 asc, u8 ascq); |
75 | extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, | 75 | extern void ata_scsi_rbuf_fill(struct ata_scsi_args *args, |
76 | unsigned int (*actor) (struct ata_scsi_args *args, | 76 | unsigned int (*actor) (struct ata_scsi_args *args, |
77 | u8 *rbuf, unsigned int buflen)); | 77 | u8 *rbuf, unsigned int buflen)); |
78 | 78 | ||
diff --git a/drivers/scsi/sata_nv.c b/drivers/scsi/sata_nv.c index b0403ccd8a25..41a3421b02b4 100644 --- a/drivers/scsi/sata_nv.c +++ b/drivers/scsi/sata_nv.c | |||
@@ -20,6 +20,12 @@ | |||
20 | * If you do not delete the provisions above, a recipient may use your | 20 | * If you do not delete the provisions above, a recipient may use your |
21 | * version of this file under either the OSL or the GPL. | 21 | * version of this file under either the OSL or the GPL. |
22 | * | 22 | * |
23 | * 0.08 | ||
24 | * - Added support for MCP51 and MCP55. | ||
25 | * | ||
26 | * 0.07 | ||
27 | * - Added support for RAID class code. | ||
28 | * | ||
23 | * 0.06 | 29 | * 0.06 |
24 | * - Added generic SATA support by using a pci_device_id that filters on | 30 | * - Added generic SATA support by using a pci_device_id that filters on |
25 | * the IDE storage class code. | 31 | * the IDE storage class code. |
@@ -48,7 +54,7 @@ | |||
48 | #include <linux/libata.h> | 54 | #include <linux/libata.h> |
49 | 55 | ||
50 | #define DRV_NAME "sata_nv" | 56 | #define DRV_NAME "sata_nv" |
51 | #define DRV_VERSION "0.6" | 57 | #define DRV_VERSION "0.8" |
52 | 58 | ||
53 | #define NV_PORTS 2 | 59 | #define NV_PORTS 2 |
54 | #define NV_PIO_MASK 0x1f | 60 | #define NV_PIO_MASK 0x1f |
@@ -116,7 +122,9 @@ enum nv_host_type | |||
116 | GENERIC, | 122 | GENERIC, |
117 | NFORCE2, | 123 | NFORCE2, |
118 | NFORCE3, | 124 | NFORCE3, |
119 | CK804 | 125 | CK804, |
126 | MCP51, | ||
127 | MCP55 | ||
120 | }; | 128 | }; |
121 | 129 | ||
122 | static struct pci_device_id nv_pci_tbl[] = { | 130 | static struct pci_device_id nv_pci_tbl[] = { |
@@ -134,9 +142,18 @@ static struct pci_device_id nv_pci_tbl[] = { | |||
134 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 142 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, |
135 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, | 143 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2, |
136 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, | 144 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, CK804 }, |
145 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA, | ||
146 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 }, | ||
147 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2, | ||
148 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP51 }, | ||
149 | { PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA, | ||
150 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, MCP55 }, | ||
137 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | 151 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, |
138 | PCI_ANY_ID, PCI_ANY_ID, | 152 | PCI_ANY_ID, PCI_ANY_ID, |
139 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, | 153 | PCI_CLASS_STORAGE_IDE<<8, 0xffff00, GENERIC }, |
154 | { PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID, | ||
155 | PCI_ANY_ID, PCI_ANY_ID, | ||
156 | PCI_CLASS_STORAGE_RAID<<8, 0xffff00, GENERIC }, | ||
140 | { 0, } /* terminate list */ | 157 | { 0, } /* terminate list */ |
141 | }; | 158 | }; |
142 | 159 | ||
@@ -274,7 +291,8 @@ static irqreturn_t nv_interrupt (int irq, void *dev_instance, | |||
274 | struct ata_port *ap; | 291 | struct ata_port *ap; |
275 | 292 | ||
276 | ap = host_set->ports[i]; | 293 | ap = host_set->ports[i]; |
277 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 294 | if (ap && |
295 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
278 | struct ata_queued_cmd *qc; | 296 | struct ata_queued_cmd *qc; |
279 | 297 | ||
280 | qc = ata_qc_from_tag(ap, ap->active_tag); | 298 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 5c1d4411457a..b8dc49fed769 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #include "sata_promise.h" | 40 | #include "sata_promise.h" |
41 | 41 | ||
42 | #define DRV_NAME "sata_promise" | 42 | #define DRV_NAME "sata_promise" |
43 | #define DRV_VERSION "1.01" | 43 | #define DRV_VERSION "1.02" |
44 | 44 | ||
45 | 45 | ||
46 | enum { | 46 | enum { |
@@ -181,6 +181,10 @@ static struct pci_device_id pdc_ata_pci_tbl[] = { | |||
181 | board_20319 }, | 181 | board_20319 }, |
182 | { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 182 | { PCI_VENDOR_ID_PROMISE, 0x3319, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
183 | board_20319 }, | 183 | board_20319 }, |
184 | { PCI_VENDOR_ID_PROMISE, 0x3519, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
185 | board_20319 }, | ||
186 | { PCI_VENDOR_ID_PROMISE, 0x3d17, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
187 | board_20319 }, | ||
184 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 188 | { PCI_VENDOR_ID_PROMISE, 0x3d18, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
185 | board_20319 }, | 189 | board_20319 }, |
186 | 190 | ||
@@ -321,11 +325,15 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc) | |||
321 | 325 | ||
322 | static void pdc_eng_timeout(struct ata_port *ap) | 326 | static void pdc_eng_timeout(struct ata_port *ap) |
323 | { | 327 | { |
328 | struct ata_host_set *host_set = ap->host_set; | ||
324 | u8 drv_stat; | 329 | u8 drv_stat; |
325 | struct ata_queued_cmd *qc; | 330 | struct ata_queued_cmd *qc; |
331 | unsigned long flags; | ||
326 | 332 | ||
327 | DPRINTK("ENTER\n"); | 333 | DPRINTK("ENTER\n"); |
328 | 334 | ||
335 | spin_lock_irqsave(&host_set->lock, flags); | ||
336 | |||
329 | qc = ata_qc_from_tag(ap, ap->active_tag); | 337 | qc = ata_qc_from_tag(ap, ap->active_tag); |
330 | if (!qc) { | 338 | if (!qc) { |
331 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 339 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
@@ -359,6 +367,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
359 | } | 367 | } |
360 | 368 | ||
361 | out: | 369 | out: |
370 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
362 | DPRINTK("EXIT\n"); | 371 | DPRINTK("EXIT\n"); |
363 | } | 372 | } |
364 | 373 | ||
@@ -441,7 +450,8 @@ static irqreturn_t pdc_interrupt (int irq, void *dev_instance, struct pt_regs *r | |||
441 | VPRINTK("port %u\n", i); | 450 | VPRINTK("port %u\n", i); |
442 | ap = host_set->ports[i]; | 451 | ap = host_set->ports[i]; |
443 | tmp = mask & (1 << (i + 1)); | 452 | tmp = mask & (1 << (i + 1)); |
444 | if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 453 | if (tmp && ap && |
454 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
445 | struct ata_queued_cmd *qc; | 455 | struct ata_queued_cmd *qc; |
446 | 456 | ||
447 | qc = ata_qc_from_tag(ap, ap->active_tag); | 457 | qc = ata_qc_from_tag(ap, ap->active_tag); |
diff --git a/drivers/scsi/sata_qstor.c b/drivers/scsi/sata_qstor.c index 1383e8a28d72..93fd06fb4f15 100644 --- a/drivers/scsi/sata_qstor.c +++ b/drivers/scsi/sata_qstor.c | |||
@@ -117,7 +117,7 @@ static void qs_phy_reset(struct ata_port *ap); | |||
117 | static void qs_qc_prep(struct ata_queued_cmd *qc); | 117 | static void qs_qc_prep(struct ata_queued_cmd *qc); |
118 | static int qs_qc_issue(struct ata_queued_cmd *qc); | 118 | static int qs_qc_issue(struct ata_queued_cmd *qc); |
119 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); | 119 | static int qs_check_atapi_dma(struct ata_queued_cmd *qc); |
120 | static void qs_bmdma_stop(struct ata_port *ap); | 120 | static void qs_bmdma_stop(struct ata_queued_cmd *qc); |
121 | static u8 qs_bmdma_status(struct ata_port *ap); | 121 | static u8 qs_bmdma_status(struct ata_port *ap); |
122 | static void qs_irq_clear(struct ata_port *ap); | 122 | static void qs_irq_clear(struct ata_port *ap); |
123 | static void qs_eng_timeout(struct ata_port *ap); | 123 | static void qs_eng_timeout(struct ata_port *ap); |
@@ -198,7 +198,7 @@ static int qs_check_atapi_dma(struct ata_queued_cmd *qc) | |||
198 | return 1; /* ATAPI DMA not supported */ | 198 | return 1; /* ATAPI DMA not supported */ |
199 | } | 199 | } |
200 | 200 | ||
201 | static void qs_bmdma_stop(struct ata_port *ap) | 201 | static void qs_bmdma_stop(struct ata_queued_cmd *qc) |
202 | { | 202 | { |
203 | /* nothing */ | 203 | /* nothing */ |
204 | } | 204 | } |
@@ -386,7 +386,8 @@ static inline unsigned int qs_intr_pkt(struct ata_host_set *host_set) | |||
386 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", | 386 | DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n", |
387 | sff1, sff0, port_no, sHST, sDST); | 387 | sff1, sff0, port_no, sHST, sDST); |
388 | handled = 1; | 388 | handled = 1; |
389 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 389 | if (ap && !(ap->flags & |
390 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | ||
390 | struct ata_queued_cmd *qc; | 391 | struct ata_queued_cmd *qc; |
391 | struct qs_port_priv *pp = ap->private_data; | 392 | struct qs_port_priv *pp = ap->private_data; |
392 | if (!pp || pp->state != qs_state_pkt) | 393 | if (!pp || pp->state != qs_state_pkt) |
@@ -417,7 +418,8 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) | |||
417 | for (port_no = 0; port_no < host_set->n_ports; ++port_no) { | 418 | for (port_no = 0; port_no < host_set->n_ports; ++port_no) { |
418 | struct ata_port *ap; | 419 | struct ata_port *ap; |
419 | ap = host_set->ports[port_no]; | 420 | ap = host_set->ports[port_no]; |
420 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 421 | if (ap && |
422 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
421 | struct ata_queued_cmd *qc; | 423 | struct ata_queued_cmd *qc; |
422 | struct qs_port_priv *pp = ap->private_data; | 424 | struct qs_port_priv *pp = ap->private_data; |
423 | if (!pp || pp->state != qs_state_mmio) | 425 | if (!pp || pp->state != qs_state_mmio) |
@@ -431,7 +433,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host_set *host_set) | |||
431 | continue; | 433 | continue; |
432 | DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", | 434 | DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n", |
433 | ap->id, qc->tf.protocol, status); | 435 | ap->id, qc->tf.protocol, status); |
434 | 436 | ||
435 | /* complete taskfile transaction */ | 437 | /* complete taskfile transaction */ |
436 | pp->state = qs_state_idle; | 438 | pp->state = qs_state_idle; |
437 | ata_qc_complete(qc, status); | 439 | ata_qc_complete(qc, status); |
diff --git a/drivers/scsi/sata_sil.c b/drivers/scsi/sata_sil.c index 49ed557a4b66..9d24d6c328b4 100644 --- a/drivers/scsi/sata_sil.c +++ b/drivers/scsi/sata_sil.c | |||
@@ -24,6 +24,11 @@ | |||
24 | * If you do not delete the provisions above, a recipient may use your | 24 | * If you do not delete the provisions above, a recipient may use your |
25 | * version of this file under either the OSL or the GPL. | 25 | * version of this file under either the OSL or the GPL. |
26 | * | 26 | * |
27 | * Documentation for SiI 3112: | ||
28 | * http://gkernel.sourceforge.net/specs/sii/3112A_SiI-DS-0095-B2.pdf.bz2 | ||
29 | * | ||
30 | * Other errata and documentation available under NDA. | ||
31 | * | ||
27 | */ | 32 | */ |
28 | 33 | ||
29 | #include <linux/kernel.h> | 34 | #include <linux/kernel.h> |
@@ -41,8 +46,11 @@ | |||
41 | #define DRV_VERSION "0.9" | 46 | #define DRV_VERSION "0.9" |
42 | 47 | ||
43 | enum { | 48 | enum { |
49 | SIL_FLAG_MOD15WRITE = (1 << 30), | ||
50 | |||
44 | sil_3112 = 0, | 51 | sil_3112 = 0, |
45 | sil_3114 = 1, | 52 | sil_3112_m15w = 1, |
53 | sil_3114 = 2, | ||
46 | 54 | ||
47 | SIL_FIFO_R0 = 0x40, | 55 | SIL_FIFO_R0 = 0x40, |
48 | SIL_FIFO_W0 = 0x41, | 56 | SIL_FIFO_W0 = 0x41, |
@@ -76,13 +84,13 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val); | |||
76 | static void sil_post_set_mode (struct ata_port *ap); | 84 | static void sil_post_set_mode (struct ata_port *ap); |
77 | 85 | ||
78 | static struct pci_device_id sil_pci_tbl[] = { | 86 | static struct pci_device_id sil_pci_tbl[] = { |
79 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 87 | { 0x1095, 0x3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
80 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 88 | { 0x1095, 0x0240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
81 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 89 | { 0x1095, 0x3512, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, |
82 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, | 90 | { 0x1095, 0x3114, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3114 }, |
83 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 91 | { 0x1002, 0x436e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
84 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 92 | { 0x1002, 0x4379, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
85 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112 }, | 93 | { 0x1002, 0x437a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, sil_3112_m15w }, |
86 | { } /* terminate list */ | 94 | { } /* terminate list */ |
87 | }; | 95 | }; |
88 | 96 | ||
@@ -174,6 +182,16 @@ static struct ata_port_info sil_port_info[] = { | |||
174 | .mwdma_mask = 0x07, /* mwdma0-2 */ | 182 | .mwdma_mask = 0x07, /* mwdma0-2 */ |
175 | .udma_mask = 0x3f, /* udma0-5 */ | 183 | .udma_mask = 0x3f, /* udma0-5 */ |
176 | .port_ops = &sil_ops, | 184 | .port_ops = &sil_ops, |
185 | }, /* sil_3112_15w - keep it sync'd w/ sil_3112 */ | ||
186 | { | ||
187 | .sht = &sil_sht, | ||
188 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
189 | ATA_FLAG_SRST | ATA_FLAG_MMIO | | ||
190 | SIL_FLAG_MOD15WRITE, | ||
191 | .pio_mask = 0x1f, /* pio0-4 */ | ||
192 | .mwdma_mask = 0x07, /* mwdma0-2 */ | ||
193 | .udma_mask = 0x3f, /* udma0-5 */ | ||
194 | .port_ops = &sil_ops, | ||
177 | }, /* sil_3114 */ | 195 | }, /* sil_3114 */ |
178 | { | 196 | { |
179 | .sht = &sil_sht, | 197 | .sht = &sil_sht, |
@@ -323,15 +341,15 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) | |||
323 | while ((len > 0) && (s[len - 1] == ' ')) | 341 | while ((len > 0) && (s[len - 1] == ' ')) |
324 | len--; | 342 | len--; |
325 | 343 | ||
326 | for (n = 0; sil_blacklist[n].product; n++) | 344 | for (n = 0; sil_blacklist[n].product; n++) |
327 | if (!memcmp(sil_blacklist[n].product, s, | 345 | if (!memcmp(sil_blacklist[n].product, s, |
328 | strlen(sil_blacklist[n].product))) { | 346 | strlen(sil_blacklist[n].product))) { |
329 | quirks = sil_blacklist[n].quirk; | 347 | quirks = sil_blacklist[n].quirk; |
330 | break; | 348 | break; |
331 | } | 349 | } |
332 | 350 | ||
333 | /* limit requests to 15 sectors */ | 351 | /* limit requests to 15 sectors */ |
334 | if (quirks & SIL_QUIRK_MOD15WRITE) { | 352 | if ((ap->flags & SIL_FLAG_MOD15WRITE) && (quirks & SIL_QUIRK_MOD15WRITE)) { |
335 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", | 353 | printk(KERN_INFO "ata%u(%u): applying Seagate errata fix\n", |
336 | ap->id, dev->devno); | 354 | ap->id, dev->devno); |
337 | ap->host->max_sectors = 15; | 355 | ap->host->max_sectors = 15; |
diff --git a/drivers/scsi/sata_sis.c b/drivers/scsi/sata_sis.c index e418b89c6b9d..b250ae0c7773 100644 --- a/drivers/scsi/sata_sis.c +++ b/drivers/scsi/sata_sis.c | |||
@@ -234,7 +234,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
234 | pci_read_config_dword(pdev, SIS_GENCTL, &genctl); | 234 | pci_read_config_dword(pdev, SIS_GENCTL, &genctl); |
235 | if ((genctl & GENCTL_IOMAPPED_SCR) == 0) | 235 | if ((genctl & GENCTL_IOMAPPED_SCR) == 0) |
236 | probe_ent->host_flags |= SIS_FLAG_CFGSCR; | 236 | probe_ent->host_flags |= SIS_FLAG_CFGSCR; |
237 | 237 | ||
238 | /* if hardware thinks SCRs are in IO space, but there are | 238 | /* if hardware thinks SCRs are in IO space, but there are |
239 | * no IO resources assigned, change to PCI cfg space. | 239 | * no IO resources assigned, change to PCI cfg space. |
240 | */ | 240 | */ |
diff --git a/drivers/scsi/sata_svw.c b/drivers/scsi/sata_svw.c index 858e07185dbd..6fd2ce1ffcd8 100644 --- a/drivers/scsi/sata_svw.c +++ b/drivers/scsi/sata_svw.c | |||
@@ -195,18 +195,18 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) | |||
195 | /* start host DMA transaction */ | 195 | /* start host DMA transaction */ |
196 | dmactl = readb(mmio + ATA_DMA_CMD); | 196 | dmactl = readb(mmio + ATA_DMA_CMD); |
197 | writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); | 197 | writeb(dmactl | ATA_DMA_START, mmio + ATA_DMA_CMD); |
198 | /* There is a race condition in certain SATA controllers that can | 198 | /* There is a race condition in certain SATA controllers that can |
199 | be seen when the r/w command is given to the controller before the | 199 | be seen when the r/w command is given to the controller before the |
200 | host DMA is started. On a Read command, the controller would initiate | 200 | host DMA is started. On a Read command, the controller would initiate |
201 | the command to the drive even before it sees the DMA start. When there | 201 | the command to the drive even before it sees the DMA start. When there |
202 | are very fast drives connected to the controller, or when the data request | 202 | are very fast drives connected to the controller, or when the data request |
203 | hits in the drive cache, there is the possibility that the drive returns a part | 203 | hits in the drive cache, there is the possibility that the drive returns a part |
204 | or all of the requested data to the controller before the DMA start is issued. | 204 | or all of the requested data to the controller before the DMA start is issued. |
205 | In this case, the controller would become confused as to what to do with the data. | 205 | In this case, the controller would become confused as to what to do with the data. |
206 | In the worst case when all the data is returned back to the controller, the | 206 | In the worst case when all the data is returned back to the controller, the |
207 | controller could hang. In other cases it could return partial data returning | 207 | controller could hang. In other cases it could return partial data returning |
208 | in data corruption. This problem has been seen in PPC systems and can also appear | 208 | in data corruption. This problem has been seen in PPC systems and can also appear |
209 | on an system with very fast disks, where the SATA controller is sitting behind a | 209 | on an system with very fast disks, where the SATA controller is sitting behind a |
210 | number of bridges, and hence there is significant latency between the r/w command | 210 | number of bridges, and hence there is significant latency between the r/w command |
211 | and the start command. */ | 211 | and the start command. */ |
212 | /* issue r/w command if the access is to ATA*/ | 212 | /* issue r/w command if the access is to ATA*/ |
@@ -214,7 +214,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc) | |||
214 | ap->ops->exec_command(ap, &qc->tf); | 214 | ap->ops->exec_command(ap, &qc->tf); |
215 | } | 215 | } |
216 | 216 | ||
217 | 217 | ||
218 | static u8 k2_stat_check_status(struct ata_port *ap) | 218 | static u8 k2_stat_check_status(struct ata_port *ap) |
219 | { | 219 | { |
220 | return readl((void *) ap->ioaddr.status_addr); | 220 | return readl((void *) ap->ioaddr.status_addr); |
diff --git a/drivers/scsi/sata_sx4.c b/drivers/scsi/sata_sx4.c index efd7d7a61135..a20d4285090a 100644 --- a/drivers/scsi/sata_sx4.c +++ b/drivers/scsi/sata_sx4.c | |||
@@ -94,7 +94,7 @@ enum { | |||
94 | PDC_DIMM1_CONTROL_OFFSET = 0x84, | 94 | PDC_DIMM1_CONTROL_OFFSET = 0x84, |
95 | PDC_SDRAM_CONTROL_OFFSET = 0x88, | 95 | PDC_SDRAM_CONTROL_OFFSET = 0x88, |
96 | PDC_I2C_WRITE = 0x00000000, | 96 | PDC_I2C_WRITE = 0x00000000, |
97 | PDC_I2C_READ = 0x00000040, | 97 | PDC_I2C_READ = 0x00000040, |
98 | PDC_I2C_START = 0x00000080, | 98 | PDC_I2C_START = 0x00000080, |
99 | PDC_I2C_MASK_INT = 0x00000020, | 99 | PDC_I2C_MASK_INT = 0x00000020, |
100 | PDC_I2C_COMPLETE = 0x00010000, | 100 | PDC_I2C_COMPLETE = 0x00010000, |
@@ -105,16 +105,16 @@ enum { | |||
105 | PDC_DIMM_SPD_COLUMN_NUM = 4, | 105 | PDC_DIMM_SPD_COLUMN_NUM = 4, |
106 | PDC_DIMM_SPD_MODULE_ROW = 5, | 106 | PDC_DIMM_SPD_MODULE_ROW = 5, |
107 | PDC_DIMM_SPD_TYPE = 11, | 107 | PDC_DIMM_SPD_TYPE = 11, |
108 | PDC_DIMM_SPD_FRESH_RATE = 12, | 108 | PDC_DIMM_SPD_FRESH_RATE = 12, |
109 | PDC_DIMM_SPD_BANK_NUM = 17, | 109 | PDC_DIMM_SPD_BANK_NUM = 17, |
110 | PDC_DIMM_SPD_CAS_LATENCY = 18, | 110 | PDC_DIMM_SPD_CAS_LATENCY = 18, |
111 | PDC_DIMM_SPD_ATTRIBUTE = 21, | 111 | PDC_DIMM_SPD_ATTRIBUTE = 21, |
112 | PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, | 112 | PDC_DIMM_SPD_ROW_PRE_CHARGE = 27, |
113 | PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, | 113 | PDC_DIMM_SPD_ROW_ACTIVE_DELAY = 28, |
114 | PDC_DIMM_SPD_RAS_CAS_DELAY = 29, | 114 | PDC_DIMM_SPD_RAS_CAS_DELAY = 29, |
115 | PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, | 115 | PDC_DIMM_SPD_ACTIVE_PRECHARGE = 30, |
116 | PDC_DIMM_SPD_SYSTEM_FREQ = 126, | 116 | PDC_DIMM_SPD_SYSTEM_FREQ = 126, |
117 | PDC_CTL_STATUS = 0x08, | 117 | PDC_CTL_STATUS = 0x08, |
118 | PDC_DIMM_WINDOW_CTLR = 0x0C, | 118 | PDC_DIMM_WINDOW_CTLR = 0x0C, |
119 | PDC_TIME_CONTROL = 0x3C, | 119 | PDC_TIME_CONTROL = 0x3C, |
120 | PDC_TIME_PERIOD = 0x40, | 120 | PDC_TIME_PERIOD = 0x40, |
@@ -157,15 +157,15 @@ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf); | |||
157 | static void pdc20621_host_stop(struct ata_host_set *host_set); | 157 | static void pdc20621_host_stop(struct ata_host_set *host_set); |
158 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe); | 158 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe); |
159 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe); | 159 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe); |
160 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, | 160 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, |
161 | u32 device, u32 subaddr, u32 *pdata); | 161 | u32 device, u32 subaddr, u32 *pdata); |
162 | static int pdc20621_prog_dimm0(struct ata_probe_ent *pe); | 162 | static int pdc20621_prog_dimm0(struct ata_probe_ent *pe); |
163 | static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe); | 163 | static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe); |
164 | #ifdef ATA_VERBOSE_DEBUG | 164 | #ifdef ATA_VERBOSE_DEBUG |
165 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, | 165 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, |
166 | void *psource, u32 offset, u32 size); | 166 | void *psource, u32 offset, u32 size); |
167 | #endif | 167 | #endif |
168 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, | 168 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, |
169 | void *psource, u32 offset, u32 size); | 169 | void *psource, u32 offset, u32 size); |
170 | static void pdc20621_irq_clear(struct ata_port *ap); | 170 | static void pdc20621_irq_clear(struct ata_port *ap); |
171 | static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); | 171 | static int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc); |
@@ -825,7 +825,8 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re | |||
825 | ap = host_set->ports[port_no]; | 825 | ap = host_set->ports[port_no]; |
826 | tmp = mask & (1 << i); | 826 | tmp = mask & (1 << i); |
827 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); | 827 | VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp); |
828 | if (tmp && ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 828 | if (tmp && ap && |
829 | !(ap->flags & (ATA_FLAG_PORT_DISABLED | ATA_FLAG_NOINTR))) { | ||
829 | struct ata_queued_cmd *qc; | 830 | struct ata_queued_cmd *qc; |
830 | 831 | ||
831 | qc = ata_qc_from_tag(ap, ap->active_tag); | 832 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -847,10 +848,14 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance, struct pt_re | |||
847 | static void pdc_eng_timeout(struct ata_port *ap) | 848 | static void pdc_eng_timeout(struct ata_port *ap) |
848 | { | 849 | { |
849 | u8 drv_stat; | 850 | u8 drv_stat; |
851 | struct ata_host_set *host_set = ap->host_set; | ||
850 | struct ata_queued_cmd *qc; | 852 | struct ata_queued_cmd *qc; |
853 | unsigned long flags; | ||
851 | 854 | ||
852 | DPRINTK("ENTER\n"); | 855 | DPRINTK("ENTER\n"); |
853 | 856 | ||
857 | spin_lock_irqsave(&host_set->lock, flags); | ||
858 | |||
854 | qc = ata_qc_from_tag(ap, ap->active_tag); | 859 | qc = ata_qc_from_tag(ap, ap->active_tag); |
855 | if (!qc) { | 860 | if (!qc) { |
856 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", | 861 | printk(KERN_ERR "ata%u: BUG: timeout without command\n", |
@@ -884,6 +889,7 @@ static void pdc_eng_timeout(struct ata_port *ap) | |||
884 | } | 889 | } |
885 | 890 | ||
886 | out: | 891 | out: |
892 | spin_unlock_irqrestore(&host_set->lock, flags); | ||
887 | DPRINTK("EXIT\n"); | 893 | DPRINTK("EXIT\n"); |
888 | } | 894 | } |
889 | 895 | ||
@@ -922,7 +928,7 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base) | |||
922 | 928 | ||
923 | 929 | ||
924 | #ifdef ATA_VERBOSE_DEBUG | 930 | #ifdef ATA_VERBOSE_DEBUG |
925 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | 931 | static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, |
926 | u32 offset, u32 size) | 932 | u32 offset, u32 size) |
927 | { | 933 | { |
928 | u32 window_size; | 934 | u32 window_size; |
@@ -936,9 +942,9 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
936 | /* hard-code chip #0 */ | 942 | /* hard-code chip #0 */ |
937 | mmio += PDC_CHIP0_OFS; | 943 | mmio += PDC_CHIP0_OFS; |
938 | 944 | ||
939 | page_mask = 0x00; | 945 | page_mask = 0x00; |
940 | window_size = 0x2000 * 4; /* 32K byte uchar size */ | 946 | window_size = 0x2000 * 4; /* 32K byte uchar size */ |
941 | idx = (u16) (offset / window_size); | 947 | idx = (u16) (offset / window_size); |
942 | 948 | ||
943 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 949 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
944 | readl(mmio + PDC_GENERAL_CTLR); | 950 | readl(mmio + PDC_GENERAL_CTLR); |
@@ -947,19 +953,19 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
947 | 953 | ||
948 | offset -= (idx * window_size); | 954 | offset -= (idx * window_size); |
949 | idx++; | 955 | idx++; |
950 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : | 956 | dist = ((long) (window_size - (offset + size))) >= 0 ? size : |
951 | (long) (window_size - offset); | 957 | (long) (window_size - offset); |
952 | memcpy_fromio((char *) psource, (char *) (dimm_mmio + offset / 4), | 958 | memcpy_fromio((char *) psource, (char *) (dimm_mmio + offset / 4), |
953 | dist); | 959 | dist); |
954 | 960 | ||
955 | psource += dist; | 961 | psource += dist; |
956 | size -= dist; | 962 | size -= dist; |
957 | for (; (long) size >= (long) window_size ;) { | 963 | for (; (long) size >= (long) window_size ;) { |
958 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 964 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
959 | readl(mmio + PDC_GENERAL_CTLR); | 965 | readl(mmio + PDC_GENERAL_CTLR); |
960 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 966 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
961 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 967 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
962 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 968 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), |
963 | window_size / 4); | 969 | window_size / 4); |
964 | psource += window_size; | 970 | psource += window_size; |
965 | size -= window_size; | 971 | size -= window_size; |
@@ -971,14 +977,14 @@ static void pdc20621_get_from_dimm(struct ata_probe_ent *pe, void *psource, | |||
971 | readl(mmio + PDC_GENERAL_CTLR); | 977 | readl(mmio + PDC_GENERAL_CTLR); |
972 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 978 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
973 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 979 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
974 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), | 980 | memcpy_fromio((char *) psource, (char *) (dimm_mmio), |
975 | size / 4); | 981 | size / 4); |
976 | } | 982 | } |
977 | } | 983 | } |
978 | #endif | 984 | #endif |
979 | 985 | ||
980 | 986 | ||
981 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | 987 | static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, |
982 | u32 offset, u32 size) | 988 | u32 offset, u32 size) |
983 | { | 989 | { |
984 | u32 window_size; | 990 | u32 window_size; |
@@ -989,16 +995,16 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
989 | struct pdc_host_priv *hpriv = pe->private_data; | 995 | struct pdc_host_priv *hpriv = pe->private_data; |
990 | void *dimm_mmio = hpriv->dimm_mmio; | 996 | void *dimm_mmio = hpriv->dimm_mmio; |
991 | 997 | ||
992 | /* hard-code chip #0 */ | 998 | /* hard-code chip #0 */ |
993 | mmio += PDC_CHIP0_OFS; | 999 | mmio += PDC_CHIP0_OFS; |
994 | 1000 | ||
995 | page_mask = 0x00; | 1001 | page_mask = 0x00; |
996 | window_size = 0x2000 * 4; /* 32K byte uchar size */ | 1002 | window_size = 0x2000 * 4; /* 32K byte uchar size */ |
997 | idx = (u16) (offset / window_size); | 1003 | idx = (u16) (offset / window_size); |
998 | 1004 | ||
999 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1005 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1000 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1006 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1001 | offset -= (idx * window_size); | 1007 | offset -= (idx * window_size); |
1002 | idx++; | 1008 | idx++; |
1003 | dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : | 1009 | dist = ((long)(s32)(window_size - (offset + size))) >= 0 ? size : |
1004 | (long) (window_size - offset); | 1010 | (long) (window_size - offset); |
@@ -1006,12 +1012,12 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1006 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 1012 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
1007 | readl(mmio + PDC_GENERAL_CTLR); | 1013 | readl(mmio + PDC_GENERAL_CTLR); |
1008 | 1014 | ||
1009 | psource += dist; | 1015 | psource += dist; |
1010 | size -= dist; | 1016 | size -= dist; |
1011 | for (; (long) size >= (long) window_size ;) { | 1017 | for (; (long) size >= (long) window_size ;) { |
1012 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1018 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1013 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1019 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
1014 | memcpy_toio((char *) (dimm_mmio), (char *) psource, | 1020 | memcpy_toio((char *) (dimm_mmio), (char *) psource, |
1015 | window_size / 4); | 1021 | window_size / 4); |
1016 | writel(0x01, mmio + PDC_GENERAL_CTLR); | 1022 | writel(0x01, mmio + PDC_GENERAL_CTLR); |
1017 | readl(mmio + PDC_GENERAL_CTLR); | 1023 | readl(mmio + PDC_GENERAL_CTLR); |
@@ -1019,7 +1025,7 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1019 | size -= window_size; | 1025 | size -= window_size; |
1020 | idx ++; | 1026 | idx ++; |
1021 | } | 1027 | } |
1022 | 1028 | ||
1023 | if (size) { | 1029 | if (size) { |
1024 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); | 1030 | writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR); |
1025 | readl(mmio + PDC_DIMM_WINDOW_CTLR); | 1031 | readl(mmio + PDC_DIMM_WINDOW_CTLR); |
@@ -1030,12 +1036,12 @@ static void pdc20621_put_to_dimm(struct ata_probe_ent *pe, void *psource, | |||
1030 | } | 1036 | } |
1031 | 1037 | ||
1032 | 1038 | ||
1033 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | 1039 | static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, |
1034 | u32 subaddr, u32 *pdata) | 1040 | u32 subaddr, u32 *pdata) |
1035 | { | 1041 | { |
1036 | void *mmio = pe->mmio_base; | 1042 | void *mmio = pe->mmio_base; |
1037 | u32 i2creg = 0; | 1043 | u32 i2creg = 0; |
1038 | u32 status; | 1044 | u32 status; |
1039 | u32 count =0; | 1045 | u32 count =0; |
1040 | 1046 | ||
1041 | /* hard-code chip #0 */ | 1047 | /* hard-code chip #0 */ |
@@ -1049,7 +1055,7 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | |||
1049 | readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); | 1055 | readl(mmio + PDC_I2C_ADDR_DATA_OFFSET); |
1050 | 1056 | ||
1051 | /* Write Control to perform read operation, mask int */ | 1057 | /* Write Control to perform read operation, mask int */ |
1052 | writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, | 1058 | writel(PDC_I2C_READ | PDC_I2C_START | PDC_I2C_MASK_INT, |
1053 | mmio + PDC_I2C_CONTROL_OFFSET); | 1059 | mmio + PDC_I2C_CONTROL_OFFSET); |
1054 | 1060 | ||
1055 | for (count = 0; count <= 1000; count ++) { | 1061 | for (count = 0; count <= 1000; count ++) { |
@@ -1062,26 +1068,26 @@ static unsigned int pdc20621_i2c_read(struct ata_probe_ent *pe, u32 device, | |||
1062 | } | 1068 | } |
1063 | 1069 | ||
1064 | *pdata = (status >> 8) & 0x000000ff; | 1070 | *pdata = (status >> 8) & 0x000000ff; |
1065 | return 1; | 1071 | return 1; |
1066 | } | 1072 | } |
1067 | 1073 | ||
1068 | 1074 | ||
1069 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe) | 1075 | static int pdc20621_detect_dimm(struct ata_probe_ent *pe) |
1070 | { | 1076 | { |
1071 | u32 data=0 ; | 1077 | u32 data=0 ; |
1072 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1078 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1073 | PDC_DIMM_SPD_SYSTEM_FREQ, &data)) { | 1079 | PDC_DIMM_SPD_SYSTEM_FREQ, &data)) { |
1074 | if (data == 100) | 1080 | if (data == 100) |
1075 | return 100; | 1081 | return 100; |
1076 | } else | 1082 | } else |
1077 | return 0; | 1083 | return 0; |
1078 | 1084 | ||
1079 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { | 1085 | if (pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) { |
1080 | if(data <= 0x75) | 1086 | if(data <= 0x75) |
1081 | return 133; | 1087 | return 133; |
1082 | } else | 1088 | } else |
1083 | return 0; | 1089 | return 0; |
1084 | 1090 | ||
1085 | return 0; | 1091 | return 0; |
1086 | } | 1092 | } |
1087 | 1093 | ||
@@ -1091,15 +1097,15 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1091 | u32 spd0[50]; | 1097 | u32 spd0[50]; |
1092 | u32 data = 0; | 1098 | u32 data = 0; |
1093 | int size, i; | 1099 | int size, i; |
1094 | u8 bdimmsize; | 1100 | u8 bdimmsize; |
1095 | void *mmio = pe->mmio_base; | 1101 | void *mmio = pe->mmio_base; |
1096 | static const struct { | 1102 | static const struct { |
1097 | unsigned int reg; | 1103 | unsigned int reg; |
1098 | unsigned int ofs; | 1104 | unsigned int ofs; |
1099 | } pdc_i2c_read_data [] = { | 1105 | } pdc_i2c_read_data [] = { |
1100 | { PDC_DIMM_SPD_TYPE, 11 }, | 1106 | { PDC_DIMM_SPD_TYPE, 11 }, |
1101 | { PDC_DIMM_SPD_FRESH_RATE, 12 }, | 1107 | { PDC_DIMM_SPD_FRESH_RATE, 12 }, |
1102 | { PDC_DIMM_SPD_COLUMN_NUM, 4 }, | 1108 | { PDC_DIMM_SPD_COLUMN_NUM, 4 }, |
1103 | { PDC_DIMM_SPD_ATTRIBUTE, 21 }, | 1109 | { PDC_DIMM_SPD_ATTRIBUTE, 21 }, |
1104 | { PDC_DIMM_SPD_ROW_NUM, 3 }, | 1110 | { PDC_DIMM_SPD_ROW_NUM, 3 }, |
1105 | { PDC_DIMM_SPD_BANK_NUM, 17 }, | 1111 | { PDC_DIMM_SPD_BANK_NUM, 17 }, |
@@ -1108,7 +1114,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1108 | { PDC_DIMM_SPD_ROW_ACTIVE_DELAY, 28 }, | 1114 | { PDC_DIMM_SPD_ROW_ACTIVE_DELAY, 28 }, |
1109 | { PDC_DIMM_SPD_RAS_CAS_DELAY, 29 }, | 1115 | { PDC_DIMM_SPD_RAS_CAS_DELAY, 29 }, |
1110 | { PDC_DIMM_SPD_ACTIVE_PRECHARGE, 30 }, | 1116 | { PDC_DIMM_SPD_ACTIVE_PRECHARGE, 30 }, |
1111 | { PDC_DIMM_SPD_CAS_LATENCY, 18 }, | 1117 | { PDC_DIMM_SPD_CAS_LATENCY, 18 }, |
1112 | }; | 1118 | }; |
1113 | 1119 | ||
1114 | /* hard-code chip #0 */ | 1120 | /* hard-code chip #0 */ |
@@ -1116,17 +1122,17 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1116 | 1122 | ||
1117 | for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++) | 1123 | for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++) |
1118 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1124 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1119 | pdc_i2c_read_data[i].reg, | 1125 | pdc_i2c_read_data[i].reg, |
1120 | &spd0[pdc_i2c_read_data[i].ofs]); | 1126 | &spd0[pdc_i2c_read_data[i].ofs]); |
1121 | 1127 | ||
1122 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); | 1128 | data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4); |
1123 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | | 1129 | data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) | |
1124 | ((((spd0[27] + 9) / 10) - 1) << 8) ; | 1130 | ((((spd0[27] + 9) / 10) - 1) << 8) ; |
1125 | data |= (((((spd0[29] > spd0[28]) | 1131 | data |= (((((spd0[29] > spd0[28]) |
1126 | ? spd0[29] : spd0[28]) + 9) / 10) - 1) << 10; | 1132 | ? spd0[29] : spd0[28]) + 9) / 10) - 1) << 10; |
1127 | data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12; | 1133 | data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12; |
1128 | 1134 | ||
1129 | if (spd0[18] & 0x08) | 1135 | if (spd0[18] & 0x08) |
1130 | data |= ((0x03) << 14); | 1136 | data |= ((0x03) << 14); |
1131 | else if (spd0[18] & 0x04) | 1137 | else if (spd0[18] & 0x04) |
1132 | data |= ((0x02) << 14); | 1138 | data |= ((0x02) << 14); |
@@ -1135,7 +1141,7 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1135 | else | 1141 | else |
1136 | data |= (0 << 14); | 1142 | data |= (0 << 14); |
1137 | 1143 | ||
1138 | /* | 1144 | /* |
1139 | Calculate the size of bDIMMSize (power of 2) and | 1145 | Calculate the size of bDIMMSize (power of 2) and |
1140 | merge the DIMM size by program start/end address. | 1146 | merge the DIMM size by program start/end address. |
1141 | */ | 1147 | */ |
@@ -1145,9 +1151,9 @@ static int pdc20621_prog_dimm0(struct ata_probe_ent *pe) | |||
1145 | data |= (((size / 16) - 1) << 16); | 1151 | data |= (((size / 16) - 1) << 16); |
1146 | data |= (0 << 23); | 1152 | data |= (0 << 23); |
1147 | data |= 8; | 1153 | data |= 8; |
1148 | writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); | 1154 | writel(data, mmio + PDC_DIMM0_CONTROL_OFFSET); |
1149 | readl(mmio + PDC_DIMM0_CONTROL_OFFSET); | 1155 | readl(mmio + PDC_DIMM0_CONTROL_OFFSET); |
1150 | return size; | 1156 | return size; |
1151 | } | 1157 | } |
1152 | 1158 | ||
1153 | 1159 | ||
@@ -1167,12 +1173,12 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) | |||
1167 | Refresh Enable (bit 17) | 1173 | Refresh Enable (bit 17) |
1168 | */ | 1174 | */ |
1169 | 1175 | ||
1170 | data = 0x022259F1; | 1176 | data = 0x022259F1; |
1171 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); | 1177 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); |
1172 | readl(mmio + PDC_SDRAM_CONTROL_OFFSET); | 1178 | readl(mmio + PDC_SDRAM_CONTROL_OFFSET); |
1173 | 1179 | ||
1174 | /* Turn on for ECC */ | 1180 | /* Turn on for ECC */ |
1175 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1181 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1176 | PDC_DIMM_SPD_TYPE, &spd0); | 1182 | PDC_DIMM_SPD_TYPE, &spd0); |
1177 | if (spd0 == 0x02) { | 1183 | if (spd0 == 0x02) { |
1178 | data |= (0x01 << 16); | 1184 | data |= (0x01 << 16); |
@@ -1186,22 +1192,22 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_probe_ent *pe) | |||
1186 | data |= (1<<19); | 1192 | data |= (1<<19); |
1187 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); | 1193 | writel(data, mmio + PDC_SDRAM_CONTROL_OFFSET); |
1188 | 1194 | ||
1189 | error = 1; | 1195 | error = 1; |
1190 | for (i = 1; i <= 10; i++) { /* polling ~5 secs */ | 1196 | for (i = 1; i <= 10; i++) { /* polling ~5 secs */ |
1191 | data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); | 1197 | data = readl(mmio + PDC_SDRAM_CONTROL_OFFSET); |
1192 | if (!(data & (1<<19))) { | 1198 | if (!(data & (1<<19))) { |
1193 | error = 0; | 1199 | error = 0; |
1194 | break; | 1200 | break; |
1195 | } | 1201 | } |
1196 | msleep(i*100); | 1202 | msleep(i*100); |
1197 | } | 1203 | } |
1198 | return error; | 1204 | return error; |
1199 | } | 1205 | } |
1200 | 1206 | ||
1201 | 1207 | ||
1202 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | 1208 | static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) |
1203 | { | 1209 | { |
1204 | int speed, size, length; | 1210 | int speed, size, length; |
1205 | u32 addr,spd0,pci_status; | 1211 | u32 addr,spd0,pci_status; |
1206 | u32 tmp=0; | 1212 | u32 tmp=0; |
1207 | u32 time_period=0; | 1213 | u32 time_period=0; |
@@ -1228,7 +1234,7 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1228 | /* Wait 3 seconds */ | 1234 | /* Wait 3 seconds */ |
1229 | msleep(3000); | 1235 | msleep(3000); |
1230 | 1236 | ||
1231 | /* | 1237 | /* |
1232 | When timer is enabled, counter is decreased every internal | 1238 | When timer is enabled, counter is decreased every internal |
1233 | clock cycle. | 1239 | clock cycle. |
1234 | */ | 1240 | */ |
@@ -1236,24 +1242,24 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1236 | tcount = readl(mmio + PDC_TIME_COUNTER); | 1242 | tcount = readl(mmio + PDC_TIME_COUNTER); |
1237 | VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount); | 1243 | VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount); |
1238 | 1244 | ||
1239 | /* | 1245 | /* |
1240 | If SX4 is on PCI-X bus, after 3 seconds, the timer counter | 1246 | If SX4 is on PCI-X bus, after 3 seconds, the timer counter |
1241 | register should be >= (0xffffffff - 3x10^8). | 1247 | register should be >= (0xffffffff - 3x10^8). |
1242 | */ | 1248 | */ |
1243 | if(tcount >= PCI_X_TCOUNT) { | 1249 | if(tcount >= PCI_X_TCOUNT) { |
1244 | ticks = (time_period - tcount); | 1250 | ticks = (time_period - tcount); |
1245 | VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks); | 1251 | VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks); |
1246 | 1252 | ||
1247 | clock = (ticks / 300000); | 1253 | clock = (ticks / 300000); |
1248 | VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock); | 1254 | VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock); |
1249 | 1255 | ||
1250 | clock = (clock * 33); | 1256 | clock = (clock * 33); |
1251 | VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock); | 1257 | VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock); |
1252 | 1258 | ||
1253 | /* PLL F Param (bit 22:16) */ | 1259 | /* PLL F Param (bit 22:16) */ |
1254 | fparam = (1400000 / clock) - 2; | 1260 | fparam = (1400000 / clock) - 2; |
1255 | VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam); | 1261 | VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam); |
1256 | 1262 | ||
1257 | /* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */ | 1263 | /* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */ |
1258 | pci_status = (0x8a001824 | (fparam << 16)); | 1264 | pci_status = (0x8a001824 | (fparam << 16)); |
1259 | } else | 1265 | } else |
@@ -1264,21 +1270,21 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1264 | writel(pci_status, mmio + PDC_CTL_STATUS); | 1270 | writel(pci_status, mmio + PDC_CTL_STATUS); |
1265 | readl(mmio + PDC_CTL_STATUS); | 1271 | readl(mmio + PDC_CTL_STATUS); |
1266 | 1272 | ||
1267 | /* | 1273 | /* |
1268 | Read SPD of DIMM by I2C interface, | 1274 | Read SPD of DIMM by I2C interface, |
1269 | and program the DIMM Module Controller. | 1275 | and program the DIMM Module Controller. |
1270 | */ | 1276 | */ |
1271 | if (!(speed = pdc20621_detect_dimm(pe))) { | 1277 | if (!(speed = pdc20621_detect_dimm(pe))) { |
1272 | printk(KERN_ERR "Detect Local DIMM Fail\n"); | 1278 | printk(KERN_ERR "Detect Local DIMM Fail\n"); |
1273 | return 1; /* DIMM error */ | 1279 | return 1; /* DIMM error */ |
1274 | } | 1280 | } |
1275 | VPRINTK("Local DIMM Speed = %d\n", speed); | 1281 | VPRINTK("Local DIMM Speed = %d\n", speed); |
1276 | 1282 | ||
1277 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ | 1283 | /* Programming DIMM0 Module Control Register (index_CID0:80h) */ |
1278 | size = pdc20621_prog_dimm0(pe); | 1284 | size = pdc20621_prog_dimm0(pe); |
1279 | VPRINTK("Local DIMM Size = %dMB\n",size); | 1285 | VPRINTK("Local DIMM Size = %dMB\n",size); |
1280 | 1286 | ||
1281 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ | 1287 | /* Programming DIMM Module Global Control Register (index_CID0:88h) */ |
1282 | if (pdc20621_prog_dimm_global(pe)) { | 1288 | if (pdc20621_prog_dimm_global(pe)) { |
1283 | printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); | 1289 | printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n"); |
1284 | return 1; | 1290 | return 1; |
@@ -1297,30 +1303,30 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) | |||
1297 | 1303 | ||
1298 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40); | 1304 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x10040, 40); |
1299 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); | 1305 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); |
1300 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1306 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1301 | test_parttern2[1], &(test_parttern2[2])); | 1307 | test_parttern2[1], &(test_parttern2[2])); |
1302 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040, | 1308 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x10040, |
1303 | 40); | 1309 | 40); |
1304 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1310 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1305 | test_parttern2[1], &(test_parttern2[2])); | 1311 | test_parttern2[1], &(test_parttern2[2])); |
1306 | 1312 | ||
1307 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40); | 1313 | pdc20621_put_to_dimm(pe, (void *) test_parttern1, 0x40, 40); |
1308 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); | 1314 | pdc20621_get_from_dimm(pe, (void *) test_parttern2, 0x40, 40); |
1309 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], | 1315 | printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0], |
1310 | test_parttern2[1], &(test_parttern2[2])); | 1316 | test_parttern2[1], &(test_parttern2[2])); |
1311 | } | 1317 | } |
1312 | #endif | 1318 | #endif |
1313 | 1319 | ||
1314 | /* ECC initiliazation. */ | 1320 | /* ECC initiliazation. */ |
1315 | 1321 | ||
1316 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, | 1322 | pdc20621_i2c_read(pe, PDC_DIMM0_SPD_DEV_ADDRESS, |
1317 | PDC_DIMM_SPD_TYPE, &spd0); | 1323 | PDC_DIMM_SPD_TYPE, &spd0); |
1318 | if (spd0 == 0x02) { | 1324 | if (spd0 == 0x02) { |
1319 | VPRINTK("Start ECC initialization\n"); | 1325 | VPRINTK("Start ECC initialization\n"); |
1320 | addr = 0; | 1326 | addr = 0; |
1321 | length = size * 1024 * 1024; | 1327 | length = size * 1024 * 1024; |
1322 | while (addr < length) { | 1328 | while (addr < length) { |
1323 | pdc20621_put_to_dimm(pe, (void *) &tmp, addr, | 1329 | pdc20621_put_to_dimm(pe, (void *) &tmp, addr, |
1324 | sizeof(u32)); | 1330 | sizeof(u32)); |
1325 | addr += sizeof(u32); | 1331 | addr += sizeof(u32); |
1326 | } | 1332 | } |
diff --git a/drivers/scsi/sata_uli.c b/drivers/scsi/sata_uli.c index a71fb54eebd3..eb202a73bc0e 100644 --- a/drivers/scsi/sata_uli.c +++ b/drivers/scsi/sata_uli.c | |||
@@ -214,7 +214,7 @@ static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
214 | rc = -ENOMEM; | 214 | rc = -ENOMEM; |
215 | goto err_out_regions; | 215 | goto err_out_regions; |
216 | } | 216 | } |
217 | 217 | ||
218 | switch (board_idx) { | 218 | switch (board_idx) { |
219 | case uli_5287: | 219 | case uli_5287: |
220 | probe_ent->port[0].scr_addr = ULI5287_BASE; | 220 | probe_ent->port[0].scr_addr = ULI5287_BASE; |
diff --git a/drivers/scsi/sata_via.c b/drivers/scsi/sata_via.c index f43183c19a12..feff10980487 100644 --- a/drivers/scsi/sata_via.c +++ b/drivers/scsi/sata_via.c | |||
@@ -347,7 +347,7 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) | |||
347 | probe_ent = vt6420_init_probe_ent(pdev); | 347 | probe_ent = vt6420_init_probe_ent(pdev); |
348 | else | 348 | else |
349 | probe_ent = vt6421_init_probe_ent(pdev); | 349 | probe_ent = vt6421_init_probe_ent(pdev); |
350 | 350 | ||
351 | if (!probe_ent) { | 351 | if (!probe_ent) { |
352 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", | 352 | printk(KERN_ERR DRV_NAME "(%s): out of memory\n", |
353 | pci_name(pdev)); | 353 | pci_name(pdev)); |
diff --git a/drivers/scsi/sata_vsc.c b/drivers/scsi/sata_vsc.c index c5e09dc6f3de..6f2562171be0 100644 --- a/drivers/scsi/sata_vsc.c +++ b/drivers/scsi/sata_vsc.c | |||
@@ -173,7 +173,8 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance, | |||
173 | struct ata_port *ap; | 173 | struct ata_port *ap; |
174 | 174 | ||
175 | ap = host_set->ports[i]; | 175 | ap = host_set->ports[i]; |
176 | if (ap && (!(ap->flags & ATA_FLAG_PORT_DISABLED))) { | 176 | if (ap && !(ap->flags & |
177 | (ATA_FLAG_PORT_DISABLED|ATA_FLAG_NOINTR))) { | ||
177 | struct ata_queued_cmd *qc; | 178 | struct ata_queued_cmd *qc; |
178 | 179 | ||
179 | qc = ata_qc_from_tag(ap, ap->active_tag); | 180 | qc = ata_qc_from_tag(ap, ap->active_tag); |
@@ -342,7 +343,7 @@ static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_d | |||
342 | 343 | ||
343 | pci_set_master(pdev); | 344 | pci_set_master(pdev); |
344 | 345 | ||
345 | /* | 346 | /* |
346 | * Config offset 0x98 is "Extended Control and Status Register 0" | 347 | * Config offset 0x98 is "Extended Control and Status Register 0" |
347 | * Default value is (1 << 28). All bits except bit 28 are reserved in | 348 | * Default value is (1 << 28). All bits except bit 28 are reserved in |
348 | * DPA mode. If bit 28 is set, LED 0 reflects all ports' activity. | 349 | * DPA mode. If bit 28 is set, LED 0 reflects all ports' activity. |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 51292f269ce5..e822ca0e97cf 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -2971,23 +2971,22 @@ static void * dev_seq_start(struct seq_file *s, loff_t *pos) | |||
2971 | { | 2971 | { |
2972 | struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); | 2972 | struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); |
2973 | 2973 | ||
2974 | s->private = it; | ||
2974 | if (! it) | 2975 | if (! it) |
2975 | return NULL; | 2976 | return NULL; |
2977 | |||
2976 | if (NULL == sg_dev_arr) | 2978 | if (NULL == sg_dev_arr) |
2977 | goto err1; | 2979 | return NULL; |
2978 | it->index = *pos; | 2980 | it->index = *pos; |
2979 | it->max = sg_last_dev(); | 2981 | it->max = sg_last_dev(); |
2980 | if (it->index >= it->max) | 2982 | if (it->index >= it->max) |
2981 | goto err1; | 2983 | return NULL; |
2982 | return it; | 2984 | return it; |
2983 | err1: | ||
2984 | kfree(it); | ||
2985 | return NULL; | ||
2986 | } | 2985 | } |
2987 | 2986 | ||
2988 | static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) | 2987 | static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) |
2989 | { | 2988 | { |
2990 | struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; | 2989 | struct sg_proc_deviter * it = s->private; |
2991 | 2990 | ||
2992 | *pos = ++it->index; | 2991 | *pos = ++it->index; |
2993 | return (it->index < it->max) ? it : NULL; | 2992 | return (it->index < it->max) ? it : NULL; |
@@ -2995,7 +2994,7 @@ static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) | |||
2995 | 2994 | ||
2996 | static void dev_seq_stop(struct seq_file *s, void *v) | 2995 | static void dev_seq_stop(struct seq_file *s, void *v) |
2997 | { | 2996 | { |
2998 | kfree (v); | 2997 | kfree(s->private); |
2999 | } | 2998 | } |
3000 | 2999 | ||
3001 | static int sg_proc_open_dev(struct inode *inode, struct file *file) | 3000 | static int sg_proc_open_dev(struct inode *inode, struct file *file) |
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 97034d3937fd..d5797618a3b9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig | |||
@@ -211,7 +211,7 @@ comment "Non-8250 serial port support" | |||
211 | 211 | ||
212 | config SERIAL_AMBA_PL010 | 212 | config SERIAL_AMBA_PL010 |
213 | tristate "ARM AMBA PL010 serial port support" | 213 | tristate "ARM AMBA PL010 serial port support" |
214 | depends on ARM_AMBA | 214 | depends on ARM_AMBA && (BROKEN || !ARCH_VERSATILE) |
215 | select SERIAL_CORE | 215 | select SERIAL_CORE |
216 | help | 216 | help |
217 | This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have | 217 | This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have |
@@ -819,7 +819,7 @@ config SERIAL_M32R_SIO_CONSOLE | |||
819 | 819 | ||
820 | config SERIAL_M32R_PLDSIO | 820 | config SERIAL_M32R_PLDSIO |
821 | bool "M32R SIO I/F on a PLD" | 821 | bool "M32R SIO I/F on a PLD" |
822 | depends on SERIAL_M32R_SIO=y | 822 | depends on SERIAL_M32R_SIO=y && (PLAT_OPSPUT || PALT_USRV || PLAT_M32700UT) |
823 | default n | 823 | default n |
824 | help | 824 | help |
825 | Say Y here if you want to use the M32R serial controller | 825 | Say Y here if you want to use the M32R serial controller |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index 0301feacbde4..9b50560b9d16 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -1123,7 +1123,7 @@ static int __init m32r_sio_console_setup(struct console *co, char *options) | |||
1123 | return uart_set_options(port, co, baud, parity, bits, flow); | 1123 | return uart_set_options(port, co, baud, parity, bits, flow); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | extern struct uart_driver m32r_sio_reg; | 1126 | static struct uart_driver m32r_sio_reg; |
1127 | static struct console m32r_sio_console = { | 1127 | static struct console m32r_sio_console = { |
1128 | .name = "ttyS", | 1128 | .name = "ttyS", |
1129 | .write = m32r_sio_console_write, | 1129 | .write = m32r_sio_console_write, |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 576f3b852fce..4528a00c45b0 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -1922,7 +1922,7 @@ static int genelink_rx_fixup (struct usbnet *dev, struct sk_buff *skb) | |||
1922 | 1922 | ||
1923 | // copy the packet data to the new skb | 1923 | // copy the packet data to the new skb |
1924 | memcpy(skb_put(gl_skb, size), packet->packet_data, size); | 1924 | memcpy(skb_put(gl_skb, size), packet->packet_data, size); |
1925 | skb_return (dev, skb); | 1925 | skb_return (dev, gl_skb); |
1926 | } | 1926 | } |
1927 | 1927 | ||
1928 | // advance to the next packet | 1928 | // advance to the next packet |
diff --git a/drivers/usb/net/zd1201.c b/drivers/usb/net/zd1201.c index 29cd801eb958..e32a80b39182 100644 --- a/drivers/usb/net/zd1201.c +++ b/drivers/usb/net/zd1201.c | |||
@@ -346,8 +346,7 @@ static void zd1201_usbrx(struct urb *urb, struct pt_regs *regs) | |||
346 | if (datalen<14) | 346 | if (datalen<14) |
347 | goto resubmit; | 347 | goto resubmit; |
348 | if ((seq & IEEE802_11_SCTL_FRAG) == 0) { | 348 | if ((seq & IEEE802_11_SCTL_FRAG) == 0) { |
349 | frag = kmalloc(sizeof(struct zd1201_frag*), | 349 | frag = kmalloc(sizeof(*frag), GFP_ATOMIC); |
350 | GFP_ATOMIC); | ||
351 | if (!frag) | 350 | if (!frag) |
352 | goto resubmit; | 351 | goto resubmit; |
353 | skb = dev_alloc_skb(IEEE802_11_DATA_LEN +14+2); | 352 | skb = dev_alloc_skb(IEEE802_11_DATA_LEN +14+2); |
diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index cbff98337aa6..5fe182d6e4ab 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig | |||
@@ -6,7 +6,7 @@ menu "Console display driver support" | |||
6 | 6 | ||
7 | config VGA_CONSOLE | 7 | config VGA_CONSOLE |
8 | bool "VGA text console" if EMBEDDED || !X86 | 8 | bool "VGA text console" if EMBEDDED || !X86 |
9 | depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC | 9 | depends on !ARCH_ACORN && !ARCH_EBSA110 && !4xx && !8xx && !SPARC32 && !SPARC64 && !M68K && !PARISC && !ARCH_VERSATILE |
10 | default y | 10 | default y |
11 | help | 11 | help |
12 | Saying Y here will allow you to use Linux in text mode through a | 12 | Saying Y here will allow you to use Linux in text mode through a |
diff --git a/drivers/video/radeonfb.c b/drivers/video/radeonfb.c index c46387024b1d..a78b9bd8f897 100644 --- a/drivers/video/radeonfb.c +++ b/drivers/video/radeonfb.c | |||
@@ -80,7 +80,7 @@ | |||
80 | #include <video/radeon.h> | 80 | #include <video/radeon.h> |
81 | #include <linux/radeonfb.h> | 81 | #include <linux/radeonfb.h> |
82 | 82 | ||
83 | #define DEBUG 1 | 83 | #define DEBUG 0 |
84 | 84 | ||
85 | #if DEBUG | 85 | #if DEBUG |
86 | #define RTRACE printk | 86 | #define RTRACE printk |
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c index bfc28abe1cb1..31ee06590de5 100644 --- a/fs/afs/mntpt.c +++ b/fs/afs/mntpt.c | |||
@@ -30,7 +30,7 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir, | |||
30 | struct dentry *dentry, | 30 | struct dentry *dentry, |
31 | struct nameidata *nd); | 31 | struct nameidata *nd); |
32 | static int afs_mntpt_open(struct inode *inode, struct file *file); | 32 | static int afs_mntpt_open(struct inode *inode, struct file *file); |
33 | static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd); | 33 | static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd); |
34 | 34 | ||
35 | struct file_operations afs_mntpt_file_operations = { | 35 | struct file_operations afs_mntpt_file_operations = { |
36 | .open = afs_mntpt_open, | 36 | .open = afs_mntpt_open, |
@@ -233,7 +233,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) | |||
233 | /* | 233 | /* |
234 | * follow a link from a mountpoint directory, thus causing it to be mounted | 234 | * follow a link from a mountpoint directory, thus causing it to be mounted |
235 | */ | 235 | */ |
236 | static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) | 236 | static void *afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) |
237 | { | 237 | { |
238 | struct vfsmount *newmnt; | 238 | struct vfsmount *newmnt; |
239 | struct dentry *old_dentry; | 239 | struct dentry *old_dentry; |
@@ -249,7 +249,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
249 | newmnt = afs_mntpt_do_automount(dentry); | 249 | newmnt = afs_mntpt_do_automount(dentry); |
250 | if (IS_ERR(newmnt)) { | 250 | if (IS_ERR(newmnt)) { |
251 | path_release(nd); | 251 | path_release(nd); |
252 | return PTR_ERR(newmnt); | 252 | return (void *)newmnt; |
253 | } | 253 | } |
254 | 254 | ||
255 | old_dentry = nd->dentry; | 255 | old_dentry = nd->dentry; |
@@ -267,7 +267,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
267 | } | 267 | } |
268 | 268 | ||
269 | kleave(" = %d", err); | 269 | kleave(" = %d", err); |
270 | return err; | 270 | return ERR_PTR(err); |
271 | } /* end afs_mntpt_follow_link() */ | 271 | } /* end afs_mntpt_follow_link() */ |
272 | 272 | ||
273 | /*****************************************************************************/ | 273 | /*****************************************************************************/ |
diff --git a/fs/autofs/symlink.c b/fs/autofs/symlink.c index f028396f1383..52e8772b066e 100644 --- a/fs/autofs/symlink.c +++ b/fs/autofs/symlink.c | |||
@@ -12,11 +12,12 @@ | |||
12 | 12 | ||
13 | #include "autofs_i.h" | 13 | #include "autofs_i.h" |
14 | 14 | ||
15 | static int autofs_follow_link(struct dentry *dentry, struct nameidata *nd) | 15 | /* Nothing to release.. */ |
16 | static void *autofs_follow_link(struct dentry *dentry, struct nameidata *nd) | ||
16 | { | 17 | { |
17 | char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; | 18 | char *s=((struct autofs_symlink *)dentry->d_inode->u.generic_ip)->data; |
18 | nd_set_link(nd, s); | 19 | nd_set_link(nd, s); |
19 | return 0; | 20 | return NULL; |
20 | } | 21 | } |
21 | 22 | ||
22 | struct inode_operations autofs_symlink_inode_operations = { | 23 | struct inode_operations autofs_symlink_inode_operations = { |
diff --git a/fs/autofs4/symlink.c b/fs/autofs4/symlink.c index c265a66edf0f..2ea2c98fd84b 100644 --- a/fs/autofs4/symlink.c +++ b/fs/autofs4/symlink.c | |||
@@ -12,11 +12,11 @@ | |||
12 | 12 | ||
13 | #include "autofs_i.h" | 13 | #include "autofs_i.h" |
14 | 14 | ||
15 | static int autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) | 15 | static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd) |
16 | { | 16 | { |
17 | struct autofs_info *ino = autofs4_dentry_ino(dentry); | 17 | struct autofs_info *ino = autofs4_dentry_ino(dentry); |
18 | nd_set_link(nd, (char *)ino->u.symlink); | 18 | nd_set_link(nd, (char *)ino->u.symlink); |
19 | return 0; | 19 | return NULL; |
20 | } | 20 | } |
21 | 21 | ||
22 | struct inode_operations autofs4_symlink_inode_operations = { | 22 | struct inode_operations autofs4_symlink_inode_operations = { |
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c index de5bb280a828..e0a6025f1d06 100644 --- a/fs/befs/linuxvfs.c +++ b/fs/befs/linuxvfs.c | |||
@@ -41,8 +41,8 @@ static struct inode *befs_alloc_inode(struct super_block *sb); | |||
41 | static void befs_destroy_inode(struct inode *inode); | 41 | static void befs_destroy_inode(struct inode *inode); |
42 | static int befs_init_inodecache(void); | 42 | static int befs_init_inodecache(void); |
43 | static void befs_destroy_inodecache(void); | 43 | static void befs_destroy_inodecache(void); |
44 | static int befs_follow_link(struct dentry *, struct nameidata *); | 44 | static void *befs_follow_link(struct dentry *, struct nameidata *); |
45 | static void befs_put_link(struct dentry *, struct nameidata *); | 45 | static void befs_put_link(struct dentry *, struct nameidata *, void *); |
46 | static int befs_utf2nls(struct super_block *sb, const char *in, int in_len, | 46 | static int befs_utf2nls(struct super_block *sb, const char *in, int in_len, |
47 | char **out, int *out_len); | 47 | char **out, int *out_len); |
48 | static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, | 48 | static int befs_nls2utf(struct super_block *sb, const char *in, int in_len, |
@@ -461,7 +461,7 @@ befs_destroy_inodecache(void) | |||
461 | * The data stream become link name. Unless the LONG_SYMLINK | 461 | * The data stream become link name. Unless the LONG_SYMLINK |
462 | * flag is set. | 462 | * flag is set. |
463 | */ | 463 | */ |
464 | static int | 464 | static void * |
465 | befs_follow_link(struct dentry *dentry, struct nameidata *nd) | 465 | befs_follow_link(struct dentry *dentry, struct nameidata *nd) |
466 | { | 466 | { |
467 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | 467 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); |
@@ -487,10 +487,10 @@ befs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
487 | } | 487 | } |
488 | 488 | ||
489 | nd_set_link(nd, link); | 489 | nd_set_link(nd, link); |
490 | return 0; | 490 | return NULL; |
491 | } | 491 | } |
492 | 492 | ||
493 | static void befs_put_link(struct dentry *dentry, struct nameidata *nd) | 493 | static void befs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
494 | { | 494 | { |
495 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); | 495 | befs_inode_info *befs_ino = BEFS_I(dentry->d_inode); |
496 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { | 496 | if (befs_ino->i_flags & BEFS_LONG_SYMLINK) { |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 78af5850c558..1fd21f66f243 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -83,8 +83,8 @@ extern int cifs_dir_notify(struct file *, unsigned long arg); | |||
83 | extern struct dentry_operations cifs_dentry_ops; | 83 | extern struct dentry_operations cifs_dentry_ops; |
84 | 84 | ||
85 | /* Functions related to symlinks */ | 85 | /* Functions related to symlinks */ |
86 | extern int cifs_follow_link(struct dentry *direntry, struct nameidata *nd); | 86 | extern void *cifs_follow_link(struct dentry *direntry, struct nameidata *nd); |
87 | extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd); | 87 | extern void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *); |
88 | extern int cifs_readlink(struct dentry *direntry, char __user *buffer, | 88 | extern int cifs_readlink(struct dentry *direntry, char __user *buffer, |
89 | int buflen); | 89 | int buflen); |
90 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, | 90 | extern int cifs_symlink(struct inode *inode, struct dentry *direntry, |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 30ab70ce5547..3497125189df 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -643,7 +643,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
643 | netfid, length, | 643 | netfid, length, |
644 | pfLock->fl_start, numUnlock, numLock, lockType, | 644 | pfLock->fl_start, numUnlock, numLock, lockType, |
645 | wait_flag); | 645 | wait_flag); |
646 | if (rc == 0 && (pfLock->fl_flags & FL_POSIX)) | 646 | if (pfLock->fl_flags & FL_POSIX) |
647 | posix_lock_file_wait(file, pfLock); | 647 | posix_lock_file_wait(file, pfLock); |
648 | FreeXid(xid); | 648 | FreeXid(xid); |
649 | return rc; | 649 | return rc; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index bde0fabfece0..ab925ef4f863 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -92,7 +92,7 @@ cifs_hl_exit: | |||
92 | return rc; | 92 | return rc; |
93 | } | 93 | } |
94 | 94 | ||
95 | int | 95 | void * |
96 | cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | 96 | cifs_follow_link(struct dentry *direntry, struct nameidata *nd) |
97 | { | 97 | { |
98 | struct inode *inode = direntry->d_inode; | 98 | struct inode *inode = direntry->d_inode; |
@@ -148,7 +148,7 @@ out: | |||
148 | out_no_free: | 148 | out_no_free: |
149 | FreeXid(xid); | 149 | FreeXid(xid); |
150 | nd_set_link(nd, target_path); | 150 | nd_set_link(nd, target_path); |
151 | return 0; | 151 | return NULL; /* No cookie */ |
152 | } | 152 | } |
153 | 153 | ||
154 | int | 154 | int |
@@ -330,7 +330,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
330 | return rc; | 330 | return rc; |
331 | } | 331 | } |
332 | 332 | ||
333 | void cifs_put_link(struct dentry *direntry, struct nameidata *nd) | 333 | void cifs_put_link(struct dentry *direntry, struct nameidata *nd, void *cookie) |
334 | { | 334 | { |
335 | char *p = nd_get_link(nd); | 335 | char *p = nd_get_link(nd); |
336 | if (!IS_ERR(p)) | 336 | if (!IS_ERR(p)) |
diff --git a/fs/devfs/base.c b/fs/devfs/base.c index 1ecfe1f184d4..8b679b67e5e0 100644 --- a/fs/devfs/base.c +++ b/fs/devfs/base.c | |||
@@ -2491,11 +2491,11 @@ static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode, | |||
2491 | return 0; | 2491 | return 0; |
2492 | } /* End Function devfs_mknod */ | 2492 | } /* End Function devfs_mknod */ |
2493 | 2493 | ||
2494 | static int devfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 2494 | static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
2495 | { | 2495 | { |
2496 | struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode); | 2496 | struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode); |
2497 | nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV)); | 2497 | nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV)); |
2498 | return 0; | 2498 | return NULL; |
2499 | } /* End Function devfs_follow_link */ | 2499 | } /* End Function devfs_follow_link */ |
2500 | 2500 | ||
2501 | static struct inode_operations devfs_iops = { | 2501 | static struct inode_operations devfs_iops = { |
diff --git a/fs/ext2/symlink.c b/fs/ext2/symlink.c index 9f7bac01d557..1e67d87cfa91 100644 --- a/fs/ext2/symlink.c +++ b/fs/ext2/symlink.c | |||
@@ -21,11 +21,11 @@ | |||
21 | #include "xattr.h" | 21 | #include "xattr.h" |
22 | #include <linux/namei.h> | 22 | #include <linux/namei.h> |
23 | 23 | ||
24 | static int ext2_follow_link(struct dentry *dentry, struct nameidata *nd) | 24 | static void *ext2_follow_link(struct dentry *dentry, struct nameidata *nd) |
25 | { | 25 | { |
26 | struct ext2_inode_info *ei = EXT2_I(dentry->d_inode); | 26 | struct ext2_inode_info *ei = EXT2_I(dentry->d_inode); |
27 | nd_set_link(nd, (char *)ei->i_data); | 27 | nd_set_link(nd, (char *)ei->i_data); |
28 | return 0; | 28 | return NULL; |
29 | } | 29 | } |
30 | 30 | ||
31 | struct inode_operations ext2_symlink_inode_operations = { | 31 | struct inode_operations ext2_symlink_inode_operations = { |
diff --git a/fs/ext3/symlink.c b/fs/ext3/symlink.c index 8c3e72818fb0..4f79122cde67 100644 --- a/fs/ext3/symlink.c +++ b/fs/ext3/symlink.c | |||
@@ -23,11 +23,11 @@ | |||
23 | #include <linux/namei.h> | 23 | #include <linux/namei.h> |
24 | #include "xattr.h" | 24 | #include "xattr.h" |
25 | 25 | ||
26 | static int ext3_follow_link(struct dentry *dentry, struct nameidata *nd) | 26 | static void * ext3_follow_link(struct dentry *dentry, struct nameidata *nd) |
27 | { | 27 | { |
28 | struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); | 28 | struct ext3_inode_info *ei = EXT3_I(dentry->d_inode); |
29 | nd_set_link(nd, (char*)ei->i_data); | 29 | nd_set_link(nd, (char*)ei->i_data); |
30 | return 0; | 30 | return NULL; |
31 | } | 31 | } |
32 | 32 | ||
33 | struct inode_operations ext3_symlink_inode_operations = { | 33 | struct inode_operations ext3_symlink_inode_operations = { |
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c index ac677ab262b2..d0401dc68d41 100644 --- a/fs/freevxfs/vxfs_immed.c +++ b/fs/freevxfs/vxfs_immed.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include "vxfs_inode.h" | 38 | #include "vxfs_inode.h" |
39 | 39 | ||
40 | 40 | ||
41 | static int vxfs_immed_follow_link(struct dentry *, struct nameidata *); | 41 | static void * vxfs_immed_follow_link(struct dentry *, struct nameidata *); |
42 | 42 | ||
43 | static int vxfs_immed_readpage(struct file *, struct page *); | 43 | static int vxfs_immed_readpage(struct file *, struct page *); |
44 | 44 | ||
@@ -72,12 +72,12 @@ struct address_space_operations vxfs_immed_aops = { | |||
72 | * Returns: | 72 | * Returns: |
73 | * Zero on success, else a negative error code. | 73 | * Zero on success, else a negative error code. |
74 | */ | 74 | */ |
75 | static int | 75 | static void * |
76 | vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) | 76 | vxfs_immed_follow_link(struct dentry *dp, struct nameidata *np) |
77 | { | 77 | { |
78 | struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); | 78 | struct vxfs_inode_info *vip = VXFS_INO(dp->d_inode); |
79 | nd_set_link(np, vip->vii_immed.vi_immed); | 79 | nd_set_link(np, vip->vii_immed.vi_immed); |
80 | return 0; | 80 | return NULL; |
81 | } | 81 | } |
82 | 82 | ||
83 | /** | 83 | /** |
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c index ff150fedb981..52930915bad8 100644 --- a/fs/hppfs/hppfs_kern.c +++ b/fs/hppfs/hppfs_kern.c | |||
@@ -38,7 +38,7 @@ struct hppfs_inode_info { | |||
38 | 38 | ||
39 | static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode) | 39 | static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode) |
40 | { | 40 | { |
41 | return(list_entry(inode, struct hppfs_inode_info, vfs_inode)); | 41 | return container_of(inode, struct hppfs_inode_info, vfs_inode); |
42 | } | 42 | } |
43 | 43 | ||
44 | #define HPPFS_SUPER_MAGIC 0xb00000ee | 44 | #define HPPFS_SUPER_MAGIC 0xb00000ee |
@@ -662,42 +662,36 @@ static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) | |||
662 | { | 662 | { |
663 | struct file *proc_file; | 663 | struct file *proc_file; |
664 | struct dentry *proc_dentry; | 664 | struct dentry *proc_dentry; |
665 | int (*readlink)(struct dentry *, char *, int); | 665 | int ret; |
666 | int err, n; | ||
667 | 666 | ||
668 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 667 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
669 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); | 668 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); |
670 | err = PTR_ERR(proc_dentry); | 669 | if (IS_ERR(proc_file)) |
671 | if(IS_ERR(proc_dentry)) | 670 | return PTR_ERR(proc_file); |
672 | return(err); | ||
673 | 671 | ||
674 | readlink = proc_dentry->d_inode->i_op->readlink; | 672 | ret = proc_dentry->d_inode->i_op->readlink(proc_dentry, buffer, buflen); |
675 | n = (*readlink)(proc_dentry, buffer, buflen); | ||
676 | 673 | ||
677 | fput(proc_file); | 674 | fput(proc_file); |
678 | 675 | ||
679 | return(n); | 676 | return ret; |
680 | } | 677 | } |
681 | 678 | ||
682 | static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 679 | static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
683 | { | 680 | { |
684 | struct file *proc_file; | 681 | struct file *proc_file; |
685 | struct dentry *proc_dentry; | 682 | struct dentry *proc_dentry; |
686 | int (*follow_link)(struct dentry *, struct nameidata *); | 683 | void *ret; |
687 | int err, n; | ||
688 | 684 | ||
689 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; | 685 | proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry; |
690 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); | 686 | proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY); |
691 | err = PTR_ERR(proc_dentry); | 687 | if (IS_ERR(proc_file)) |
692 | if(IS_ERR(proc_dentry)) | 688 | return proc_file; |
693 | return(err); | ||
694 | 689 | ||
695 | follow_link = proc_dentry->d_inode->i_op->follow_link; | 690 | ret = proc_dentry->d_inode->i_op->follow_link(proc_dentry, nd); |
696 | n = (*follow_link)(proc_dentry, nd); | ||
697 | 691 | ||
698 | fput(proc_file); | 692 | fput(proc_file); |
699 | 693 | ||
700 | return(n); | 694 | return ret; |
701 | } | 695 | } |
702 | 696 | ||
703 | static struct inode_operations hppfs_dir_iops = { | 697 | static struct inode_operations hppfs_dir_iops = { |
diff --git a/fs/inotify.c b/fs/inotify.c index 868901b1e779..2e4e2a57708c 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -353,7 +353,7 @@ static int inotify_dev_get_wd(struct inotify_device *dev, | |||
353 | do { | 353 | do { |
354 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) | 354 | if (unlikely(!idr_pre_get(&dev->idr, GFP_KERNEL))) |
355 | return -ENOSPC; | 355 | return -ENOSPC; |
356 | ret = idr_get_new_above(&dev->idr, watch, dev->last_wd, &watch->wd); | 356 | ret = idr_get_new_above(&dev->idr, watch, dev->last_wd+1, &watch->wd); |
357 | } while (ret == -EAGAIN); | 357 | } while (ret == -EAGAIN); |
358 | 358 | ||
359 | return ret; | 359 | return ret; |
diff --git a/fs/ioprio.c b/fs/ioprio.c index 97e1f088ba00..d1c1f2b2c9da 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -62,6 +62,8 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
62 | 62 | ||
63 | break; | 63 | break; |
64 | case IOPRIO_CLASS_IDLE: | 64 | case IOPRIO_CLASS_IDLE: |
65 | if (!capable(CAP_SYS_ADMIN)) | ||
66 | return -EPERM; | ||
65 | break; | 67 | break; |
66 | default: | 68 | default: |
67 | return -EINVAL; | 69 | return -EINVAL; |
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c index 65ab6b001dca..82ef484f5e12 100644 --- a/fs/jffs2/symlink.c +++ b/fs/jffs2/symlink.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <linux/namei.h> | 18 | #include <linux/namei.h> |
19 | #include "nodelist.h" | 19 | #include "nodelist.h" |
20 | 20 | ||
21 | static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); | 21 | static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); |
22 | 22 | ||
23 | struct inode_operations jffs2_symlink_inode_operations = | 23 | struct inode_operations jffs2_symlink_inode_operations = |
24 | { | 24 | { |
@@ -27,9 +27,10 @@ struct inode_operations jffs2_symlink_inode_operations = | |||
27 | .setattr = jffs2_setattr | 27 | .setattr = jffs2_setattr |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) | 30 | static void *jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) |
31 | { | 31 | { |
32 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); | 32 | struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode); |
33 | char *p = (char *)f->dents; | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * We don't acquire the f->sem mutex here since the only data we | 36 | * We don't acquire the f->sem mutex here since the only data we |
@@ -45,19 +46,20 @@ static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
45 | * nd_set_link() call. | 46 | * nd_set_link() call. |
46 | */ | 47 | */ |
47 | 48 | ||
48 | if (!f->dents) { | 49 | if (!p) { |
49 | printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); | 50 | printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n"); |
50 | return -EIO; | 51 | p = ERR_PTR(-EIO); |
52 | } else { | ||
53 | D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); | ||
51 | } | 54 | } |
52 | D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents)); | ||
53 | 55 | ||
54 | nd_set_link(nd, (char *)f->dents); | 56 | nd_set_link(nd, p); |
55 | 57 | ||
56 | /* | 58 | /* |
57 | * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe | 59 | * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe |
58 | * since the only way that may cause f->dents to be changed is iput() operation. | 60 | * since the only way that may cause f->dents to be changed is iput() operation. |
59 | * But VFS will not use f->dents after iput() has been called. | 61 | * But VFS will not use f->dents after iput() has been called. |
60 | */ | 62 | */ |
61 | return 0; | 63 | return NULL; |
62 | } | 64 | } |
63 | 65 | ||
diff --git a/fs/jfs/symlink.c b/fs/jfs/symlink.c index 287d8d6c3cfd..16477b3835e1 100644 --- a/fs/jfs/symlink.c +++ b/fs/jfs/symlink.c | |||
@@ -22,11 +22,11 @@ | |||
22 | #include "jfs_inode.h" | 22 | #include "jfs_inode.h" |
23 | #include "jfs_xattr.h" | 23 | #include "jfs_xattr.h" |
24 | 24 | ||
25 | static int jfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 25 | static void *jfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
26 | { | 26 | { |
27 | char *s = JFS_IP(dentry->d_inode)->i_inline; | 27 | char *s = JFS_IP(dentry->d_inode)->i_inline; |
28 | nd_set_link(nd, s); | 28 | nd_set_link(nd, s); |
29 | return 0; | 29 | return NULL; |
30 | } | 30 | } |
31 | 31 | ||
32 | struct inode_operations jfs_symlink_inode_operations = { | 32 | struct inode_operations jfs_symlink_inode_operations = { |
diff --git a/fs/namei.c b/fs/namei.c index b85f158aef0c..6ec1f0fefc5b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -501,6 +501,7 @@ struct path { | |||
501 | static inline int __do_follow_link(struct path *path, struct nameidata *nd) | 501 | static inline int __do_follow_link(struct path *path, struct nameidata *nd) |
502 | { | 502 | { |
503 | int error; | 503 | int error; |
504 | void *cookie; | ||
504 | struct dentry *dentry = path->dentry; | 505 | struct dentry *dentry = path->dentry; |
505 | 506 | ||
506 | touch_atime(path->mnt, dentry); | 507 | touch_atime(path->mnt, dentry); |
@@ -508,13 +509,15 @@ static inline int __do_follow_link(struct path *path, struct nameidata *nd) | |||
508 | 509 | ||
509 | if (path->mnt == nd->mnt) | 510 | if (path->mnt == nd->mnt) |
510 | mntget(path->mnt); | 511 | mntget(path->mnt); |
511 | error = dentry->d_inode->i_op->follow_link(dentry, nd); | 512 | cookie = dentry->d_inode->i_op->follow_link(dentry, nd); |
512 | if (!error) { | 513 | error = PTR_ERR(cookie); |
514 | if (!IS_ERR(cookie)) { | ||
513 | char *s = nd_get_link(nd); | 515 | char *s = nd_get_link(nd); |
516 | error = 0; | ||
514 | if (s) | 517 | if (s) |
515 | error = __vfs_follow_link(nd, s); | 518 | error = __vfs_follow_link(nd, s); |
516 | if (dentry->d_inode->i_op->put_link) | 519 | if (dentry->d_inode->i_op->put_link) |
517 | dentry->d_inode->i_op->put_link(dentry, nd); | 520 | dentry->d_inode->i_op->put_link(dentry, nd, cookie); |
518 | } | 521 | } |
519 | dput(dentry); | 522 | dput(dentry); |
520 | mntput(path->mnt); | 523 | mntput(path->mnt); |
@@ -2344,15 +2347,17 @@ out: | |||
2344 | int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) | 2347 | int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) |
2345 | { | 2348 | { |
2346 | struct nameidata nd; | 2349 | struct nameidata nd; |
2347 | int res; | 2350 | void *cookie; |
2351 | |||
2348 | nd.depth = 0; | 2352 | nd.depth = 0; |
2349 | res = dentry->d_inode->i_op->follow_link(dentry, &nd); | 2353 | cookie = dentry->d_inode->i_op->follow_link(dentry, &nd); |
2350 | if (!res) { | 2354 | if (!IS_ERR(cookie)) { |
2351 | res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); | 2355 | int res = vfs_readlink(dentry, buffer, buflen, nd_get_link(&nd)); |
2352 | if (dentry->d_inode->i_op->put_link) | 2356 | if (dentry->d_inode->i_op->put_link) |
2353 | dentry->d_inode->i_op->put_link(dentry, &nd); | 2357 | dentry->d_inode->i_op->put_link(dentry, &nd, cookie); |
2358 | cookie = ERR_PTR(res); | ||
2354 | } | 2359 | } |
2355 | return res; | 2360 | return PTR_ERR(cookie); |
2356 | } | 2361 | } |
2357 | 2362 | ||
2358 | int vfs_follow_link(struct nameidata *nd, const char *link) | 2363 | int vfs_follow_link(struct nameidata *nd, const char *link) |
@@ -2395,23 +2400,20 @@ int page_readlink(struct dentry *dentry, char __user *buffer, int buflen) | |||
2395 | return res; | 2400 | return res; |
2396 | } | 2401 | } |
2397 | 2402 | ||
2398 | int page_follow_link_light(struct dentry *dentry, struct nameidata *nd) | 2403 | void *page_follow_link_light(struct dentry *dentry, struct nameidata *nd) |
2399 | { | 2404 | { |
2400 | struct page *page; | 2405 | struct page *page = NULL; |
2401 | nd_set_link(nd, page_getlink(dentry, &page)); | 2406 | nd_set_link(nd, page_getlink(dentry, &page)); |
2402 | return 0; | 2407 | return page; |
2403 | } | 2408 | } |
2404 | 2409 | ||
2405 | void page_put_link(struct dentry *dentry, struct nameidata *nd) | 2410 | void page_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) |
2406 | { | 2411 | { |
2407 | if (!IS_ERR(nd_get_link(nd))) { | 2412 | struct page *page = cookie; |
2408 | struct page *page; | 2413 | |
2409 | page = find_get_page(dentry->d_inode->i_mapping, 0); | 2414 | if (page) { |
2410 | if (!page) | ||
2411 | BUG(); | ||
2412 | kunmap(page); | 2415 | kunmap(page); |
2413 | page_cache_release(page); | 2416 | page_cache_release(page); |
2414 | page_cache_release(page); | ||
2415 | } | 2417 | } |
2416 | } | 2418 | } |
2417 | 2419 | ||
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b38a57e78a63..2df639f143e8 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -182,14 +182,16 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page) | |||
182 | /* We requested READDIRPLUS, but the server doesn't grok it */ | 182 | /* We requested READDIRPLUS, but the server doesn't grok it */ |
183 | if (error == -ENOTSUPP && desc->plus) { | 183 | if (error == -ENOTSUPP && desc->plus) { |
184 | NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; | 184 | NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; |
185 | NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; | 185 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); |
186 | desc->plus = 0; | 186 | desc->plus = 0; |
187 | goto again; | 187 | goto again; |
188 | } | 188 | } |
189 | goto error; | 189 | goto error; |
190 | } | 190 | } |
191 | SetPageUptodate(page); | 191 | SetPageUptodate(page); |
192 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; | 192 | spin_lock(&inode->i_lock); |
193 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
194 | spin_unlock(&inode->i_lock); | ||
193 | /* Ensure consistent page alignment of the data. | 195 | /* Ensure consistent page alignment of the data. |
194 | * Note: assumes we have exclusive access to this mapping either | 196 | * Note: assumes we have exclusive access to this mapping either |
195 | * through inode->i_sem or some other mechanism. | 197 | * through inode->i_sem or some other mechanism. |
@@ -462,7 +464,9 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
462 | page, | 464 | page, |
463 | NFS_SERVER(inode)->dtsize, | 465 | NFS_SERVER(inode)->dtsize, |
464 | desc->plus); | 466 | desc->plus); |
465 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; | 467 | spin_lock(&inode->i_lock); |
468 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
469 | spin_unlock(&inode->i_lock); | ||
466 | desc->page = page; | 470 | desc->page = page; |
467 | desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ | 471 | desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ |
468 | if (desc->error >= 0) { | 472 | if (desc->error >= 0) { |
@@ -545,7 +549,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
545 | break; | 549 | break; |
546 | } | 550 | } |
547 | if (res == -ETOOSMALL && desc->plus) { | 551 | if (res == -ETOOSMALL && desc->plus) { |
548 | NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; | 552 | clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); |
549 | nfs_zap_caches(inode); | 553 | nfs_zap_caches(inode); |
550 | desc->plus = 0; | 554 | desc->plus = 0; |
551 | desc->entry->eof = 0; | 555 | desc->entry->eof = 0; |
@@ -608,7 +612,7 @@ static inline int nfs_check_verifier(struct inode *dir, struct dentry *dentry) | |||
608 | { | 612 | { |
609 | if (IS_ROOT(dentry)) | 613 | if (IS_ROOT(dentry)) |
610 | return 1; | 614 | return 1; |
611 | if ((NFS_FLAGS(dir) & NFS_INO_INVALID_ATTR) != 0 | 615 | if ((NFS_I(dir)->cache_validity & NFS_INO_INVALID_ATTR) != 0 |
612 | || nfs_attribute_timeout(dir)) | 616 | || nfs_attribute_timeout(dir)) |
613 | return 0; | 617 | return 0; |
614 | return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata); | 618 | return nfs_verify_change_attribute(dir, (unsigned long)dentry->d_fsdata); |
@@ -935,6 +939,7 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
935 | error = nfs_revalidate_inode(NFS_SERVER(dir), dir); | 939 | error = nfs_revalidate_inode(NFS_SERVER(dir), dir); |
936 | if (error < 0) { | 940 | if (error < 0) { |
937 | res = ERR_PTR(error); | 941 | res = ERR_PTR(error); |
942 | unlock_kernel(); | ||
938 | goto out; | 943 | goto out; |
939 | } | 944 | } |
940 | 945 | ||
@@ -1575,11 +1580,12 @@ out: | |||
1575 | 1580 | ||
1576 | int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) | 1581 | int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs_access_entry *res) |
1577 | { | 1582 | { |
1578 | struct nfs_access_entry *cache = &NFS_I(inode)->cache_access; | 1583 | struct nfs_inode *nfsi = NFS_I(inode); |
1584 | struct nfs_access_entry *cache = &nfsi->cache_access; | ||
1579 | 1585 | ||
1580 | if (cache->cred != cred | 1586 | if (cache->cred != cred |
1581 | || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) | 1587 | || time_after(jiffies, cache->jiffies + NFS_ATTRTIMEO(inode)) |
1582 | || (NFS_FLAGS(inode) & NFS_INO_INVALID_ACCESS)) | 1588 | || (nfsi->cache_validity & NFS_INO_INVALID_ACCESS)) |
1583 | return -ENOENT; | 1589 | return -ENOENT; |
1584 | memcpy(res, cache, sizeof(*res)); | 1590 | memcpy(res, cache, sizeof(*res)); |
1585 | return 0; | 1591 | return 0; |
@@ -1587,14 +1593,18 @@ int nfs_access_get_cached(struct inode *inode, struct rpc_cred *cred, struct nfs | |||
1587 | 1593 | ||
1588 | void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) | 1594 | void nfs_access_add_cache(struct inode *inode, struct nfs_access_entry *set) |
1589 | { | 1595 | { |
1590 | struct nfs_access_entry *cache = &NFS_I(inode)->cache_access; | 1596 | struct nfs_inode *nfsi = NFS_I(inode); |
1597 | struct nfs_access_entry *cache = &nfsi->cache_access; | ||
1591 | 1598 | ||
1592 | if (cache->cred != set->cred) { | 1599 | if (cache->cred != set->cred) { |
1593 | if (cache->cred) | 1600 | if (cache->cred) |
1594 | put_rpccred(cache->cred); | 1601 | put_rpccred(cache->cred); |
1595 | cache->cred = get_rpccred(set->cred); | 1602 | cache->cred = get_rpccred(set->cred); |
1596 | } | 1603 | } |
1597 | NFS_FLAGS(inode) &= ~NFS_INO_INVALID_ACCESS; | 1604 | /* FIXME: replace current access_cache BKL reliance with inode->i_lock */ |
1605 | spin_lock(&inode->i_lock); | ||
1606 | nfsi->cache_validity &= ~NFS_INO_INVALID_ACCESS; | ||
1607 | spin_unlock(&inode->i_lock); | ||
1598 | cache->jiffies = set->jiffies; | 1608 | cache->jiffies = set->jiffies; |
1599 | cache->mask = set->mask; | 1609 | cache->mask = set->mask; |
1600 | } | 1610 | } |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 5621ba9885f4..f6b9eda925c5 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -134,9 +134,10 @@ nfs_file_release(struct inode *inode, struct file *filp) | |||
134 | */ | 134 | */ |
135 | static int nfs_revalidate_file(struct inode *inode, struct file *filp) | 135 | static int nfs_revalidate_file(struct inode *inode, struct file *filp) |
136 | { | 136 | { |
137 | struct nfs_inode *nfsi = NFS_I(inode); | ||
137 | int retval = 0; | 138 | int retval = 0; |
138 | 139 | ||
139 | if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode)) | 140 | if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode)) |
140 | retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode); | 141 | retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode); |
141 | nfs_revalidate_mapping(inode, filp->f_mapping); | 142 | nfs_revalidate_mapping(inode, filp->f_mapping); |
142 | return 0; | 143 | return 0; |
@@ -164,7 +165,7 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) | |||
164 | goto force_reval; | 165 | goto force_reval; |
165 | if (nfsi->npages != 0) | 166 | if (nfsi->npages != 0) |
166 | return 0; | 167 | return 0; |
167 | if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode)) | 168 | if (!(nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode)) |
168 | return 0; | 169 | return 0; |
169 | force_reval: | 170 | force_reval: |
170 | return __nfs_revalidate_inode(server, inode); | 171 | return __nfs_revalidate_inode(server, inode); |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index bb7ca022bcb2..541b418327c8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -615,14 +615,18 @@ nfs_zap_caches(struct inode *inode) | |||
615 | struct nfs_inode *nfsi = NFS_I(inode); | 615 | struct nfs_inode *nfsi = NFS_I(inode); |
616 | int mode = inode->i_mode; | 616 | int mode = inode->i_mode; |
617 | 617 | ||
618 | spin_lock(&inode->i_lock); | ||
619 | |||
618 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); | 620 | NFS_ATTRTIMEO(inode) = NFS_MINATTRTIMEO(inode); |
619 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; | 621 | NFS_ATTRTIMEO_UPDATE(inode) = jiffies; |
620 | 622 | ||
621 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); | 623 | memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); |
622 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) | 624 | if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) |
623 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 625 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
624 | else | 626 | else |
625 | nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; | 627 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; |
628 | |||
629 | spin_unlock(&inode->i_lock); | ||
626 | } | 630 | } |
627 | 631 | ||
628 | static void nfs_zap_acl_cache(struct inode *inode) | 632 | static void nfs_zap_acl_cache(struct inode *inode) |
@@ -632,7 +636,9 @@ static void nfs_zap_acl_cache(struct inode *inode) | |||
632 | clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache; | 636 | clear_acl_cache = NFS_PROTO(inode)->clear_acl_cache; |
633 | if (clear_acl_cache != NULL) | 637 | if (clear_acl_cache != NULL) |
634 | clear_acl_cache(inode); | 638 | clear_acl_cache(inode); |
635 | NFS_I(inode)->flags &= ~NFS_INO_INVALID_ACL; | 639 | spin_lock(&inode->i_lock); |
640 | NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL; | ||
641 | spin_unlock(&inode->i_lock); | ||
636 | } | 642 | } |
637 | 643 | ||
638 | /* | 644 | /* |
@@ -739,7 +745,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
739 | inode->i_fop = &nfs_dir_operations; | 745 | inode->i_fop = &nfs_dir_operations; |
740 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) | 746 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) |
741 | && fattr->size <= NFS_LIMIT_READDIRPLUS) | 747 | && fattr->size <= NFS_LIMIT_READDIRPLUS) |
742 | NFS_FLAGS(inode) |= NFS_INO_ADVISE_RDPLUS; | 748 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); |
743 | } else if (S_ISLNK(inode->i_mode)) | 749 | } else if (S_ISLNK(inode->i_mode)) |
744 | inode->i_op = &nfs_symlink_inode_operations; | 750 | inode->i_op = &nfs_symlink_inode_operations; |
745 | else | 751 | else |
@@ -841,7 +847,9 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) | |||
841 | inode->i_uid = attr->ia_uid; | 847 | inode->i_uid = attr->ia_uid; |
842 | if ((attr->ia_valid & ATTR_GID) != 0) | 848 | if ((attr->ia_valid & ATTR_GID) != 0) |
843 | inode->i_gid = attr->ia_gid; | 849 | inode->i_gid = attr->ia_gid; |
844 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 850 | spin_lock(&inode->i_lock); |
851 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | ||
852 | spin_unlock(&inode->i_lock); | ||
845 | } | 853 | } |
846 | if ((attr->ia_valid & ATTR_SIZE) != 0) { | 854 | if ((attr->ia_valid & ATTR_SIZE) != 0) { |
847 | inode->i_size = attr->ia_size; | 855 | inode->i_size = attr->ia_size; |
@@ -849,31 +857,47 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr) | |||
849 | } | 857 | } |
850 | } | 858 | } |
851 | 859 | ||
860 | static int nfs_wait_schedule(void *word) | ||
861 | { | ||
862 | if (signal_pending(current)) | ||
863 | return -ERESTARTSYS; | ||
864 | schedule(); | ||
865 | return 0; | ||
866 | } | ||
867 | |||
852 | /* | 868 | /* |
853 | * Wait for the inode to get unlocked. | 869 | * Wait for the inode to get unlocked. |
854 | * (Used for NFS_INO_LOCKED and NFS_INO_REVALIDATING). | ||
855 | */ | 870 | */ |
856 | static int | 871 | static int nfs_wait_on_inode(struct inode *inode) |
857 | nfs_wait_on_inode(struct inode *inode, int flag) | ||
858 | { | 872 | { |
859 | struct rpc_clnt *clnt = NFS_CLIENT(inode); | 873 | struct rpc_clnt *clnt = NFS_CLIENT(inode); |
860 | struct nfs_inode *nfsi = NFS_I(inode); | 874 | struct nfs_inode *nfsi = NFS_I(inode); |
861 | 875 | sigset_t oldmask; | |
862 | int error; | 876 | int error; |
863 | if (!(NFS_FLAGS(inode) & flag)) | 877 | |
864 | return 0; | ||
865 | atomic_inc(&inode->i_count); | 878 | atomic_inc(&inode->i_count); |
866 | error = nfs_wait_event(clnt, nfsi->nfs_i_wait, | 879 | rpc_clnt_sigmask(clnt, &oldmask); |
867 | !(NFS_FLAGS(inode) & flag)); | 880 | error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING, |
881 | nfs_wait_schedule, TASK_INTERRUPTIBLE); | ||
882 | rpc_clnt_sigunmask(clnt, &oldmask); | ||
868 | iput(inode); | 883 | iput(inode); |
884 | |||
869 | return error; | 885 | return error; |
870 | } | 886 | } |
871 | 887 | ||
888 | static void nfs_wake_up_inode(struct inode *inode) | ||
889 | { | ||
890 | struct nfs_inode *nfsi = NFS_I(inode); | ||
891 | |||
892 | clear_bit(NFS_INO_REVALIDATING, &nfsi->flags); | ||
893 | smp_mb__after_clear_bit(); | ||
894 | wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING); | ||
895 | } | ||
896 | |||
872 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 897 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) |
873 | { | 898 | { |
874 | struct inode *inode = dentry->d_inode; | 899 | struct inode *inode = dentry->d_inode; |
875 | struct nfs_inode *nfsi = NFS_I(inode); | 900 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
876 | int need_atime = nfsi->flags & NFS_INO_INVALID_ATIME; | ||
877 | int err; | 901 | int err; |
878 | 902 | ||
879 | if (__IS_FLG(inode, MS_NOATIME)) | 903 | if (__IS_FLG(inode, MS_NOATIME)) |
@@ -1019,7 +1043,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1019 | struct nfs_fattr fattr; | 1043 | struct nfs_fattr fattr; |
1020 | struct nfs_inode *nfsi = NFS_I(inode); | 1044 | struct nfs_inode *nfsi = NFS_I(inode); |
1021 | unsigned long verifier; | 1045 | unsigned long verifier; |
1022 | unsigned int flags; | 1046 | unsigned long cache_validity; |
1023 | 1047 | ||
1024 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", | 1048 | dfprintk(PAGECACHE, "NFS: revalidating (%s/%Ld)\n", |
1025 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); | 1049 | inode->i_sb->s_id, (long long)NFS_FILEID(inode)); |
@@ -1030,18 +1054,19 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1030 | if (NFS_STALE(inode)) | 1054 | if (NFS_STALE(inode)) |
1031 | goto out_nowait; | 1055 | goto out_nowait; |
1032 | 1056 | ||
1033 | while (NFS_REVALIDATING(inode)) { | 1057 | status = nfs_wait_on_inode(inode); |
1034 | status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING); | 1058 | if (status < 0) |
1035 | if (status < 0) | 1059 | goto out; |
1036 | goto out_nowait; | 1060 | if (NFS_STALE(inode)) { |
1037 | if (NFS_ATTRTIMEO(inode) == 0) | 1061 | status = -ESTALE; |
1038 | continue; | 1062 | /* Do we trust the cached ESTALE? */ |
1039 | if (NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) | 1063 | if (NFS_ATTRTIMEO(inode) != 0) { |
1040 | continue; | 1064 | if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) { |
1041 | status = NFS_STALE(inode) ? -ESTALE : 0; | 1065 | /* no */ |
1042 | goto out_nowait; | 1066 | } else |
1067 | goto out; | ||
1068 | } | ||
1043 | } | 1069 | } |
1044 | NFS_FLAGS(inode) |= NFS_INO_REVALIDATING; | ||
1045 | 1070 | ||
1046 | /* Protect against RPC races by saving the change attribute */ | 1071 | /* Protect against RPC races by saving the change attribute */ |
1047 | verifier = nfs_save_change_attribute(inode); | 1072 | verifier = nfs_save_change_attribute(inode); |
@@ -1053,7 +1078,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1053 | if (status == -ESTALE) { | 1078 | if (status == -ESTALE) { |
1054 | nfs_zap_caches(inode); | 1079 | nfs_zap_caches(inode); |
1055 | if (!S_ISDIR(inode->i_mode)) | 1080 | if (!S_ISDIR(inode->i_mode)) |
1056 | NFS_FLAGS(inode) |= NFS_INO_STALE; | 1081 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); |
1057 | } | 1082 | } |
1058 | goto out; | 1083 | goto out; |
1059 | } | 1084 | } |
@@ -1065,25 +1090,30 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1065 | (long long)NFS_FILEID(inode), status); | 1090 | (long long)NFS_FILEID(inode), status); |
1066 | goto out; | 1091 | goto out; |
1067 | } | 1092 | } |
1068 | flags = nfsi->flags; | 1093 | spin_lock(&inode->i_lock); |
1069 | nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE; | 1094 | cache_validity = nfsi->cache_validity; |
1095 | nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE; | ||
1096 | |||
1070 | /* | 1097 | /* |
1071 | * We may need to keep the attributes marked as invalid if | 1098 | * We may need to keep the attributes marked as invalid if |
1072 | * we raced with nfs_end_attr_update(). | 1099 | * we raced with nfs_end_attr_update(). |
1073 | */ | 1100 | */ |
1074 | if (verifier == nfsi->cache_change_attribute) | 1101 | if (verifier == nfsi->cache_change_attribute) |
1075 | nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); | 1102 | nfsi->cache_validity &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); |
1076 | /* Do the page cache invalidation */ | 1103 | spin_unlock(&inode->i_lock); |
1104 | |||
1077 | nfs_revalidate_mapping(inode, inode->i_mapping); | 1105 | nfs_revalidate_mapping(inode, inode->i_mapping); |
1078 | if (flags & NFS_INO_INVALID_ACL) | 1106 | |
1107 | if (cache_validity & NFS_INO_INVALID_ACL) | ||
1079 | nfs_zap_acl_cache(inode); | 1108 | nfs_zap_acl_cache(inode); |
1109 | |||
1080 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", | 1110 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", |
1081 | inode->i_sb->s_id, | 1111 | inode->i_sb->s_id, |
1082 | (long long)NFS_FILEID(inode)); | 1112 | (long long)NFS_FILEID(inode)); |
1083 | 1113 | ||
1084 | out: | 1114 | out: |
1085 | NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; | 1115 | nfs_wake_up_inode(inode); |
1086 | wake_up(&nfsi->nfs_i_wait); | 1116 | |
1087 | out_nowait: | 1117 | out_nowait: |
1088 | unlock_kernel(); | 1118 | unlock_kernel(); |
1089 | return status; | 1119 | return status; |
@@ -1107,7 +1137,7 @@ int nfs_attribute_timeout(struct inode *inode) | |||
1107 | */ | 1137 | */ |
1108 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 1138 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) |
1109 | { | 1139 | { |
1110 | if (!(NFS_FLAGS(inode) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) | 1140 | if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) |
1111 | && !nfs_attribute_timeout(inode)) | 1141 | && !nfs_attribute_timeout(inode)) |
1112 | return NFS_STALE(inode) ? -ESTALE : 0; | 1142 | return NFS_STALE(inode) ? -ESTALE : 0; |
1113 | return __nfs_revalidate_inode(server, inode); | 1143 | return __nfs_revalidate_inode(server, inode); |
@@ -1122,19 +1152,23 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
1122 | { | 1152 | { |
1123 | struct nfs_inode *nfsi = NFS_I(inode); | 1153 | struct nfs_inode *nfsi = NFS_I(inode); |
1124 | 1154 | ||
1125 | if (nfsi->flags & NFS_INO_INVALID_DATA) { | 1155 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { |
1126 | if (S_ISREG(inode->i_mode)) { | 1156 | if (S_ISREG(inode->i_mode)) { |
1127 | if (filemap_fdatawrite(mapping) == 0) | 1157 | if (filemap_fdatawrite(mapping) == 0) |
1128 | filemap_fdatawait(mapping); | 1158 | filemap_fdatawait(mapping); |
1129 | nfs_wb_all(inode); | 1159 | nfs_wb_all(inode); |
1130 | } | 1160 | } |
1131 | invalidate_inode_pages2(mapping); | 1161 | invalidate_inode_pages2(mapping); |
1132 | nfsi->flags &= ~NFS_INO_INVALID_DATA; | 1162 | |
1163 | spin_lock(&inode->i_lock); | ||
1164 | nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; | ||
1133 | if (S_ISDIR(inode->i_mode)) { | 1165 | if (S_ISDIR(inode->i_mode)) { |
1134 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); | 1166 | memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); |
1135 | /* This ensures we revalidate child dentries */ | 1167 | /* This ensures we revalidate child dentries */ |
1136 | nfsi->cache_change_attribute++; | 1168 | nfsi->cache_change_attribute++; |
1137 | } | 1169 | } |
1170 | spin_unlock(&inode->i_lock); | ||
1171 | |||
1138 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", | 1172 | dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", |
1139 | inode->i_sb->s_id, | 1173 | inode->i_sb->s_id, |
1140 | (long long)NFS_FILEID(inode)); | 1174 | (long long)NFS_FILEID(inode)); |
@@ -1164,10 +1198,12 @@ void nfs_end_data_update(struct inode *inode) | |||
1164 | 1198 | ||
1165 | if (!nfs_have_delegation(inode, FMODE_READ)) { | 1199 | if (!nfs_have_delegation(inode, FMODE_READ)) { |
1166 | /* Mark the attribute cache for revalidation */ | 1200 | /* Mark the attribute cache for revalidation */ |
1167 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1201 | spin_lock(&inode->i_lock); |
1202 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; | ||
1168 | /* Directories and symlinks: invalidate page cache too */ | 1203 | /* Directories and symlinks: invalidate page cache too */ |
1169 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) | 1204 | if (S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)) |
1170 | nfsi->flags |= NFS_INO_INVALID_DATA; | 1205 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
1206 | spin_unlock(&inode->i_lock); | ||
1171 | } | 1207 | } |
1172 | nfsi->cache_change_attribute ++; | 1208 | nfsi->cache_change_attribute ++; |
1173 | atomic_dec(&nfsi->data_updates); | 1209 | atomic_dec(&nfsi->data_updates); |
@@ -1192,6 +1228,8 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1192 | if (nfs_have_delegation(inode, FMODE_READ)) | 1228 | if (nfs_have_delegation(inode, FMODE_READ)) |
1193 | return 0; | 1229 | return 0; |
1194 | 1230 | ||
1231 | spin_lock(&inode->i_lock); | ||
1232 | |||
1195 | /* Are we in the process of updating data on the server? */ | 1233 | /* Are we in the process of updating data on the server? */ |
1196 | data_unstable = nfs_caches_unstable(inode); | 1234 | data_unstable = nfs_caches_unstable(inode); |
1197 | 1235 | ||
@@ -1200,19 +1238,23 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1200 | && nfsi->change_attr == fattr->pre_change_attr) | 1238 | && nfsi->change_attr == fattr->pre_change_attr) |
1201 | nfsi->change_attr = fattr->change_attr; | 1239 | nfsi->change_attr = fattr->change_attr; |
1202 | if (nfsi->change_attr != fattr->change_attr) { | 1240 | if (nfsi->change_attr != fattr->change_attr) { |
1203 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1241 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
1204 | if (!data_unstable) | 1242 | if (!data_unstable) |
1205 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; | 1243 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; |
1206 | } | 1244 | } |
1207 | } | 1245 | } |
1208 | 1246 | ||
1209 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) | 1247 | if ((fattr->valid & NFS_ATTR_FATTR) == 0) { |
1248 | spin_unlock(&inode->i_lock); | ||
1210 | return 0; | 1249 | return 0; |
1250 | } | ||
1211 | 1251 | ||
1212 | /* Has the inode gone and changed behind our back? */ | 1252 | /* Has the inode gone and changed behind our back? */ |
1213 | if (nfsi->fileid != fattr->fileid | 1253 | if (nfsi->fileid != fattr->fileid |
1214 | || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) | 1254 | || (inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { |
1255 | spin_unlock(&inode->i_lock); | ||
1215 | return -EIO; | 1256 | return -EIO; |
1257 | } | ||
1216 | 1258 | ||
1217 | cur_size = i_size_read(inode); | 1259 | cur_size = i_size_read(inode); |
1218 | new_isize = nfs_size_to_loff_t(fattr->size); | 1260 | new_isize = nfs_size_to_loff_t(fattr->size); |
@@ -1227,30 +1269,31 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1227 | 1269 | ||
1228 | /* Verify a few of the more important attributes */ | 1270 | /* Verify a few of the more important attributes */ |
1229 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { | 1271 | if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { |
1230 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1272 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
1231 | if (!data_unstable) | 1273 | if (!data_unstable) |
1232 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; | 1274 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; |
1233 | } | 1275 | } |
1234 | if (cur_size != new_isize) { | 1276 | if (cur_size != new_isize) { |
1235 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1277 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
1236 | if (nfsi->npages == 0) | 1278 | if (nfsi->npages == 0) |
1237 | nfsi->flags |= NFS_INO_REVAL_PAGECACHE; | 1279 | nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE; |
1238 | } | 1280 | } |
1239 | 1281 | ||
1240 | /* Have any file permissions changed? */ | 1282 | /* Have any file permissions changed? */ |
1241 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) | 1283 | if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) |
1242 | || inode->i_uid != fattr->uid | 1284 | || inode->i_uid != fattr->uid |
1243 | || inode->i_gid != fattr->gid) | 1285 | || inode->i_gid != fattr->gid) |
1244 | nfsi->flags |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; | 1286 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS | NFS_INO_INVALID_ACL; |
1245 | 1287 | ||
1246 | /* Has the link count changed? */ | 1288 | /* Has the link count changed? */ |
1247 | if (inode->i_nlink != fattr->nlink) | 1289 | if (inode->i_nlink != fattr->nlink) |
1248 | nfsi->flags |= NFS_INO_INVALID_ATTR; | 1290 | nfsi->cache_validity |= NFS_INO_INVALID_ATTR; |
1249 | 1291 | ||
1250 | if (!timespec_equal(&inode->i_atime, &fattr->atime)) | 1292 | if (!timespec_equal(&inode->i_atime, &fattr->atime)) |
1251 | nfsi->flags |= NFS_INO_INVALID_ATIME; | 1293 | nfsi->cache_validity |= NFS_INO_INVALID_ATIME; |
1252 | 1294 | ||
1253 | nfsi->read_cache_jiffies = fattr->timestamp; | 1295 | nfsi->read_cache_jiffies = fattr->timestamp; |
1296 | spin_unlock(&inode->i_lock); | ||
1254 | return 0; | 1297 | return 0; |
1255 | } | 1298 | } |
1256 | 1299 | ||
@@ -1289,11 +1332,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1289 | goto out_err; | 1332 | goto out_err; |
1290 | } | 1333 | } |
1291 | 1334 | ||
1335 | spin_lock(&inode->i_lock); | ||
1336 | |||
1292 | /* | 1337 | /* |
1293 | * Make sure the inode's type hasn't changed. | 1338 | * Make sure the inode's type hasn't changed. |
1294 | */ | 1339 | */ |
1295 | if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) | 1340 | if ((inode->i_mode & S_IFMT) != (fattr->mode & S_IFMT)) { |
1341 | spin_unlock(&inode->i_lock); | ||
1296 | goto out_changed; | 1342 | goto out_changed; |
1343 | } | ||
1297 | 1344 | ||
1298 | /* | 1345 | /* |
1299 | * Update the read time so we don't revalidate too often. | 1346 | * Update the read time so we don't revalidate too often. |
@@ -1384,8 +1431,9 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1384 | || S_ISLNK(inode->i_mode))) | 1431 | || S_ISLNK(inode->i_mode))) |
1385 | invalid &= ~NFS_INO_INVALID_DATA; | 1432 | invalid &= ~NFS_INO_INVALID_DATA; |
1386 | if (!nfs_have_delegation(inode, FMODE_READ)) | 1433 | if (!nfs_have_delegation(inode, FMODE_READ)) |
1387 | nfsi->flags |= invalid; | 1434 | nfsi->cache_validity |= invalid; |
1388 | 1435 | ||
1436 | spin_unlock(&inode->i_lock); | ||
1389 | return 0; | 1437 | return 0; |
1390 | out_changed: | 1438 | out_changed: |
1391 | /* | 1439 | /* |
@@ -1402,7 +1450,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign | |||
1402 | */ | 1450 | */ |
1403 | nfs_invalidate_inode(inode); | 1451 | nfs_invalidate_inode(inode); |
1404 | out_err: | 1452 | out_err: |
1405 | NFS_FLAGS(inode) |= NFS_INO_STALE; | 1453 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); |
1406 | return -ESTALE; | 1454 | return -ESTALE; |
1407 | } | 1455 | } |
1408 | 1456 | ||
@@ -1961,7 +2009,8 @@ static struct inode *nfs_alloc_inode(struct super_block *sb) | |||
1961 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); | 2009 | nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); |
1962 | if (!nfsi) | 2010 | if (!nfsi) |
1963 | return NULL; | 2011 | return NULL; |
1964 | nfsi->flags = 0; | 2012 | nfsi->flags = 0UL; |
2013 | nfsi->cache_validity = 0UL; | ||
1965 | #ifdef CONFIG_NFS_V3_ACL | 2014 | #ifdef CONFIG_NFS_V3_ACL |
1966 | nfsi->acl_access = ERR_PTR(-EAGAIN); | 2015 | nfsi->acl_access = ERR_PTR(-EAGAIN); |
1967 | nfsi->acl_default = ERR_PTR(-EAGAIN); | 2016 | nfsi->acl_default = ERR_PTR(-EAGAIN); |
@@ -1993,7 +2042,6 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) | |||
1993 | nfsi->ndirty = 0; | 2042 | nfsi->ndirty = 0; |
1994 | nfsi->ncommit = 0; | 2043 | nfsi->ncommit = 0; |
1995 | nfsi->npages = 0; | 2044 | nfsi->npages = 0; |
1996 | init_waitqueue_head(&nfsi->nfs_i_wait); | ||
1997 | nfs4_init_once(nfsi); | 2045 | nfs4_init_once(nfsi); |
1998 | } | 2046 | } |
1999 | } | 2047 | } |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index 1b7a3ef2f813..6a5bbc0ae941 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -308,7 +308,9 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
308 | nfs_begin_data_update(inode); | 308 | nfs_begin_data_update(inode); |
309 | status = rpc_call(server->client_acl, ACLPROC3_SETACL, | 309 | status = rpc_call(server->client_acl, ACLPROC3_SETACL, |
310 | &args, &fattr, 0); | 310 | &args, &fattr, 0); |
311 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ACCESS; | 311 | spin_lock(&inode->i_lock); |
312 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ACCESS; | ||
313 | spin_unlock(&inode->i_lock); | ||
312 | nfs_end_data_update(inode); | 314 | nfs_end_data_update(inode); |
313 | dprintk("NFS reply setacl: %d\n", status); | 315 | dprintk("NFS reply setacl: %d\n", status); |
314 | 316 | ||
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 6f866b8aa2d5..6ceb1d471f20 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -140,7 +140,9 @@ static int nfs_readpage_sync(struct nfs_open_context *ctx, struct inode *inode, | |||
140 | if (rdata->res.eof != 0 || result == 0) | 140 | if (rdata->res.eof != 0 || result == 0) |
141 | break; | 141 | break; |
142 | } while (count); | 142 | } while (count); |
143 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ATIME; | 143 | spin_lock(&inode->i_lock); |
144 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
145 | spin_unlock(&inode->i_lock); | ||
144 | 146 | ||
145 | if (count) | 147 | if (count) |
146 | memclear_highpage_flush(page, rdata->args.pgbase, count); | 148 | memclear_highpage_flush(page, rdata->args.pgbase, count); |
@@ -473,7 +475,9 @@ void nfs_readpage_result(struct rpc_task *task) | |||
473 | } | 475 | } |
474 | task->tk_status = -EIO; | 476 | task->tk_status = -EIO; |
475 | } | 477 | } |
476 | NFS_FLAGS(data->inode) |= NFS_INO_INVALID_ATIME; | 478 | spin_lock(&data->inode->i_lock); |
479 | NFS_I(data->inode)->cache_validity |= NFS_INO_INVALID_ATIME; | ||
480 | spin_unlock(&data->inode->i_lock); | ||
477 | data->complete(data, status); | 481 | data->complete(data, status); |
478 | } | 482 | } |
479 | 483 | ||
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 35f106599144..18dc95b0b646 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -27,26 +27,14 @@ | |||
27 | 27 | ||
28 | /* Symlink caching in the page cache is even more simplistic | 28 | /* Symlink caching in the page cache is even more simplistic |
29 | * and straight-forward than readdir caching. | 29 | * and straight-forward than readdir caching. |
30 | * | ||
31 | * At the beginning of the page we store pointer to struct page in question, | ||
32 | * simplifying nfs_put_link() (if inode got invalidated we can't find the page | ||
33 | * to be freed via pagecache lookup). | ||
34 | * The NUL-terminated string follows immediately thereafter. | ||
35 | */ | 30 | */ |
36 | 31 | ||
37 | struct nfs_symlink { | ||
38 | struct page *page; | ||
39 | char body[0]; | ||
40 | }; | ||
41 | |||
42 | static int nfs_symlink_filler(struct inode *inode, struct page *page) | 32 | static int nfs_symlink_filler(struct inode *inode, struct page *page) |
43 | { | 33 | { |
44 | const unsigned int pgbase = offsetof(struct nfs_symlink, body); | ||
45 | const unsigned int pglen = PAGE_SIZE - pgbase; | ||
46 | int error; | 34 | int error; |
47 | 35 | ||
48 | lock_kernel(); | 36 | lock_kernel(); |
49 | error = NFS_PROTO(inode)->readlink(inode, page, pgbase, pglen); | 37 | error = NFS_PROTO(inode)->readlink(inode, page, 0, PAGE_SIZE); |
50 | unlock_kernel(); | 38 | unlock_kernel(); |
51 | if (error < 0) | 39 | if (error < 0) |
52 | goto error; | 40 | goto error; |
@@ -60,11 +48,10 @@ error: | |||
60 | return -EIO; | 48 | return -EIO; |
61 | } | 49 | } |
62 | 50 | ||
63 | static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 51 | static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
64 | { | 52 | { |
65 | struct inode *inode = dentry->d_inode; | 53 | struct inode *inode = dentry->d_inode; |
66 | struct page *page; | 54 | struct page *page; |
67 | struct nfs_symlink *p; | ||
68 | void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode)); | 55 | void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode)); |
69 | if (err) | 56 | if (err) |
70 | goto read_failed; | 57 | goto read_failed; |
@@ -78,28 +65,20 @@ static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
78 | err = ERR_PTR(-EIO); | 65 | err = ERR_PTR(-EIO); |
79 | goto getlink_read_error; | 66 | goto getlink_read_error; |
80 | } | 67 | } |
81 | p = kmap(page); | 68 | nd_set_link(nd, kmap(page)); |
82 | p->page = page; | 69 | return page; |
83 | nd_set_link(nd, p->body); | ||
84 | return 0; | ||
85 | 70 | ||
86 | getlink_read_error: | 71 | getlink_read_error: |
87 | page_cache_release(page); | 72 | page_cache_release(page); |
88 | read_failed: | 73 | read_failed: |
89 | nd_set_link(nd, err); | 74 | nd_set_link(nd, err); |
90 | return 0; | 75 | return NULL; |
91 | } | 76 | } |
92 | 77 | ||
93 | static void nfs_put_link(struct dentry *dentry, struct nameidata *nd) | 78 | static void nfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) |
94 | { | 79 | { |
95 | char *s = nd_get_link(nd); | 80 | if (cookie) { |
96 | if (!IS_ERR(s)) { | 81 | struct page *page = cookie; |
97 | struct nfs_symlink *p; | ||
98 | struct page *page; | ||
99 | |||
100 | p = container_of(s, struct nfs_symlink, body[0]); | ||
101 | page = p->page; | ||
102 | |||
103 | kunmap(page); | 82 | kunmap(page); |
104 | page_cache_release(page); | 83 | page_cache_release(page); |
105 | } | 84 | } |
diff --git a/fs/proc/base.c b/fs/proc/base.c index ace151fa4878..491f2d9f89ac 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -890,7 +890,7 @@ static struct file_operations proc_seccomp_operations = { | |||
890 | }; | 890 | }; |
891 | #endif /* CONFIG_SECCOMP */ | 891 | #endif /* CONFIG_SECCOMP */ |
892 | 892 | ||
893 | static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 893 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
894 | { | 894 | { |
895 | struct inode *inode = dentry->d_inode; | 895 | struct inode *inode = dentry->d_inode; |
896 | int error = -EACCES; | 896 | int error = -EACCES; |
@@ -907,7 +907,7 @@ static int proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
907 | error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); | 907 | error = PROC_I(inode)->op.proc_get_link(inode, &nd->dentry, &nd->mnt); |
908 | nd->last_type = LAST_BIND; | 908 | nd->last_type = LAST_BIND; |
909 | out: | 909 | out: |
910 | return error; | 910 | return ERR_PTR(error); |
911 | } | 911 | } |
912 | 912 | ||
913 | static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, | 913 | static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt, |
@@ -1692,11 +1692,11 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | |||
1692 | return vfs_readlink(dentry,buffer,buflen,tmp); | 1692 | return vfs_readlink(dentry,buffer,buflen,tmp); |
1693 | } | 1693 | } |
1694 | 1694 | ||
1695 | static int proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 1695 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
1696 | { | 1696 | { |
1697 | char tmp[30]; | 1697 | char tmp[30]; |
1698 | sprintf(tmp, "%d", current->tgid); | 1698 | sprintf(tmp, "%d", current->tgid); |
1699 | return vfs_follow_link(nd,tmp); | 1699 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
1700 | } | 1700 | } |
1701 | 1701 | ||
1702 | static struct inode_operations proc_self_inode_operations = { | 1702 | static struct inode_operations proc_self_inode_operations = { |
diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 6c6315d04028..abe8920313fb 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c | |||
@@ -329,10 +329,10 @@ static void release_inode_number(unsigned int inum) | |||
329 | spin_unlock(&proc_inum_lock); | 329 | spin_unlock(&proc_inum_lock); |
330 | } | 330 | } |
331 | 331 | ||
332 | static int proc_follow_link(struct dentry *dentry, struct nameidata *nd) | 332 | static void *proc_follow_link(struct dentry *dentry, struct nameidata *nd) |
333 | { | 333 | { |
334 | nd_set_link(nd, PDE(dentry->d_inode)->data); | 334 | nd_set_link(nd, PDE(dentry->d_inode)->data); |
335 | return 0; | 335 | return NULL; |
336 | } | 336 | } |
337 | 337 | ||
338 | static struct inode_operations proc_link_inode_operations = { | 338 | static struct inode_operations proc_link_inode_operations = { |
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index d9f614a57731..ff291c973a56 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -1985,7 +1985,7 @@ int reiserfs_new_inode(struct reiserfs_transaction_handle *th, | |||
1985 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking | 1985 | * iput doesn't deadlock in reiserfs_delete_xattrs. The locking |
1986 | * code really needs to be reworked, but this will take care of it | 1986 | * code really needs to be reworked, but this will take care of it |
1987 | * for now. -jeffm */ | 1987 | * for now. -jeffm */ |
1988 | if (REISERFS_I(dir)->i_acl_default) { | 1988 | if (REISERFS_I(dir)->i_acl_default && !IS_ERR(REISERFS_I(dir)->i_acl_default)) { |
1989 | reiserfs_write_unlock_xattrs(dir->i_sb); | 1989 | reiserfs_write_unlock_xattrs(dir->i_sb); |
1990 | iput(inode); | 1990 | iput(inode); |
1991 | reiserfs_write_lock_xattrs(dir->i_sb); | 1991 | reiserfs_write_lock_xattrs(dir->i_sb); |
diff --git a/fs/smbfs/symlink.c b/fs/smbfs/symlink.c index 8b069e06433d..0c64bc3a0127 100644 --- a/fs/smbfs/symlink.c +++ b/fs/smbfs/symlink.c | |||
@@ -34,7 +34,7 @@ int smb_symlink(struct inode *inode, struct dentry *dentry, const char *oldname) | |||
34 | return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname); | 34 | return smb_proc_symlink(server_from_dentry(dentry), dentry, oldname); |
35 | } | 35 | } |
36 | 36 | ||
37 | static int smb_follow_link(struct dentry *dentry, struct nameidata *nd) | 37 | static void *smb_follow_link(struct dentry *dentry, struct nameidata *nd) |
38 | { | 38 | { |
39 | char *link = __getname(); | 39 | char *link = __getname(); |
40 | DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); | 40 | DEBUG1("followlink of %s/%s\n", DENTRY_PATH(dentry)); |
@@ -52,10 +52,10 @@ static int smb_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
52 | } | 52 | } |
53 | } | 53 | } |
54 | nd_set_link(nd, link); | 54 | nd_set_link(nd, link); |
55 | return 0; | 55 | return NULL; |
56 | } | 56 | } |
57 | 57 | ||
58 | static void smb_put_link(struct dentry *dentry, struct nameidata *nd) | 58 | static void smb_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
59 | { | 59 | { |
60 | char *s = nd_get_link(nd); | 60 | char *s = nd_get_link(nd); |
61 | if (!IS_ERR(s)) | 61 | if (!IS_ERR(s)) |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index d727dc960634..970a33f03299 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -228,6 +228,10 @@ void sysfs_hash_and_remove(struct dentry * dir, const char * name) | |||
228 | struct sysfs_dirent * sd; | 228 | struct sysfs_dirent * sd; |
229 | struct sysfs_dirent * parent_sd = dir->d_fsdata; | 229 | struct sysfs_dirent * parent_sd = dir->d_fsdata; |
230 | 230 | ||
231 | if (dir->d_inode == NULL) | ||
232 | /* no inode means this hasn't been made visible yet */ | ||
233 | return; | ||
234 | |||
231 | down(&dir->d_inode->i_sem); | 235 | down(&dir->d_inode->i_sem); |
232 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { | 236 | list_for_each_entry(sd, &parent_sd->s_children, s_sibling) { |
233 | if (!sd->s_element) | 237 | if (!sd->s_element) |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index fae57c83a722..de402fa915f2 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -151,17 +151,17 @@ static int sysfs_getlink(struct dentry *dentry, char * path) | |||
151 | 151 | ||
152 | } | 152 | } |
153 | 153 | ||
154 | static int sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) | 154 | static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) |
155 | { | 155 | { |
156 | int error = -ENOMEM; | 156 | int error = -ENOMEM; |
157 | unsigned long page = get_zeroed_page(GFP_KERNEL); | 157 | unsigned long page = get_zeroed_page(GFP_KERNEL); |
158 | if (page) | 158 | if (page) |
159 | error = sysfs_getlink(dentry, (char *) page); | 159 | error = sysfs_getlink(dentry, (char *) page); |
160 | nd_set_link(nd, error ? ERR_PTR(error) : (char *)page); | 160 | nd_set_link(nd, error ? ERR_PTR(error) : (char *)page); |
161 | return 0; | 161 | return NULL; |
162 | } | 162 | } |
163 | 163 | ||
164 | static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd) | 164 | static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) |
165 | { | 165 | { |
166 | char *page = nd_get_link(nd); | 166 | char *page = nd_get_link(nd); |
167 | if (!IS_ERR(page)) | 167 | if (!IS_ERR(page)) |
diff --git a/fs/sysv/symlink.c b/fs/sysv/symlink.c index ed637db2dcb1..b85ce61d635c 100644 --- a/fs/sysv/symlink.c +++ b/fs/sysv/symlink.c | |||
@@ -8,10 +8,10 @@ | |||
8 | #include "sysv.h" | 8 | #include "sysv.h" |
9 | #include <linux/namei.h> | 9 | #include <linux/namei.h> |
10 | 10 | ||
11 | static int sysv_follow_link(struct dentry *dentry, struct nameidata *nd) | 11 | static void *sysv_follow_link(struct dentry *dentry, struct nameidata *nd) |
12 | { | 12 | { |
13 | nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data); | 13 | nd_set_link(nd, (char *)SYSV_I(dentry->d_inode)->i_data); |
14 | return 0; | 14 | return NULL; |
15 | } | 15 | } |
16 | 16 | ||
17 | struct inode_operations sysv_fast_symlink_inode_operations = { | 17 | struct inode_operations sysv_fast_symlink_inode_operations = { |
diff --git a/fs/ufs/symlink.c b/fs/ufs/symlink.c index a0e49149098f..337512ed5781 100644 --- a/fs/ufs/symlink.c +++ b/fs/ufs/symlink.c | |||
@@ -29,11 +29,11 @@ | |||
29 | #include <linux/namei.h> | 29 | #include <linux/namei.h> |
30 | #include <linux/ufs_fs.h> | 30 | #include <linux/ufs_fs.h> |
31 | 31 | ||
32 | static int ufs_follow_link(struct dentry *dentry, struct nameidata *nd) | 32 | static void *ufs_follow_link(struct dentry *dentry, struct nameidata *nd) |
33 | { | 33 | { |
34 | struct ufs_inode_info *p = UFS_I(dentry->d_inode); | 34 | struct ufs_inode_info *p = UFS_I(dentry->d_inode); |
35 | nd_set_link(nd, (char*)p->i_u1.i_symlink); | 35 | nd_set_link(nd, (char*)p->i_u1.i_symlink); |
36 | return 0; | 36 | return NULL; |
37 | } | 37 | } |
38 | 38 | ||
39 | struct inode_operations ufs_fast_symlink_inode_operations = { | 39 | struct inode_operations ufs_fast_symlink_inode_operations = { |
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index 407e99359391..f252605514eb 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -374,7 +374,7 @@ linvfs_rename( | |||
374 | * we need to be very careful about how much stack we use. | 374 | * we need to be very careful about how much stack we use. |
375 | * uio is kmalloced for this reason... | 375 | * uio is kmalloced for this reason... |
376 | */ | 376 | */ |
377 | STATIC int | 377 | STATIC void * |
378 | linvfs_follow_link( | 378 | linvfs_follow_link( |
379 | struct dentry *dentry, | 379 | struct dentry *dentry, |
380 | struct nameidata *nd) | 380 | struct nameidata *nd) |
@@ -391,14 +391,14 @@ linvfs_follow_link( | |||
391 | link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); | 391 | link = (char *)kmalloc(MAXNAMELEN+1, GFP_KERNEL); |
392 | if (!link) { | 392 | if (!link) { |
393 | nd_set_link(nd, ERR_PTR(-ENOMEM)); | 393 | nd_set_link(nd, ERR_PTR(-ENOMEM)); |
394 | return 0; | 394 | return NULL; |
395 | } | 395 | } |
396 | 396 | ||
397 | uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL); | 397 | uio = (uio_t *)kmalloc(sizeof(uio_t), GFP_KERNEL); |
398 | if (!uio) { | 398 | if (!uio) { |
399 | kfree(link); | 399 | kfree(link); |
400 | nd_set_link(nd, ERR_PTR(-ENOMEM)); | 400 | nd_set_link(nd, ERR_PTR(-ENOMEM)); |
401 | return 0; | 401 | return NULL; |
402 | } | 402 | } |
403 | 403 | ||
404 | vp = LINVFS_GET_VP(dentry->d_inode); | 404 | vp = LINVFS_GET_VP(dentry->d_inode); |
@@ -422,10 +422,10 @@ linvfs_follow_link( | |||
422 | kfree(uio); | 422 | kfree(uio); |
423 | 423 | ||
424 | nd_set_link(nd, link); | 424 | nd_set_link(nd, link); |
425 | return 0; | 425 | return NULL; |
426 | } | 426 | } |
427 | 427 | ||
428 | static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd) | 428 | static void linvfs_put_link(struct dentry *dentry, struct nameidata *nd, void *p) |
429 | { | 429 | { |
430 | char *s = nd_get_link(nd); | 430 | char *s = nd_get_link(nd); |
431 | if (!IS_ERR(s)) | 431 | if (!IS_ERR(s)) |
diff --git a/include/asm-alpha/system.h b/include/asm-alpha/system.h index c08ce970ff8c..bdb4d66418f1 100644 --- a/include/asm-alpha/system.h +++ b/include/asm-alpha/system.h | |||
@@ -443,22 +443,19 @@ __xchg_u64(volatile long *m, unsigned long val) | |||
443 | if something tries to do an invalid xchg(). */ | 443 | if something tries to do an invalid xchg(). */ |
444 | extern void __xchg_called_with_bad_pointer(void); | 444 | extern void __xchg_called_with_bad_pointer(void); |
445 | 445 | ||
446 | static inline unsigned long | 446 | #define __xchg(ptr, x, size) \ |
447 | __xchg(volatile void *ptr, unsigned long x, int size) | 447 | ({ \ |
448 | { | 448 | unsigned long __xchg__res; \ |
449 | switch (size) { | 449 | volatile void *__xchg__ptr = (ptr); \ |
450 | case 1: | 450 | switch (size) { \ |
451 | return __xchg_u8(ptr, x); | 451 | case 1: __xchg__res = __xchg_u8(__xchg__ptr, x); break; \ |
452 | case 2: | 452 | case 2: __xchg__res = __xchg_u16(__xchg__ptr, x); break; \ |
453 | return __xchg_u16(ptr, x); | 453 | case 4: __xchg__res = __xchg_u32(__xchg__ptr, x); break; \ |
454 | case 4: | 454 | case 8: __xchg__res = __xchg_u64(__xchg__ptr, x); break; \ |
455 | return __xchg_u32(ptr, x); | 455 | default: __xchg_called_with_bad_pointer(); __xchg__res = x; \ |
456 | case 8: | 456 | } \ |
457 | return __xchg_u64(ptr, x); | 457 | __xchg__res; \ |
458 | } | 458 | }) |
459 | __xchg_called_with_bad_pointer(); | ||
460 | return x; | ||
461 | } | ||
462 | 459 | ||
463 | #define xchg(ptr,x) \ | 460 | #define xchg(ptr,x) \ |
464 | ({ \ | 461 | ({ \ |
diff --git a/include/asm-arm/arch-ixp4xx/timex.h b/include/asm-arm/arch-ixp4xx/timex.h index 38c9d77d3727..3745e35cc030 100644 --- a/include/asm-arm/arch-ixp4xx/timex.h +++ b/include/asm-arm/arch-ixp4xx/timex.h | |||
@@ -7,7 +7,9 @@ | |||
7 | 7 | ||
8 | /* | 8 | /* |
9 | * We use IXP425 General purpose timer for our timer needs, it runs at | 9 | * We use IXP425 General purpose timer for our timer needs, it runs at |
10 | * 66.66... MHz | 10 | * 66.66... MHz. We do a convulted calculation of CLOCK_TICK_RATE b/c the |
11 | * timer register ignores the bottom 2 bits of the LATCH value. | ||
11 | */ | 12 | */ |
12 | #define CLOCK_TICK_RATE (66666666) | 13 | #define FREQ 66666666 |
14 | #define CLOCK_TICK_RATE (((FREQ / HZ & ~IXP4XX_OST_RELOAD_MASK) + 1) * HZ) | ||
13 | 15 | ||
diff --git a/include/asm-arm/bug.h b/include/asm-arm/bug.h index 24d11672eb60..7fb02138f585 100644 --- a/include/asm-arm/bug.h +++ b/include/asm-arm/bug.h | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | #ifdef CONFIG_BUG | 6 | #ifdef CONFIG_BUG |
7 | #ifdef CONFIG_DEBUG_BUGVERBOSE | 7 | #ifdef CONFIG_DEBUG_BUGVERBOSE |
8 | extern volatile void __bug(const char *file, int line, void *data); | 8 | extern void __bug(const char *file, int line, void *data) __attribute__((noreturn)); |
9 | 9 | ||
10 | /* give file/line information */ | 10 | /* give file/line information */ |
11 | #define BUG() __bug(__FILE__, __LINE__, NULL) | 11 | #define BUG() __bug(__FILE__, __LINE__, NULL) |
diff --git a/include/asm-arm/cpu-multi32.h b/include/asm-arm/cpu-multi32.h index ff48022e4720..4679f63688e9 100644 --- a/include/asm-arm/cpu-multi32.h +++ b/include/asm-arm/cpu-multi32.h | |||
@@ -31,7 +31,7 @@ extern struct processor { | |||
31 | /* | 31 | /* |
32 | * Special stuff for a reset | 32 | * Special stuff for a reset |
33 | */ | 33 | */ |
34 | volatile void (*reset)(unsigned long addr); | 34 | void (*reset)(unsigned long addr) __attribute__((noreturn)); |
35 | /* | 35 | /* |
36 | * Idle the processor | 36 | * Idle the processor |
37 | */ | 37 | */ |
diff --git a/include/asm-arm/cpu-single.h b/include/asm-arm/cpu-single.h index b5ec5d54665d..6723e67244fa 100644 --- a/include/asm-arm/cpu-single.h +++ b/include/asm-arm/cpu-single.h | |||
@@ -41,4 +41,4 @@ extern int cpu_do_idle(void); | |||
41 | extern void cpu_dcache_clean_area(void *, int); | 41 | extern void cpu_dcache_clean_area(void *, int); |
42 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); | 42 | extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm); |
43 | extern void cpu_set_pte(pte_t *ptep, pte_t pte); | 43 | extern void cpu_set_pte(pte_t *ptep, pte_t pte); |
44 | extern volatile void cpu_reset(unsigned long addr); | 44 | extern void cpu_reset(unsigned long addr) __attribute__((noreturn)); |
diff --git a/include/asm-ia64/io.h b/include/asm-ia64/io.h index 491e9d1fc538..54e7637a326c 100644 --- a/include/asm-ia64/io.h +++ b/include/asm-ia64/io.h | |||
@@ -120,14 +120,6 @@ static inline void ___ia64_mmiowb(void) | |||
120 | ia64_mfa(); | 120 | ia64_mfa(); |
121 | } | 121 | } |
122 | 122 | ||
123 | static inline const unsigned long | ||
124 | __ia64_get_io_port_base (void) | ||
125 | { | ||
126 | extern unsigned long ia64_iobase; | ||
127 | |||
128 | return ia64_iobase; | ||
129 | } | ||
130 | |||
131 | static inline void* | 123 | static inline void* |
132 | __ia64_mk_io_addr (unsigned long port) | 124 | __ia64_mk_io_addr (unsigned long port) |
133 | { | 125 | { |
diff --git a/include/asm-m32r/smp.h b/include/asm-m32r/smp.h index b9a20cdad65f..7885b7df84a2 100644 --- a/include/asm-m32r/smp.h +++ b/include/asm-m32r/smp.h | |||
@@ -61,9 +61,7 @@ extern physid_mask_t phys_cpu_present_map; | |||
61 | * Some lowlevel functions might want to know about | 61 | * Some lowlevel functions might want to know about |
62 | * the real CPU ID <-> CPU # mapping. | 62 | * the real CPU ID <-> CPU # mapping. |
63 | */ | 63 | */ |
64 | extern volatile int physid_2_cpu[NR_CPUS]; | ||
65 | extern volatile int cpu_2_physid[NR_CPUS]; | 64 | extern volatile int cpu_2_physid[NR_CPUS]; |
66 | #define physid_to_cpu(physid) physid_2_cpu[physid] | ||
67 | #define cpu_to_physid(cpu_id) cpu_2_physid[cpu_id] | 65 | #define cpu_to_physid(cpu_id) cpu_2_physid[cpu_id] |
68 | 66 | ||
69 | #define raw_smp_processor_id() (current_thread_info()->cpu) | 67 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
diff --git a/include/asm-m68k/page.h b/include/asm-m68k/page.h index 99a516709210..206313e2a817 100644 --- a/include/asm-m68k/page.h +++ b/include/asm-m68k/page.h | |||
@@ -138,13 +138,13 @@ extern unsigned long m68k_memoffset; | |||
138 | #define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) | 138 | #define __pa(vaddr) ((unsigned long)(vaddr)+m68k_memoffset) |
139 | #define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) | 139 | #define __va(paddr) ((void *)((unsigned long)(paddr)-m68k_memoffset)) |
140 | #else | 140 | #else |
141 | #define __pa(vaddr) virt_to_phys((void *)vaddr) | 141 | #define __pa(vaddr) virt_to_phys((void *)(vaddr)) |
142 | #define __va(paddr) phys_to_virt((unsigned long)paddr) | 142 | #define __va(paddr) phys_to_virt((unsigned long)(paddr)) |
143 | #endif | 143 | #endif |
144 | 144 | ||
145 | #else /* !CONFIG_SUN3 */ | 145 | #else /* !CONFIG_SUN3 */ |
146 | /* This #define is a horrible hack to suppress lots of warnings. --m */ | 146 | /* This #define is a horrible hack to suppress lots of warnings. --m */ |
147 | #define __pa(x) ___pa((unsigned long)x) | 147 | #define __pa(x) ___pa((unsigned long)(x)) |
148 | static inline unsigned long ___pa(unsigned long x) | 148 | static inline unsigned long ___pa(unsigned long x) |
149 | { | 149 | { |
150 | if(x == 0) | 150 | if(x == 0) |
diff --git a/include/asm-ppc/ibm44x.h b/include/asm-ppc/ibm44x.h index 21e41c9b7267..e5374be86aef 100644 --- a/include/asm-ppc/ibm44x.h +++ b/include/asm-ppc/ibm44x.h | |||
@@ -423,11 +423,7 @@ | |||
423 | #define MQ0_CONFIG_SIZE_2G 0x0000c000 | 423 | #define MQ0_CONFIG_SIZE_2G 0x0000c000 |
424 | 424 | ||
425 | /* Internal SRAM Controller 440GX/440SP */ | 425 | /* Internal SRAM Controller 440GX/440SP */ |
426 | #ifdef CONFIG_440SP | ||
427 | #define DCRN_SRAM0_BASE 0x100 | ||
428 | #else /* 440GX */ | ||
429 | #define DCRN_SRAM0_BASE 0x000 | 426 | #define DCRN_SRAM0_BASE 0x000 |
430 | #endif | ||
431 | 427 | ||
432 | #define DCRN_SRAM0_SB0CR (DCRN_SRAM0_BASE + 0x020) | 428 | #define DCRN_SRAM0_SB0CR (DCRN_SRAM0_BASE + 0x020) |
433 | #define DCRN_SRAM0_SB1CR (DCRN_SRAM0_BASE + 0x021) | 429 | #define DCRN_SRAM0_SB1CR (DCRN_SRAM0_BASE + 0x021) |
diff --git a/include/asm-ppc/ppc4xx_dma.h b/include/asm-ppc/ppc4xx_dma.h index 8636cdbf6f8f..a415001165fa 100644 --- a/include/asm-ppc/ppc4xx_dma.h +++ b/include/asm-ppc/ppc4xx_dma.h | |||
@@ -285,7 +285,7 @@ typedef uint32_t sgl_handle_t; | |||
285 | 285 | ||
286 | #define GET_DMA_POLARITY(chan) (DMAReq_ActiveLow(chan) | DMAAck_ActiveLow(chan) | EOT_ActiveLow(chan)) | 286 | #define GET_DMA_POLARITY(chan) (DMAReq_ActiveLow(chan) | DMAAck_ActiveLow(chan) | EOT_ActiveLow(chan)) |
287 | 287 | ||
288 | #elif defined(CONFIG_STBXXX_DMA) /* stb03xxx */ | 288 | #elif defined(CONFIG_STB03xxx) /* stb03xxx */ |
289 | 289 | ||
290 | #define DMA_PPC4xx_SIZE 4096 | 290 | #define DMA_PPC4xx_SIZE 4096 |
291 | 291 | ||
diff --git a/include/asm-ppc/time.h b/include/asm-ppc/time.h index ce09b47fa819..321fb75b5f22 100644 --- a/include/asm-ppc/time.h +++ b/include/asm-ppc/time.h | |||
@@ -58,7 +58,7 @@ static __inline__ void set_dec(unsigned int val) | |||
58 | /* Accessor functions for the timebase (RTC on 601) registers. */ | 58 | /* Accessor functions for the timebase (RTC on 601) registers. */ |
59 | /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ | 59 | /* If one day CONFIG_POWER is added just define __USE_RTC as 1 */ |
60 | #ifdef CONFIG_6xx | 60 | #ifdef CONFIG_6xx |
61 | extern __inline__ int const __USE_RTC(void) { | 61 | extern __inline__ int __attribute_pure__ __USE_RTC(void) { |
62 | return (mfspr(SPRN_PVR)>>16) == 1; | 62 | return (mfspr(SPRN_PVR)>>16) == 1; |
63 | } | 63 | } |
64 | #else | 64 | #else |
diff --git a/include/asm-ppc64/bug.h b/include/asm-ppc64/bug.h index 169868fa307d..160178278861 100644 --- a/include/asm-ppc64/bug.h +++ b/include/asm-ppc64/bug.h | |||
@@ -43,8 +43,8 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
43 | ".section __bug_table,\"a\"\n\t" \ | 43 | ".section __bug_table,\"a\"\n\t" \ |
44 | " .llong 1b,%1,%2,%3\n" \ | 44 | " .llong 1b,%1,%2,%3\n" \ |
45 | ".previous" \ | 45 | ".previous" \ |
46 | : : "r" (x), "i" (__LINE__), "i" (__FILE__), \ | 46 | : : "r" ((long long)(x)), "i" (__LINE__), \ |
47 | "i" (__FUNCTION__)); \ | 47 | "i" (__FILE__), "i" (__FUNCTION__)); \ |
48 | } while (0) | 48 | } while (0) |
49 | 49 | ||
50 | #define WARN_ON(x) do { \ | 50 | #define WARN_ON(x) do { \ |
@@ -53,7 +53,8 @@ struct bug_entry *find_bug(unsigned long bugaddr); | |||
53 | ".section __bug_table,\"a\"\n\t" \ | 53 | ".section __bug_table,\"a\"\n\t" \ |
54 | " .llong 1b,%1,%2,%3\n" \ | 54 | " .llong 1b,%1,%2,%3\n" \ |
55 | ".previous" \ | 55 | ".previous" \ |
56 | : : "r" (x), "i" (__LINE__ + BUG_WARNING_TRAP), \ | 56 | : : "r" ((long long)(x)), \ |
57 | "i" (__LINE__ + BUG_WARNING_TRAP), \ | ||
57 | "i" (__FILE__), "i" (__FUNCTION__)); \ | 58 | "i" (__FILE__), "i" (__FUNCTION__)); \ |
58 | } while (0) | 59 | } while (0) |
59 | 60 | ||
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h index a7f43a251f81..3e3bfe6a8fa8 100644 --- a/include/asm-s390/uaccess.h +++ b/include/asm-s390/uaccess.h | |||
@@ -149,11 +149,11 @@ struct exception_table_entry | |||
149 | }) | 149 | }) |
150 | #endif | 150 | #endif |
151 | 151 | ||
152 | #ifndef __CHECKER__ | ||
153 | #define __put_user(x, ptr) \ | 152 | #define __put_user(x, ptr) \ |
154 | ({ \ | 153 | ({ \ |
155 | __typeof__(*(ptr)) __x = (x); \ | 154 | __typeof__(*(ptr)) __x = (x); \ |
156 | int __pu_err; \ | 155 | int __pu_err; \ |
156 | __chk_user_ptr(ptr); \ | ||
157 | switch (sizeof (*(ptr))) { \ | 157 | switch (sizeof (*(ptr))) { \ |
158 | case 1: \ | 158 | case 1: \ |
159 | case 2: \ | 159 | case 2: \ |
@@ -167,14 +167,6 @@ struct exception_table_entry | |||
167 | } \ | 167 | } \ |
168 | __pu_err; \ | 168 | __pu_err; \ |
169 | }) | 169 | }) |
170 | #else | ||
171 | #define __put_user(x, ptr) \ | ||
172 | ({ \ | ||
173 | void __user *p; \ | ||
174 | p = (ptr); \ | ||
175 | 0; \ | ||
176 | }) | ||
177 | #endif | ||
178 | 170 | ||
179 | #define put_user(x, ptr) \ | 171 | #define put_user(x, ptr) \ |
180 | ({ \ | 172 | ({ \ |
@@ -213,11 +205,11 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
213 | }) | 205 | }) |
214 | #endif | 206 | #endif |
215 | 207 | ||
216 | #ifndef __CHECKER__ | ||
217 | #define __get_user(x, ptr) \ | 208 | #define __get_user(x, ptr) \ |
218 | ({ \ | 209 | ({ \ |
219 | __typeof__(*(ptr)) __x; \ | 210 | __typeof__(*(ptr)) __x; \ |
220 | int __gu_err; \ | 211 | int __gu_err; \ |
212 | __chk_user_ptr(ptr); \ | ||
221 | switch (sizeof(*(ptr))) { \ | 213 | switch (sizeof(*(ptr))) { \ |
222 | case 1: \ | 214 | case 1: \ |
223 | case 2: \ | 215 | case 2: \ |
@@ -232,15 +224,6 @@ extern int __put_user_bad(void) __attribute__((noreturn)); | |||
232 | (x) = __x; \ | 224 | (x) = __x; \ |
233 | __gu_err; \ | 225 | __gu_err; \ |
234 | }) | 226 | }) |
235 | #else | ||
236 | #define __get_user(x, ptr) \ | ||
237 | ({ \ | ||
238 | void __user *p; \ | ||
239 | p = (ptr); \ | ||
240 | 0; \ | ||
241 | }) | ||
242 | #endif | ||
243 | |||
244 | 227 | ||
245 | #define get_user(x, ptr) \ | 228 | #define get_user(x, ptr) \ |
246 | ({ \ | 229 | ({ \ |
diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index 4e7701d6d23c..ea89e8f223ea 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h | |||
@@ -295,8 +295,14 @@ | |||
295 | #define __NR_add_key 285 | 295 | #define __NR_add_key 285 |
296 | #define __NR_request_key 286 | 296 | #define __NR_request_key 286 |
297 | #define __NR_keyctl 287 | 297 | #define __NR_keyctl 287 |
298 | #define __NR_ioprio_set 288 | ||
299 | #define __NR_ioprio_get 289 | ||
300 | #define __NR_inotify_init 290 | ||
301 | #define __NR_inotify_add_watch 291 | ||
302 | #define __NR_inotify_rm_watch 292 | ||
298 | 303 | ||
299 | #define NR_syscalls 288 | 304 | |
305 | #define NR_syscalls 293 | ||
300 | 306 | ||
301 | /* user-visible error numbers are in the range -1 - -124: see <asm-sh/errno.h> */ | 307 | /* user-visible error numbers are in the range -1 - -124: see <asm-sh/errno.h> */ |
302 | 308 | ||
diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h index 95f0b130405c..2a1cfa404ea4 100644 --- a/include/asm-sh64/unistd.h +++ b/include/asm-sh64/unistd.h | |||
@@ -338,8 +338,13 @@ | |||
338 | #define __NR_add_key 313 | 338 | #define __NR_add_key 313 |
339 | #define __NR_request_key 314 | 339 | #define __NR_request_key 314 |
340 | #define __NR_keyctl 315 | 340 | #define __NR_keyctl 315 |
341 | #define __NR_ioprio_set 316 | ||
342 | #define __NR_ioprio_get 317 | ||
343 | #define __NR_inotify_init 318 | ||
344 | #define __NR_inotify_add_watch 319 | ||
345 | #define __NR_inotify_rm_watch 320 | ||
341 | 346 | ||
342 | #define NR_syscalls 316 | 347 | #define NR_syscalls 321 |
343 | 348 | ||
344 | /* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */ | 349 | /* user-visible error numbers are in the range -1 - -125: see <asm-sh64/errno.h> */ |
345 | 350 | ||
diff --git a/include/asm-sparc64/thread_info.h b/include/asm-sparc64/thread_info.h index 352d9943661a..c94d8b3991bd 100644 --- a/include/asm-sparc64/thread_info.h +++ b/include/asm-sparc64/thread_info.h | |||
@@ -68,6 +68,9 @@ struct thread_info { | |||
68 | 68 | ||
69 | struct restart_block restart_block; | 69 | struct restart_block restart_block; |
70 | 70 | ||
71 | struct pt_regs *kern_una_regs; | ||
72 | unsigned int kern_una_insn; | ||
73 | |||
71 | unsigned long fpregs[0] __attribute__ ((aligned(64))); | 74 | unsigned long fpregs[0] __attribute__ ((aligned(64))); |
72 | }; | 75 | }; |
73 | 76 | ||
@@ -103,6 +106,8 @@ struct thread_info { | |||
103 | #define TI_PCR 0x00000490 | 106 | #define TI_PCR 0x00000490 |
104 | #define TI_CEE_STUFF 0x00000498 | 107 | #define TI_CEE_STUFF 0x00000498 |
105 | #define TI_RESTART_BLOCK 0x000004a0 | 108 | #define TI_RESTART_BLOCK 0x000004a0 |
109 | #define TI_KUNA_REGS 0x000004c8 | ||
110 | #define TI_KUNA_INSN 0x000004d0 | ||
106 | #define TI_FPREGS 0x00000500 | 111 | #define TI_FPREGS 0x00000500 |
107 | 112 | ||
108 | /* We embed this in the uppermost byte of thread_info->flags */ | 113 | /* We embed this in the uppermost byte of thread_info->flags */ |
diff --git a/include/asm-x86_64/e820.h b/include/asm-x86_64/e820.h index 8e94edf0b984..e682edc24a68 100644 --- a/include/asm-x86_64/e820.h +++ b/include/asm-x86_64/e820.h | |||
@@ -51,6 +51,8 @@ extern int e820_mapped(unsigned long start, unsigned long end, unsigned type); | |||
51 | 51 | ||
52 | extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end); | 52 | extern void e820_bootmem_free(pg_data_t *pgdat, unsigned long start,unsigned long end); |
53 | extern void e820_setup_gap(void); | 53 | extern void e820_setup_gap(void); |
54 | extern unsigned long e820_hole_size(unsigned long start_pfn, | ||
55 | unsigned long end_pfn); | ||
54 | 56 | ||
55 | extern void __init parse_memopt(char *p, char **end); | 57 | extern void __init parse_memopt(char *p, char **end); |
56 | 58 | ||
diff --git a/include/linux/ata.h b/include/linux/ata.h index ca5fcadf9981..9d25e9886d60 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h | |||
@@ -108,6 +108,8 @@ enum { | |||
108 | 108 | ||
109 | /* ATA device commands */ | 109 | /* ATA device commands */ |
110 | ATA_CMD_CHK_POWER = 0xE5, /* check power mode */ | 110 | ATA_CMD_CHK_POWER = 0xE5, /* check power mode */ |
111 | ATA_CMD_STANDBY = 0xE2, /* place in standby power mode */ | ||
112 | ATA_CMD_IDLE = 0xE3, /* place in idle power mode */ | ||
111 | ATA_CMD_EDD = 0x90, /* execute device diagnostic */ | 113 | ATA_CMD_EDD = 0x90, /* execute device diagnostic */ |
112 | ATA_CMD_FLUSH = 0xE7, | 114 | ATA_CMD_FLUSH = 0xE7, |
113 | ATA_CMD_FLUSH_EXT = 0xEA, | 115 | ATA_CMD_FLUSH_EXT = 0xEA, |
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index a0ab26aab450..d7021c391b2b 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
@@ -408,6 +408,8 @@ struct ethtool_ops { | |||
408 | #define SUPPORTED_FIBRE (1 << 10) | 408 | #define SUPPORTED_FIBRE (1 << 10) |
409 | #define SUPPORTED_BNC (1 << 11) | 409 | #define SUPPORTED_BNC (1 << 11) |
410 | #define SUPPORTED_10000baseT_Full (1 << 12) | 410 | #define SUPPORTED_10000baseT_Full (1 << 12) |
411 | #define SUPPORTED_Pause (1 << 13) | ||
412 | #define SUPPORTED_Asym_Pause (1 << 14) | ||
411 | 413 | ||
412 | /* Indicates what features are advertised by the interface. */ | 414 | /* Indicates what features are advertised by the interface. */ |
413 | #define ADVERTISED_10baseT_Half (1 << 0) | 415 | #define ADVERTISED_10baseT_Half (1 << 0) |
@@ -423,6 +425,8 @@ struct ethtool_ops { | |||
423 | #define ADVERTISED_FIBRE (1 << 10) | 425 | #define ADVERTISED_FIBRE (1 << 10) |
424 | #define ADVERTISED_BNC (1 << 11) | 426 | #define ADVERTISED_BNC (1 << 11) |
425 | #define ADVERTISED_10000baseT_Full (1 << 12) | 427 | #define ADVERTISED_10000baseT_Full (1 << 12) |
428 | #define ADVERTISED_Pause (1 << 13) | ||
429 | #define ADVERTISED_Asym_Pause (1 << 14) | ||
426 | 430 | ||
427 | /* The following are all involved in forcing a particular link | 431 | /* The following are all involved in forcing a particular link |
428 | * mode for the device for setting things. When getting the | 432 | * mode for the device for setting things. When getting the |
diff --git a/include/linux/fs.h b/include/linux/fs.h index f9adf75fd9b4..67e6732d4fdc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -993,8 +993,8 @@ struct inode_operations { | |||
993 | int (*rename) (struct inode *, struct dentry *, | 993 | int (*rename) (struct inode *, struct dentry *, |
994 | struct inode *, struct dentry *); | 994 | struct inode *, struct dentry *); |
995 | int (*readlink) (struct dentry *, char __user *,int); | 995 | int (*readlink) (struct dentry *, char __user *,int); |
996 | int (*follow_link) (struct dentry *, struct nameidata *); | 996 | void * (*follow_link) (struct dentry *, struct nameidata *); |
997 | void (*put_link) (struct dentry *, struct nameidata *); | 997 | void (*put_link) (struct dentry *, struct nameidata *, void *); |
998 | void (*truncate) (struct inode *); | 998 | void (*truncate) (struct inode *); |
999 | int (*permission) (struct inode *, int, struct nameidata *); | 999 | int (*permission) (struct inode *, int, struct nameidata *); |
1000 | int (*setattr) (struct dentry *, struct iattr *); | 1000 | int (*setattr) (struct dentry *, struct iattr *); |
@@ -1602,8 +1602,8 @@ extern struct file_operations generic_ro_fops; | |||
1602 | extern int vfs_readlink(struct dentry *, char __user *, int, const char *); | 1602 | extern int vfs_readlink(struct dentry *, char __user *, int, const char *); |
1603 | extern int vfs_follow_link(struct nameidata *, const char *); | 1603 | extern int vfs_follow_link(struct nameidata *, const char *); |
1604 | extern int page_readlink(struct dentry *, char __user *, int); | 1604 | extern int page_readlink(struct dentry *, char __user *, int); |
1605 | extern int page_follow_link_light(struct dentry *, struct nameidata *); | 1605 | extern void *page_follow_link_light(struct dentry *, struct nameidata *); |
1606 | extern void page_put_link(struct dentry *, struct nameidata *); | 1606 | extern void page_put_link(struct dentry *, struct nameidata *, void *); |
1607 | extern int page_symlink(struct inode *inode, const char *symname, int len); | 1607 | extern int page_symlink(struct inode *inode, const char *symname, int len); |
1608 | extern struct inode_operations page_symlink_inode_operations; | 1608 | extern struct inode_operations page_symlink_inode_operations; |
1609 | extern int generic_readlink(struct dentry *, char __user *, int); | 1609 | extern int generic_readlink(struct dentry *, char __user *, int); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 6cd9ba63563b..7c09540c52bc 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -113,6 +113,8 @@ enum { | |||
113 | ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ | 113 | ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ |
114 | ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ | 114 | ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ |
115 | ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ | 115 | ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ |
116 | ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once | ||
117 | * proper HSM is in place. */ | ||
116 | 118 | ||
117 | ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ | 119 | ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ |
118 | ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ | 120 | ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ |
@@ -363,7 +365,7 @@ struct ata_port_operations { | |||
363 | 365 | ||
364 | void (*host_stop) (struct ata_host_set *host_set); | 366 | void (*host_stop) (struct ata_host_set *host_set); |
365 | 367 | ||
366 | void (*bmdma_stop) (struct ata_port *ap); | 368 | void (*bmdma_stop) (struct ata_queued_cmd *qc); |
367 | u8 (*bmdma_status) (struct ata_port *ap); | 369 | u8 (*bmdma_status) (struct ata_port *ap); |
368 | }; | 370 | }; |
369 | 371 | ||
@@ -424,7 +426,7 @@ extern void ata_dev_id_string(u16 *id, unsigned char *s, | |||
424 | extern void ata_dev_config(struct ata_port *ap, unsigned int i); | 426 | extern void ata_dev_config(struct ata_port *ap, unsigned int i); |
425 | extern void ata_bmdma_setup (struct ata_queued_cmd *qc); | 427 | extern void ata_bmdma_setup (struct ata_queued_cmd *qc); |
426 | extern void ata_bmdma_start (struct ata_queued_cmd *qc); | 428 | extern void ata_bmdma_start (struct ata_queued_cmd *qc); |
427 | extern void ata_bmdma_stop(struct ata_port *ap); | 429 | extern void ata_bmdma_stop(struct ata_queued_cmd *qc); |
428 | extern u8 ata_bmdma_status(struct ata_port *ap); | 430 | extern u8 ata_bmdma_status(struct ata_port *ap); |
429 | extern void ata_bmdma_irq_clear(struct ata_port *ap); | 431 | extern void ata_bmdma_irq_clear(struct ata_port *ap); |
430 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); | 432 | extern void ata_qc_complete(struct ata_queued_cmd *qc, u8 drv_stat); |
@@ -644,7 +646,7 @@ static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) | |||
644 | ap->ops->scr_write(ap, reg, val); | 646 | ap->ops->scr_write(ap, reg, val); |
645 | } | 647 | } |
646 | 648 | ||
647 | static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, | 649 | static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, |
648 | u32 val) | 650 | u32 val) |
649 | { | 651 | { |
650 | ap->ops->scr_write(ap, reg, val); | 652 | ap->ops->scr_write(ap, reg, val); |
diff --git a/include/linux/mii.h b/include/linux/mii.h index 374b615ea9ea..9b8d0476988a 100644 --- a/include/linux/mii.h +++ b/include/linux/mii.h | |||
@@ -22,6 +22,7 @@ | |||
22 | #define MII_EXPANSION 0x06 /* Expansion register */ | 22 | #define MII_EXPANSION 0x06 /* Expansion register */ |
23 | #define MII_CTRL1000 0x09 /* 1000BASE-T control */ | 23 | #define MII_CTRL1000 0x09 /* 1000BASE-T control */ |
24 | #define MII_STAT1000 0x0a /* 1000BASE-T status */ | 24 | #define MII_STAT1000 0x0a /* 1000BASE-T status */ |
25 | #define MII_ESTATUS 0x0f /* Extended Status */ | ||
25 | #define MII_DCOUNTER 0x12 /* Disconnect counter */ | 26 | #define MII_DCOUNTER 0x12 /* Disconnect counter */ |
26 | #define MII_FCSCOUNTER 0x13 /* False carrier counter */ | 27 | #define MII_FCSCOUNTER 0x13 /* False carrier counter */ |
27 | #define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ | 28 | #define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */ |
@@ -54,7 +55,10 @@ | |||
54 | #define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ | 55 | #define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */ |
55 | #define BMSR_RFAULT 0x0010 /* Remote fault detected */ | 56 | #define BMSR_RFAULT 0x0010 /* Remote fault detected */ |
56 | #define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ | 57 | #define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */ |
57 | #define BMSR_RESV 0x07c0 /* Unused... */ | 58 | #define BMSR_RESV 0x00c0 /* Unused... */ |
59 | #define BMSR_ESTATEN 0x0100 /* Extended Status in R15 */ | ||
60 | #define BMSR_100FULL2 0x0200 /* Can do 100BASE-T2 HDX */ | ||
61 | #define BMSR_100HALF2 0x0400 /* Can do 100BASE-T2 FDX */ | ||
58 | #define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ | 62 | #define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */ |
59 | #define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ | 63 | #define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */ |
60 | #define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ | 64 | #define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */ |
@@ -114,6 +118,9 @@ | |||
114 | #define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ | 118 | #define EXPANSION_MFAULTS 0x0010 /* Multiple faults detected */ |
115 | #define EXPANSION_RESV 0xffe0 /* Unused... */ | 119 | #define EXPANSION_RESV 0xffe0 /* Unused... */ |
116 | 120 | ||
121 | #define ESTATUS_1000_TFULL 0x2000 /* Can do 1000BT Full */ | ||
122 | #define ESTATUS_1000_THALF 0x1000 /* Can do 1000BT Half */ | ||
123 | |||
117 | /* N-way test register. */ | 124 | /* N-way test register. */ |
118 | #define NWAYTEST_RESV1 0x00ff /* Unused... */ | 125 | #define NWAYTEST_RESV1 0x00ff /* Unused... */ |
119 | #define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ | 126 | #define NWAYTEST_LOOPBACK 0x0100 /* Enable loopback for N-way */ |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 7d78a783c64a..9a6047ff1b25 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
@@ -112,7 +112,8 @@ struct nfs_inode { | |||
112 | /* | 112 | /* |
113 | * Various flags | 113 | * Various flags |
114 | */ | 114 | */ |
115 | unsigned int flags; | 115 | unsigned long flags; /* atomic bit ops */ |
116 | unsigned long cache_validity; /* bit mask */ | ||
116 | 117 | ||
117 | /* | 118 | /* |
118 | * read_cache_jiffies is when we started read-caching this inode, | 119 | * read_cache_jiffies is when we started read-caching this inode, |
@@ -174,8 +175,6 @@ struct nfs_inode { | |||
174 | /* Open contexts for shared mmap writes */ | 175 | /* Open contexts for shared mmap writes */ |
175 | struct list_head open_files; | 176 | struct list_head open_files; |
176 | 177 | ||
177 | wait_queue_head_t nfs_i_wait; | ||
178 | |||
179 | #ifdef CONFIG_NFS_V4 | 178 | #ifdef CONFIG_NFS_V4 |
180 | struct nfs4_cached_acl *nfs4_acl; | 179 | struct nfs4_cached_acl *nfs4_acl; |
181 | /* NFSv4 state */ | 180 | /* NFSv4 state */ |
@@ -188,17 +187,21 @@ struct nfs_inode { | |||
188 | }; | 187 | }; |
189 | 188 | ||
190 | /* | 189 | /* |
191 | * Legal inode flag values | 190 | * Cache validity bit flags |
192 | */ | 191 | */ |
193 | #define NFS_INO_STALE 0x0001 /* possible stale inode */ | 192 | #define NFS_INO_INVALID_ATTR 0x0001 /* cached attrs are invalid */ |
194 | #define NFS_INO_ADVISE_RDPLUS 0x0002 /* advise readdirplus */ | 193 | #define NFS_INO_INVALID_DATA 0x0002 /* cached data is invalid */ |
195 | #define NFS_INO_REVALIDATING 0x0004 /* revalidating attrs */ | 194 | #define NFS_INO_INVALID_ATIME 0x0004 /* cached atime is invalid */ |
196 | #define NFS_INO_INVALID_ATTR 0x0008 /* cached attrs are invalid */ | 195 | #define NFS_INO_INVALID_ACCESS 0x0008 /* cached access cred invalid */ |
197 | #define NFS_INO_INVALID_DATA 0x0010 /* cached data is invalid */ | 196 | #define NFS_INO_INVALID_ACL 0x0010 /* cached acls are invalid */ |
198 | #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ | 197 | #define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */ |
199 | #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ | 198 | |
200 | #define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */ | 199 | /* |
201 | #define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */ | 200 | * Bit offsets in flags field |
201 | */ | ||
202 | #define NFS_INO_REVALIDATING (0) /* revalidating attrs */ | ||
203 | #define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */ | ||
204 | #define NFS_INO_STALE (2) /* possible stale inode */ | ||
202 | 205 | ||
203 | static inline struct nfs_inode *NFS_I(struct inode *inode) | 206 | static inline struct nfs_inode *NFS_I(struct inode *inode) |
204 | { | 207 | { |
@@ -224,8 +227,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode) | |||
224 | #define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp) | 227 | #define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp) |
225 | 228 | ||
226 | #define NFS_FLAGS(inode) (NFS_I(inode)->flags) | 229 | #define NFS_FLAGS(inode) (NFS_I(inode)->flags) |
227 | #define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING) | 230 | #define NFS_STALE(inode) (test_bit(NFS_INO_STALE, &NFS_FLAGS(inode))) |
228 | #define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE) | ||
229 | 231 | ||
230 | #define NFS_FILEID(inode) (NFS_I(inode)->fileid) | 232 | #define NFS_FILEID(inode) (NFS_I(inode)->fileid) |
231 | 233 | ||
@@ -236,8 +238,11 @@ static inline int nfs_caches_unstable(struct inode *inode) | |||
236 | 238 | ||
237 | static inline void NFS_CACHEINV(struct inode *inode) | 239 | static inline void NFS_CACHEINV(struct inode *inode) |
238 | { | 240 | { |
239 | if (!nfs_caches_unstable(inode)) | 241 | if (!nfs_caches_unstable(inode)) { |
240 | NFS_FLAGS(inode) |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | 242 | spin_lock(&inode->i_lock); |
243 | NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATTR | NFS_INO_INVALID_ACCESS; | ||
244 | spin_unlock(&inode->i_lock); | ||
245 | } | ||
241 | } | 246 | } |
242 | 247 | ||
243 | static inline int nfs_server_capable(struct inode *inode, int cap) | 248 | static inline int nfs_server_capable(struct inode *inode, int cap) |
@@ -247,7 +252,7 @@ static inline int nfs_server_capable(struct inode *inode, int cap) | |||
247 | 252 | ||
248 | static inline int NFS_USE_READDIRPLUS(struct inode *inode) | 253 | static inline int NFS_USE_READDIRPLUS(struct inode *inode) |
249 | { | 254 | { |
250 | return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS; | 255 | return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); |
251 | } | 256 | } |
252 | 257 | ||
253 | /** | 258 | /** |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 51e61e96051c..499a5325f67f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -881,7 +881,7 @@ | |||
881 | #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e | 881 | #define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e |
882 | #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 | 882 | #define PCI_DEVICE_ID_APPLE_UNI_N_FW2 0x0030 |
883 | #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 | 883 | #define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 |
884 | #define PCI_DEVIEC_ID_APPLE_UNI_N_ATA 0x0033 | 884 | #define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033 |
885 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 | 885 | #define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 |
886 | #define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b | 886 | #define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b |
887 | #define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e | 887 | #define PCI_DEVICE_ID_APPLE_KEYLARGO_I 0x003e |
@@ -1249,6 +1249,7 @@ | |||
1249 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 | 1249 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 |
1250 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 | 1250 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 |
1251 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E | 1251 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E |
1252 | #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x036F | ||
1252 | #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 | 1253 | #define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 |
1253 | #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 | 1254 | #define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 |
1254 | #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B | 1255 | #define PCI_DEVICE_ID_NVIDIA_MCP51_AUDIO 0x026B |
@@ -1580,6 +1581,7 @@ | |||
1580 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 | 1581 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 |
1581 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 | 1582 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 |
1582 | #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 | 1583 | #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 |
1584 | #define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 | ||
1583 | #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 | 1585 | #define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 |
1584 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 | 1586 | #define PCI_DEVICE_ID_SERVERWORKS_OSB4USB 0x0220 |
1585 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB | 1587 | #define PCI_DEVICE_ID_SERVERWORKS_CSB5USB PCI_DEVICE_ID_SERVERWORKS_OSB4USB |
@@ -2184,6 +2186,9 @@ | |||
2184 | #define PCI_VENDOR_ID_SIBYTE 0x166d | 2186 | #define PCI_VENDOR_ID_SIBYTE 0x166d |
2185 | #define PCI_DEVICE_ID_BCM1250_HT 0x0002 | 2187 | #define PCI_DEVICE_ID_BCM1250_HT 0x0002 |
2186 | 2188 | ||
2189 | #define PCI_VENDOR_ID_NETCELL 0x169c | ||
2190 | #define PCI_DEVICE_ID_REVOLUTION 0x0044 | ||
2191 | |||
2187 | #define PCI_VENDOR_ID_LINKSYS 0x1737 | 2192 | #define PCI_VENDOR_ID_LINKSYS 0x1737 |
2188 | #define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 | 2193 | #define PCI_DEVICE_ID_LINKSYS_EG1032 0x1032 |
2189 | #define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 | 2194 | #define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 |
diff --git a/include/linux/phy.h b/include/linux/phy.h new file mode 100644 index 000000000000..72cb67b66e0c --- /dev/null +++ b/include/linux/phy.h | |||
@@ -0,0 +1,377 @@ | |||
1 | /* | ||
2 | * include/linux/phy.h | ||
3 | * | ||
4 | * Framework and drivers for configuring and reading different PHYs | ||
5 | * Based on code in sungem_phy.c and gianfar_phy.c | ||
6 | * | ||
7 | * Author: Andy Fleming | ||
8 | * | ||
9 | * Copyright (c) 2004 Freescale Semiconductor, Inc. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | #ifndef __PHY_H | ||
19 | #define __PHY_H | ||
20 | |||
21 | #include <linux/spinlock.h> | ||
22 | #include <linux/device.h> | ||
23 | |||
24 | #define PHY_BASIC_FEATURES (SUPPORTED_10baseT_Half | \ | ||
25 | SUPPORTED_10baseT_Full | \ | ||
26 | SUPPORTED_100baseT_Half | \ | ||
27 | SUPPORTED_100baseT_Full | \ | ||
28 | SUPPORTED_Autoneg | \ | ||
29 | SUPPORTED_TP | \ | ||
30 | SUPPORTED_MII) | ||
31 | |||
32 | #define PHY_GBIT_FEATURES (PHY_BASIC_FEATURES | \ | ||
33 | SUPPORTED_1000baseT_Half | \ | ||
34 | SUPPORTED_1000baseT_Full) | ||
35 | |||
36 | /* Set phydev->irq to PHY_POLL if interrupts are not supported, | ||
37 | * or not desired for this PHY. Set to PHY_IGNORE_INTERRUPT if | ||
38 | * the attached driver handles the interrupt | ||
39 | */ | ||
40 | #define PHY_POLL -1 | ||
41 | #define PHY_IGNORE_INTERRUPT -2 | ||
42 | |||
43 | #define PHY_HAS_INTERRUPT 0x00000001 | ||
44 | #define PHY_HAS_MAGICANEG 0x00000002 | ||
45 | |||
46 | #define MII_BUS_MAX 4 | ||
47 | |||
48 | |||
49 | #define PHY_INIT_TIMEOUT 100000 | ||
50 | #define PHY_STATE_TIME 1 | ||
51 | #define PHY_FORCE_TIMEOUT 10 | ||
52 | #define PHY_AN_TIMEOUT 10 | ||
53 | |||
54 | #define PHY_MAX_ADDR 32 | ||
55 | |||
56 | /* The Bus class for PHYs. Devices which provide access to | ||
57 | * PHYs should register using this structure */ | ||
58 | struct mii_bus { | ||
59 | const char *name; | ||
60 | int id; | ||
61 | void *priv; | ||
62 | int (*read)(struct mii_bus *bus, int phy_id, int regnum); | ||
63 | int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); | ||
64 | int (*reset)(struct mii_bus *bus); | ||
65 | |||
66 | /* A lock to ensure that only one thing can read/write | ||
67 | * the MDIO bus at a time */ | ||
68 | spinlock_t mdio_lock; | ||
69 | |||
70 | struct device *dev; | ||
71 | |||
72 | /* list of all PHYs on bus */ | ||
73 | struct phy_device *phy_map[PHY_MAX_ADDR]; | ||
74 | |||
75 | /* Pointer to an array of interrupts, each PHY's | ||
76 | * interrupt at the index matching its address */ | ||
77 | int *irq; | ||
78 | }; | ||
79 | |||
80 | #define PHY_INTERRUPT_DISABLED 0x0 | ||
81 | #define PHY_INTERRUPT_ENABLED 0x80000000 | ||
82 | |||
83 | /* PHY state machine states: | ||
84 | * | ||
85 | * DOWN: PHY device and driver are not ready for anything. probe | ||
86 | * should be called if and only if the PHY is in this state, | ||
87 | * given that the PHY device exists. | ||
88 | * - PHY driver probe function will, depending on the PHY, set | ||
89 | * the state to STARTING or READY | ||
90 | * | ||
91 | * STARTING: PHY device is coming up, and the ethernet driver is | ||
92 | * not ready. PHY drivers may set this in the probe function. | ||
93 | * If they do, they are responsible for making sure the state is | ||
94 | * eventually set to indicate whether the PHY is UP or READY, | ||
95 | * depending on the state when the PHY is done starting up. | ||
96 | * - PHY driver will set the state to READY | ||
97 | * - start will set the state to PENDING | ||
98 | * | ||
99 | * READY: PHY is ready to send and receive packets, but the | ||
100 | * controller is not. By default, PHYs which do not implement | ||
101 | * probe will be set to this state by phy_probe(). If the PHY | ||
102 | * driver knows the PHY is ready, and the PHY state is STARTING, | ||
103 | * then it sets this STATE. | ||
104 | * - start will set the state to UP | ||
105 | * | ||
106 | * PENDING: PHY device is coming up, but the ethernet driver is | ||
107 | * ready. phy_start will set this state if the PHY state is | ||
108 | * STARTING. | ||
109 | * - PHY driver will set the state to UP when the PHY is ready | ||
110 | * | ||
111 | * UP: The PHY and attached device are ready to do work. | ||
112 | * Interrupts should be started here. | ||
113 | * - timer moves to AN | ||
114 | * | ||
115 | * AN: The PHY is currently negotiating the link state. Link is | ||
116 | * therefore down for now. phy_timer will set this state when it | ||
117 | * detects the state is UP. config_aneg will set this state | ||
118 | * whenever called with phydev->autoneg set to AUTONEG_ENABLE. | ||
119 | * - If autonegotiation finishes, but there's no link, it sets | ||
120 | * the state to NOLINK. | ||
121 | * - If aneg finishes with link, it sets the state to RUNNING, | ||
122 | * and calls adjust_link | ||
123 | * - If autonegotiation did not finish after an arbitrary amount | ||
124 | * of time, autonegotiation should be tried again if the PHY | ||
125 | * supports "magic" autonegotiation (back to AN) | ||
126 | * - If it didn't finish, and no magic_aneg, move to FORCING. | ||
127 | * | ||
128 | * NOLINK: PHY is up, but not currently plugged in. | ||
129 | * - If the timer notes that the link comes back, we move to RUNNING | ||
130 | * - config_aneg moves to AN | ||
131 | * - phy_stop moves to HALTED | ||
132 | * | ||
133 | * FORCING: PHY is being configured with forced settings | ||
134 | * - if link is up, move to RUNNING | ||
135 | * - If link is down, we drop to the next highest setting, and | ||
136 | * retry (FORCING) after a timeout | ||
137 | * - phy_stop moves to HALTED | ||
138 | * | ||
139 | * RUNNING: PHY is currently up, running, and possibly sending | ||
140 | * and/or receiving packets | ||
141 | * - timer will set CHANGELINK if we're polling (this ensures the | ||
142 | * link state is polled every other cycle of this state machine, | ||
143 | * which makes it every other second) | ||
144 | * - irq will set CHANGELINK | ||
145 | * - config_aneg will set AN | ||
146 | * - phy_stop moves to HALTED | ||
147 | * | ||
148 | * CHANGELINK: PHY experienced a change in link state | ||
149 | * - timer moves to RUNNING if link | ||
150 | * - timer moves to NOLINK if the link is down | ||
151 | * - phy_stop moves to HALTED | ||
152 | * | ||
153 | * HALTED: PHY is up, but no polling or interrupts are done. Or | ||
154 | * PHY is in an error state. | ||
155 | * | ||
156 | * - phy_start moves to RESUMING | ||
157 | * | ||
158 | * RESUMING: PHY was halted, but now wants to run again. | ||
159 | * - If we are forcing, or aneg is done, timer moves to RUNNING | ||
160 | * - If aneg is not done, timer moves to AN | ||
161 | * - phy_stop moves to HALTED | ||
162 | */ | ||
163 | enum phy_state { | ||
164 | PHY_DOWN=0, | ||
165 | PHY_STARTING, | ||
166 | PHY_READY, | ||
167 | PHY_PENDING, | ||
168 | PHY_UP, | ||
169 | PHY_AN, | ||
170 | PHY_RUNNING, | ||
171 | PHY_NOLINK, | ||
172 | PHY_FORCING, | ||
173 | PHY_CHANGELINK, | ||
174 | PHY_HALTED, | ||
175 | PHY_RESUMING | ||
176 | }; | ||
177 | |||
178 | /* phy_device: An instance of a PHY | ||
179 | * | ||
180 | * drv: Pointer to the driver for this PHY instance | ||
181 | * bus: Pointer to the bus this PHY is on | ||
182 | * dev: driver model device structure for this PHY | ||
183 | * phy_id: UID for this device found during discovery | ||
184 | * state: state of the PHY for management purposes | ||
185 | * dev_flags: Device-specific flags used by the PHY driver. | ||
186 | * addr: Bus address of PHY | ||
187 | * link_timeout: The number of timer firings to wait before the | ||
188 | * giving up on the current attempt at acquiring a link | ||
189 | * irq: IRQ number of the PHY's interrupt (-1 if none) | ||
190 | * phy_timer: The timer for handling the state machine | ||
191 | * phy_queue: A work_queue for the interrupt | ||
192 | * attached_dev: The attached enet driver's device instance ptr | ||
193 | * adjust_link: Callback for the enet controller to respond to | ||
194 | * changes in the link state. | ||
195 | * adjust_state: Callback for the enet driver to respond to | ||
196 | * changes in the state machine. | ||
197 | * | ||
198 | * speed, duplex, pause, supported, advertising, and | ||
199 | * autoneg are used like in mii_if_info | ||
200 | * | ||
201 | * interrupts currently only supports enabled or disabled, | ||
202 | * but could be changed in the future to support enabling | ||
203 | * and disabling specific interrupts | ||
204 | * | ||
205 | * Contains some infrastructure for polling and interrupt | ||
206 | * handling, as well as handling shifts in PHY hardware state | ||
207 | */ | ||
208 | struct phy_device { | ||
209 | /* Information about the PHY type */ | ||
210 | /* And management functions */ | ||
211 | struct phy_driver *drv; | ||
212 | |||
213 | struct mii_bus *bus; | ||
214 | |||
215 | struct device dev; | ||
216 | |||
217 | u32 phy_id; | ||
218 | |||
219 | enum phy_state state; | ||
220 | |||
221 | u32 dev_flags; | ||
222 | |||
223 | /* Bus address of the PHY (0-32) */ | ||
224 | int addr; | ||
225 | |||
226 | /* forced speed & duplex (no autoneg) | ||
227 | * partner speed & duplex & pause (autoneg) | ||
228 | */ | ||
229 | int speed; | ||
230 | int duplex; | ||
231 | int pause; | ||
232 | int asym_pause; | ||
233 | |||
234 | /* The most recently read link state */ | ||
235 | int link; | ||
236 | |||
237 | /* Enabled Interrupts */ | ||
238 | u32 interrupts; | ||
239 | |||
240 | /* Union of PHY and Attached devices' supported modes */ | ||
241 | /* See mii.h for more info */ | ||
242 | u32 supported; | ||
243 | u32 advertising; | ||
244 | |||
245 | int autoneg; | ||
246 | |||
247 | int link_timeout; | ||
248 | |||
249 | /* Interrupt number for this PHY | ||
250 | * -1 means no interrupt */ | ||
251 | int irq; | ||
252 | |||
253 | /* private data pointer */ | ||
254 | /* For use by PHYs to maintain extra state */ | ||
255 | void *priv; | ||
256 | |||
257 | /* Interrupt and Polling infrastructure */ | ||
258 | struct work_struct phy_queue; | ||
259 | struct timer_list phy_timer; | ||
260 | |||
261 | spinlock_t lock; | ||
262 | |||
263 | struct net_device *attached_dev; | ||
264 | |||
265 | void (*adjust_link)(struct net_device *dev); | ||
266 | |||
267 | void (*adjust_state)(struct net_device *dev); | ||
268 | }; | ||
269 | #define to_phy_device(d) container_of(d, struct phy_device, dev) | ||
270 | |||
271 | /* struct phy_driver: Driver structure for a particular PHY type | ||
272 | * | ||
273 | * phy_id: The result of reading the UID registers of this PHY | ||
274 | * type, and ANDing them with the phy_id_mask. This driver | ||
275 | * only works for PHYs with IDs which match this field | ||
276 | * name: The friendly name of this PHY type | ||
277 | * phy_id_mask: Defines the important bits of the phy_id | ||
278 | * features: A list of features (speed, duplex, etc) supported | ||
279 | * by this PHY | ||
280 | * flags: A bitfield defining certain other features this PHY | ||
281 | * supports (like interrupts) | ||
282 | * | ||
283 | * The drivers must implement config_aneg and read_status. All | ||
284 | * other functions are optional. Note that none of these | ||
285 | * functions should be called from interrupt time. The goal is | ||
286 | * for the bus read/write functions to be able to block when the | ||
287 | * bus transaction is happening, and be freed up by an interrupt | ||
288 | * (The MPC85xx has this ability, though it is not currently | ||
289 | * supported in the driver). | ||
290 | */ | ||
291 | struct phy_driver { | ||
292 | u32 phy_id; | ||
293 | char *name; | ||
294 | unsigned int phy_id_mask; | ||
295 | u32 features; | ||
296 | u32 flags; | ||
297 | |||
298 | /* Called to initialize the PHY, | ||
299 | * including after a reset */ | ||
300 | int (*config_init)(struct phy_device *phydev); | ||
301 | |||
302 | /* Called during discovery. Used to set | ||
303 | * up device-specific structures, if any */ | ||
304 | int (*probe)(struct phy_device *phydev); | ||
305 | |||
306 | /* PHY Power Management */ | ||
307 | int (*suspend)(struct phy_device *phydev); | ||
308 | int (*resume)(struct phy_device *phydev); | ||
309 | |||
310 | /* Configures the advertisement and resets | ||
311 | * autonegotiation if phydev->autoneg is on, | ||
312 | * forces the speed to the current settings in phydev | ||
313 | * if phydev->autoneg is off */ | ||
314 | int (*config_aneg)(struct phy_device *phydev); | ||
315 | |||
316 | /* Determines the negotiated speed and duplex */ | ||
317 | int (*read_status)(struct phy_device *phydev); | ||
318 | |||
319 | /* Clears any pending interrupts */ | ||
320 | int (*ack_interrupt)(struct phy_device *phydev); | ||
321 | |||
322 | /* Enables or disables interrupts */ | ||
323 | int (*config_intr)(struct phy_device *phydev); | ||
324 | |||
325 | /* Clears up any memory if needed */ | ||
326 | void (*remove)(struct phy_device *phydev); | ||
327 | |||
328 | struct device_driver driver; | ||
329 | }; | ||
330 | #define to_phy_driver(d) container_of(d, struct phy_driver, driver) | ||
331 | |||
332 | int phy_read(struct phy_device *phydev, u16 regnum); | ||
333 | int phy_write(struct phy_device *phydev, u16 regnum, u16 val); | ||
334 | struct phy_device* get_phy_device(struct mii_bus *bus, int addr); | ||
335 | int phy_clear_interrupt(struct phy_device *phydev); | ||
336 | int phy_config_interrupt(struct phy_device *phydev, u32 interrupts); | ||
337 | struct phy_device * phy_attach(struct net_device *dev, | ||
338 | const char *phy_id, u32 flags); | ||
339 | struct phy_device * phy_connect(struct net_device *dev, const char *phy_id, | ||
340 | void (*handler)(struct net_device *), u32 flags); | ||
341 | void phy_disconnect(struct phy_device *phydev); | ||
342 | void phy_detach(struct phy_device *phydev); | ||
343 | void phy_start(struct phy_device *phydev); | ||
344 | void phy_stop(struct phy_device *phydev); | ||
345 | int phy_start_aneg(struct phy_device *phydev); | ||
346 | |||
347 | int mdiobus_register(struct mii_bus *bus); | ||
348 | void mdiobus_unregister(struct mii_bus *bus); | ||
349 | void phy_sanitize_settings(struct phy_device *phydev); | ||
350 | int phy_stop_interrupts(struct phy_device *phydev); | ||
351 | |||
352 | static inline int phy_read_status(struct phy_device *phydev) { | ||
353 | return phydev->drv->read_status(phydev); | ||
354 | } | ||
355 | |||
356 | int genphy_config_advert(struct phy_device *phydev); | ||
357 | int genphy_setup_forced(struct phy_device *phydev); | ||
358 | int genphy_restart_aneg(struct phy_device *phydev); | ||
359 | int genphy_config_aneg(struct phy_device *phydev); | ||
360 | int genphy_update_link(struct phy_device *phydev); | ||
361 | int genphy_read_status(struct phy_device *phydev); | ||
362 | void phy_driver_unregister(struct phy_driver *drv); | ||
363 | int phy_driver_register(struct phy_driver *new_driver); | ||
364 | void phy_prepare_link(struct phy_device *phydev, | ||
365 | void (*adjust_link)(struct net_device *)); | ||
366 | void phy_start_machine(struct phy_device *phydev, | ||
367 | void (*handler)(struct net_device *)); | ||
368 | void phy_stop_machine(struct phy_device *phydev); | ||
369 | int phy_ethtool_sset(struct phy_device *phydev, struct ethtool_cmd *cmd); | ||
370 | int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd); | ||
371 | int phy_mii_ioctl(struct phy_device *phydev, | ||
372 | struct mii_ioctl_data *mii_data, int cmd); | ||
373 | int phy_start_interrupts(struct phy_device *phydev); | ||
374 | void phy_print_status(struct phy_device *phydev); | ||
375 | |||
376 | extern struct bus_type mdio_bus_type; | ||
377 | #endif /* __PHY_H */ | ||
diff --git a/include/net/ax25.h b/include/net/ax25.h index 828a3a93dda1..3696f988a9f1 100644 --- a/include/net/ax25.h +++ b/include/net/ax25.h | |||
@@ -139,11 +139,25 @@ enum { | |||
139 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ | 139 | #define AX25_DEF_DS_TIMEOUT (3 * 60 * HZ) /* DAMA timeout 3 minutes */ |
140 | 140 | ||
141 | typedef struct ax25_uid_assoc { | 141 | typedef struct ax25_uid_assoc { |
142 | struct ax25_uid_assoc *next; | 142 | struct hlist_node uid_node; |
143 | atomic_t refcount; | ||
143 | uid_t uid; | 144 | uid_t uid; |
144 | ax25_address call; | 145 | ax25_address call; |
145 | } ax25_uid_assoc; | 146 | } ax25_uid_assoc; |
146 | 147 | ||
148 | #define ax25_uid_for_each(__ax25, node, list) \ | ||
149 | hlist_for_each_entry(__ax25, node, list, uid_node) | ||
150 | |||
151 | #define ax25_uid_hold(ax25) \ | ||
152 | atomic_inc(&((ax25)->refcount)) | ||
153 | |||
154 | static inline void ax25_uid_put(ax25_uid_assoc *assoc) | ||
155 | { | ||
156 | if (atomic_dec_and_test(&assoc->refcount)) { | ||
157 | kfree(assoc); | ||
158 | } | ||
159 | } | ||
160 | |||
147 | typedef struct { | 161 | typedef struct { |
148 | ax25_address calls[AX25_MAX_DIGIS]; | 162 | ax25_address calls[AX25_MAX_DIGIS]; |
149 | unsigned char repeated[AX25_MAX_DIGIS]; | 163 | unsigned char repeated[AX25_MAX_DIGIS]; |
@@ -376,7 +390,7 @@ extern unsigned long ax25_display_timer(struct timer_list *); | |||
376 | 390 | ||
377 | /* ax25_uid.c */ | 391 | /* ax25_uid.c */ |
378 | extern int ax25_uid_policy; | 392 | extern int ax25_uid_policy; |
379 | extern ax25_address *ax25_findbyuid(uid_t); | 393 | extern ax25_uid_assoc *ax25_findbyuid(uid_t); |
380 | extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); | 394 | extern int ax25_uid_ioctl(int, struct sockaddr_ax25 *); |
381 | extern struct file_operations ax25_uid_fops; | 395 | extern struct file_operations ax25_uid_fops; |
382 | extern void ax25_uid_free(void); | 396 | extern void ax25_uid_free(void); |
diff --git a/include/net/sock.h b/include/net/sock.h index a1042d08becd..e9b1dbab90d0 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -384,6 +384,11 @@ enum sock_flags { | |||
384 | SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ | 384 | SOCK_QUEUE_SHRUNK, /* write queue has been shrunk recently */ |
385 | }; | 385 | }; |
386 | 386 | ||
387 | static inline void sock_copy_flags(struct sock *nsk, struct sock *osk) | ||
388 | { | ||
389 | nsk->sk_flags = osk->sk_flags; | ||
390 | } | ||
391 | |||
387 | static inline void sock_set_flag(struct sock *sk, enum sock_flags flag) | 392 | static inline void sock_set_flag(struct sock *sk, enum sock_flags flag) |
388 | { | 393 | { |
389 | __set_bit(flag, &sk->sk_flags); | 394 | __set_bit(flag, &sk->sk_flags); |
diff --git a/include/sound/core.h b/include/sound/core.h index 38b357fc8958..f72b3ef515e2 100644 --- a/include/sound/core.h +++ b/include/sound/core.h | |||
@@ -360,11 +360,13 @@ int snd_device_free_all(snd_card_t *card, snd_device_cmd_t cmd); | |||
360 | 360 | ||
361 | /* isadma.c */ | 361 | /* isadma.c */ |
362 | 362 | ||
363 | #ifdef CONFIG_ISA_DMA_API | ||
363 | #define DMA_MODE_NO_ENABLE 0x0100 | 364 | #define DMA_MODE_NO_ENABLE 0x0100 |
364 | 365 | ||
365 | void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode); | 366 | void snd_dma_program(unsigned long dma, unsigned long addr, unsigned int size, unsigned short mode); |
366 | void snd_dma_disable(unsigned long dma); | 367 | void snd_dma_disable(unsigned long dma); |
367 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size); | 368 | unsigned int snd_dma_pointer(unsigned long dma, unsigned int size); |
369 | #endif | ||
368 | 370 | ||
369 | /* misc.c */ | 371 | /* misc.c */ |
370 | 372 | ||
diff --git a/kernel/cpuset.c b/kernel/cpuset.c index 21a4e3b2cbda..8ab1b4e518b8 100644 --- a/kernel/cpuset.c +++ b/kernel/cpuset.c | |||
@@ -627,6 +627,14 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial) | |||
627 | * Call with cpuset_sem held. May nest a call to the | 627 | * Call with cpuset_sem held. May nest a call to the |
628 | * lock_cpu_hotplug()/unlock_cpu_hotplug() pair. | 628 | * lock_cpu_hotplug()/unlock_cpu_hotplug() pair. |
629 | */ | 629 | */ |
630 | |||
631 | /* | ||
632 | * Hack to avoid 2.6.13 partial node dynamic sched domain bug. | ||
633 | * Disable letting 'cpu_exclusive' cpusets define dynamic sched | ||
634 | * domains, until the sched domain can handle partial nodes. | ||
635 | * Remove this #if hackery when sched domains fixed. | ||
636 | */ | ||
637 | #if 0 | ||
630 | static void update_cpu_domains(struct cpuset *cur) | 638 | static void update_cpu_domains(struct cpuset *cur) |
631 | { | 639 | { |
632 | struct cpuset *c, *par = cur->parent; | 640 | struct cpuset *c, *par = cur->parent; |
@@ -667,6 +675,11 @@ static void update_cpu_domains(struct cpuset *cur) | |||
667 | partition_sched_domains(&pspan, &cspan); | 675 | partition_sched_domains(&pspan, &cspan); |
668 | unlock_cpu_hotplug(); | 676 | unlock_cpu_hotplug(); |
669 | } | 677 | } |
678 | #else | ||
679 | static void update_cpu_domains(struct cpuset *cur) | ||
680 | { | ||
681 | } | ||
682 | #endif | ||
670 | 683 | ||
671 | static int update_cpumask(struct cpuset *cs, char *buf) | 684 | static int update_cpumask(struct cpuset *cs, char *buf) |
672 | { | 685 | { |
diff --git a/kernel/sched.c b/kernel/sched.c index a646e4f36c41..5f889d0cbfcc 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3378,8 +3378,8 @@ EXPORT_SYMBOL(set_user_nice); | |||
3378 | */ | 3378 | */ |
3379 | int can_nice(const task_t *p, const int nice) | 3379 | int can_nice(const task_t *p, const int nice) |
3380 | { | 3380 | { |
3381 | /* convert nice value [19,-20] to rlimit style value [0,39] */ | 3381 | /* convert nice value [19,-20] to rlimit style value [1,40] */ |
3382 | int nice_rlim = 19 - nice; | 3382 | int nice_rlim = 20 - nice; |
3383 | return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || | 3383 | return (nice_rlim <= p->signal->rlim[RLIMIT_NICE].rlim_cur || |
3384 | capable(CAP_SYS_NICE)); | 3384 | capable(CAP_SYS_NICE)); |
3385 | } | 3385 | } |
diff --git a/kernel/timer.c b/kernel/timer.c index f2a11887a726..5377f40723ff 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1023,7 +1023,7 @@ asmlinkage long sys_getppid(void) | |||
1023 | parent = me->group_leader->real_parent; | 1023 | parent = me->group_leader->real_parent; |
1024 | for (;;) { | 1024 | for (;;) { |
1025 | pid = parent->tgid; | 1025 | pid = parent->tgid; |
1026 | #ifdef CONFIG_SMP | 1026 | #if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT) |
1027 | { | 1027 | { |
1028 | struct task_struct *old = parent; | 1028 | struct task_struct *old = parent; |
1029 | 1029 | ||
@@ -207,7 +207,7 @@ build_up: | |||
207 | } | 207 | } |
208 | 208 | ||
209 | /** | 209 | /** |
210 | * idr_get_new_above - allocate new idr entry above a start id | 210 | * idr_get_new_above - allocate new idr entry above or equal to a start id |
211 | * @idp: idr handle | 211 | * @idp: idr handle |
212 | * @ptr: pointer you want associated with the ide | 212 | * @ptr: pointer you want associated with the ide |
213 | * @start_id: id to start search at | 213 | * @start_id: id to start search at |
diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a9bda0a361f3..e4e9031dd9c3 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c | |||
@@ -269,6 +269,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
269 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ | 269 | int qualifier; /* 'h', 'l', or 'L' for integer fields */ |
270 | /* 'z' support added 23/7/1999 S.H. */ | 270 | /* 'z' support added 23/7/1999 S.H. */ |
271 | /* 'z' changed to 'Z' --davidm 1/25/99 */ | 271 | /* 'z' changed to 'Z' --davidm 1/25/99 */ |
272 | /* 't' added for ptrdiff_t */ | ||
272 | 273 | ||
273 | /* Reject out-of-range values early */ | 274 | /* Reject out-of-range values early */ |
274 | if (unlikely((int) size < 0)) { | 275 | if (unlikely((int) size < 0)) { |
@@ -339,7 +340,7 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
339 | /* get the conversion qualifier */ | 340 | /* get the conversion qualifier */ |
340 | qualifier = -1; | 341 | qualifier = -1; |
341 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || | 342 | if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || |
342 | *fmt =='Z' || *fmt == 'z') { | 343 | *fmt =='Z' || *fmt == 'z' || *fmt == 't') { |
343 | qualifier = *fmt; | 344 | qualifier = *fmt; |
344 | ++fmt; | 345 | ++fmt; |
345 | if (qualifier == 'l' && *fmt == 'l') { | 346 | if (qualifier == 'l' && *fmt == 'l') { |
@@ -467,6 +468,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) | |||
467 | num = (signed long) num; | 468 | num = (signed long) num; |
468 | } else if (qualifier == 'Z' || qualifier == 'z') { | 469 | } else if (qualifier == 'Z' || qualifier == 'z') { |
469 | num = va_arg(args, size_t); | 470 | num = va_arg(args, size_t); |
471 | } else if (qualifier == 't') { | ||
472 | num = va_arg(args, ptrdiff_t); | ||
470 | } else if (qualifier == 'h') { | 473 | } else if (qualifier == 'h') { |
471 | num = (unsigned short) va_arg(args, int); | 474 | num = (unsigned short) va_arg(args, int); |
472 | if (flags & SIGN) | 475 | if (flags & SIGN) |
diff --git a/mm/shmem.c b/mm/shmem.c index e64fa726a790..5a81b1ee4f7a 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -1773,32 +1773,27 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s | |||
1773 | return 0; | 1773 | return 0; |
1774 | } | 1774 | } |
1775 | 1775 | ||
1776 | static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) | 1776 | static void *shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd) |
1777 | { | 1777 | { |
1778 | nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); | 1778 | nd_set_link(nd, (char *)SHMEM_I(dentry->d_inode)); |
1779 | return 0; | 1779 | return NULL; |
1780 | } | 1780 | } |
1781 | 1781 | ||
1782 | static int shmem_follow_link(struct dentry *dentry, struct nameidata *nd) | 1782 | static void *shmem_follow_link(struct dentry *dentry, struct nameidata *nd) |
1783 | { | 1783 | { |
1784 | struct page *page = NULL; | 1784 | struct page *page = NULL; |
1785 | int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); | 1785 | int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ, NULL); |
1786 | nd_set_link(nd, res ? ERR_PTR(res) : kmap(page)); | 1786 | nd_set_link(nd, res ? ERR_PTR(res) : kmap(page)); |
1787 | return 0; | 1787 | return page; |
1788 | } | 1788 | } |
1789 | 1789 | ||
1790 | static void shmem_put_link(struct dentry *dentry, struct nameidata *nd) | 1790 | static void shmem_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) |
1791 | { | 1791 | { |
1792 | if (!IS_ERR(nd_get_link(nd))) { | 1792 | if (!IS_ERR(nd_get_link(nd))) { |
1793 | struct page *page; | 1793 | struct page *page = cookie; |
1794 | |||
1795 | page = find_get_page(dentry->d_inode->i_mapping, 0); | ||
1796 | if (!page) | ||
1797 | BUG(); | ||
1798 | kunmap(page); | 1794 | kunmap(page); |
1799 | mark_page_accessed(page); | 1795 | mark_page_accessed(page); |
1800 | page_cache_release(page); | 1796 | page_cache_release(page); |
1801 | page_cache_release(page); | ||
1802 | } | 1797 | } |
1803 | } | 1798 | } |
1804 | 1799 | ||
diff --git a/net/802/tr.c b/net/802/tr.c index a755e880f4ba..1bb7dc1b85cd 100644 --- a/net/802/tr.c +++ b/net/802/tr.c | |||
@@ -251,10 +251,11 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device * | |||
251 | unsigned int hash; | 251 | unsigned int hash; |
252 | struct rif_cache *entry; | 252 | struct rif_cache *entry; |
253 | unsigned char *olddata; | 253 | unsigned char *olddata; |
254 | unsigned long flags; | ||
254 | static const unsigned char mcast_func_addr[] | 255 | static const unsigned char mcast_func_addr[] |
255 | = {0xC0,0x00,0x00,0x04,0x00,0x00}; | 256 | = {0xC0,0x00,0x00,0x04,0x00,0x00}; |
256 | 257 | ||
257 | spin_lock_bh(&rif_lock); | 258 | spin_lock_irqsave(&rif_lock, flags); |
258 | 259 | ||
259 | /* | 260 | /* |
260 | * Broadcasts are single route as stated in RFC 1042 | 261 | * Broadcasts are single route as stated in RFC 1042 |
@@ -323,7 +324,7 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0], | |||
323 | else | 324 | else |
324 | slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); | 325 | slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); |
325 | olddata = skb->data; | 326 | olddata = skb->data; |
326 | spin_unlock_bh(&rif_lock); | 327 | spin_unlock_irqrestore(&rif_lock, flags); |
327 | 328 | ||
328 | skb_pull(skb, slack); | 329 | skb_pull(skb, slack); |
329 | memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); | 330 | memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); |
@@ -337,10 +338,11 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0], | |||
337 | static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) | 338 | static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) |
338 | { | 339 | { |
339 | unsigned int hash, rii_p = 0; | 340 | unsigned int hash, rii_p = 0; |
341 | unsigned long flags; | ||
340 | struct rif_cache *entry; | 342 | struct rif_cache *entry; |
341 | 343 | ||
342 | 344 | ||
343 | spin_lock_bh(&rif_lock); | 345 | spin_lock_irqsave(&rif_lock, flags); |
344 | 346 | ||
345 | /* | 347 | /* |
346 | * Firstly see if the entry exists | 348 | * Firstly see if the entry exists |
@@ -378,7 +380,7 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", | |||
378 | if(!entry) | 380 | if(!entry) |
379 | { | 381 | { |
380 | printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); | 382 | printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); |
381 | spin_unlock_bh(&rif_lock); | 383 | spin_unlock_irqrestore(&rif_lock, flags); |
382 | return; | 384 | return; |
383 | } | 385 | } |
384 | 386 | ||
@@ -420,7 +422,7 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", | |||
420 | } | 422 | } |
421 | entry->last_used=jiffies; | 423 | entry->last_used=jiffies; |
422 | } | 424 | } |
423 | spin_unlock_bh(&rif_lock); | 425 | spin_unlock_irqrestore(&rif_lock, flags); |
424 | } | 426 | } |
425 | 427 | ||
426 | /* | 428 | /* |
@@ -430,9 +432,9 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n", | |||
430 | static void rif_check_expire(unsigned long dummy) | 432 | static void rif_check_expire(unsigned long dummy) |
431 | { | 433 | { |
432 | int i; | 434 | int i; |
433 | unsigned long next_interval = jiffies + sysctl_tr_rif_timeout/2; | 435 | unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2; |
434 | 436 | ||
435 | spin_lock_bh(&rif_lock); | 437 | spin_lock_irqsave(&rif_lock, flags); |
436 | 438 | ||
437 | for(i =0; i < RIF_TABLE_SIZE; i++) { | 439 | for(i =0; i < RIF_TABLE_SIZE; i++) { |
438 | struct rif_cache *entry, **pentry; | 440 | struct rif_cache *entry, **pentry; |
@@ -454,7 +456,7 @@ static void rif_check_expire(unsigned long dummy) | |||
454 | } | 456 | } |
455 | } | 457 | } |
456 | 458 | ||
457 | spin_unlock_bh(&rif_lock); | 459 | spin_unlock_irqrestore(&rif_lock, flags); |
458 | 460 | ||
459 | mod_timer(&rif_timer, next_interval); | 461 | mod_timer(&rif_timer, next_interval); |
460 | 462 | ||
@@ -485,7 +487,7 @@ static struct rif_cache *rif_get_idx(loff_t pos) | |||
485 | 487 | ||
486 | static void *rif_seq_start(struct seq_file *seq, loff_t *pos) | 488 | static void *rif_seq_start(struct seq_file *seq, loff_t *pos) |
487 | { | 489 | { |
488 | spin_lock_bh(&rif_lock); | 490 | spin_lock_irq(&rif_lock); |
489 | 491 | ||
490 | return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; | 492 | return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; |
491 | } | 493 | } |
@@ -516,7 +518,7 @@ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos) | |||
516 | 518 | ||
517 | static void rif_seq_stop(struct seq_file *seq, void *v) | 519 | static void rif_seq_stop(struct seq_file *seq, void *v) |
518 | { | 520 | { |
519 | spin_unlock_bh(&rif_lock); | 521 | spin_unlock_irq(&rif_lock); |
520 | } | 522 | } |
521 | 523 | ||
522 | static int rif_seq_show(struct seq_file *seq, void *v) | 524 | static int rif_seq_show(struct seq_file *seq, void *v) |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 707097deac3d..a5c94f11547c 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -875,12 +875,7 @@ struct sock *ax25_make_new(struct sock *osk, struct ax25_dev *ax25_dev) | |||
875 | sk->sk_sndbuf = osk->sk_sndbuf; | 875 | sk->sk_sndbuf = osk->sk_sndbuf; |
876 | sk->sk_state = TCP_ESTABLISHED; | 876 | sk->sk_state = TCP_ESTABLISHED; |
877 | sk->sk_sleep = osk->sk_sleep; | 877 | sk->sk_sleep = osk->sk_sleep; |
878 | 878 | sock_copy_flags(sk, osk); | |
879 | if (sock_flag(osk, SOCK_DBG)) | ||
880 | sock_set_flag(sk, SOCK_DBG); | ||
881 | |||
882 | if (sock_flag(osk, SOCK_ZAPPED)) | ||
883 | sock_set_flag(sk, SOCK_ZAPPED); | ||
884 | 879 | ||
885 | oax25 = ax25_sk(osk); | 880 | oax25 = ax25_sk(osk); |
886 | 881 | ||
@@ -1007,7 +1002,8 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1007 | struct sock *sk = sock->sk; | 1002 | struct sock *sk = sock->sk; |
1008 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; | 1003 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; |
1009 | ax25_dev *ax25_dev = NULL; | 1004 | ax25_dev *ax25_dev = NULL; |
1010 | ax25_address *call; | 1005 | ax25_uid_assoc *user; |
1006 | ax25_address call; | ||
1011 | ax25_cb *ax25; | 1007 | ax25_cb *ax25; |
1012 | int err = 0; | 1008 | int err = 0; |
1013 | 1009 | ||
@@ -1026,9 +1022,15 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1026 | if (addr->fsa_ax25.sax25_family != AF_AX25) | 1022 | if (addr->fsa_ax25.sax25_family != AF_AX25) |
1027 | return -EINVAL; | 1023 | return -EINVAL; |
1028 | 1024 | ||
1029 | call = ax25_findbyuid(current->euid); | 1025 | user = ax25_findbyuid(current->euid); |
1030 | if (call == NULL && ax25_uid_policy && !capable(CAP_NET_ADMIN)) { | 1026 | if (user) { |
1031 | return -EACCES; | 1027 | call = user->call; |
1028 | ax25_uid_put(user); | ||
1029 | } else { | ||
1030 | if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) | ||
1031 | return -EACCES; | ||
1032 | |||
1033 | call = addr->fsa_ax25.sax25_call; | ||
1032 | } | 1034 | } |
1033 | 1035 | ||
1034 | lock_sock(sk); | 1036 | lock_sock(sk); |
@@ -1039,10 +1041,7 @@ static int ax25_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
1039 | goto out; | 1041 | goto out; |
1040 | } | 1042 | } |
1041 | 1043 | ||
1042 | if (call == NULL) | 1044 | ax25->source_addr = call; |
1043 | ax25->source_addr = addr->fsa_ax25.sax25_call; | ||
1044 | else | ||
1045 | ax25->source_addr = *call; | ||
1046 | 1045 | ||
1047 | /* | 1046 | /* |
1048 | * User already set interface with SO_BINDTODEVICE | 1047 | * User already set interface with SO_BINDTODEVICE |
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c index 44b99b1ff9f8..c288526da4ce 100644 --- a/net/ax25/ax25_route.c +++ b/net/ax25/ax25_route.c | |||
@@ -422,8 +422,8 @@ static inline void ax25_adjust_path(ax25_address *addr, ax25_digi *digipeat) | |||
422 | */ | 422 | */ |
423 | int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | 423 | int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) |
424 | { | 424 | { |
425 | ax25_uid_assoc *user; | ||
425 | ax25_route *ax25_rt; | 426 | ax25_route *ax25_rt; |
426 | ax25_address *call; | ||
427 | int err; | 427 | int err; |
428 | 428 | ||
429 | if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) | 429 | if ((ax25_rt = ax25_get_route(addr, NULL)) == NULL) |
@@ -434,16 +434,18 @@ int ax25_rt_autobind(ax25_cb *ax25, ax25_address *addr) | |||
434 | goto put; | 434 | goto put; |
435 | } | 435 | } |
436 | 436 | ||
437 | if ((call = ax25_findbyuid(current->euid)) == NULL) { | 437 | user = ax25_findbyuid(current->euid); |
438 | if (user) { | ||
439 | ax25->source_addr = user->call; | ||
440 | ax25_uid_put(user); | ||
441 | } else { | ||
438 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { | 442 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { |
439 | err = -EPERM; | 443 | err = -EPERM; |
440 | goto put; | 444 | goto put; |
441 | } | 445 | } |
442 | call = (ax25_address *)ax25->ax25_dev->dev->dev_addr; | 446 | ax25->source_addr = *(ax25_address *)ax25->ax25_dev->dev->dev_addr; |
443 | } | 447 | } |
444 | 448 | ||
445 | ax25->source_addr = *call; | ||
446 | |||
447 | if (ax25_rt->digipeat != NULL) { | 449 | if (ax25_rt->digipeat != NULL) { |
448 | if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { | 450 | if ((ax25->digipeat = kmalloc(sizeof(ax25_digi), GFP_ATOMIC)) == NULL) { |
449 | err = -ENOMEM; | 451 | err = -ENOMEM; |
diff --git a/net/ax25/ax25_uid.c b/net/ax25/ax25_uid.c index cea6b7d19729..a8b3822f3ee4 100644 --- a/net/ax25/ax25_uid.c +++ b/net/ax25/ax25_uid.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/fcntl.h> | 28 | #include <linux/fcntl.h> |
29 | #include <linux/mm.h> | 29 | #include <linux/mm.h> |
30 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
31 | #include <linux/list.h> | ||
31 | #include <linux/notifier.h> | 32 | #include <linux/notifier.h> |
32 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
33 | #include <linux/seq_file.h> | 34 | #include <linux/seq_file.h> |
@@ -41,38 +42,41 @@ | |||
41 | * Callsign/UID mapper. This is in kernel space for security on multi-amateur machines. | 42 | * Callsign/UID mapper. This is in kernel space for security on multi-amateur machines. |
42 | */ | 43 | */ |
43 | 44 | ||
44 | static ax25_uid_assoc *ax25_uid_list; | 45 | HLIST_HEAD(ax25_uid_list); |
45 | static DEFINE_RWLOCK(ax25_uid_lock); | 46 | static DEFINE_RWLOCK(ax25_uid_lock); |
46 | 47 | ||
47 | int ax25_uid_policy = 0; | 48 | int ax25_uid_policy = 0; |
48 | 49 | ||
49 | ax25_address *ax25_findbyuid(uid_t uid) | 50 | ax25_uid_assoc *ax25_findbyuid(uid_t uid) |
50 | { | 51 | { |
51 | ax25_uid_assoc *ax25_uid; | 52 | ax25_uid_assoc *ax25_uid, *res = NULL; |
52 | ax25_address *res = NULL; | 53 | struct hlist_node *node; |
53 | 54 | ||
54 | read_lock(&ax25_uid_lock); | 55 | read_lock(&ax25_uid_lock); |
55 | for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { | 56 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
56 | if (ax25_uid->uid == uid) { | 57 | if (ax25_uid->uid == uid) { |
57 | res = &ax25_uid->call; | 58 | ax25_uid_hold(ax25_uid); |
59 | res = ax25_uid; | ||
58 | break; | 60 | break; |
59 | } | 61 | } |
60 | } | 62 | } |
61 | read_unlock(&ax25_uid_lock); | 63 | read_unlock(&ax25_uid_lock); |
62 | 64 | ||
63 | return NULL; | 65 | return res; |
64 | } | 66 | } |
65 | 67 | ||
66 | int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | 68 | int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) |
67 | { | 69 | { |
68 | ax25_uid_assoc *s, *ax25_uid; | 70 | ax25_uid_assoc *ax25_uid; |
71 | struct hlist_node *node; | ||
72 | ax25_uid_assoc *user; | ||
69 | unsigned long res; | 73 | unsigned long res; |
70 | 74 | ||
71 | switch (cmd) { | 75 | switch (cmd) { |
72 | case SIOCAX25GETUID: | 76 | case SIOCAX25GETUID: |
73 | res = -ENOENT; | 77 | res = -ENOENT; |
74 | read_lock(&ax25_uid_lock); | 78 | read_lock(&ax25_uid_lock); |
75 | for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { | 79 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
76 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { | 80 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { |
77 | res = ax25_uid->uid; | 81 | res = ax25_uid->uid; |
78 | break; | 82 | break; |
@@ -85,19 +89,22 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
85 | case SIOCAX25ADDUID: | 89 | case SIOCAX25ADDUID: |
86 | if (!capable(CAP_NET_ADMIN)) | 90 | if (!capable(CAP_NET_ADMIN)) |
87 | return -EPERM; | 91 | return -EPERM; |
88 | if (ax25_findbyuid(sax->sax25_uid)) | 92 | user = ax25_findbyuid(sax->sax25_uid); |
93 | if (user) { | ||
94 | ax25_uid_put(user); | ||
89 | return -EEXIST; | 95 | return -EEXIST; |
96 | } | ||
90 | if (sax->sax25_uid == 0) | 97 | if (sax->sax25_uid == 0) |
91 | return -EINVAL; | 98 | return -EINVAL; |
92 | if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL) | 99 | if ((ax25_uid = kmalloc(sizeof(*ax25_uid), GFP_KERNEL)) == NULL) |
93 | return -ENOMEM; | 100 | return -ENOMEM; |
94 | 101 | ||
102 | atomic_set(&ax25_uid->refcount, 1); | ||
95 | ax25_uid->uid = sax->sax25_uid; | 103 | ax25_uid->uid = sax->sax25_uid; |
96 | ax25_uid->call = sax->sax25_call; | 104 | ax25_uid->call = sax->sax25_call; |
97 | 105 | ||
98 | write_lock(&ax25_uid_lock); | 106 | write_lock(&ax25_uid_lock); |
99 | ax25_uid->next = ax25_uid_list; | 107 | hlist_add_head(&ax25_uid->uid_node, &ax25_uid_list); |
100 | ax25_uid_list = ax25_uid; | ||
101 | write_unlock(&ax25_uid_lock); | 108 | write_unlock(&ax25_uid_lock); |
102 | 109 | ||
103 | return 0; | 110 | return 0; |
@@ -106,34 +113,21 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
106 | if (!capable(CAP_NET_ADMIN)) | 113 | if (!capable(CAP_NET_ADMIN)) |
107 | return -EPERM; | 114 | return -EPERM; |
108 | 115 | ||
116 | ax25_uid = NULL; | ||
109 | write_lock(&ax25_uid_lock); | 117 | write_lock(&ax25_uid_lock); |
110 | for (ax25_uid = ax25_uid_list; ax25_uid != NULL; ax25_uid = ax25_uid->next) { | 118 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
111 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) { | 119 | if (ax25cmp(&sax->sax25_call, &ax25_uid->call) == 0) |
112 | break; | 120 | break; |
113 | } | ||
114 | } | 121 | } |
115 | if (ax25_uid == NULL) { | 122 | if (ax25_uid == NULL) { |
116 | write_unlock(&ax25_uid_lock); | 123 | write_unlock(&ax25_uid_lock); |
117 | return -ENOENT; | 124 | return -ENOENT; |
118 | } | 125 | } |
119 | if ((s = ax25_uid_list) == ax25_uid) { | 126 | hlist_del_init(&ax25_uid->uid_node); |
120 | ax25_uid_list = s->next; | 127 | ax25_uid_put(ax25_uid); |
121 | write_unlock(&ax25_uid_lock); | ||
122 | kfree(ax25_uid); | ||
123 | return 0; | ||
124 | } | ||
125 | while (s != NULL && s->next != NULL) { | ||
126 | if (s->next == ax25_uid) { | ||
127 | s->next = ax25_uid->next; | ||
128 | write_unlock(&ax25_uid_lock); | ||
129 | kfree(ax25_uid); | ||
130 | return 0; | ||
131 | } | ||
132 | s = s->next; | ||
133 | } | ||
134 | write_unlock(&ax25_uid_lock); | 128 | write_unlock(&ax25_uid_lock); |
135 | 129 | ||
136 | return -ENOENT; | 130 | return 0; |
137 | 131 | ||
138 | default: | 132 | default: |
139 | return -EINVAL; | 133 | return -EINVAL; |
@@ -147,13 +141,11 @@ int ax25_uid_ioctl(int cmd, struct sockaddr_ax25 *sax) | |||
147 | static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos) | 141 | static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos) |
148 | { | 142 | { |
149 | struct ax25_uid_assoc *pt; | 143 | struct ax25_uid_assoc *pt; |
150 | int i = 1; | 144 | struct hlist_node *node; |
145 | int i = 0; | ||
151 | 146 | ||
152 | read_lock(&ax25_uid_lock); | 147 | read_lock(&ax25_uid_lock); |
153 | if (*pos == 0) | 148 | ax25_uid_for_each(pt, node, &ax25_uid_list) { |
154 | return SEQ_START_TOKEN; | ||
155 | |||
156 | for (pt = ax25_uid_list; pt != NULL; pt = pt->next) { | ||
157 | if (i == *pos) | 149 | if (i == *pos) |
158 | return pt; | 150 | return pt; |
159 | ++i; | 151 | ++i; |
@@ -164,8 +156,9 @@ static void *ax25_uid_seq_start(struct seq_file *seq, loff_t *pos) | |||
164 | static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) | 156 | static void *ax25_uid_seq_next(struct seq_file *seq, void *v, loff_t *pos) |
165 | { | 157 | { |
166 | ++*pos; | 158 | ++*pos; |
167 | return (v == SEQ_START_TOKEN) ? ax25_uid_list : | 159 | |
168 | ((struct ax25_uid_assoc *) v)->next; | 160 | return hlist_entry(((ax25_uid_assoc *)v)->uid_node.next, |
161 | ax25_uid_assoc, uid_node); | ||
169 | } | 162 | } |
170 | 163 | ||
171 | static void ax25_uid_seq_stop(struct seq_file *seq, void *v) | 164 | static void ax25_uid_seq_stop(struct seq_file *seq, void *v) |
@@ -179,7 +172,6 @@ static int ax25_uid_seq_show(struct seq_file *seq, void *v) | |||
179 | seq_printf(seq, "Policy: %d\n", ax25_uid_policy); | 172 | seq_printf(seq, "Policy: %d\n", ax25_uid_policy); |
180 | else { | 173 | else { |
181 | struct ax25_uid_assoc *pt = v; | 174 | struct ax25_uid_assoc *pt = v; |
182 | |||
183 | 175 | ||
184 | seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call)); | 176 | seq_printf(seq, "%6d %s\n", pt->uid, ax2asc(&pt->call)); |
185 | } | 177 | } |
@@ -213,16 +205,13 @@ struct file_operations ax25_uid_fops = { | |||
213 | */ | 205 | */ |
214 | void __exit ax25_uid_free(void) | 206 | void __exit ax25_uid_free(void) |
215 | { | 207 | { |
216 | ax25_uid_assoc *s, *ax25_uid; | 208 | ax25_uid_assoc *ax25_uid; |
209 | struct hlist_node *node; | ||
217 | 210 | ||
218 | write_lock(&ax25_uid_lock); | 211 | write_lock(&ax25_uid_lock); |
219 | ax25_uid = ax25_uid_list; | 212 | ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) { |
220 | while (ax25_uid != NULL) { | 213 | hlist_del_init(&ax25_uid->uid_node); |
221 | s = ax25_uid; | 214 | ax25_uid_put(ax25_uid); |
222 | ax25_uid = ax25_uid->next; | ||
223 | |||
224 | kfree(s); | ||
225 | } | 215 | } |
226 | ax25_uid_list = NULL; | ||
227 | write_unlock(&ax25_uid_lock); | 216 | write_unlock(&ax25_uid_lock); |
228 | } | 217 | } |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index a701405fab0b..45efd5f4741b 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -1333,9 +1333,9 @@ err:; | |||
1333 | } | 1333 | } |
1334 | 1334 | ||
1335 | static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *plen, const struct flowi *flp, | 1335 | static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *plen, const struct flowi *flp, |
1336 | struct fib_result *res, int *err) | 1336 | struct fib_result *res) |
1337 | { | 1337 | { |
1338 | int i; | 1338 | int err, i; |
1339 | t_key mask; | 1339 | t_key mask; |
1340 | struct leaf_info *li; | 1340 | struct leaf_info *li; |
1341 | struct hlist_head *hhead = &l->list; | 1341 | struct hlist_head *hhead = &l->list; |
@@ -1348,18 +1348,18 @@ static inline int check_leaf(struct trie *t, struct leaf *l, t_key key, int *pl | |||
1348 | if (l->key != (key & mask)) | 1348 | if (l->key != (key & mask)) |
1349 | continue; | 1349 | continue; |
1350 | 1350 | ||
1351 | if (((*err) = fib_semantic_match(&li->falh, flp, res, l->key, mask, i)) == 0) { | 1351 | if ((err = fib_semantic_match(&li->falh, flp, res, l->key, mask, i)) <= 0) { |
1352 | *plen = i; | 1352 | *plen = i; |
1353 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 1353 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
1354 | t->stats.semantic_match_passed++; | 1354 | t->stats.semantic_match_passed++; |
1355 | #endif | 1355 | #endif |
1356 | return 1; | 1356 | return err; |
1357 | } | 1357 | } |
1358 | #ifdef CONFIG_IP_FIB_TRIE_STATS | 1358 | #ifdef CONFIG_IP_FIB_TRIE_STATS |
1359 | t->stats.semantic_match_miss++; | 1359 | t->stats.semantic_match_miss++; |
1360 | #endif | 1360 | #endif |
1361 | } | 1361 | } |
1362 | return 0; | 1362 | return 1; |
1363 | } | 1363 | } |
1364 | 1364 | ||
1365 | static int | 1365 | static int |
@@ -1386,7 +1386,7 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result | |||
1386 | 1386 | ||
1387 | /* Just a leaf? */ | 1387 | /* Just a leaf? */ |
1388 | if (IS_LEAF(n)) { | 1388 | if (IS_LEAF(n)) { |
1389 | if (check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret)) | 1389 | if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0) |
1390 | goto found; | 1390 | goto found; |
1391 | goto failed; | 1391 | goto failed; |
1392 | } | 1392 | } |
@@ -1508,7 +1508,7 @@ fn_trie_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result | |||
1508 | continue; | 1508 | continue; |
1509 | } | 1509 | } |
1510 | if (IS_LEAF(n)) { | 1510 | if (IS_LEAF(n)) { |
1511 | if (check_leaf(t, (struct leaf *)n, key, &plen, flp, res, &ret)) | 1511 | if ((ret = check_leaf(t, (struct leaf *)n, key, &plen, flp, res)) <= 0) |
1512 | goto found; | 1512 | goto found; |
1513 | } | 1513 | } |
1514 | backtrace: | 1514 | backtrace: |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 3d78464f64ea..badfc5849973 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -349,12 +349,12 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param, | |||
349 | { | 349 | { |
350 | struct sk_buff *skb; | 350 | struct sk_buff *skb; |
351 | 351 | ||
352 | ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, | 352 | if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, |
353 | icmp_param->data_len+icmp_param->head_len, | 353 | icmp_param->data_len+icmp_param->head_len, |
354 | icmp_param->head_len, | 354 | icmp_param->head_len, |
355 | ipc, rt, MSG_DONTWAIT); | 355 | ipc, rt, MSG_DONTWAIT) < 0) |
356 | 356 | ip_flush_pending_frames(icmp_socket->sk); | |
357 | if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { | 357 | else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { |
358 | struct icmphdr *icmph = skb->h.icmph; | 358 | struct icmphdr *icmph = skb->h.icmph; |
359 | unsigned int csum = 0; | 359 | unsigned int csum = 0; |
360 | struct sk_buff *skb1; | 360 | struct sk_buff *skb1; |
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c index 95473953c406..ab18a853d7ce 100644 --- a/net/ipv4/inetpeer.c +++ b/net/ipv4/inetpeer.c | |||
@@ -450,10 +450,13 @@ static void peer_check_expire(unsigned long dummy) | |||
450 | /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime | 450 | /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime |
451 | * interval depending on the total number of entries (more entries, | 451 | * interval depending on the total number of entries (more entries, |
452 | * less interval). */ | 452 | * less interval). */ |
453 | peer_periodic_timer.expires = jiffies | 453 | if (peer_total >= inet_peer_threshold) |
454 | + inet_peer_gc_maxtime | 454 | peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime; |
455 | - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ * | 455 | else |
456 | peer_total / inet_peer_threshold * HZ; | 456 | peer_periodic_timer.expires = jiffies |
457 | + inet_peer_gc_maxtime | ||
458 | - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ * | ||
459 | peer_total / inet_peer_threshold * HZ; | ||
457 | add_timer(&peer_periodic_timer); | 460 | add_timer(&peer_periodic_timer); |
458 | } | 461 | } |
459 | 462 | ||
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 2065944fd9e5..7ded6e60f43a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -358,7 +358,7 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name) | |||
358 | int cpu; | 358 | int cpu; |
359 | 359 | ||
360 | /* This can be any valid CPU ID so we don't need locking. */ | 360 | /* This can be any valid CPU ID so we don't need locking. */ |
361 | cpu = smp_processor_id(); | 361 | cpu = raw_smp_processor_id(); |
362 | 362 | ||
363 | list_for_each_entry(pos, &ipcomp_tfms_list, list) { | 363 | list_for_each_entry(pos, &ipcomp_tfms_list, list) { |
364 | struct crypto_tfm *tfm; | 364 | struct crypto_tfm *tfm; |
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index eda1fba431a4..c6baa8174389 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c | |||
@@ -214,6 +214,12 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) | |||
214 | break; | 214 | break; |
215 | 215 | ||
216 | case IPQ_COPY_PACKET: | 216 | case IPQ_COPY_PACKET: |
217 | if (entry->skb->ip_summed == CHECKSUM_HW && | ||
218 | (*errp = skb_checksum_help(entry->skb, | ||
219 | entry->info->outdev == NULL))) { | ||
220 | read_unlock_bh(&queue_lock); | ||
221 | return NULL; | ||
222 | } | ||
217 | if (copy_range == 0 || copy_range > entry->skb->len) | 223 | if (copy_range == 0 || copy_range > entry->skb->len) |
218 | data_len = entry->skb->len; | 224 | data_len = entry->skb->len; |
219 | else | 225 | else |
@@ -385,6 +391,7 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
385 | if (!skb_ip_make_writable(&e->skb, v->data_len)) | 391 | if (!skb_ip_make_writable(&e->skb, v->data_len)) |
386 | return -ENOMEM; | 392 | return -ENOMEM; |
387 | memcpy(e->skb->data, v->payload, v->data_len); | 393 | memcpy(e->skb->data, v->payload, v->data_len); |
394 | e->skb->ip_summed = CHECKSUM_NONE; | ||
388 | e->skb->nfcache |= NFC_ALTERED; | 395 | e->skb->nfcache |= NFC_ALTERED; |
389 | 396 | ||
390 | /* | 397 | /* |
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c index ada9911118e9..94a0ce1c1c9d 100644 --- a/net/ipv4/netfilter/ipt_ECN.c +++ b/net/ipv4/netfilter/ipt_ECN.c | |||
@@ -61,16 +61,20 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward) | |||
61 | if (!tcph) | 61 | if (!tcph) |
62 | return 0; | 62 | return 0; |
63 | 63 | ||
64 | if (!(einfo->operation & IPT_ECN_OP_SET_ECE | 64 | if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) || |
65 | || tcph->ece == einfo->proto.tcp.ece) | 65 | tcph->ece == einfo->proto.tcp.ece) && |
66 | && (!(einfo->operation & IPT_ECN_OP_SET_CWR | 66 | ((!(einfo->operation & IPT_ECN_OP_SET_CWR) || |
67 | || tcph->cwr == einfo->proto.tcp.cwr))) | 67 | tcph->cwr == einfo->proto.tcp.cwr))) |
68 | return 1; | 68 | return 1; |
69 | 69 | ||
70 | if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph))) | 70 | if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph))) |
71 | return 0; | 71 | return 0; |
72 | tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4; | 72 | tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4; |
73 | 73 | ||
74 | if ((*pskb)->ip_summed == CHECKSUM_HW && | ||
75 | skb_checksum_help(*pskb, inward)) | ||
76 | return 0; | ||
77 | |||
74 | diffs[0] = ((u_int16_t *)tcph)[6]; | 78 | diffs[0] = ((u_int16_t *)tcph)[6]; |
75 | if (einfo->operation & IPT_ECN_OP_SET_ECE) | 79 | if (einfo->operation & IPT_ECN_OP_SET_ECE) |
76 | tcph->ece = einfo->proto.tcp.ece; | 80 | tcph->ece = einfo->proto.tcp.ece; |
@@ -79,13 +83,10 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward) | |||
79 | diffs[1] = ((u_int16_t *)tcph)[6]; | 83 | diffs[1] = ((u_int16_t *)tcph)[6]; |
80 | diffs[0] = diffs[0] ^ 0xFFFF; | 84 | diffs[0] = diffs[0] ^ 0xFFFF; |
81 | 85 | ||
82 | if ((*pskb)->ip_summed != CHECKSUM_HW) | 86 | if ((*pskb)->ip_summed != CHECKSUM_UNNECESSARY) |
83 | tcph->check = csum_fold(csum_partial((char *)diffs, | 87 | tcph->check = csum_fold(csum_partial((char *)diffs, |
84 | sizeof(diffs), | 88 | sizeof(diffs), |
85 | tcph->check^0xFFFF)); | 89 | tcph->check^0xFFFF)); |
86 | else | ||
87 | if (skb_checksum_help(*pskb, inward)) | ||
88 | return 0; | ||
89 | (*pskb)->nfcache |= NFC_ALTERED; | 90 | (*pskb)->nfcache |= NFC_ALTERED; |
90 | return 1; | 91 | return 1; |
91 | } | 92 | } |
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c index 1049050b2bfb..7b84a254440e 100644 --- a/net/ipv4/netfilter/ipt_TCPMSS.c +++ b/net/ipv4/netfilter/ipt_TCPMSS.c | |||
@@ -61,6 +61,10 @@ ipt_tcpmss_target(struct sk_buff **pskb, | |||
61 | if (!skb_ip_make_writable(pskb, (*pskb)->len)) | 61 | if (!skb_ip_make_writable(pskb, (*pskb)->len)) |
62 | return NF_DROP; | 62 | return NF_DROP; |
63 | 63 | ||
64 | if ((*pskb)->ip_summed == CHECKSUM_HW && | ||
65 | skb_checksum_help(*pskb, out == NULL)) | ||
66 | return NF_DROP; | ||
67 | |||
64 | iph = (*pskb)->nh.iph; | 68 | iph = (*pskb)->nh.iph; |
65 | tcplen = (*pskb)->len - iph->ihl*4; | 69 | tcplen = (*pskb)->len - iph->ihl*4; |
66 | 70 | ||
@@ -186,9 +190,6 @@ ipt_tcpmss_target(struct sk_buff **pskb, | |||
186 | newmss); | 190 | newmss); |
187 | 191 | ||
188 | retmodified: | 192 | retmodified: |
189 | /* We never hw checksum SYN packets. */ | ||
190 | BUG_ON((*pskb)->ip_summed == CHECKSUM_HW); | ||
191 | |||
192 | (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; | 193 | (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; |
193 | return IPT_CONTINUE; | 194 | return IPT_CONTINUE; |
194 | } | 195 | } |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ddb6ce4ecff2..69b1fcf70077 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -584,7 +584,7 @@ static inline void skb_entail(struct sock *sk, struct tcp_sock *tp, | |||
584 | sk_charge_skb(sk, skb); | 584 | sk_charge_skb(sk, skb); |
585 | if (!sk->sk_send_head) | 585 | if (!sk->sk_send_head) |
586 | sk->sk_send_head = skb; | 586 | sk->sk_send_head = skb; |
587 | else if (tp->nonagle&TCP_NAGLE_PUSH) | 587 | if (tp->nonagle & TCP_NAGLE_PUSH) |
588 | tp->nonagle &= ~TCP_NAGLE_PUSH; | 588 | tp->nonagle &= ~TCP_NAGLE_PUSH; |
589 | } | 589 | } |
590 | 590 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5d91213d34c0..67c670886c1f 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -242,9 +242,14 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum) | |||
242 | tcp_port_rover = rover; | 242 | tcp_port_rover = rover; |
243 | spin_unlock(&tcp_portalloc_lock); | 243 | spin_unlock(&tcp_portalloc_lock); |
244 | 244 | ||
245 | /* Exhausted local port range during search? */ | 245 | /* Exhausted local port range during search? It is not |
246 | * possible for us to be holding one of the bind hash | ||
247 | * locks if this test triggers, because if 'remaining' | ||
248 | * drops to zero, we broke out of the do/while loop at | ||
249 | * the top level, not from the 'break;' statement. | ||
250 | */ | ||
246 | ret = 1; | 251 | ret = 1; |
247 | if (remaining <= 0) | 252 | if (unlikely(remaining <= 0)) |
248 | goto fail; | 253 | goto fail; |
249 | 254 | ||
250 | /* OK, here is the one we will use. HEAD is | 255 | /* OK, here is the one we will use. HEAD is |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 566045e58437..dd30dd137b74 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -925,10 +925,6 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_ | |||
925 | 925 | ||
926 | limit = min(send_win, cong_win); | 926 | limit = min(send_win, cong_win); |
927 | 927 | ||
928 | /* If sk_send_head can be sent fully now, just do it. */ | ||
929 | if (skb->len <= limit) | ||
930 | return 0; | ||
931 | |||
932 | if (sysctl_tcp_tso_win_divisor) { | 928 | if (sysctl_tcp_tso_win_divisor) { |
933 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); | 929 | u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); |
934 | 930 | ||
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c index 423feb46ccc0..135383ef538f 100644 --- a/net/ipv6/ipcomp6.c +++ b/net/ipv6/ipcomp6.c | |||
@@ -354,7 +354,7 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name) | |||
354 | int cpu; | 354 | int cpu; |
355 | 355 | ||
356 | /* This can be any valid CPU ID so we don't need locking. */ | 356 | /* This can be any valid CPU ID so we don't need locking. */ |
357 | cpu = smp_processor_id(); | 357 | cpu = raw_smp_processor_id(); |
358 | 358 | ||
359 | list_for_each_entry(pos, &ipcomp6_tfms_list, list) { | 359 | list_for_each_entry(pos, &ipcomp6_tfms_list, list) { |
360 | struct crypto_tfm *tfm; | 360 | struct crypto_tfm *tfm; |
diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 5493180f0d44..a16df5b27c84 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c | |||
@@ -211,6 +211,12 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp) | |||
211 | break; | 211 | break; |
212 | 212 | ||
213 | case IPQ_COPY_PACKET: | 213 | case IPQ_COPY_PACKET: |
214 | if (entry->skb->ip_summed == CHECKSUM_HW && | ||
215 | (*errp = skb_checksum_help(entry->skb, | ||
216 | entry->info->outdev == NULL))) { | ||
217 | read_unlock_bh(&queue_lock); | ||
218 | return NULL; | ||
219 | } | ||
214 | if (copy_range == 0 || copy_range > entry->skb->len) | 220 | if (copy_range == 0 || copy_range > entry->skb->len) |
215 | data_len = entry->skb->len; | 221 | data_len = entry->skb->len; |
216 | else | 222 | else |
@@ -381,6 +387,7 @@ ipq_mangle_ipv6(ipq_verdict_msg_t *v, struct ipq_queue_entry *e) | |||
381 | if (!skb_ip_make_writable(&e->skb, v->data_len)) | 387 | if (!skb_ip_make_writable(&e->skb, v->data_len)) |
382 | return -ENOMEM; | 388 | return -ENOMEM; |
383 | memcpy(e->skb->data, v->payload, v->data_len); | 389 | memcpy(e->skb->data, v->payload, v->data_len); |
390 | e->skb->ip_summed = CHECKSUM_NONE; | ||
384 | e->skb->nfcache |= NFC_ALTERED; | 391 | e->skb->nfcache |= NFC_ALTERED; |
385 | 392 | ||
386 | /* | 393 | /* |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index f6e288dc116e..ef29cfd936d3 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -158,9 +158,14 @@ static int tcp_v6_get_port(struct sock *sk, unsigned short snum) | |||
158 | tcp_port_rover = rover; | 158 | tcp_port_rover = rover; |
159 | spin_unlock(&tcp_portalloc_lock); | 159 | spin_unlock(&tcp_portalloc_lock); |
160 | 160 | ||
161 | /* Exhausted local port range during search? */ | 161 | /* Exhausted local port range during search? It is not |
162 | * possible for us to be holding one of the bind hash | ||
163 | * locks if this test triggers, because if 'remaining' | ||
164 | * drops to zero, we broke out of the do/while loop at | ||
165 | * the top level, not from the 'break;' statement. | ||
166 | */ | ||
162 | ret = 1; | 167 | ret = 1; |
163 | if (remaining <= 0) | 168 | if (unlikely(remaining <= 0)) |
164 | goto fail; | 169 | goto fail; |
165 | 170 | ||
166 | /* OK, here is the one we will use. */ | 171 | /* OK, here is the one we will use. */ |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 31ed4a9a1d06..162a85fed150 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -459,12 +459,7 @@ static struct sock *nr_make_new(struct sock *osk) | |||
459 | sk->sk_sndbuf = osk->sk_sndbuf; | 459 | sk->sk_sndbuf = osk->sk_sndbuf; |
460 | sk->sk_state = TCP_ESTABLISHED; | 460 | sk->sk_state = TCP_ESTABLISHED; |
461 | sk->sk_sleep = osk->sk_sleep; | 461 | sk->sk_sleep = osk->sk_sleep; |
462 | 462 | sock_copy_flags(sk, osk); | |
463 | if (sock_flag(osk, SOCK_ZAPPED)) | ||
464 | sock_set_flag(sk, SOCK_ZAPPED); | ||
465 | |||
466 | if (sock_flag(osk, SOCK_DBG)) | ||
467 | sock_set_flag(sk, SOCK_DBG); | ||
468 | 463 | ||
469 | skb_queue_head_init(&nr->ack_queue); | 464 | skb_queue_head_init(&nr->ack_queue); |
470 | skb_queue_head_init(&nr->reseq_queue); | 465 | skb_queue_head_init(&nr->reseq_queue); |
@@ -541,7 +536,8 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
541 | struct nr_sock *nr = nr_sk(sk); | 536 | struct nr_sock *nr = nr_sk(sk); |
542 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; | 537 | struct full_sockaddr_ax25 *addr = (struct full_sockaddr_ax25 *)uaddr; |
543 | struct net_device *dev; | 538 | struct net_device *dev; |
544 | ax25_address *user, *source; | 539 | ax25_uid_assoc *user; |
540 | ax25_address *source; | ||
545 | 541 | ||
546 | lock_sock(sk); | 542 | lock_sock(sk); |
547 | if (!sock_flag(sk, SOCK_ZAPPED)) { | 543 | if (!sock_flag(sk, SOCK_ZAPPED)) { |
@@ -580,16 +576,19 @@ static int nr_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
580 | } else { | 576 | } else { |
581 | source = &addr->fsa_ax25.sax25_call; | 577 | source = &addr->fsa_ax25.sax25_call; |
582 | 578 | ||
583 | if ((user = ax25_findbyuid(current->euid)) == NULL) { | 579 | user = ax25_findbyuid(current->euid); |
580 | if (user) { | ||
581 | nr->user_addr = user->call; | ||
582 | ax25_uid_put(user); | ||
583 | } else { | ||
584 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { | 584 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) { |
585 | release_sock(sk); | 585 | release_sock(sk); |
586 | dev_put(dev); | 586 | dev_put(dev); |
587 | return -EPERM; | 587 | return -EPERM; |
588 | } | 588 | } |
589 | user = source; | 589 | nr->user_addr = *source; |
590 | } | 590 | } |
591 | 591 | ||
592 | nr->user_addr = *user; | ||
593 | nr->source_addr = *source; | 592 | nr->source_addr = *source; |
594 | } | 593 | } |
595 | 594 | ||
@@ -609,7 +608,8 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
609 | struct sock *sk = sock->sk; | 608 | struct sock *sk = sock->sk; |
610 | struct nr_sock *nr = nr_sk(sk); | 609 | struct nr_sock *nr = nr_sk(sk); |
611 | struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr; | 610 | struct sockaddr_ax25 *addr = (struct sockaddr_ax25 *)uaddr; |
612 | ax25_address *user, *source = NULL; | 611 | ax25_address *source = NULL; |
612 | ax25_uid_assoc *user; | ||
613 | struct net_device *dev; | 613 | struct net_device *dev; |
614 | 614 | ||
615 | lock_sock(sk); | 615 | lock_sock(sk); |
@@ -650,16 +650,19 @@ static int nr_connect(struct socket *sock, struct sockaddr *uaddr, | |||
650 | } | 650 | } |
651 | source = (ax25_address *)dev->dev_addr; | 651 | source = (ax25_address *)dev->dev_addr; |
652 | 652 | ||
653 | if ((user = ax25_findbyuid(current->euid)) == NULL) { | 653 | user = ax25_findbyuid(current->euid); |
654 | if (user) { | ||
655 | nr->user_addr = user->call; | ||
656 | ax25_uid_put(user); | ||
657 | } else { | ||
654 | if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) { | 658 | if (ax25_uid_policy && !capable(CAP_NET_ADMIN)) { |
655 | dev_put(dev); | 659 | dev_put(dev); |
656 | release_sock(sk); | 660 | release_sock(sk); |
657 | return -EPERM; | 661 | return -EPERM; |
658 | } | 662 | } |
659 | user = source; | 663 | nr->user_addr = *source; |
660 | } | 664 | } |
661 | 665 | ||
662 | nr->user_addr = *user; | ||
663 | nr->source_addr = *source; | 666 | nr->source_addr = *source; |
664 | nr->device = dev; | 667 | nr->device = dev; |
665 | 668 | ||
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 7eb6a5bf93ea..5480caf8ccc2 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -556,12 +556,7 @@ static struct sock *rose_make_new(struct sock *osk) | |||
556 | sk->sk_sndbuf = osk->sk_sndbuf; | 556 | sk->sk_sndbuf = osk->sk_sndbuf; |
557 | sk->sk_state = TCP_ESTABLISHED; | 557 | sk->sk_state = TCP_ESTABLISHED; |
558 | sk->sk_sleep = osk->sk_sleep; | 558 | sk->sk_sleep = osk->sk_sleep; |
559 | 559 | sock_copy_flags(sk, osk); | |
560 | if (sock_flag(osk, SOCK_ZAPPED)) | ||
561 | sock_set_flag(sk, SOCK_ZAPPED); | ||
562 | |||
563 | if (sock_flag(osk, SOCK_DBG)) | ||
564 | sock_set_flag(sk, SOCK_DBG); | ||
565 | 560 | ||
566 | init_timer(&rose->timer); | 561 | init_timer(&rose->timer); |
567 | init_timer(&rose->idletimer); | 562 | init_timer(&rose->idletimer); |
@@ -631,7 +626,8 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
631 | struct rose_sock *rose = rose_sk(sk); | 626 | struct rose_sock *rose = rose_sk(sk); |
632 | struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; | 627 | struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; |
633 | struct net_device *dev; | 628 | struct net_device *dev; |
634 | ax25_address *user, *source; | 629 | ax25_address *source; |
630 | ax25_uid_assoc *user; | ||
635 | int n; | 631 | int n; |
636 | 632 | ||
637 | if (!sock_flag(sk, SOCK_ZAPPED)) | 633 | if (!sock_flag(sk, SOCK_ZAPPED)) |
@@ -656,14 +652,17 @@ static int rose_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
656 | 652 | ||
657 | source = &addr->srose_call; | 653 | source = &addr->srose_call; |
658 | 654 | ||
659 | if ((user = ax25_findbyuid(current->euid)) == NULL) { | 655 | user = ax25_findbyuid(current->euid); |
656 | if (user) { | ||
657 | rose->source_call = user->call; | ||
658 | ax25_uid_put(user); | ||
659 | } else { | ||
660 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) | 660 | if (ax25_uid_policy && !capable(CAP_NET_BIND_SERVICE)) |
661 | return -EACCES; | 661 | return -EACCES; |
662 | user = source; | 662 | rose->source_call = *source; |
663 | } | 663 | } |
664 | 664 | ||
665 | rose->source_addr = addr->srose_addr; | 665 | rose->source_addr = addr->srose_addr; |
666 | rose->source_call = *user; | ||
667 | rose->device = dev; | 666 | rose->device = dev; |
668 | rose->source_ndigis = addr->srose_ndigis; | 667 | rose->source_ndigis = addr->srose_ndigis; |
669 | 668 | ||
@@ -690,8 +689,8 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
690 | struct rose_sock *rose = rose_sk(sk); | 689 | struct rose_sock *rose = rose_sk(sk); |
691 | struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; | 690 | struct sockaddr_rose *addr = (struct sockaddr_rose *)uaddr; |
692 | unsigned char cause, diagnostic; | 691 | unsigned char cause, diagnostic; |
693 | ax25_address *user; | ||
694 | struct net_device *dev; | 692 | struct net_device *dev; |
693 | ax25_uid_assoc *user; | ||
695 | int n; | 694 | int n; |
696 | 695 | ||
697 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { | 696 | if (sk->sk_state == TCP_ESTABLISHED && sock->state == SS_CONNECTING) { |
@@ -741,12 +740,14 @@ static int rose_connect(struct socket *sock, struct sockaddr *uaddr, int addr_le | |||
741 | if ((dev = rose_dev_first()) == NULL) | 740 | if ((dev = rose_dev_first()) == NULL) |
742 | return -ENETUNREACH; | 741 | return -ENETUNREACH; |
743 | 742 | ||
744 | if ((user = ax25_findbyuid(current->euid)) == NULL) | 743 | user = ax25_findbyuid(current->euid); |
744 | if (!user) | ||
745 | return -EINVAL; | 745 | return -EINVAL; |
746 | 746 | ||
747 | memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN); | 747 | memcpy(&rose->source_addr, dev->dev_addr, ROSE_ADDR_LEN); |
748 | rose->source_call = *user; | 748 | rose->source_call = user->call; |
749 | rose->device = dev; | 749 | rose->device = dev; |
750 | ax25_uid_put(user); | ||
750 | 751 | ||
751 | rose_insert_socket(sk); /* Finish the bind */ | 752 | rose_insert_socket(sk); /* Finish the bind */ |
752 | } | 753 | } |
diff --git a/net/rose/rose_route.c b/net/rose/rose_route.c index ff73ebb912b8..25da6f699fd0 100644 --- a/net/rose/rose_route.c +++ b/net/rose/rose_route.c | |||
@@ -994,8 +994,10 @@ int rose_route_frame(struct sk_buff *skb, ax25_cb *ax25) | |||
994 | * 1. The frame isn't for us, | 994 | * 1. The frame isn't for us, |
995 | * 2. It isn't "owned" by any existing route. | 995 | * 2. It isn't "owned" by any existing route. |
996 | */ | 996 | */ |
997 | if (frametype != ROSE_CALL_REQUEST) /* XXX */ | 997 | if (frametype != ROSE_CALL_REQUEST) { /* XXX */ |
998 | return 0; | 998 | res = 0; |
999 | goto out; | ||
1000 | } | ||
999 | 1001 | ||
1000 | len = (((skb->data[3] >> 4) & 0x0F) + 1) / 2; | 1002 | len = (((skb->data[3] >> 4) & 0x0F) + 1) / 2; |
1001 | len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2; | 1003 | len += (((skb->data[3] >> 0) & 0x0F) + 1) / 2; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index 8edefd5d095d..0d066c965342 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -438,6 +438,7 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops) | |||
438 | if (!ops->init || ops->init(sch, NULL) == 0) | 438 | if (!ops->init || ops->init(sch, NULL) == 0) |
439 | return sch; | 439 | return sch; |
440 | 440 | ||
441 | qdisc_destroy(sch); | ||
441 | errout: | 442 | errout: |
442 | return NULL; | 443 | return NULL; |
443 | } | 444 | } |
diff --git a/net/sctp/proc.c b/net/sctp/proc.c index 98d49ec9b74b..b74f7772b576 100644 --- a/net/sctp/proc.c +++ b/net/sctp/proc.c | |||
@@ -57,6 +57,7 @@ static struct snmp_mib sctp_snmp_list[] = { | |||
57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), | 57 | SNMP_MIB_ITEM("SctpReasmUsrMsgs", SCTP_MIB_REASMUSRMSGS), |
58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), | 58 | SNMP_MIB_ITEM("SctpOutSCTPPacks", SCTP_MIB_OUTSCTPPACKS), |
59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), | 59 | SNMP_MIB_ITEM("SctpInSCTPPacks", SCTP_MIB_INSCTPPACKS), |
60 | SNMP_MIB_SENTINEL | ||
60 | }; | 61 | }; |
61 | 62 | ||
62 | /* Return the current value of a particular entry in the mib by adding its | 63 | /* Return the current value of a particular entry in the mib by adding its |
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 24c21f2a33a7..5a7265aeaf83 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -185,9 +185,7 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | |||
185 | sg->page = body->pages[i]; | 185 | sg->page = body->pages[i]; |
186 | sg->offset = offset; | 186 | sg->offset = offset; |
187 | sg->length = thislen; | 187 | sg->length = thislen; |
188 | kmap(sg->page); /* XXX kmap_atomic? */ | ||
189 | crypto_digest_update(tfm, sg, 1); | 188 | crypto_digest_update(tfm, sg, 1); |
190 | kunmap(sg->page); | ||
191 | len -= thislen; | 189 | len -= thislen; |
192 | i++; | 190 | i++; |
193 | offset = 0; | 191 | offset = 0; |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 9b9f94c915d2..09ffca54b373 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
@@ -359,11 +359,16 @@ handle_modversions(struct module *mod, struct elf_info *info, | |||
359 | /* ignore __this_module, it will be resolved shortly */ | 359 | /* ignore __this_module, it will be resolved shortly */ |
360 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) | 360 | if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) |
361 | break; | 361 | break; |
362 | #ifdef STT_REGISTER | 362 | /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */ |
363 | #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER) | ||
364 | /* add compatibility with older glibc */ | ||
365 | #ifndef STT_SPARC_REGISTER | ||
366 | #define STT_SPARC_REGISTER STT_REGISTER | ||
367 | #endif | ||
363 | if (info->hdr->e_machine == EM_SPARC || | 368 | if (info->hdr->e_machine == EM_SPARC || |
364 | info->hdr->e_machine == EM_SPARCV9) { | 369 | info->hdr->e_machine == EM_SPARCV9) { |
365 | /* Ignore register directives. */ | 370 | /* Ignore register directives. */ |
366 | if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER) | 371 | if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER) |
367 | break; | 372 | break; |
368 | } | 373 | } |
369 | #endif | 374 | #endif |
diff --git a/sound/Kconfig b/sound/Kconfig index ee794ae06040..b65ee4701f98 100644 --- a/sound/Kconfig +++ b/sound/Kconfig | |||
@@ -77,7 +77,7 @@ source "sound/parisc/Kconfig" | |||
77 | endmenu | 77 | endmenu |
78 | 78 | ||
79 | menu "Open Sound System" | 79 | menu "Open Sound System" |
80 | depends on SOUND!=n && (BROKEN || (!SPARC32 && !SPARC64)) | 80 | depends on SOUND!=n |
81 | 81 | ||
82 | config SOUND_PRIME | 82 | config SOUND_PRIME |
83 | tristate "Open Sound System (DEPRECATED)" | 83 | tristate "Open Sound System (DEPRECATED)" |
diff --git a/sound/core/Makefile b/sound/core/Makefile index 764ac184b223..969d75528bde 100644 --- a/sound/core/Makefile +++ b/sound/core/Makefile | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | snd-objs := sound.o init.o memory.o info.o control.o misc.o \ | 6 | snd-objs := sound.o init.o memory.o info.o control.o misc.o \ |
7 | device.o wrappers.o | 7 | device.o wrappers.o |
8 | ifeq ($(CONFIG_ISA),y) | 8 | ifeq ($(CONFIG_ISA_DMA_API),y) |
9 | snd-objs += isadma.o | 9 | snd-objs += isadma.o |
10 | endif | 10 | endif |
11 | ifeq ($(CONFIG_SND_OSSEMUL),y) | 11 | ifeq ($(CONFIG_SND_OSSEMUL),y) |
diff --git a/sound/core/sound.c b/sound/core/sound.c index 7612884f530b..3271e9245490 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c | |||
@@ -432,7 +432,7 @@ EXPORT_SYMBOL(snd_device_new); | |||
432 | EXPORT_SYMBOL(snd_device_register); | 432 | EXPORT_SYMBOL(snd_device_register); |
433 | EXPORT_SYMBOL(snd_device_free); | 433 | EXPORT_SYMBOL(snd_device_free); |
434 | /* isadma.c */ | 434 | /* isadma.c */ |
435 | #ifdef CONFIG_ISA | 435 | #ifdef CONFIG_ISA_DMA_API |
436 | EXPORT_SYMBOL(snd_dma_program); | 436 | EXPORT_SYMBOL(snd_dma_program); |
437 | EXPORT_SYMBOL(snd_dma_disable); | 437 | EXPORT_SYMBOL(snd_dma_disable); |
438 | EXPORT_SYMBOL(snd_dma_pointer); | 438 | EXPORT_SYMBOL(snd_dma_pointer); |
diff --git a/sound/isa/Kconfig b/sound/isa/Kconfig index 148a856a43ad..be4ea60a3679 100644 --- a/sound/isa/Kconfig +++ b/sound/isa/Kconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # ALSA ISA drivers | 1 | # ALSA ISA drivers |
2 | 2 | ||
3 | menu "ISA devices" | 3 | menu "ISA devices" |
4 | depends on SND!=n && ISA | 4 | depends on SND!=n && ISA && ISA_DMA_API |
5 | 5 | ||
6 | config SND_AD1848_LIB | 6 | config SND_AD1848_LIB |
7 | tristate | 7 | tristate |
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 7bd95ceab7cc..953e5f3ea03d 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -6,7 +6,7 @@ | |||
6 | # Prompt user for primary drivers. | 6 | # Prompt user for primary drivers. |
7 | config SOUND_BT878 | 7 | config SOUND_BT878 |
8 | tristate "BT878 audio dma" | 8 | tristate "BT878 audio dma" |
9 | depends on SOUND_PRIME | 9 | depends on SOUND_PRIME && PCI |
10 | ---help--- | 10 | ---help--- |
11 | Audio DMA support for bt878 based grabber boards. As you might have | 11 | Audio DMA support for bt878 based grabber boards. As you might have |
12 | already noticed, bt878 is listed with two functions in /proc/pci. | 12 | already noticed, bt878 is listed with two functions in /proc/pci. |
@@ -80,14 +80,14 @@ config SOUND_EMU10K1 | |||
80 | 80 | ||
81 | config MIDI_EMU10K1 | 81 | config MIDI_EMU10K1 |
82 | bool "Creative SBLive! MIDI (EXPERIMENTAL)" | 82 | bool "Creative SBLive! MIDI (EXPERIMENTAL)" |
83 | depends on SOUND_EMU10K1 && EXPERIMENTAL | 83 | depends on SOUND_EMU10K1 && EXPERIMENTAL && ISA_DMA_API |
84 | help | 84 | help |
85 | Say Y if you want to be able to use the OSS /dev/sequencer | 85 | Say Y if you want to be able to use the OSS /dev/sequencer |
86 | interface. This code is still experimental. | 86 | interface. This code is still experimental. |
87 | 87 | ||
88 | config SOUND_FUSION | 88 | config SOUND_FUSION |
89 | tristate "Crystal SoundFusion (CS4280/461x)" | 89 | tristate "Crystal SoundFusion (CS4280/461x)" |
90 | depends on SOUND_PRIME | 90 | depends on SOUND_PRIME && PCI |
91 | help | 91 | help |
92 | This module drives the Crystal SoundFusion devices (CS4280/46xx | 92 | This module drives the Crystal SoundFusion devices (CS4280/46xx |
93 | series) when wired as native sound drivers with AC97 codecs. If | 93 | series) when wired as native sound drivers with AC97 codecs. If |
@@ -95,7 +95,7 @@ config SOUND_FUSION | |||
95 | 95 | ||
96 | config SOUND_CS4281 | 96 | config SOUND_CS4281 |
97 | tristate "Crystal Sound CS4281" | 97 | tristate "Crystal Sound CS4281" |
98 | depends on SOUND_PRIME | 98 | depends on SOUND_PRIME && PCI |
99 | help | 99 | help |
100 | Picture and feature list at | 100 | Picture and feature list at |
101 | <http://www.pcbroker.com/crystal4281.html>. | 101 | <http://www.pcbroker.com/crystal4281.html>. |
@@ -179,7 +179,7 @@ config SOUND_HARMONY | |||
179 | 179 | ||
180 | config SOUND_SONICVIBES | 180 | config SOUND_SONICVIBES |
181 | tristate "S3 SonicVibes" | 181 | tristate "S3 SonicVibes" |
182 | depends on SOUND_PRIME | 182 | depends on SOUND_PRIME && PCI |
183 | help | 183 | help |
184 | Say Y or M if you have a PCI sound card utilizing the S3 | 184 | Say Y or M if you have a PCI sound card utilizing the S3 |
185 | SonicVibes chipset. To find out if your sound card uses a | 185 | SonicVibes chipset. To find out if your sound card uses a |
@@ -226,7 +226,7 @@ config SOUND_AU1550_AC97 | |||
226 | 226 | ||
227 | config SOUND_TRIDENT | 227 | config SOUND_TRIDENT |
228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" | 228 | tristate "Trident 4DWave DX/NX, SiS 7018 or ALi 5451 PCI Audio Core" |
229 | depends on SOUND_PRIME | 229 | depends on SOUND_PRIME && PCI |
230 | ---help--- | 230 | ---help--- |
231 | Say Y or M if you have a PCI sound card utilizing the Trident | 231 | Say Y or M if you have a PCI sound card utilizing the Trident |
232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 | 232 | 4DWave-DX/NX chipset or your mother board chipset has SiS 7018 |
@@ -503,7 +503,7 @@ config SOUND_VIA82CXXX | |||
503 | 503 | ||
504 | config MIDI_VIA82CXXX | 504 | config MIDI_VIA82CXXX |
505 | bool "VIA 82C686 MIDI" | 505 | bool "VIA 82C686 MIDI" |
506 | depends on SOUND_VIA82CXXX | 506 | depends on SOUND_VIA82CXXX && ISA_DMA_API |
507 | help | 507 | help |
508 | Answer Y to use the MIDI interface of the Via686. You may need to | 508 | Answer Y to use the MIDI interface of the Via686. You may need to |
509 | enable this in the BIOS before it will work. This is for connection | 509 | enable this in the BIOS before it will work. This is for connection |
@@ -512,7 +512,7 @@ config MIDI_VIA82CXXX | |||
512 | 512 | ||
513 | config SOUND_OSS | 513 | config SOUND_OSS |
514 | tristate "OSS sound modules" | 514 | tristate "OSS sound modules" |
515 | depends on SOUND_PRIME | 515 | depends on SOUND_PRIME && ISA_DMA_API |
516 | help | 516 | help |
517 | OSS is the Open Sound System suite of sound card drivers. They make | 517 | OSS is the Open Sound System suite of sound card drivers. They make |
518 | sound programming easier since they provide a common API. Say Y or | 518 | sound programming easier since they provide a common API. Say Y or |
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index db9afb61d6ff..9bf3ee544d86 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
@@ -80,7 +80,7 @@ obj-$(CONFIG_SOUND_ALI5455) += ali5455.o ac97_codec.o | |||
80 | obj-$(CONFIG_SOUND_IT8172) += ite8172.o ac97_codec.o | 80 | obj-$(CONFIG_SOUND_IT8172) += ite8172.o ac97_codec.o |
81 | obj-$(CONFIG_SOUND_FORTE) += forte.o ac97_codec.o | 81 | obj-$(CONFIG_SOUND_FORTE) += forte.o ac97_codec.o |
82 | 82 | ||
83 | obj-$(CONFIG_SOUND_AD1980) += ac97_plugin_ad1980.o | 83 | obj-$(CONFIG_SOUND_AD1980) += ac97_plugin_ad1980.o ac97_codec.o |
84 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o | 84 | obj-$(CONFIG_SOUND_WM97XX) += ac97_plugin_wm97xx.o |
85 | 85 | ||
86 | ifeq ($(CONFIG_MIDI_EMU10K1),y) | 86 | ifeq ($(CONFIG_MIDI_EMU10K1),y) |
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c index 7e9f667cf7a7..b9a640fe48b1 100644 --- a/sound/oss/i810_audio.c +++ b/sound/oss/i810_audio.c | |||
@@ -3430,9 +3430,9 @@ out_iospace: | |||
3430 | release_mem_region(card->iobase_mmio_phys, 256); | 3430 | release_mem_region(card->iobase_mmio_phys, 256); |
3431 | } | 3431 | } |
3432 | out_pio: | 3432 | out_pio: |
3433 | release_region(card->iobase, 64); | ||
3434 | out_region2: | ||
3435 | release_region(card->ac97base, 256); | 3433 | release_region(card->ac97base, 256); |
3434 | out_region2: | ||
3435 | release_region(card->iobase, 64); | ||
3436 | out_region1: | 3436 | out_region1: |
3437 | pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, | 3437 | pci_free_consistent(pci_dev, sizeof(struct i810_channel)*NR_HW_CH, |
3438 | card->channel, card->chandma); | 3438 | card->channel, card->chandma); |
diff --git a/sound/oss/vidc.h b/sound/oss/vidc.h index bab7044572d3..d5b8064dc565 100644 --- a/sound/oss/vidc.h +++ b/sound/oss/vidc.h | |||
@@ -10,10 +10,6 @@ | |||
10 | * VIDC sound function prototypes | 10 | * VIDC sound function prototypes |
11 | */ | 11 | */ |
12 | 12 | ||
13 | /* vidc.c */ | ||
14 | |||
15 | extern int vidc_busy; | ||
16 | |||
17 | /* vidc_fill.S */ | 13 | /* vidc_fill.S */ |
18 | 14 | ||
19 | /* | 15 | /* |
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 6d7a00f34d82..26b42bb20a0a 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -314,7 +314,7 @@ config SND_YMFPCI | |||
314 | 314 | ||
315 | config SND_ALS4000 | 315 | config SND_ALS4000 |
316 | tristate "Avance Logic ALS4000" | 316 | tristate "Avance Logic ALS4000" |
317 | depends on SND | 317 | depends on SND && ISA_DMA_API |
318 | select SND_OPL3_LIB | 318 | select SND_OPL3_LIB |
319 | select SND_MPU401_UART | 319 | select SND_MPU401_UART |
320 | select SND_PCM | 320 | select SND_PCM |