static int
islpci_upload_fw(islpci_private *priv)
{
	islpci_state_t old_state;
	u32 rc;

	old_state = islpci_set_state(priv, PRV_STATE_BOOT);

	printk(KERN_DEBUG "%s: uploading firmware...\n", priv->ndev->name);

	rc = isl_upload_firmware(priv);
	if (rc) {
		/* error uploading the firmware */
		printk(KERN_ERR "%s: could not upload firmware ('%s')\n",
		       priv->ndev->name, priv->firmware);

		islpci_set_state(priv, old_state);
		return rc;
	}

	printk(KERN_DEBUG "%s: firmware upload complete\n",
	       priv->ndev->name);

	islpci_set_state(priv, PRV_STATE_POSTBOOT);

	return 0;
}
/* this one removes one(!!) instance only */
static void
prism54_remove(struct pci_dev *pdev)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);

	if (!__in_cleanup_module) {
		printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name);
		islpci_set_state(priv, PRV_STATE_OFF);
	}

	printk(KERN_DEBUG "%s: removing device\n", ndev->name);

	unregister_netdev(ndev);

	/* free the interrupt request */

	if (islpci_get_state(priv) != PRV_STATE_OFF) {
		isl38xx_disable_interrupts(priv->device_base);
		islpci_set_state(priv, PRV_STATE_OFF);
		/* This bellow causes a lockup at rmmod time. It might be
		 * because some interrupts still linger after rmmod time,
		 * see bug #17 */
		/* pci_set_power_state(pdev, 3);*/	/* try to power-off */
	}

	free_irq(pdev->irq, priv);

	/* free the PCI memory and unmap the remapped page */
	islpci_free_memory(priv);

	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;

	pci_clear_mwi(pdev);

	pci_release_regions(pdev);

	pci_disable_device(pdev);
}
Пример #3
0
static void
prism54_remove(struct pci_dev *pdev)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);

	if (!__in_cleanup_module) {
		printk(KERN_DEBUG "%s: hot unplug detected\n", ndev->name);
		islpci_set_state(priv, PRV_STATE_OFF);
	}

	printk(KERN_DEBUG "%s: removing device\n", ndev->name);

	unregister_netdev(ndev);

	

	if (islpci_get_state(priv) != PRV_STATE_OFF) {
		isl38xx_disable_interrupts(priv->device_base);
		islpci_set_state(priv, PRV_STATE_OFF);
		
			
	}

	free_irq(pdev->irq, priv);

	
	islpci_free_memory(priv);

	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;

	pci_clear_mwi(pdev);

	pci_release_regions(pdev);

	pci_disable_device(pdev);
}
static int
prism54_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);


	pci_save_state(pdev);

	
	isl38xx_disable_interrupts(priv->device_base);

	islpci_set_state(priv, PRV_STATE_OFF);

	netif_stop_queue(ndev);
	netif_device_detach(ndev);

	return 0;
}
Пример #5
0
static int
prism54_bring_down(islpci_private *priv)
{
	void __iomem *device_base = priv->device_base;
	u32 reg;
	/* we are going to shutdown the device */
	islpci_set_state(priv, PRV_STATE_PREBOOT);

	/* disable all device interrupts in case they weren't */
	isl38xx_disable_interrupts(priv->device_base);  

	/* For safety reasons, we may want to ensure that no DMA transfer is
	 * currently in progress by emptying the TX and RX queues. */

	/* wait until interrupts have finished executing on other CPUs */
	synchronize_irq(priv->pdev->irq);

	reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
	reg &= ~(ISL38XX_CTRL_STAT_RESET | ISL38XX_CTRL_STAT_RAMBOOT);
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	reg |= ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();
	udelay(ISL38XX_WRITEIO_DELAY);

	/* clear the Reset bit */
	reg &= ~ISL38XX_CTRL_STAT_RESET;
	writel(reg, device_base + ISL38XX_CTRL_STAT_REG);
	wmb();

	/* wait a while for the device to reset */
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(50*HZ/1000);

	return 0;
}
static int
prism54_suspend(struct pci_dev *pdev, pm_message_t state)
{
	struct net_device *ndev = pci_get_drvdata(pdev);
	islpci_private *priv = ndev ? netdev_priv(ndev) : NULL;
	BUG_ON(!priv);


	pci_save_state(pdev);

	/* tell the device not to trigger interrupts for now... */
	isl38xx_disable_interrupts(priv->device_base);

	/* from now on assume the hardware was already powered down
	   and don't touch it anymore */
	islpci_set_state(priv, PRV_STATE_OFF);

	netif_stop_queue(ndev);
	netif_device_detach(ndev);

	return 0;
}
Пример #7
0
int
islpci_reset(islpci_private *priv, int reload_firmware)
{
	isl38xx_control_block *cb =    /* volatile not needed */
		(isl38xx_control_block *) priv->control_block;
	unsigned counter;
	int rc;

	if (reload_firmware)
		islpci_set_state(priv, PRV_STATE_PREBOOT);
	else
		islpci_set_state(priv, PRV_STATE_POSTBOOT);

	printk(KERN_DEBUG "%s: resetting device...\n", priv->ndev->name);

	/* disable all device interrupts in case they weren't */
	isl38xx_disable_interrupts(priv->device_base);

	/* flush all management queues */
	priv->index_mgmt_tx = 0;
	priv->index_mgmt_rx = 0;

	/* clear the indexes in the frame pointer */
	for (counter = 0; counter < ISL38XX_CB_QCOUNT; counter++) {
		cb->driver_curr_frag[counter] = cpu_to_le32(0);
		cb->device_curr_frag[counter] = cpu_to_le32(0);
	}

	/* reset the mgmt receive queue */
	for (counter = 0; counter < ISL38XX_CB_MGMT_QSIZE; counter++) {
		isl38xx_fragment *frag = &cb->rx_data_mgmt[counter];
		frag->size = cpu_to_le16(MGMT_FRAME_SIZE);
		frag->flags = 0;
		frag->address = cpu_to_le32(priv->mgmt_rx[counter].pci_addr);
	}

	for (counter = 0; counter < ISL38XX_CB_RX_QSIZE; counter++) {
		cb->rx_data_low[counter].address =
		    cpu_to_le32((u32) priv->pci_map_rx_address[counter]);
	}

	/* since the receive queues are filled with empty fragments, now we can
	 * set the corresponding indexes in the Control Block */
	priv->control_block->driver_curr_frag[ISL38XX_CB_RX_DATA_LQ] =
	    cpu_to_le32(ISL38XX_CB_RX_QSIZE);
	priv->control_block->driver_curr_frag[ISL38XX_CB_RX_MGMTQ] =
	    cpu_to_le32(ISL38XX_CB_MGMT_QSIZE);

	/* reset the remaining real index registers and full flags */
	priv->free_data_rx = 0;
	priv->free_data_tx = 0;
	priv->data_low_tx_full = 0;

	if (reload_firmware) { /* Should we load the firmware ? */
	/* now that the data structures are cleaned up, upload
	 * firmware and reset interface */
		rc = islpci_upload_fw(priv);
		if (rc) {
			printk(KERN_ERR "%s: islpci_reset: failure\n",
				priv->ndev->name);
			return rc;
		}
	}

	/* finally reset interface */
	rc = islpci_reset_if(priv);
	if (rc)
		printk(KERN_ERR "prism54: Your card/socket may be faulty, or IRQ line too busy :(\n");
	return rc;
}
Пример #8
0
static int
islpci_reset_if(islpci_private *priv)
{
	long remaining;
	int result = -ETIME;
	int count;

	DEFINE_WAIT(wait);
	prepare_to_wait(&priv->reset_done, &wait, TASK_UNINTERRUPTIBLE);

	/* now the last step is to reset the interface */
	isl38xx_interface_reset(priv->device_base, priv->device_host_address);
	islpci_set_state(priv, PRV_STATE_PREINIT);

        for(count = 0; count < 2 && result; count++) {
		/* The software reset acknowledge needs about 220 msec here.
		 * Be conservative and wait for up to one second. */

		remaining = schedule_timeout_uninterruptible(HZ);

		if(remaining > 0) {
			result = 0;
			break;
		}

		/* If we're here it's because our IRQ hasn't yet gone through.
		 * Retry a bit more...
		 */
		printk(KERN_ERR "%s: no 'reset complete' IRQ seen - retrying\n",
			priv->ndev->name);
	}

	finish_wait(&priv->reset_done, &wait);

	if (result) {
		printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
		return result;
	}

	islpci_set_state(priv, PRV_STATE_INIT);

	/* Now that the device is 100% up, let's allow
	 * for the other interrupts --
	 * NOTE: this is not *yet* true since we've only allowed the
	 * INIT interrupt on the IRQ line. We can perhaps poll
	 * the IRQ line until we know for sure the reset went through */
	isl38xx_enable_common_interrupts(priv->device_base);

	down_write(&priv->mib_sem);
	result = mgt_commit(priv);
	if (result) {
		printk(KERN_ERR "%s: interface reset failure\n", priv->ndev->name);
		up_write(&priv->mib_sem);
		return result;
	}
	up_write(&priv->mib_sem);

	islpci_set_state(priv, PRV_STATE_READY);

	printk(KERN_DEBUG "%s: interface reset complete\n", priv->ndev->name);
	return 0;
}
Пример #9
0
irqreturn_t
islpci_interrupt(int irq, void *config)
{
	u32 reg;
	islpci_private *priv = config;
	struct net_device *ndev = priv->ndev;
	void __iomem *device = priv->device_base;
	int powerstate = ISL38XX_PSM_POWERSAVE_STATE;

	/* lock the interrupt handler */
	spin_lock(&priv->slock);

	/* received an interrupt request on a shared IRQ line
	 * first check whether the device is in sleep mode */
	reg = readl(device + ISL38XX_CTRL_STAT_REG);
	if (reg & ISL38XX_CTRL_STAT_SLEEPMODE)
		/* device is in sleep mode, IRQ was generated by someone else */
	{
#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
#endif
		spin_unlock(&priv->slock);
		return IRQ_NONE;
	}


	/* check whether there is any source of interrupt on the device */
	reg = readl(device + ISL38XX_INT_IDENT_REG);

	/* also check the contents of the Interrupt Enable Register, because this
	 * will filter out interrupt sources from other devices on the same irq ! */
	reg &= readl(device + ISL38XX_INT_EN_REG);
	reg &= ISL38XX_INT_SOURCES;

	if (reg != 0) {
		if (islpci_get_state(priv) != PRV_STATE_SLEEP)
			powerstate = ISL38XX_PSM_ACTIVE_STATE;

		/* reset the request bits in the Identification register */
		isl38xx_w32_flush(device, reg, ISL38XX_INT_ACK_REG);

#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_FUNCTION_CALLS,
		      "IRQ: Identification register 0x%p 0x%x \n", device, reg);
#endif

		/* check for each bit in the register separately */
		if (reg & ISL38XX_INT_IDENT_UPDATE) {
#if VERBOSE > SHOW_ERROR_MESSAGES
			/* Queue has been updated */
			DEBUG(SHOW_TRACING, "IRQ: Update flag \n");

			DEBUG(SHOW_QUEUE_INDEXES,
			      "CB drv Qs: [%i][%i][%i][%i][%i][%i]\n",
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[0]),
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[1]),
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[2]),
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[3]),
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[4]),
			      le32_to_cpu(priv->control_block->
					  driver_curr_frag[5])
			    );

			DEBUG(SHOW_QUEUE_INDEXES,
			      "CB dev Qs: [%i][%i][%i][%i][%i][%i]\n",
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[0]),
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[1]),
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[2]),
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[3]),
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[4]),
			      le32_to_cpu(priv->control_block->
					  device_curr_frag[5])
			    );
