nfs: new subdir Documentation/filesystems/nfs
[safe/jmp/linux-2.6] / drivers / uio / uio_pci_generic.c
1 /* uio_pci_generic - generic UIO driver for PCI 2.3 devices
2  *
3  * Copyright (C) 2009 Red Hat, Inc.
4  * Author: Michael S. Tsirkin <mst@redhat.com>
5  *
6  * This work is licensed under the terms of the GNU GPL, version 2.
7  *
8  * Since the driver does not declare any device ids, you must allocate
9  * id and bind the device to the driver yourself.  For example:
10  *
11  * # echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
12  * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
13  * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
14  * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
15  * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
16  *
17  * Driver won't bind to devices which do not support the Interrupt Disable Bit
18  * in the command register. All devices compliant to PCI 2.3 (circa 2002) and
19  * all compliant PCI Express devices should support this bit.
20  */
21
22 #include <linux/device.h>
23 #include <linux/module.h>
24 #include <linux/pci.h>
25 #include <linux/uio_driver.h>
26 #include <linux/spinlock.h>
27
28 #define DRIVER_VERSION  "0.01.0"
29 #define DRIVER_AUTHOR   "Michael S. Tsirkin <mst@redhat.com>"
30 #define DRIVER_DESC     "Generic UIO driver for PCI 2.3 devices"
31
32 struct uio_pci_generic_dev {
33         struct uio_info info;
34         struct pci_dev *pdev;
35         spinlock_t lock; /* guards command register accesses */
36 };
37
38 static inline struct uio_pci_generic_dev *
39 to_uio_pci_generic_dev(struct uio_info *info)
40 {
41         return container_of(info, struct uio_pci_generic_dev, info);
42 }
43
44 /* Interrupt handler. Read/modify/write the command register to disable
45  * the interrupt. */
46 static irqreturn_t irqhandler(int irq, struct uio_info *info)
47 {
48         struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
49         struct pci_dev *pdev = gdev->pdev;
50         irqreturn_t ret = IRQ_NONE;
51         u32 cmd_status_dword;
52         u16 origcmd, newcmd, status;
53
54         /* We do a single dword read to retrieve both command and status.
55          * Document assumptions that make this possible. */
56         BUILD_BUG_ON(PCI_COMMAND % 4);
57         BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
58
59         spin_lock_irq(&gdev->lock);
60         pci_block_user_cfg_access(pdev);
61
62         /* Read both command and status registers in a single 32-bit operation.
63          * Note: we could cache the value for command and move the status read
64          * out of the lock if there was a way to get notified of user changes
65          * to command register through sysfs. Should be good for shared irqs. */
66         pci_read_config_dword(pdev, PCI_COMMAND, &cmd_status_dword);
67         origcmd = cmd_status_dword;
68         status = cmd_status_dword >> 16;
69
70         /* Check interrupt status register to see whether our device
71          * triggered the interrupt. */
72         if (!(status & PCI_STATUS_INTERRUPT))
73                 goto done;
74
75         /* We triggered the interrupt, disable it. */
76         newcmd = origcmd | PCI_COMMAND_INTX_DISABLE;
77         if (newcmd != origcmd)
78                 pci_write_config_word(pdev, PCI_COMMAND, newcmd);
79
80         /* UIO core will signal the user process. */
81         ret = IRQ_HANDLED;
82 done:
83
84         pci_unblock_user_cfg_access(pdev);
85         spin_unlock_irq(&gdev->lock);
86         return ret;
87 }
88
89 /* Verify that the device supports Interrupt Disable bit in command register,
90  * per PCI 2.3, by flipping this bit and reading it back: this bit was readonly
91  * in PCI 2.2. */
92 static int __devinit verify_pci_2_3(struct pci_dev *pdev)
93 {
94         u16 orig, new;
95         int err = 0;
96
97         pci_block_user_cfg_access(pdev);
98         pci_read_config_word(pdev, PCI_COMMAND, &orig);
99         pci_write_config_word(pdev, PCI_COMMAND,
100                               orig ^ PCI_COMMAND_INTX_DISABLE);
101         pci_read_config_word(pdev, PCI_COMMAND, &new);
102         /* There's no way to protect against
103          * hardware bugs or detect them reliably, but as long as we know
104          * what the value should be, let's go ahead and check it. */
105         if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
106                 err = -EBUSY;
107                 dev_err(&pdev->dev, "Command changed from 0x%x to 0x%x: "
108                         "driver or HW bug?\n", orig, new);
109                 goto err;
110         }
111         if (!((new ^ orig) & PCI_COMMAND_INTX_DISABLE)) {
112                 dev_warn(&pdev->dev, "Device does not support "
113                          "disabling interrupts: unable to bind.\n");
114                 err = -ENODEV;
115                 goto err;
116         }
117         /* Now restore the original value. */
118         pci_write_config_word(pdev, PCI_COMMAND, orig);
119 err:
120         pci_unblock_user_cfg_access(pdev);
121         return err;
122 }
123
124 static int __devinit probe(struct pci_dev *pdev,
125                            const struct pci_device_id *id)
126 {
127         struct uio_pci_generic_dev *gdev;
128         int err;
129
130         if (!pdev->irq) {
131                 dev_warn(&pdev->dev, "No IRQ assigned to device: "
132                          "no support for interrupts?\n");
133                 return -ENODEV;
134         }
135
136         err = pci_enable_device(pdev);
137         if (err) {
138                 dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
139                         __func__, err);
140                 return err;
141         }
142
143         err = verify_pci_2_3(pdev);
144         if (err)
145                 goto err_verify;
146
147         gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
148         if (!gdev) {
149                 err = -ENOMEM;
150                 goto err_alloc;
151         }
152
153         gdev->info.name = "uio_pci_generic";
154         gdev->info.version = DRIVER_VERSION;
155         gdev->info.irq = pdev->irq;
156         gdev->info.irq_flags = IRQF_SHARED;
157         gdev->info.handler = irqhandler;
158         gdev->pdev = pdev;
159         spin_lock_init(&gdev->lock);
160
161         if (uio_register_device(&pdev->dev, &gdev->info))
162                 goto err_register;
163         pci_set_drvdata(pdev, gdev);
164
165         return 0;
166 err_register:
167         kfree(gdev);
168 err_alloc:
169 err_verify:
170         pci_disable_device(pdev);
171         return err;
172 }
173
174 static void remove(struct pci_dev *pdev)
175 {
176         struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
177
178         uio_unregister_device(&gdev->info);
179         pci_disable_device(pdev);
180         kfree(gdev);
181 }
182
183 static struct pci_driver driver = {
184         .name = "uio_pci_generic",
185         .id_table = NULL, /* only dynamic id's */
186         .probe = probe,
187         .remove = remove,
188 };
189
190 static int __init init(void)
191 {
192         pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
193         return pci_register_driver(&driver);
194 }
195
196 static void __exit cleanup(void)
197 {
198         pci_unregister_driver(&driver);
199 }
200
201 module_init(init);
202 module_exit(cleanup);
203
204 MODULE_VERSION(DRIVER_VERSION);
205 MODULE_LICENSE("GPL v2");
206 MODULE_AUTHOR(DRIVER_AUTHOR);
207 MODULE_DESCRIPTION(DRIVER_DESC);