linux/drivers
Anton Vorontsov 79675900cb ucc_geth: Fix three oopses in PHY {de,}initialization code
When there are no free snums, UCC ethernet should gracefully fail, but
currently it oopses this way:

  # ifconfig eth0 up
  fill_init_enet_entries: Can not get SNUM.
  ucc_geth_startup: Can not fill p_init_enet_param_shadow.
  eth0: Cannot configure net device, aborting.
  Unable to handle kernel paging request for data at address 0x00000190
  Faulting instruction address: 0xc0294c88
  Oops: Kernel access of bad area, sig: 11 [#1]
  [...]
  NIP [c0294c88] mutex_lock+0x0/0x1c
  LR [c01b6be8] phy_stop+0x20/0x70
  Call Trace:
  [efb25da0] [efb2eb60] 0xefb2eb60 (unreliable)
  [efb25db0] [c01b2058] ucc_geth_stop+0x2c/0x8c
  [efb25dd0] [c01b4194] ucc_geth_open+0x48/0x27c
  [efb25df0] [c020eec0] dev_open+0xc0/0x118
  [...]

This is because the ucc_geth_stop() routine assumes that ugeth->phydev
is always initialized by the ucc_geth_open(), while it is not in case
of errors.

If we add a check to the ucc_geth_stop(), then another oops pops up:

  Unable to handle kernel paging request for data at address 0x00000004
  Faulting instruction address: 0xc01b46a4
  Oops: Kernel access of bad area, sig: 11 [#1]
  [...]
  NIP [c01b46a4] adjust_link+0x20/0x1b4
  LR [c01b770c] phy_state_machine+0xdc/0x44c
  Call Trace:
  [ef83bf10] [c021b388] linkwatch_schedule_work+0x74/0xf8 (unreliable)
  [ef83bf40] [c01b770c] phy_state_machine+0xdc/0x44c
  [ef83bf60] [c004c13c] run_workqueue+0xb8/0x148
  [ef83bf90] [c004c870] worker_thread+0x70/0xd0
  [ef83bfd0] [c00505fc] kthread+0x48/0x84
  [ef83bff0] [c000f464] kernel_thread+0x4c/0x68
  [...]

That one happens because ucc_geth_stop() does not call phy_disconnect()
and so phylib state machine is running without any idea that a MAC has
just died.

Also, when device tree specifies fixed-link, and CONFIG_FIXED_PHY
is disabled, we'll get this oops:

  0:01 not found
  eth2: Could not attach to PHY
  eth2: Cannot initialize PHY, aborting.
  Unable to handle kernel paging request for data at address 0x00000190
  Faulting instruction address: 0xc02967d0
  Oops: Kernel access of bad area, sig: 11 [#1]
  [...]
  NIP [c02967d0] mutex_lock+0x0/0x1c
  LR [c01b6bcc] phy_stop+0x20/0x70
  Call Trace:
  [ef82be50] [efb6bb60] 0xefb6bb60 (unreliable)
  [ef82be60] [c01b2058] ucc_geth_stop+0x2c/0x8c
  [ef82be80] [c01b4194] ucc_geth_open+0x48/0x27c
  [ef82bea0] [c0210a04] dev_open+0xc0/0x118
  [ef82bec0] [c020f85c] dev_change_flags+0x84/0x1ac
  [ef82bee0] [c037b768] ic_open_devs+0x168/0x2bc
  [ef82bf20] [c037ca98] ip_auto_config+0x90/0x28c
  [ef82bf60] [c0001b9c] do_one_initcall+0x34/0x1a0
  [ef82bfd0] [c035e240] do_initcalls+0x38/0x58
  [ef82bfe0] [c035e2c4] kernel_init+0x30/0x90
  [ef82bff0] [c000f464] kernel_thread+0x4c/0x68
  [...]

And again, ucc_geth_stop() assumes that ugeth->phydev is there, while
it isn't.

This patch fixes all three oopses simply by rearranging some code:

- In ucc_geth_open(): move init_phy() call to the beginning, so
  that we only call ucc_geth_stop() with a PHY attached;
- Move phy_disconnect() call from ucc_geth_close() to
  ucc_geth_stop(), so that we'll always disconnect the PHY.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2009-03-27 16:00:03 -07:00
..
accessibility
acpi Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-03-26 15:23:24 -07:00
amba amba: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:22 -07:00
ata [libata] Improve timeout handling 2009-03-24 22:52:39 -04:00
atm atm: fix non-const printk argument 2009-03-21 19:06:51 -07:00
auxdisplay
base Driver core: Fix device_move() vs. dpm list ordering, v2 2009-03-24 16:38:26 -07:00
block Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k 2009-03-26 16:15:31 -07:00
bluetooth
cdrom
char Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
clocksource
connector
cpufreq Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/davej/cpufreq 2009-03-26 11:04:08 -07:00
cpuidle
crypto Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6 2009-03-26 11:04:34 -07:00
dca Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6 2009-03-23 09:25:58 -07:00
dio dio: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:22 -07:00
dma dma: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:22 -07:00
edac edac: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:21 -07:00
eisa eisa: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:22 -07:00
firewire
firmware
gpio gpio: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:23 -07:00
gpu Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
hid Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
hwmon hwmon: (f75375s) Remove unnecessary and confusing initialization 2009-03-12 13:36:39 +01:00
i2c Driver core: implement uevent suppress in kobject 2009-03-24 16:38:26 -07:00
ide Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
idle
ieee1394 Rationalize fasync return values 2009-03-16 08:34:35 -06:00
infiniband RDMA/nes: Fix mis-merge 2009-03-26 17:00:25 -07:00
input Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
isdn Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-03-26 15:23:24 -07:00
leds
lguest lguest: fix for CONFIG_SPARSE_IRQ=y 2009-03-09 10:06:29 +10:30
macintosh
mca mca: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:23 -07:00
md dm crypt: wait for endio to complete before destruction 2009-03-16 17:44:36 +00:00
media Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
memstick
message
mfd mfd: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:23 -07:00
misc
mmc mmc: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:21 -07:00
mtd Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
net ucc_geth: Fix three oopses in PHY {de,}initialization code 2009-03-27 16:00:03 -07:00
nubus
of
oprofile
parisc parisc: sba_iommu: fix build bug when CONFIG_PARISC_AGP=y 2009-03-15 13:36:22 -07:00
parport
pci Merge branch 'irq-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip 2009-03-26 16:06:50 -07:00
pcmcia platform driver: fix incorrect use of 'platform_bus_type' with 'struct device_driver' 2009-03-24 16:38:25 -07:00
platform Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
pnp
power ds2760_battery.c: fix division by zero 2009-03-12 16:20:23 -07:00
ps3
rapidio rapidio: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:21 -07:00
regulator
rtc Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
s390 Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6 2009-03-26 16:04:22 -07:00
sbus sbus: Auto-load openprom module when device opened. 2009-03-13 14:30:08 -07:00
scsi Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/geert/linux-m68k 2009-03-26 16:15:31 -07:00
serial Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
sh Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6 2009-03-26 11:17:04 -07:00
sn
spi spi: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:21 -07:00
ssb
staging Merge branch 'topic/snd_card_new-err' into for-linus 2009-03-24 00:35:35 +01:00
tc tc: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:22 -07:00
telephony
thermal
uio UIO: Take offset into account when determining number of pages that can be mapped 2009-03-24 16:38:25 -07:00
usb Merge branch 'bkl-removal' of git://git.lwn.net/linux-2.6 2009-03-26 16:14:02 -07:00
uwb
video Merge branch 'master' of /home/davem/src/GIT/linux-2.6/ 2009-03-26 15:23:24 -07:00
virtio
w1 drivers/w1/masters/w1-gpio.c: fix read_bit() 2009-03-12 16:20:23 -07:00
watchdog Merge git://git.kernel.org/pub/scm/linux/kernel/git/wim/linux-2.6-watchdog 2009-03-26 15:48:11 -07:00
xen
zorro zorro: struct device - replace bus_id with dev_name(), dev_set_name() 2009-03-24 16:38:21 -07:00
Kconfig
Makefile