0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/pci.h>
0012 #include <linux/slab.h>
0013 #include "xillybus.h"
0014
0015 MODULE_DESCRIPTION("Xillybus driver for PCIe");
0016 MODULE_AUTHOR("Eli Billauer, Xillybus Ltd.");
0017 MODULE_ALIAS("xillybus_pcie");
0018 MODULE_LICENSE("GPL v2");
0019
0020 #define PCI_DEVICE_ID_XILLYBUS 0xebeb
0021
0022 #define PCI_VENDOR_ID_ACTEL 0x11aa
0023 #define PCI_VENDOR_ID_LATTICE 0x1204
0024
0025 static const char xillyname[] = "xillybus_pcie";
0026
0027 static const struct pci_device_id xillyids[] = {
0028 {PCI_DEVICE(PCI_VENDOR_ID_XILINX, PCI_DEVICE_ID_XILLYBUS)},
0029 {PCI_DEVICE(PCI_VENDOR_ID_ALTERA, PCI_DEVICE_ID_XILLYBUS)},
0030 {PCI_DEVICE(PCI_VENDOR_ID_ACTEL, PCI_DEVICE_ID_XILLYBUS)},
0031 {PCI_DEVICE(PCI_VENDOR_ID_LATTICE, PCI_DEVICE_ID_XILLYBUS)},
0032 { }
0033 };
0034
0035 static int xilly_probe(struct pci_dev *pdev,
0036 const struct pci_device_id *ent)
0037 {
0038 struct xilly_endpoint *endpoint;
0039 int rc;
0040
0041 endpoint = xillybus_init_endpoint(&pdev->dev);
0042
0043 if (!endpoint)
0044 return -ENOMEM;
0045
0046 pci_set_drvdata(pdev, endpoint);
0047
0048 endpoint->owner = THIS_MODULE;
0049
0050 rc = pcim_enable_device(pdev);
0051 if (rc) {
0052 dev_err(endpoint->dev,
0053 "pcim_enable_device() failed. Aborting.\n");
0054 return rc;
0055 }
0056
0057
0058
0059 pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S);
0060
0061 if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM)) {
0062 dev_err(endpoint->dev,
0063 "Incorrect BAR configuration. Aborting.\n");
0064 return -ENODEV;
0065 }
0066
0067 rc = pcim_iomap_regions(pdev, 0x01, xillyname);
0068 if (rc) {
0069 dev_err(endpoint->dev,
0070 "pcim_iomap_regions() failed. Aborting.\n");
0071 return rc;
0072 }
0073
0074 endpoint->registers = pcim_iomap_table(pdev)[0];
0075
0076 pci_set_master(pdev);
0077
0078
0079 if (pci_enable_msi(pdev)) {
0080 dev_err(endpoint->dev,
0081 "Failed to enable MSI interrupts. Aborting.\n");
0082 return -ENODEV;
0083 }
0084 rc = devm_request_irq(&pdev->dev, pdev->irq, xillybus_isr, 0,
0085 xillyname, endpoint);
0086 if (rc) {
0087 dev_err(endpoint->dev,
0088 "Failed to register MSI handler. Aborting.\n");
0089 return -ENODEV;
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099 if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
0100 endpoint->dma_using_dac = 0;
0101 } else if (!dma_set_mask(&pdev->dev, DMA_BIT_MASK(64))) {
0102 endpoint->dma_using_dac = 1;
0103 } else {
0104 dev_err(endpoint->dev, "Failed to set DMA mask. Aborting.\n");
0105 return -ENODEV;
0106 }
0107
0108 return xillybus_endpoint_discovery(endpoint);
0109 }
0110
0111 static void xilly_remove(struct pci_dev *pdev)
0112 {
0113 struct xilly_endpoint *endpoint = pci_get_drvdata(pdev);
0114
0115 xillybus_endpoint_remove(endpoint);
0116 }
0117
0118 MODULE_DEVICE_TABLE(pci, xillyids);
0119
0120 static struct pci_driver xillybus_driver = {
0121 .name = xillyname,
0122 .id_table = xillyids,
0123 .probe = xilly_probe,
0124 .remove = xilly_remove,
0125 };
0126
0127 module_pci_driver(xillybus_driver);