aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-05-23 16:57:58 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-23 23:14:14 -0400
commitc15395c0dbdd646ca80945a7578c8c6cd44ce942 (patch)
tree6a1d0df3fb9ccd16f286daca6fcd1f4787a54a7c
parent14441960e8c27a64487e0b455b323e784f33583f (diff)
phantom: move to unlocked_ioctl
phantom's ioctl is often (4000 times a sec or so) invoked, don't acquire BKL and block other processes. Signed-off-by: Jiri Slaby <xslaby@phantom.fi.muni.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/misc/phantom.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index 35b139b0e5f2..4b5959b2c934 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -47,6 +47,7 @@ struct phantom_device {
47 struct cdev cdev; 47 struct cdev cdev;
48 48
49 struct mutex open_lock; 49 struct mutex open_lock;
50 spinlock_t ioctl_lock;
50}; 51};
51 52
52static unsigned char phantom_devices[PHANTOM_MAX_MINORS]; 53static unsigned char phantom_devices[PHANTOM_MAX_MINORS];
@@ -71,8 +72,8 @@ static int phantom_status(struct phantom_device *dev, unsigned long newstat)
71 * File ops 72 * File ops
72 */ 73 */
73 74
74static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd, 75static long phantom_ioctl(struct file *file, unsigned int cmd,
75 u_long arg) 76 unsigned long arg)
76{ 77{
77 struct phantom_device *dev = file->private_data; 78 struct phantom_device *dev = file->private_data;
78 struct phm_regs rs; 79 struct phm_regs rs;
@@ -92,24 +93,30 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
92 if (r.reg > 7) 93 if (r.reg > 7)
93 return -EINVAL; 94 return -EINVAL;
94 95
96 spin_lock(&dev->ioctl_lock);
95 if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) && 97 if (r.reg == PHN_CONTROL && (r.value & PHN_CTL_IRQ) &&
96 phantom_status(dev, dev->status | PHB_RUNNING)) 98 phantom_status(dev, dev->status | PHB_RUNNING)){
99 spin_unlock(&dev->ioctl_lock);
97 return -ENODEV; 100 return -ENODEV;
101 }
98 102
99 pr_debug("phantom: writing %x to %u\n", r.value, r.reg); 103 pr_debug("phantom: writing %x to %u\n", r.value, r.reg);
100 iowrite32(r.value, dev->iaddr + r.reg); 104 iowrite32(r.value, dev->iaddr + r.reg);
101 105
102 if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ)) 106 if (r.reg == PHN_CONTROL && !(r.value & PHN_CTL_IRQ))
103 phantom_status(dev, dev->status & ~PHB_RUNNING); 107 phantom_status(dev, dev->status & ~PHB_RUNNING);
108 spin_unlock(&dev->ioctl_lock);
104 break; 109 break;
105 case PHN_SET_REGS: 110 case PHN_SET_REGS:
106 if (copy_from_user(&rs, argp, sizeof(rs))) 111 if (copy_from_user(&rs, argp, sizeof(rs)))
107 return -EFAULT; 112 return -EFAULT;
108 113
109 pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask); 114 pr_debug("phantom: SRS %u regs %x\n", rs.count, rs.mask);
115 spin_lock(&dev->ioctl_lock);
110 for (i = 0; i < min(rs.count, 8U); i++) 116 for (i = 0; i < min(rs.count, 8U); i++)
111 if ((1 << i) & rs.mask) 117 if ((1 << i) & rs.mask)
112 iowrite32(rs.values[i], dev->oaddr + i); 118 iowrite32(rs.values[i], dev->oaddr + i);
119 spin_unlock(&dev->ioctl_lock);
113 break; 120 break;
114 case PHN_GET_REG: 121 case PHN_GET_REG:
115 if (copy_from_user(&r, argp, sizeof(r))) 122 if (copy_from_user(&r, argp, sizeof(r)))
@@ -128,9 +135,11 @@ static int phantom_ioctl(struct inode *inode, struct file *file, u_int cmd,
128 return -EFAULT; 135 return -EFAULT;
129 136
130 pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask); 137 pr_debug("phantom: GRS %u regs %x\n", rs.count, rs.mask);
138 spin_lock(&dev->ioctl_lock);
131 for (i = 0; i < min(rs.count, 8U); i++) 139 for (i = 0; i < min(rs.count, 8U); i++)
132 if ((1 << i) & rs.mask) 140 if ((1 << i) & rs.mask)
133 rs.values[i] = ioread32(dev->iaddr + i); 141 rs.values[i] = ioread32(dev->iaddr + i);
142 spin_unlock(&dev->ioctl_lock);
134 143
135 if (copy_to_user(argp, &rs, sizeof(rs))) 144 if (copy_to_user(argp, &rs, sizeof(rs)))
136 return -EFAULT; 145 return -EFAULT;
@@ -199,7 +208,7 @@ static unsigned int phantom_poll(struct file *file, poll_table *wait)
199static struct file_operations phantom_file_ops = { 208static struct file_operations phantom_file_ops = {
200 .open = phantom_open, 209 .open = phantom_open,
201 .release = phantom_release, 210 .release = phantom_release,
202 .ioctl = phantom_ioctl, 211 .unlocked_ioctl = phantom_ioctl,
203 .poll = phantom_poll, 212 .poll = phantom_poll,
204}; 213};
205 214
@@ -282,6 +291,7 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
282 } 291 }
283 292
284 mutex_init(&pht->open_lock); 293 mutex_init(&pht->open_lock);
294 spin_lock_init(&pht->ioctl_lock);
285 init_waitqueue_head(&pht->wait); 295 init_waitqueue_head(&pht->wait);
286 cdev_init(&pht->cdev, &phantom_file_ops); 296 cdev_init(&pht->cdev, &phantom_file_ops);
287 pht->cdev.owner = THIS_MODULE; 297 pht->cdev.owner = THIS_MODULE;