#endif

			/* cleanup the data low transmit queue */
			islpci_eth_cleanup_transmit(priv, priv->control_block);

			/* device is in active state, update the
			 * powerstate flag if necessary */
			powerstate = ISL38XX_PSM_ACTIVE_STATE;

			/* check all three queues in priority order
			 * call the PIMFOR receive function until the
			 * queue is empty */
			if (isl38xx_in_queue(priv->control_block,
						ISL38XX_CB_RX_MGMTQ) != 0) {
#if VERBOSE > SHOW_ERROR_MESSAGES
				DEBUG(SHOW_TRACING,
				      "Received frame in Management Queue\n");
#endif
				islpci_mgt_receive(ndev);

				islpci_mgt_cleanup_transmit(ndev);

				/* Refill slots in receive queue */
				islpci_mgmt_rx_fill(ndev);

				/* no need to trigger the device, next
                                   islpci_mgt_transaction does it */
			}

			while (isl38xx_in_queue(priv->control_block,
						ISL38XX_CB_RX_DATA_LQ) != 0) {
#if VERBOSE > SHOW_ERROR_MESSAGES
				DEBUG(SHOW_TRACING,
				      "Received frame in Data Low Queue \n");
#endif
				islpci_eth_receive(priv);
			}

			/* check whether the data transmit queues were full */
			if (priv->data_low_tx_full) {
				/* check whether the transmit is not full anymore */
				if (ISL38XX_CB_TX_QSIZE -
				    isl38xx_in_queue(priv->control_block,
						     ISL38XX_CB_TX_DATA_LQ) >=
				    ISL38XX_MIN_QTHRESHOLD) {
					/* nope, the driver is ready for more network frames */
					netif_wake_queue(priv->ndev);

					/* reset the full flag */
					priv->data_low_tx_full = 0;
				}
			}
		}

		if (reg & ISL38XX_INT_IDENT_INIT) {
			/* Device has been initialized */
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING,
			      "IRQ: Init flag, device initialized \n");
