aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ibmveth.c
diff options
context:
space:
mode:
authorMichael Ellerman <michael@ellerman.id.au>2006-10-03 13:24:23 -0400
committerJeff Garzik <jeff@garzik.org>2006-10-05 06:43:23 -0400
commitbbedefccc6b0da43cfaf785dac89c88bc59cb6ed (patch)
tree331fe1b4cd7eab50f7f20254d93d30558b67d1eb /drivers/net/ibmveth.c
parent489b10c1f63fafcb89c330a0603694652068132a (diff)
[PATCH] ibmveth: Harden driver initilisation
This patch has been floating around for a while now, Santi originally sent it in March: http://www.spinics.net/lists/netdev/msg00471.html After a kexec the ibmveth driver will fail when trying to register with the Hypervisor because the previous kernel has not unregistered. So if the registration fails, we unregister and then try again. We don't unconditionally unregister, because we don't want to disturb the regular code path for 99% of users. Signed-off-by: Michael Ellerman <michael@ellerman.id.au> Acked-by: Anton Blanchard <anton@samba.org> Signed-off-by: Santiago Leon <santil@us.ibm.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/ibmveth.c')
-rw-r--r--drivers/net/ibmveth.c32
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 767203d35bc2..df3a59efa7a8 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -437,6 +437,31 @@ static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
437 &adapter->rx_buff_pool[i]); 437 &adapter->rx_buff_pool[i]);
438} 438}
439 439
440static int ibmveth_register_logical_lan(struct ibmveth_adapter *adapter,
441 union ibmveth_buf_desc rxq_desc, u64 mac_address)
442{
443 int rc, try_again = 1;
444
445 /* After a kexec the adapter will still be open, so our attempt to
446 * open it will fail. So if we get a failure we free the adapter and
447 * try again, but only once. */
448retry:
449 rc = h_register_logical_lan(adapter->vdev->unit_address,
450 adapter->buffer_list_dma, rxq_desc.desc,
451 adapter->filter_list_dma, mac_address);
452
453 if (rc != H_SUCCESS && try_again) {
454 do {
455 rc = h_free_logical_lan(adapter->vdev->unit_address);
456 } while (H_IS_LONG_BUSY(rc) || (rc == H_BUSY));
457
458 try_again = 0;
459 goto retry;
460 }
461
462 return rc;
463}
464
440static int ibmveth_open(struct net_device *netdev) 465static int ibmveth_open(struct net_device *netdev)
441{ 466{
442 struct ibmveth_adapter *adapter = netdev->priv; 467 struct ibmveth_adapter *adapter = netdev->priv;
@@ -502,12 +527,7 @@ static int ibmveth_open(struct net_device *netdev)
502 ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr); 527 ibmveth_debug_printk("filter list @ 0x%p\n", adapter->filter_list_addr);
503 ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr); 528 ibmveth_debug_printk("receive q @ 0x%p\n", adapter->rx_queue.queue_addr);
504 529
505 530 lpar_rc = ibmveth_register_logical_lan(adapter, rxq_desc, mac_address);
506 lpar_rc = h_register_logical_lan(adapter->vdev->unit_address,
507 adapter->buffer_list_dma,
508 rxq_desc.desc,
509 adapter->filter_list_dma,
510 mac_address);
511 531
512 if(lpar_rc != H_SUCCESS) { 532 if(lpar_rc != H_SUCCESS) {
513 ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc); 533 ibmveth_error_printk("h_register_logical_lan failed with %ld\n", lpar_rc);