in solos-pci.c [1191:1350]
static int fpga_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int err;
uint16_t fpga_ver;
uint8_t major_ver, minor_ver;
uint32_t data32;
struct solos_card *card;
card = kzalloc(sizeof(*card), GFP_KERNEL);
if (!card)
return -ENOMEM;
card->dev = dev;
init_waitqueue_head(&card->fw_wq);
init_waitqueue_head(&card->param_wq);
err = pci_enable_device(dev);
if (err) {
dev_warn(&dev->dev, "Failed to enable PCI device\n");
goto out;
}
err = dma_set_mask_and_coherent(&dev->dev, DMA_BIT_MASK(32));
if (err) {
dev_warn(&dev->dev, "Failed to set 32-bit DMA mask\n");
goto out;
}
err = pci_request_regions(dev, "solos");
if (err) {
dev_warn(&dev->dev, "Failed to request regions\n");
goto out;
}
card->config_regs = pci_iomap(dev, 0, CONFIG_RAM_SIZE);
if (!card->config_regs) {
dev_warn(&dev->dev, "Failed to ioremap config registers\n");
err = -ENOMEM;
goto out_release_regions;
}
card->buffers = pci_iomap(dev, 1, DATA_RAM_SIZE);
if (!card->buffers) {
dev_warn(&dev->dev, "Failed to ioremap data buffers\n");
err = -ENOMEM;
goto out_unmap_config;
}
if (reset) {
iowrite32(1, card->config_regs + FPGA_MODE);
ioread32(card->config_regs + FPGA_MODE);
iowrite32(0, card->config_regs + FPGA_MODE);
ioread32(card->config_regs + FPGA_MODE);
}
data32 = ioread32(card->config_regs + FPGA_VER);
fpga_ver = (data32 & 0x0000FFFF);
major_ver = ((data32 & 0xFF000000) >> 24);
minor_ver = ((data32 & 0x00FF0000) >> 16);
card->fpga_version = FPGA_VERSION(major_ver,minor_ver);
if (card->fpga_version > LEGACY_BUFFERS)
card->buffer_size = BUF_SIZE;
else
card->buffer_size = OLD_BUF_SIZE;
dev_info(&dev->dev, "Solos FPGA Version %d.%02d svn-%d\n",
major_ver, minor_ver, fpga_ver);
if (fpga_ver < 37 && (fpga_upgrade || firmware_upgrade ||
db_fpga_upgrade || db_firmware_upgrade)) {
dev_warn(&dev->dev,
"FPGA too old; cannot upgrade flash. Use JTAG.\n");
fpga_upgrade = firmware_upgrade = 0;
db_fpga_upgrade = db_firmware_upgrade = 0;
}
/* Stopped using Atmel flash after 0.03-38 */
if (fpga_ver < 39)
card->atmel_flash = 1;
else
card->atmel_flash = 0;
data32 = ioread32(card->config_regs + PORTS);
card->nr_ports = (data32 & 0x000000FF);
if (card->fpga_version >= DMA_SUPPORTED) {
pci_set_master(dev);
card->using_dma = 1;
if (1) { /* All known FPGA versions so far */
card->dma_alignment = 3;
card->dma_bounce = kmalloc_array(card->nr_ports,
BUF_SIZE, GFP_KERNEL);
if (!card->dma_bounce) {
dev_warn(&card->dev->dev, "Failed to allocate DMA bounce buffers\n");
err = -ENOMEM;
/* Fallback to MMIO doesn't work */
goto out_unmap_both;
}
}
} else {
card->using_dma = 0;
/* Set RX empty flag for all ports */
iowrite32(0xF0, card->config_regs + FLAGS_ADDR);
}
pci_set_drvdata(dev, card);
tasklet_init(&card->tlet, solos_bh, (unsigned long)card);
spin_lock_init(&card->tx_lock);
spin_lock_init(&card->tx_queue_lock);
spin_lock_init(&card->cli_queue_lock);
spin_lock_init(&card->param_queue_lock);
INIT_LIST_HEAD(&card->param_queue);
err = request_irq(dev->irq, solos_irq, IRQF_SHARED,
"solos-pci", card);
if (err) {
dev_dbg(&card->dev->dev, "Failed to request interrupt IRQ: %d\n", dev->irq);
goto out_unmap_both;
}
iowrite32(1, card->config_regs + IRQ_EN_ADDR);
if (fpga_upgrade)
flash_upgrade(card, 0);
if (firmware_upgrade)
flash_upgrade(card, 1);
if (db_fpga_upgrade)
flash_upgrade(card, 2);
if (db_firmware_upgrade)
flash_upgrade(card, 3);
err = atm_init(card, &dev->dev);
if (err)
goto out_free_irq;
if (card->fpga_version >= DMA_SUPPORTED &&
sysfs_create_group(&card->dev->dev.kobj, &gpio_attr_group))
dev_err(&card->dev->dev, "Could not register parameter group for GPIOs\n");
return 0;
out_free_irq:
iowrite32(0, card->config_regs + IRQ_EN_ADDR);
free_irq(dev->irq, card);
tasklet_kill(&card->tlet);
out_unmap_both:
kfree(card->dma_bounce);
pci_iounmap(dev, card->buffers);
out_unmap_config:
pci_iounmap(dev, card->config_regs);
out_release_regions:
pci_release_regions(dev);
out:
kfree(card);
return err;
}