#endif
			wake_up(&priv->reset_done);
		}

		if (reg & ISL38XX_INT_IDENT_SLEEP) {
			/* Device intends to move to powersave state */
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "IRQ: Sleep flag \n");
#endif
			isl38xx_handle_sleep_request(priv->control_block,
						     &powerstate,
						     priv->device_base);
		}

		if (reg & ISL38XX_INT_IDENT_WAKEUP) {
			/* Device has been woken up to active state */
#if VERBOSE > SHOW_ERROR_MESSAGES
			DEBUG(SHOW_TRACING, "IRQ: Wakeup flag \n");
#endif

			isl38xx_handle_wakeup(priv->control_block,
					      &powerstate, priv->device_base);
		}
	} else {
#if VERBOSE > SHOW_ERROR_MESSAGES
		DEBUG(SHOW_TRACING, "Assuming someone else called the IRQ\n");
#endif
		spin_unlock(&priv->slock);
		return IRQ_NONE;
	}

	/* sleep -> ready */
	if (islpci_get_state(priv) == PRV_STATE_SLEEP
	    && powerstate == ISL38XX_PSM_ACTIVE_STATE)
		islpci_set_state(priv, PRV_STATE_READY);

	/* !sleep -> sleep */
	if (islpci_get_state(priv) != PRV_STATE_SLEEP
	    && powerstate == ISL38XX_PSM_POWERSAVE_STATE)
		islpci_set_state(priv, PRV_STATE_SLEEP);

	/* unlock the interrupt handler */
	spin_unlock(&priv->slock);

	return IRQ_HANDLED;
}
static int
prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net_device *ndev;
	u8 latency_tmr;
	u32 mem_addr;
	islpci_private *priv;
	int rvalue;

	/* Enable the pci device */
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
		return -ENODEV;
	}

	/* check whether the latency timer is set correctly */
	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr);
