diff options
author | Lennert Buytenhek <buytenh@wantstofly.org> | 2005-11-23 06:49:05 -0500 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-12-01 02:25:25 -0500 |
commit | 0c49919a4706cc8c72ff381da7f3ae094e6df03a (patch) | |
tree | fe755520cdbf3ecabec1678eb6f6cc1e7362c062 /drivers/net/ixp2000/ixpdev.c | |
parent | 35b8fcab1b293cadd54cdf9e9636cc576d2cad88 (diff) |
[PATCH] ixp2000: register netdevices last
Do not register our netdevices with the kernel until we've actually
finished setting up the hardware and microcode.
Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/net/ixp2000/ixpdev.c')
-rw-r--r-- | drivers/net/ixp2000/ixpdev.c | 35 |
1 files changed, 17 insertions, 18 deletions
diff --git a/drivers/net/ixp2000/ixpdev.c b/drivers/net/ixp2000/ixpdev.c index 216aad1911e6..d9fd57d7a4b3 100644 --- a/drivers/net/ixp2000/ixpdev.c +++ b/drivers/net/ixp2000/ixpdev.c | |||
@@ -300,15 +300,6 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, | |||
300 | nds = __nds; | 300 | nds = __nds; |
301 | set_port_admin_status = __set_port_admin_status; | 301 | set_port_admin_status = __set_port_admin_status; |
302 | 302 | ||
303 | for (i = 0; i < nds_count; i++) { | ||
304 | err = register_netdev(nds[i]); | ||
305 | if (err) { | ||
306 | while (--i >= 0) | ||
307 | unregister_netdev(nds[i]); | ||
308 | goto err_out; | ||
309 | } | ||
310 | } | ||
311 | |||
312 | for (i = 0; i < RX_BUF_COUNT; i++) { | 303 | for (i = 0; i < RX_BUF_COUNT; i++) { |
313 | void *buf; | 304 | void *buf; |
314 | 305 | ||
@@ -317,7 +308,7 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, | |||
317 | err = -ENOMEM; | 308 | err = -ENOMEM; |
318 | while (--i >= 0) | 309 | while (--i >= 0) |
319 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); | 310 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); |
320 | goto err_unregister; | 311 | goto err_out; |
321 | } | 312 | } |
322 | rx_desc[i].buf_addr = virt_to_phys(buf); | 313 | rx_desc[i].buf_addr = virt_to_phys(buf); |
323 | rx_desc[i].buf_length = PAGE_SIZE; | 314 | rx_desc[i].buf_length = PAGE_SIZE; |
@@ -355,7 +346,6 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, | |||
355 | ixp2000_uengine_load(0, &ixp2400_rx); | 346 | ixp2000_uengine_load(0, &ixp2400_rx); |
356 | ixp2000_uengine_start_contexts(0, 0xff); | 347 | ixp2000_uengine_start_contexts(0, 0xff); |
357 | 348 | ||
358 | |||
359 | /* 256 entries, ring status set means 'empty', base address 0x0800. */ | 349 | /* 256 entries, ring status set means 'empty', base address 0x0800. */ |
360 | ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800); | 350 | ixp2000_reg_write(RING_TX_PENDING_BASE, 0x44000800); |
361 | ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000); | 351 | ixp2000_reg_write(RING_TX_PENDING_HEAD, 0x00000000); |
@@ -369,16 +359,25 @@ int ixpdev_init(int __nds_count, struct net_device **__nds, | |||
369 | ixp2000_uengine_load(1, &ixp2400_tx); | 359 | ixp2000_uengine_load(1, &ixp2400_tx); |
370 | ixp2000_uengine_start_contexts(1, 0xff); | 360 | ixp2000_uengine_start_contexts(1, 0xff); |
371 | 361 | ||
362 | for (i = 0; i < nds_count; i++) { | ||
363 | err = register_netdev(nds[i]); | ||
364 | if (err) { | ||
365 | while (--i >= 0) | ||
366 | unregister_netdev(nds[i]); | ||
367 | goto err_free_tx; | ||
368 | } | ||
369 | } | ||
370 | |||
372 | return 0; | 371 | return 0; |
373 | 372 | ||
373 | err_free_tx: | ||
374 | for (i = 0; i < TX_BUF_COUNT; i++) | ||
375 | free_page((unsigned long)phys_to_virt(tx_desc[i].buf_addr)); | ||
376 | |||
374 | err_free_rx: | 377 | err_free_rx: |
375 | for (i = 0; i < RX_BUF_COUNT; i++) | 378 | for (i = 0; i < RX_BUF_COUNT; i++) |
376 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); | 379 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); |
377 | 380 | ||
378 | err_unregister: | ||
379 | for (i = 0; i < nds_count; i++) | ||
380 | unregister_netdev(nds[i]); | ||
381 | |||
382 | err_out: | 381 | err_out: |
383 | return err; | 382 | return err; |
384 | } | 383 | } |
@@ -389,6 +388,9 @@ void ixpdev_deinit(void) | |||
389 | 388 | ||
390 | /* @@@ Flush out pending packets. */ | 389 | /* @@@ Flush out pending packets. */ |
391 | 390 | ||
391 | for (i = 0; i < nds_count; i++) | ||
392 | unregister_netdev(nds[i]); | ||
393 | |||
392 | ixp2000_uengine_stop_contexts(1, 0xff); | 394 | ixp2000_uengine_stop_contexts(1, 0xff); |
393 | ixp2000_uengine_stop_contexts(0, 0xff); | 395 | ixp2000_uengine_stop_contexts(0, 0xff); |
394 | ixp2000_uengine_reset(0x3); | 396 | ixp2000_uengine_reset(0x3); |
@@ -398,7 +400,4 @@ void ixpdev_deinit(void) | |||
398 | 400 | ||
399 | for (i = 0; i < RX_BUF_COUNT; i++) | 401 | for (i = 0; i < RX_BUF_COUNT; i++) |
400 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); | 402 | free_page((unsigned long)phys_to_virt(rx_desc[i].buf_addr)); |
401 | |||
402 | for (i = 0; i < nds_count; i++) | ||
403 | unregister_netdev(nds[i]); | ||
404 | } | 403 | } |