diff options
Diffstat (limited to 'drivers/bluetooth')
-rw-r--r-- | drivers/bluetooth/hci_vhci.c | 43 |
1 files changed, 15 insertions, 28 deletions
diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c index 379d3025cf33..0f5e04934cec 100644 --- a/drivers/bluetooth/hci_vhci.c +++ b/drivers/bluetooth/hci_vhci.c | |||
@@ -179,41 +179,31 @@ static inline ssize_t vhci_put_user(struct vhci_data *data, | |||
179 | static ssize_t vhci_read(struct file *file, | 179 | static ssize_t vhci_read(struct file *file, |
180 | char __user *buf, size_t count, loff_t *pos) | 180 | char __user *buf, size_t count, loff_t *pos) |
181 | { | 181 | { |
182 | DECLARE_WAITQUEUE(wait, current); | ||
183 | struct vhci_data *data = file->private_data; | 182 | struct vhci_data *data = file->private_data; |
184 | struct sk_buff *skb; | 183 | struct sk_buff *skb; |
185 | ssize_t ret = 0; | 184 | ssize_t ret = 0; |
186 | 185 | ||
187 | add_wait_queue(&data->read_wait, &wait); | ||
188 | while (count) { | 186 | while (count) { |
189 | set_current_state(TASK_INTERRUPTIBLE); | ||
190 | |||
191 | skb = skb_dequeue(&data->readq); | 187 | skb = skb_dequeue(&data->readq); |
192 | if (!skb) { | 188 | if (skb) { |
193 | if (file->f_flags & O_NONBLOCK) { | 189 | ret = vhci_put_user(data, skb, buf, count); |
194 | ret = -EAGAIN; | 190 | if (ret < 0) |
195 | break; | 191 | skb_queue_head(&data->readq, skb); |
196 | } | 192 | else |
197 | 193 | kfree_skb(skb); | |
198 | if (signal_pending(current)) { | 194 | break; |
199 | ret = -ERESTARTSYS; | ||
200 | break; | ||
201 | } | ||
202 | |||
203 | schedule(); | ||
204 | continue; | ||
205 | } | 195 | } |
206 | 196 | ||
207 | if (access_ok(VERIFY_WRITE, buf, count)) | 197 | if (file->f_flags & O_NONBLOCK) { |
208 | ret = vhci_put_user(data, skb, buf, count); | 198 | ret = -EAGAIN; |
209 | else | 199 | break; |
210 | ret = -EFAULT; | 200 | } |
211 | 201 | ||
212 | kfree_skb(skb); | 202 | ret = wait_event_interruptible(data->read_wait, |
213 | break; | 203 | !skb_queue_empty(&data->readq)); |
204 | if (ret < 0) | ||
205 | break; | ||
214 | } | 206 | } |
215 | set_current_state(TASK_RUNNING); | ||
216 | remove_wait_queue(&data->read_wait, &wait); | ||
217 | 207 | ||
218 | return ret; | 208 | return ret; |
219 | } | 209 | } |
@@ -223,9 +213,6 @@ static ssize_t vhci_write(struct file *file, | |||
223 | { | 213 | { |
224 | struct vhci_data *data = file->private_data; | 214 | struct vhci_data *data = file->private_data; |
225 | 215 | ||
226 | if (!access_ok(VERIFY_READ, buf, count)) | ||
227 | return -EFAULT; | ||
228 | |||
229 | return vhci_get_user(data, buf, count); | 216 | return vhci_get_user(data, buf, count); |
230 | } | 217 | } |
231 | 218 | ||