#endif
	if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) {
		/* set the latency timer */
		pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
				      PCIDEVICE_LATENCY_TIMER_VAL);
	}

	/* enable PCI DMA */
	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
		goto do_pci_disable_device;
        }

	/* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT)
	 * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT)
	 *	The RETRY_TIMEOUT is used to set the number of retries that the core, as a
	 *	Master, will perform before abandoning a cycle. The default value for
	 *	RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new
	 *	devices. A write of zero to the RETRY_TIMEOUT register disables this
	 *	function to allow use with any non-compliant legacy devices that may
	 *	execute more retries.
	 *
	 *	Writing zero to both these two registers will disable both timeouts and
	 *	*can* solve problems caused by devices that are slow to respond.
	 *	Make this configurable - MSW
	 */
	if ( init_pcitm >= 0 ) {
		pci_write_config_byte(pdev, 0x40, (u8)init_pcitm);
		pci_write_config_byte(pdev, 0x41, (u8)init_pcitm);
	} else {
		printk(KERN_INFO "PCI TRDY/RETRY unchanged\n");
	}

	/* request the pci device I/O regions */
	rvalue = pci_request_regions(pdev, DRV_NAME);
	if (rvalue) {
		printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n",
		       DRV_NAME, rvalue);
		goto do_pci_disable_device;
	}

	/* check if the memory window is indeed set */
	rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr);
	if (rvalue || !mem_addr) {
		printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n",
		       DRV_NAME);
		goto do_pci_release_regions;
	}

	/* enable PCI bus-mastering */
	DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME);
	pci_set_master(pdev);

	/* enable MWI */
	pci_try_set_mwi(pdev);

	/* setup the network device interface and its structure */
	if (!(ndev = islpci_setup(pdev))) {
		/* error configuring the driver as a network device */
		printk(KERN_ERR "%s: could not configure network device\n",
		       DRV_NAME);
		goto do_pci_clear_mwi;
	}

	priv = netdev_priv(ndev);
	islpci_set_state(priv, PRV_STATE_PREBOOT); /* we are attempting to boot */

	/* card is in unknown state yet, might have some interrupts pending */
	isl38xx_disable_interrupts(priv->device_base);

	/* request for the interrupt before uploading the firmware */
	rvalue = request_irq(pdev->irq, islpci_interrupt,
			     IRQF_SHARED, ndev->name, priv);

	if (rvalue) {
		/* error, could not hook the handler to the irq */
		printk(KERN_ERR "%s: could not install IRQ handler\n",
		       ndev->name);
		goto do_unregister_netdev;
	}

	/* firmware upload is triggered in islpci_open */

	return 0;

      do_unregister_netdev:
	unregister_netdev(ndev);
	islpci_free_memory(priv);
	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;
      do_pci_clear_mwi:
	pci_clear_mwi(pdev);
      do_pci_release_regions:
	pci_release_regions(pdev);
      do_pci_disable_device:
	pci_disable_device(pdev);
	return -EIO;
}
Пример #11
0
static int
prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	struct net_device *ndev;
	u8 latency_tmr;
	u32 mem_addr;
	islpci_private *priv;
	int rvalue;

	
	if (pci_enable_device(pdev)) {
		printk(KERN_ERR "%s: pci_enable_device() failed.\n", DRV_NAME);
		return -ENODEV;
	}

	
	pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency_tmr);
