/* 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); }
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; }
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_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; }
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; }
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; }
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; }