Beispiel #1
0
static void p54p_firmware_step2(const struct firmware *fw,
				void *context)
{
	struct p54p_priv *priv = context;
	struct ieee80211_hw *dev = priv->common.hw;
	struct pci_dev *pdev = priv->pdev;
	int err;

	if (!fw) {
		dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
		err = -ENOENT;
		goto out;
	}

	priv->firmware = fw;

	err = p54p_open(dev);
	if (err)
		goto out;
	err = p54_read_eeprom(dev);
	p54p_stop(dev);
	if (err)
		goto out;

	err = p54_register_common(dev, &pdev->dev);
	if (err)
		goto out;

out:

	complete(&priv->fw_loaded);

	if (err) {
		struct device *parent = pdev->dev.parent;

		if (parent)
			device_lock(parent);

		/*
		 * This will indirectly result in a call to p54p_remove.
		 * Hence, we don't need to bother with freeing any
		 * allocated ressources at all.
		 */
		device_release_driver(&pdev->dev);

		if (parent)
			device_unlock(parent);
	}

	pci_dev_put(pdev);
}
Beispiel #2
0
static int __devinit p54spi_probe(struct spi_device *spi)
{
	struct p54s_priv *priv = NULL;
	struct ieee80211_hw *hw;
	int ret = -EINVAL;

	hw = p54_init_common(sizeof(*priv));
	if (!hw) {
		dev_err(&spi->dev, "could not alloc ieee80211_hw");
		return -ENOMEM;
	}

	priv = hw->priv;
	priv->hw = hw;
	dev_set_drvdata(&spi->dev, priv);
	priv->spi = spi;

	spi->bits_per_word = 16;
	spi->max_speed_hz = 24000000;

	ret = spi_setup(spi);
	if (ret < 0) {
		dev_err(&priv->spi->dev, "spi_setup failed");
		goto err_free_common;
	}

	ret = gpio_request(p54spi_gpio_power, "p54spi power");
	if (ret < 0) {
		dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret);
		goto err_free_common;
	}

	ret = gpio_request(p54spi_gpio_irq, "p54spi irq");
	if (ret < 0) {
		dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret);
		goto err_free_common;
	}

	gpio_direction_output(p54spi_gpio_power, 0);
	gpio_direction_input(p54spi_gpio_irq);

	ret = request_irq(gpio_to_irq(p54spi_gpio_irq),
			  p54spi_interrupt, IRQF_DISABLED, "p54spi",
			  priv->spi);
	if (ret < 0) {
		dev_err(&priv->spi->dev, "request_irq() failed");
		goto err_free_common;
	}

	set_irq_type(gpio_to_irq(p54spi_gpio_irq),
		     IRQ_TYPE_EDGE_RISING);

	disable_irq(gpio_to_irq(p54spi_gpio_irq));

	INIT_WORK(&priv->work, p54spi_work);
	init_completion(&priv->fw_comp);
	INIT_LIST_HEAD(&priv->tx_pending);
	mutex_init(&priv->mutex);
	spin_lock_init(&priv->tx_lock);
	SET_IEEE80211_DEV(hw, &spi->dev);
	priv->common.open = p54spi_op_start;
	priv->common.stop = p54spi_op_stop;
	priv->common.tx = p54spi_op_tx;

	ret = p54spi_request_firmware(hw);
	if (ret < 0)
		goto err_free_common;

	ret = p54spi_request_eeprom(hw);
	if (ret)
		goto err_free_common;

	ret = p54_register_common(hw, &priv->spi->dev);
	if (ret)
		goto err_free_common;

	return 0;

err_free_common:
	p54_free_common(priv->hw);
	return ret;
}
Beispiel #3
0
static int __devinit p54p_probe(struct pci_dev *pdev,
				const struct pci_device_id *id)
{
	struct p54p_priv *priv;
	struct ieee80211_hw *dev;
	unsigned long mem_addr, mem_len;
	int err;

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "Cannot enable new PCI device\n");
		return err;
	}

	mem_addr = pci_resource_start(pdev, 0);
	mem_len = pci_resource_len(pdev, 0);
	if (mem_len < sizeof(struct p54p_csr)) {
		dev_err(&pdev->dev, "Too short PCI resources\n");
		goto err_disable_dev;
	}

	err = pci_request_regions(pdev, "p54pci");
	if (err) {
		dev_err(&pdev->dev, "Cannot obtain PCI resources\n");
		goto err_disable_dev;
	}

	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
		dev_err(&pdev->dev, "No suitable DMA available\n");
		goto err_free_reg;
	}

	pci_set_master(pdev);
	pci_try_set_mwi(pdev);

	pci_write_config_byte(pdev, 0x40, 0);
	pci_write_config_byte(pdev, 0x41, 0);

	dev = p54_init_common(sizeof(*priv));
	if (!dev) {
		dev_err(&pdev->dev, "ieee80211 alloc failed\n");
		err = -ENOMEM;
		goto err_free_reg;
	}

	priv = dev->priv;
	priv->pdev = pdev;

	SET_IEEE80211_DEV(dev, &pdev->dev);
	pci_set_drvdata(pdev, dev);

	priv->map = ioremap(mem_addr, mem_len);
	if (!priv->map) {
		dev_err(&pdev->dev, "Cannot map device memory\n");
		err = -ENOMEM;
		goto err_free_dev;
	}

	priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
						  &priv->ring_control_dma);
	if (!priv->ring_control) {
		dev_err(&pdev->dev, "Cannot allocate rings\n");
		err = -ENOMEM;
		goto err_iounmap;
	}
	priv->common.open = p54p_open;
	priv->common.stop = p54p_stop;
	priv->common.tx = p54p_tx;

	spin_lock_init(&priv->lock);
	tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev);

	err = request_firmware(&priv->firmware, "isl3886pci",
			       &priv->pdev->dev);
	if (err) {
		dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n");
		err = request_firmware(&priv->firmware, "isl3886",
				       &priv->pdev->dev);
		if (err)
			goto err_free_common;
	}

	err = p54p_open(dev);
	if (err)
		goto err_free_common;
	err = p54_read_eeprom(dev);
	p54p_stop(dev);
	if (err)
		goto err_free_common;

	err = p54_register_common(dev, &pdev->dev);
	if (err)
		goto err_free_common;

	return 0;

 err_free_common:
	release_firmware(priv->firmware);
	pci_free_consistent(pdev, sizeof(*priv->ring_control),
			    priv->ring_control, priv->ring_control_dma);

 err_iounmap:
	iounmap(priv->map);

 err_free_dev:
	pci_set_drvdata(pdev, NULL);
	p54_free_common(dev);

 err_free_reg:
	pci_release_regions(pdev);
 err_disable_dev:
	pci_disable_device(pdev);
	return err;
}