#if VERBOSE > SHOW_ERROR_MESSAGES
	DEBUG(SHOW_TRACING, "latency timer: %x\n", latency_tmr);
#endif
	if (latency_tmr < PCIDEVICE_LATENCY_TIMER_MIN) {
		
		pci_write_config_byte(pdev, PCI_LATENCY_TIMER,
				      PCIDEVICE_LATENCY_TIMER_VAL);
	}

	
	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		printk(KERN_ERR "%s: 32-bit PCI DMA not supported", DRV_NAME);
		goto do_pci_disable_device;
        }

	
	if ( init_pcitm >= 0 ) {
		pci_write_config_byte(pdev, 0x40, (u8)init_pcitm);
		pci_write_config_byte(pdev, 0x41, (u8)init_pcitm);
	} else {
		printk(KERN_INFO "PCI TRDY/RETRY unchanged\n");
	}

	
	rvalue = pci_request_regions(pdev, DRV_NAME);
	if (rvalue) {
		printk(KERN_ERR "%s: pci_request_regions failure (rc=%d)\n",
		       DRV_NAME, rvalue);
		goto do_pci_disable_device;
	}

	
	rvalue = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &mem_addr);
	if (rvalue || !mem_addr) {
		printk(KERN_ERR "%s: PCI device memory region not configured; fix your BIOS or CardBus bridge/drivers\n",
		       DRV_NAME);
		goto do_pci_release_regions;
	}

	
	DEBUG(SHOW_TRACING, "%s: pci_set_master(pdev)\n", DRV_NAME);
	pci_set_master(pdev);

	
	pci_try_set_mwi(pdev);

	
	if (!(ndev = islpci_setup(pdev))) {
		
		printk(KERN_ERR "%s: could not configure network device\n",
		       DRV_NAME);
		goto do_pci_clear_mwi;
	}

	priv = netdev_priv(ndev);
	islpci_set_state(priv, PRV_STATE_PREBOOT); 

	
	isl38xx_disable_interrupts(priv->device_base);

	
	rvalue = request_irq(pdev->irq, &islpci_interrupt,
			     IRQF_SHARED, ndev->name, priv);

	if (rvalue) {
		
		printk(KERN_ERR "%s: could not install IRQ handler\n",
		       ndev->name);
		goto do_unregister_netdev;
	}

	

	return 0;

      do_unregister_netdev:
	unregister_netdev(ndev);
	islpci_free_memory(priv);
	pci_set_drvdata(pdev, NULL);
	free_netdev(ndev);
	priv = NULL;
      do_pci_clear_mwi:
	pci_clear_mwi(pdev);
      do_pci_release_regions:
	pci_release_regions(pdev);
      do_pci_disable_device:
	pci_disable_device(pdev);
	return -EIO;
}