RESEND [PATCH 3/3] NetXen: Graceful teardown of interface and hardware upon module unload

Resending patch 3/3 only.

These changes allow driver close routine to be called during module unload,
to clean-up buffers and other software resources, flush queues etc. Also,
hardware is reset to pristine state.

Signed-off-by: Dhananjay Phadke <dhananjay@netxen.com>
Signed-off-by: Milan Bag <mbag@netxen.com>
Signed-off-by: Wen Xiong <wenxiong@us.ibm.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index 2b40a5a..aac1542 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -377,7 +377,7 @@
 						   recv_crb_registers[ctx].
 						   crb_rcvpeg_state));
 		while (state != PHAN_PEG_RCV_INITIALIZED && loops < 20) {
-			udelay(100);
+			msleep(1);
 			/* Window 1 call */
 			state = readl(NETXEN_CRB_NORMALIZE(adapter,
 							   recv_crb_registers
@@ -394,7 +394,7 @@
 	}
 	adapter->intr_scheme = readl(
 		NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
-	printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netdev->name,
+	printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
 			adapter->intr_scheme);
 	DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");
 
@@ -701,7 +701,7 @@
 		adapter->curr_window = 0;
 }
 
-void netxen_load_firmware(struct netxen_adapter *adapter)
+int netxen_load_firmware(struct netxen_adapter *adapter)
 {
 	int i;
 	u32 data, size = 0;
@@ -713,15 +713,24 @@
 	writel(1, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
 
 	for (i = 0; i < size; i++) {
-		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0) {
-			DPRINTK(ERR,
-				"Error in netxen_rom_fast_read(). Will skip"
-				"loading flash image\n");
-			return;
-		}
+		int retries = 10;
+		if (netxen_rom_fast_read(adapter, flashaddr, (int *)&data) != 0)
+			return -EIO;
+
 		off = netxen_nic_pci_set_window(adapter, memaddr);
 		addr = pci_base_offset(adapter, off);
 		writel(data, addr);
+		do {
+			if (readl(addr) == data)
+				break;
+			msleep(100);
+			writel(data, addr);
+		} while (--retries);
+		if (!retries) {
+			printk(KERN_ERR "%s: firmware load aborted, write failed at 0x%x\n",
+					netxen_nic_driver_name, memaddr);
+			return -EIO;
+		}
 		flashaddr += 4;
 		memaddr += 4;
 	}
@@ -731,7 +740,7 @@
 	       NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CHIP_CLK_CTRL));
 	writel(0, NETXEN_CRB_NORMALIZE(adapter, NETXEN_ROMUSB_GLB_CAS_RST));
 
-	udelay(100);
+	return 0;
 }
 
 int