diff options
author | Al Viro <viro@ftp.linux.org.uk> | 2008-01-13 09:17:35 -0500 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2008-01-18 14:44:33 -0500 |
commit | b665982409fd5e4d3f1b71591d2f6badf9d2ee99 (patch) | |
tree | 00f16223e91563bd99cb4a42178f62e693aa2030 /drivers/net/pcmcia | |
parent | c15561f0e5615607e2b5524c4b3af64d20cd6e28 (diff) |
3c574, 3c515 bitfields abuse
wn3_config is shared by these cards; the way we deal with it is both bad C
(union abuse) and broken on big-endian. For 3c515 it's less serious (ISA
cards are quite rare outside of little-endian boxen), but 3c574 is a pcmcia
one and that'd better be endian-independent... Fix is the same in both
cases.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/pcmcia')
-rw-r--r-- | drivers/net/pcmcia/3c574_cs.c | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 288177716a49..36a7ba3134ce 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -187,14 +187,16 @@ enum Window1 { | |||
187 | enum Window3 { /* Window 3: MAC/config bits. */ | 187 | enum Window3 { /* Window 3: MAC/config bits. */ |
188 | Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, | 188 | Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8, |
189 | }; | 189 | }; |
190 | union wn3_config { | 190 | enum wn3_config { |
191 | int i; | 191 | Ram_size = 7, |
192 | struct w3_config_fields { | 192 | Ram_width = 8, |
193 | unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2; | 193 | Ram_speed = 0x30, |
194 | int pad8:8; | 194 | Rom_size = 0xc0, |
195 | unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1; | 195 | Ram_split_shift = 16, |
196 | int pad24:7; | 196 | Ram_split = 3 << Ram_split_shift, |
197 | } u; | 197 | Xcvr_shift = 20, |
198 | Xcvr = 7 << Xcvr_shift, | ||
199 | Autoselect = 0x1000000, | ||
198 | }; | 200 | }; |
199 | 201 | ||
200 | enum Window4 { /* Window 4: Xcvr/media bits. */ | 202 | enum Window4 { /* Window 4: Xcvr/media bits. */ |
@@ -342,7 +344,7 @@ static int tc574_config(struct pcmcia_device *link) | |||
342 | kio_addr_t ioaddr; | 344 | kio_addr_t ioaddr; |
343 | __be16 *phys_addr; | 345 | __be16 *phys_addr; |
344 | char *cardname; | 346 | char *cardname; |
345 | union wn3_config config; | 347 | __u32 config; |
346 | DECLARE_MAC_BUF(mac); | 348 | DECLARE_MAC_BUF(mac); |
347 | 349 | ||
348 | phys_addr = (__be16 *)dev->dev_addr; | 350 | phys_addr = (__be16 *)dev->dev_addr; |
@@ -401,9 +403,9 @@ static int tc574_config(struct pcmcia_device *link) | |||
401 | outw(0<<11, ioaddr + RunnerRdCtrl); | 403 | outw(0<<11, ioaddr + RunnerRdCtrl); |
402 | printk(KERN_INFO " ASIC rev %d,", mcr>>3); | 404 | printk(KERN_INFO " ASIC rev %d,", mcr>>3); |
403 | EL3WINDOW(3); | 405 | EL3WINDOW(3); |
404 | config.i = inl(ioaddr + Wn3_Config); | 406 | config = inl(ioaddr + Wn3_Config); |
405 | lp->default_media = config.u.xcvr; | 407 | lp->default_media = (config & Xcvr) >> Xcvr_shift; |
406 | lp->autoselect = config.u.autoselect; | 408 | lp->autoselect = config & Autoselect ? 1 : 0; |
407 | } | 409 | } |
408 | 410 | ||
409 | init_timer(&lp->media); | 411 | init_timer(&lp->media); |
@@ -464,8 +466,9 @@ static int tc574_config(struct pcmcia_device *link) | |||
464 | dev->name, cardname, dev->base_addr, dev->irq, | 466 | dev->name, cardname, dev->base_addr, dev->irq, |
465 | print_mac(mac, dev->dev_addr)); | 467 | print_mac(mac, dev->dev_addr)); |
466 | printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", | 468 | printk(" %dK FIFO split %s Rx:Tx, %sMII interface.\n", |
467 | 8 << config.u.ram_size, ram_split[config.u.ram_split], | 469 | 8 << config & Ram_size, |
468 | config.u.autoselect ? "autoselect " : ""); | 470 | ram_split[(config & Ram_split) >> Ram_split_shift], |
471 | config & Autoselect ? "autoselect " : ""); | ||
469 | 472 | ||
470 | return 0; | 473 | return 0; |
471 | 474 | ||